diff -Nru a/CREDITS b/CREDITS
--- a/CREDITS	Wed Mar  5 07:11:17 2003
+++ b/CREDITS	Tue Mar 18 08:47:34 2003
@@ -1840,10 +1840,10 @@
 S: Germany
 
 N: Achim Leubner
-E: achim@vortex.de
-D: GDT SCSI Disk Array Controller driver
-S: ICP vortex Computersysteme GmbH
-S: Flein
+E: achim.leubner@intel.com
+D: GDT Disk Array Controller/Storage RAID controller driver
+S: ICP vortex GmbH, an Intel company
+S: Neckarsulm
 S: Germany
 
 N: Phil Lewis
diff -Nru a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
--- a/Documentation/DocBook/kernel-api.tmpl	Fri Feb 28 03:48:28 2003
+++ b/Documentation/DocBook/kernel-api.tmpl	Sat Mar  1 05:50:59 2003
@@ -89,7 +89,11 @@
      <title>Memory Management in Linux</title>
      <sect1><title>The Slab Cache</title>
 !Emm/slab.c
-      </sect1>
+     </sect1>
+     <sect1><title>User Space Memory Access</title>
+!Iinclude/asm-i386/uaccess.h
+!Iarch/i386/lib/usercopy.c
+     </sect1>
   </chapter>
 
   <chapter id="proc">
diff -Nru a/Documentation/DocBook/kernel-hacking.tmpl b/Documentation/DocBook/kernel-hacking.tmpl
--- a/Documentation/DocBook/kernel-hacking.tmpl	Wed Feb 19 12:24:42 2003
+++ b/Documentation/DocBook/kernel-hacking.tmpl	Sat Mar 22 22:14:58 2003
@@ -319,7 +319,7 @@
   </para>
 
   <programlisting>
-asmlinkage int sys_mycall(int arg) 
+asmlinkage long sys_mycall(int arg)
 {
         return 0; 
 }
diff -Nru a/Documentation/fb/cirrusfb.txt b/Documentation/fb/cirrusfb.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/fb/cirrusfb.txt	Tue Mar  4 05:34:41 2003
@@ -0,0 +1,97 @@
+
+		Framebuffer driver for Cirrus Logic chipsets
+		Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
+
+
+
+{ just a little something to get people going; contributors welcome! }
+
+
+
+Chip families supported:
+	SD64
+	Piccolo
+	Picasso
+	Spectrum
+	Alpine (GD-543x/4x)
+	Picasso4 (GD-5446)
+	GD-5480
+	Laguna (GD-546x)
+
+Bus's supported:
+	PCI
+	Zorro
+
+Architectures supported:
+	i386
+	Alpha
+	PPC (Motorola Powerstack)
+	m68k (Amiga)
+
+
+
+Default video modes
+-------------------
+At the moment, there are two kernel command line arguments supported:
+
+mode:640x480
+mode:800x600
+	or
+mode:1024x768
+
+Full support for startup video modes (modedb) will be integrated soon.
+
+Version 1.9.9.1
+---------------
+* Fix memory detection for 512kB case
+* 800x600 mode
+* Fixed timings
+* Hint for AXP: Use -accel false -vyres -1 when changing resolution
+
+
+Version 1.9.4.4
+---------------
+* Preliminary Laguna support
+* Overhaul color register routines.
+* Associated with the above, console colors are now obtained from a LUT
+  called 'palette' instead of from the VGA registers.  This code was
+  modeled after that in atyfb and matroxfb.
+* Code cleanup, add comments.
+* Overhaul SR07 handling.
+* Bug fixes.
+
+
+Version 1.9.4.3
+---------------
+* Correctly set default startup video mode.
+* Do not override ram size setting.  Define
+  CLGEN_USE_HARDCODED_RAM_SETTINGS if you _do_ want to override the RAM
+  setting.
+* Compile fixes related to new 2.3.x IORESOURCE_IO[PORT] symbol changes.
+* Use new 2.3.x resource allocation.
+* Some code cleanup.
+
+
+Version 1.9.4.2
+---------------
+* Casting fixes.
+* Assertions no longer cause an oops on purpose.
+* Bug fixes.
+
+
+Version 1.9.4.1
+---------------
+* Add compatibility support.  Now requires a 2.1.x, 2.2.x or 2.3.x kernel.
+
+
+Version 1.9.4
+-------------
+* Several enhancements, smaller memory footprint, a few bugfixes.
+* Requires kernel 2.3.14-pre1 or later.
+
+
+Version 1.9.3
+-------------
+* Bundled with kernel 2.3.14-pre1 or later.
+
+
diff -Nru a/Documentation/fb/clgenfb.txt b/Documentation/fb/clgenfb.txt
--- a/Documentation/fb/clgenfb.txt	Mon Oct 28 21:14:41 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,97 +0,0 @@
-
-		Framebuffer driver for Cirrus Logic chipsets
-		Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
-
-
-
-{ just a little something to get people going; contributors welcome! }
-
-
-
-Chip families supported:
-	SD64
-	Piccolo
-	Picasso
-	Spectrum
-	Alpine (GD-543x/4x)
-	Picasso4 (GD-5446)
-	GD-5480
-	Laguna (GD-546x)
-
-Bus's supported:
-	PCI
-	Zorro
-
-Architectures supported:
-	i386
-	Alpha
-	PPC (Motorola Powerstack)
-	m68k (Amiga)
-
-
-
-Default video modes
--------------------
-At the moment, there are two kernel command line arguments supported:
-
-mode:640x480
-mode:800x600
-	or
-mode:1024x768
-
-Full support for startup video modes (modedb) will be integrated soon.
-
-Version 1.9.9.1
----------------
-* Fix memory detection for 512kB case
-* 800x600 mode
-* Fixed timings
-* Hint for AXP: Use -accel false -vyres -1 when changing resolution
-
-
-Version 1.9.4.4
----------------
-* Preliminary Laguna support
-* Overhaul color register routines.
-* Associated with the above, console colors are now obtained from a LUT
-  called 'palette' instead of from the VGA registers.  This code was
-  modeled after that in atyfb and matroxfb.
-* Code cleanup, add comments.
-* Overhaul SR07 handling.
-* Bug fixes.
-
-
-Version 1.9.4.3
----------------
-* Correctly set default startup video mode.
-* Do not override ram size setting.  Define
-  CLGEN_USE_HARDCODED_RAM_SETTINGS if you _do_ want to override the RAM
-  setting.
-* Compile fixes related to new 2.3.x IORESOURCE_IO[PORT] symbol changes.
-* Use new 2.3.x resource allocation.
-* Some code cleanup.
-
-
-Version 1.9.4.2
----------------
-* Casting fixes.
-* Assertions no longer cause an oops on purpose.
-* Bug fixes.
-
-
-Version 1.9.4.1
----------------
-* Add compatibility support.  Now requires a 2.1.x, 2.2.x or 2.3.x kernel.
-
-
-Version 1.9.4
--------------
-* Several enhancements, smaller memory footprint, a few bugfixes.
-* Requires kernel 2.3.14-pre1 or later.
-
-
-Version 1.9.3
--------------
-* Bundled with kernel 2.3.14-pre1 or later.
-
-
diff -Nru a/Documentation/fb/matroxfb.txt b/Documentation/fb/matroxfb.txt
--- a/Documentation/fb/matroxfb.txt	Sat Feb  2 14:08:43 2002
+++ b/Documentation/fb/matroxfb.txt	Mon Mar 10 10:17:50 2003
@@ -22,11 +22,11 @@
 How to use it?
 ==============
 
-Switching modes is done using the video=matrox:vesa:... boot parameter
+Switching modes is done using the video=matroxfb:vesa:... boot parameter
 or using `fbset' program.
 
 If you want, for example, enable a resolution of 1280x1024x24bpp you should
-pass to the kernel this command line: "video=matrox:vesa:0x1BB".
+pass to the kernel this command line: "video=matroxfb:vesa:0x1BB".
 
 You should compile in both vgacon (to boot if you remove you Matrox from
 box) and matroxfb (for graphics mode). You should not compile-in vesafb
@@ -73,7 +73,7 @@
 with your old number passed to vesafb.
 
 Non-listed number can be achieved by more complicated command-line, for
-example 1600x1200x32bpp can be specified by `video=matrox:vesa:0x11C,depth:32'.
+example 1600x1200x32bpp can be specified by `video=matroxfb:vesa:0x11C,depth:32'.
 
 
 X11
@@ -106,7 +106,7 @@
 =============
 
 You can pass kernel command line options to matroxfb with
-`video=matrox:option1,option2:value2,option3' (multiple options should be 
+`video=matroxfb:option1,option2:value2,option3' (multiple options should be 
 separated by comma, values are separated from options by `:'). 
 Accepted options:
 
@@ -116,7 +116,7 @@
 	   memory usable for on-screen display (i.e. max. 8 MB).
 disabled - do not load driver; you can use also `off', but `disabled'
            is here too.
-enabled  - load driver, if you have `video=matrox:disabled' in LILO
+enabled  - load driver, if you have `video=matroxfb:disabled' in LILO
            configuration, you can override it by this (you cannot override
 	   `off'). It is default.
 noaccel  - do not use acceleration engine. It does not work on Alphas.
@@ -380,7 +380,7 @@
    XFree when secondary head used to use acceleration.
  + secondary head always powerups in 640x480@60-32 videomode. You have to use
    fbset to change this mode.
- + secondary head always powerups in monitor mode. You have to use matroxset
+ + secondary head always powerups in monitor mode. You have to use fbmatroxset
    to change it to TV mode. Also, you must select at least 525 lines for
    NTSC output and 625 lines for PAL output.
  + kernel is not fully multihead ready. So some things are impossible to do.
diff -Nru a/Documentation/fb/pvr2fb.txt b/Documentation/fb/pvr2fb.txt
--- a/Documentation/fb/pvr2fb.txt	Tue Feb  5 11:11:20 2002
+++ b/Documentation/fb/pvr2fb.txt	Mon Mar 10 10:17:50 2003
@@ -22,7 +22,7 @@
 =============
 
 You can pass kernel command line options to pvr2fb with
-`video=pvr2:option1,option2:value2,option3' (multiple options should be
+`video=pvr2fb:option1,option2:value2,option3' (multiple options should be
 separated by comma, values are separated from options by `:').
 Accepted options:
 
diff -Nru a/Documentation/fb/sa1100fb.txt b/Documentation/fb/sa1100fb.txt
--- a/Documentation/fb/sa1100fb.txt	Tue Feb  5 09:40:37 2002
+++ b/Documentation/fb/sa1100fb.txt	Mon Mar 10 10:17:50 2003
@@ -11,7 +11,7 @@
 
 For most common passive displays, giving the option
 
-video=sa1100:bpp:<value>,lccr0:<value>,lccr1:<value>,lccr2:<value>,lccr3:<value>
+video=sa1100fb:bpp:<value>,lccr0:<value>,lccr1:<value>,lccr2:<value>,lccr3:<value>
 
 on the kernel command line should be enough to configure the
 controller. The bits per pixel (bpp) value should be 4, 8, 12, or
diff -Nru a/Documentation/fb/tgafb.txt b/Documentation/fb/tgafb.txt
--- a/Documentation/fb/tgafb.txt	Tue Feb  5 09:40:37 2002
+++ b/Documentation/fb/tgafb.txt	Mon Mar 10 10:17:50 2003
@@ -36,7 +36,7 @@
 =============
 
 You can pass kernel command line options to tgafb with
-`video=tga:option1,option2:value2,option3' (multiple options should be
+`video=tgafb:option1,option2:value2,option3' (multiple options should be
 separated by comma, values are separated from options by `:').
 Accepted options:
 
diff -Nru a/Documentation/fb/vesafb.txt b/Documentation/fb/vesafb.txt
--- a/Documentation/fb/vesafb.txt	Tue Feb  5 09:40:37 2002
+++ b/Documentation/fb/vesafb.txt	Mon Mar 10 10:17:50 2003
@@ -112,9 +112,9 @@
 seems not to work with some BIOS versions, but there are options
 to turn it on.
 
-You can pass options to vesafb using "video=vesa:option" on
+You can pass options to vesafb using "video=vesafb:option" on
 the kernel command line.  Multiple options should be separated
-by comma, like this: "video=vesa:ypan,invers"
+by comma, like this: "video=vesafb:ypan,invers"
 
 Accepted options:
 
diff -Nru a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt
--- a/Documentation/filesystems/sysfs.txt	Tue Mar 11 10:20:18 2003
+++ b/Documentation/filesystems/sysfs.txt	Tue Mar 18 10:09:49 2003
@@ -60,7 +60,7 @@
 you publically humiliated and your code rewritten without notice. 
 
 
-An attriubte definition is simply:
+An attribute definition is simply:
 
 struct attribute {
         char                    * name;
@@ -261,7 +261,7 @@
 that point to the device's directory under root/.
 
 drivers/ contains a directory for each device driver that is loaded
-for devices on that particular bus (this assmumes that drivers do not
+for devices on that particular bus (this assumes that drivers do not
 span multiple bus types).
 
 
diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt	Sun Mar 16 22:33:11 2003
+++ b/Documentation/kernel-parameters.txt	Tue Mar 18 08:49:00 2003
@@ -713,7 +713,6 @@
 					numbers ourselves, overriding
 					whatever the firmware may have
 					done.
-
 		usepirqmask		[IA-32] Honor the possible IRQ mask
 					stored in the BIOS $PIR table. This is
 					needed on some systems with broken
@@ -721,6 +720,7 @@
 					and Omnibook XE3 notebooks. This will
 					have no effect if ACPI IRQ routing is
 					enabled.
+		noacpi			[IA-32] Do not use ACPI for IRQ routing.
 
 	pcmv=		[HW,PCMCIA] BadgePAD 4
 
diff -Nru a/Documentation/networking/e100.txt b/Documentation/networking/e100.txt
--- a/Documentation/networking/e100.txt	Fri Oct 18 14:45:07 2002
+++ b/Documentation/networking/e100.txt	Sun Mar 16 20:38:55 2003
@@ -1,7 +1,7 @@
 Linux* Base Driver for the Intel(R) PRO/100 Family of Adapters
 ==============================================================
 
-September 16, 2002
+November 19, 2002
 
 
 Contents
@@ -19,7 +19,7 @@
 ===============
 
 This file describes the Linux* Base Driver for the Intel(R) PRO/100 Family of
-Adapters, version 2.1.x.  This driver includes support for Itanium(TM)-based 
+Adapters, version 2.2.x.  This driver includes support for Itanium(TM)-based 
 systems.
 
 
@@ -94,8 +94,9 @@
 Command Line Parameters
 =======================
 
-The following optional parameters are used by entering them on the command 
-line with the modprobe or insmod command using this syntax:
+If the driver is built as a module, the  following optional parameters are 
+used by entering them on the command line with the modprobe or insmod command
+using this syntax:
 
      modprobe e100 [<option>=<VAL1>,<VAL2>,...]
 
diff -Nru a/Documentation/networking/e1000.txt b/Documentation/networking/e1000.txt
--- a/Documentation/networking/e1000.txt	Fri Oct 18 15:07:51 2002
+++ b/Documentation/networking/e1000.txt	Mon Mar 17 12:36:33 2003
@@ -1,7 +1,7 @@
 Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
 ===============================================================
 
-October 12, 2002
+January 8, 2003
 
 
 Contents
@@ -20,33 +20,17 @@
 ===============
 
 This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family
-of Adapters, version 4.4.x.  This driver includes support for 
+of Adapters, version 5.0.x.  This driver includes support for 
 Itanium(TM)-based systems.
 
-This release version includes the following:
-
-   - Support for the ethtool 1.6 interface. A third-party application can use
-     the ethtool interface to get and set driver parameters.
-
-   - Zero copy. This feature provides faster data throughput. Enabled by
-     default in supporting kernels. It is not supported on the Intel(R)
-     PRO/1000 Gigabit Server Adapter.
-
-Features include:
-
-   - Support for the 82545 and 82546-based adapters listed below
-
-   - Wake on LAN* support via ethtool for 82540, 82544, 82545, and 82546-
-     based adapters
-
-   - Adaptive IFS for increased performance at half duplex
 
+Native VLANs are now available with supported kernels.
 
 
 Supported Adapters
 ==================
 
-The following Intel network adapters are compatible with the drivers in this
+The following Intel network adapters are compatible with the drivers in this 
 release:
 
    Controller  Adapter Name                         Board IDs
@@ -65,6 +49,7 @@
    82544       PRO/1000 T Desktop Adapter           A62947-xxx
 
    82540       PRO/1000 MT Desktop Adapter          A78408-xxx
+   82541                                            C91016-xxx
 
    82545       PRO/1000 MT Server Adapter           A92165-xxx
 
@@ -77,33 +62,42 @@
    82546       PRO/1000 MF Dual Port Server Adapter A91620-xxx
 
 
-To verify your Intel adapter is supported, find the board ID number on the
-adapter. Look for a label that has a barcode and a number in the format of
-123456-001 (six digits hyphen three digits). Match this to the list of
-numbers above.
 
-For more information on how to identify your adapter, go to the Adapter &
+To verify your Intel adapter is supported, find the board ID number on the 
+adapter. Look for a label that has a barcode and a number in the format  
+A12345-001. Match this to the list of numbers above.
+
+For more information on how to identify your adapter, go to the Adapter & 
 Driver ID Guide at:
 
     http://support.intel.com/support/network/adapter/pro100/21397.htm
 
-For the latest Intel network drivers for Linux, go to:
+For the latest Intel network drivers for Linux, refer to the following
 
-    http://appsr.intel.com/scripts-df/support_intel.asp
+    http://downloadfinder.intel.com/scripts-df/support_intel.asp
 
 
 Command Line Parameters
 =======================
 
-If the driver is built as a module, the following optional parameters are 
-used by entering them on the command line with the modprobe or insmod command. 
+If the driver is built as a module, the  following optional parameters are 
+used by entering them on the command line with the modprobe or insmod command
+using this syntax:
+
+     modprobe e1000 [<option>=<VAL1>,<VAL2>,...]
+
+     insmod e1000 [<option>=<VAL1>,<VAL2>,...] 
+
 For example, with two PRO/1000 PCI adapters, entering:
 
-    insmod e1000 TxDescriptors=80,128
+     insmod e1000 TxDescriptors=80,128
 
-loads the e1000 driver with 80 TX resources for the first adapter and 128 TX
+loads the e1000 driver with 80 TX resources for the first adapter and 128 TX 
 resources for the second adapter.
 
+The default value for each parameter is generally the recommended setting,
+unless otherwise noted.
+
 For more information about the AutoNeg, Duplex, and Speed parameters, see the
 "Speed and Duplex Configuration" section in this document.
 
@@ -129,6 +123,20 @@
     This parameter controls the automatic generation(Tx) and response(Rx) to 
     Ethernet PAUSE frames.
 
+InterruptThrottleRate
+Valid Range: 100-100000 (0=off, 1=dynamic)
+Default Value: 1
+    This value represents the maximum number of interrupts per second the 
+    controller generates. InterruptThrottleRate is another setting used in 
+    interrupt moderation. Dynamic mode uses a heuristic algorithm to adjust 
+    InterruptThrottleRate based on the current traffic load.
+
+    NOTE: InterruptThrottleRate takes precedence over the TxAbsIntDelay and 
+          RxAbsIntDelay parameters. In other words, minimizing the receive 
+          and/or transmit absolute delays does not force the controller to 
+          generate more interrupts than what the Interrupt Throttle Rate 
+          allows.
+
 RxDescriptors
 Valid Range: 80-256 for 82542 and 82543-based adapters
              80-4096 for 82540, 82544, 82545, and 82546-based adapters
@@ -154,9 +162,9 @@
     descriptors.
 
     CAUTION: When setting RxIntDelay to a value other than 0, adapters may 
-             hang (stop transmitting) under certain network conditions. If
+             hang (stop transmitting) under certain network conditions. If 
              this occurs a NETDEV WATCHDOG message is logged in the system
-             event log. In addition, the controller is automatically reset,
+             event log. In addition, the controller is automatically reset, 
              restoring the network connection. To eliminate the potential for
              the hang ensure that RxIntDelay is set to 0.
 
@@ -176,7 +184,7 @@
     Speed forces the line speed to the specified value in megabits per second
     (Mbps). If this parameter is not specified or is set to 0 and the link 
     partner is set to auto-negotiate, the board will auto-detect the correct 
-    speed. Duplex must also be set when Speed is set to either 10 or 100.
+    speed. Duplex should also be set when Speed is set to either 10 or 100.
 
 TxDescriptors
 Valid Range: 80-256 for 82542 and 82543-based adapters
@@ -190,7 +198,7 @@
 Valid Range: 0-65535 (0=off)
 Default Value: 64
     This value delays the generation of transmit interrupts in units of 
-    1.024 microseconds.  Transmit interrupt reduction can improve CPU
+    1.024 microseconds. Transmit interrupt reduction can improve CPU
     efficiency if properly tuned for specific network traffic. If the
     system is reporting dropped transmits, this value may be set too high
     causing the driver to run out of available transmit descriptors.
@@ -205,7 +213,7 @@
     along with TxIntDelay, may improve traffic throughput in specific 
     network conditions.
 
-XsumRX (not available on the PRO/1000 Gigabit Server Adapter)
+XsumRX (not available on the 82542-based adapter)
 Valid Range: 0-1
 Default Value: 1
     A value of '1' indicates that the driver should enable IP checksum
@@ -215,10 +223,10 @@
 Speed and Duplex Configuration
 ==============================
 
-Three keywords are used to control the speed and duplex configuration. These
+Three keywords are used to control the speed and duplex configuration. These 
 keywords are Speed, Duplex, and AutoNeg.
 
-If the board uses a fiber interface, these keywords are ignored, and the
+If the board uses a fiber interface, these keywords are ignored, and the 
 fiber interface board only links at 1000 Mbps full-duplex.
 
 For copper-based boards, the keywords interact as follows:
@@ -230,23 +238,23 @@
   If Speed = 1000, limited auto-negotiation is enabled and only 1000 Mbps is
   advertised (The 1000BaseT spec requires auto-negotiation.)
 
-  If Speed = 10 or 100, then both Speed and Duplex must be set. Auto-
-  negotiation is disabled, and the AutoNeg parameter is ignored. Partner MUST
+  If Speed = 10 or 100, then both Speed and Duplex should be set. Auto-
+  negotiation is disabled, and the AutoNeg parameter is ignored. Partner SHOULD
   also be forced.
 
 The AutoNeg parameter is used when more control is required over the auto-
-negotiation process.  When this parameter is used, Speed and Duplex must not
-be specified.  This parameter is a bitmap that specifies which speed and
+negotiation process.  When this parameter is used, Speed and Duplex must not 
+be specified.  This parameter is a bitmap that specifies which speed and 
 duplex settings are advertised to the link partner.
 
 Bit            7      6      5       4       3      2      1       0
 Speed (Mbps)   N/A    N/A    1000    N/A     100    100    10      10
 Duplex                       Full            Full   Half   Full    Half
 
-Note that setting AutoNeg does not guarantee that the board will link at the
-highest specified speed or duplex mode, but the board will link at the
+Note that setting AutoNeg does not guarantee that the board will link at the 
+highest specified speed or duplex mode, but the board will link at the 
 highest possible speed/duplex of the link partner IF the link partner is also
-set to auto-negotiate. If the link partner is forced speed/duplex, the
+set to auto-negotiate. If the link partner is forced speed/duplex, the 
 adapter MUST be forced to the same speed/duplex.
 
 
@@ -256,13 +264,19 @@
   Jumbo Frames
   ------------
 
-  The driver supports Jumbo Frames for all adapters except 82542-based
-  adapters.  Jumbo Frames support is enabled by changing the MTU to a value
-  larger than the default of 1500.  Use the ifconfig command to increase the
+  The driver supports Jumbo Frames for all adapters except 82542-based 
+  adapters. Jumbo Frames support is enabled by changing the MTU to a value 
+  larger than the default of 1500. Use the ifconfig command to increase the 
   MTU size. For example:
 
         ifconfig ethx mtu 9000 up
 
+  The maximum MTU setting for Jumbo Frames is 16110. This value coincides 
+  with the maximum Jumbo Frames size of 16128.
+
+  NOTE: Jumbo Frames are supported at 1000 Mbps only. Using Jumbo Frames at 
+  10 or 100 Mbps may result in poor performance or loss of link.
+
 
 Known Issues
 ============
@@ -270,33 +284,33 @@
   Jumbo Frames System Requirement
   -------------------------------
 
-  Memory allocation failures have been observed on Linux systems with 64 MB
-  of RAM or less that are running Jumbo Frames. If you are using Jumbo
-  Frames, your system may require more than the advertised minimum
+  Memory allocation failures have been observed on Linux systems with 64 MB 
+  of RAM or less that are running Jumbo Frames. If you are using Jumbo 
+  Frames, your system may require more than the advertised minimum 
   requirement of 64 MB of system memory.
 
 
 Support
 =======
 
-For general information and support, go to the Intel support website at:
+For general information, go to the Intel support website at:
 
     http://support.intel.com
 
 If an issue is identified with the released source code on the supported
-kernel with a supported adapter, email the specific information related to
+kernel with a supported adapter, email the specific information related to 
 the issue to linux.nics@intel.com.
 
 
 License
 =======
 
-This software program is released under the terms of a license agreement
-between you ('Licensee') and Intel. Do not use or load this software or any
-associated materials (collectively, the 'Software') until you have carefully
-read the full terms and conditions of the LICENSE located in this software
-package. By loading or using the Software, you agree to the terms of this
-Agreement. If you do not agree with the terms of this Agreement, do not
+This software program is released under the terms of a license agreement 
+between you ('Licensee') and Intel. Do not use or load this software or any 
+associated materials (collectively, the 'Software') until you have carefully 
+read the full terms and conditions of the LICENSE located in this software 
+package. By loading or using the Software, you agree to the terms of this 
+Agreement. If you do not agree with the terms of this Agreement, do not 
 install or use the Software.
 
 * Other names and brands may be claimed as the property of others.
diff -Nru a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
--- a/Documentation/sound/alsa/ALSA-Configuration.txt	Tue Mar 11 10:20:18 2003
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt	Thu Mar 20 08:41:10 2003
@@ -520,13 +520,19 @@
 
     Module for Envy24 (ICE1712) based PCI soundcards.
 			* MidiMan M Audio Delta 1010
+			* MidiMan M Audio Delta 1010LT
 			* MidiMan M Audio Delta DiO 2496
 			* MidiMan M Audio Delta 66
 			* MidiMan M Audio Delta 44
+			* MidiMan M Audio Delta 410
 			* MidiMan M Audio Audiophile 2496
                         * TerraTec EWS 88MT
                         * TerraTec EWS 88D
                         * TerraTec EWX 24/96
+                        * TerraTec DMX 6Fire
+                        * Hoontech SoundTrack DSP 24
+                        * Hoontech SoundTrack DSP 24 Value
+                        * Hoontech SoundTrack DSP 24 Media 7.1
 
     omni	- Omni I/O support for MidiMan M-Audio Delta44/66
 
@@ -534,6 +540,15 @@
     is not used with all Envy24 based cards (for example in the MidiMan Delta
     serie).
 
+  Module snd-ice1724
+  ------------------
+
+    Module for Envy24HT (VT/ICE1724) based PCI soundcards.
+			* MidiMan M Audio Revolution 7.1
+			* AMP Ltd AUDIO2000
+
+    Module supports up to 8 cards and autoprobe.
+
   Module snd-intel8x0
   -------------------
 
@@ -659,7 +674,7 @@
     Module supports autoprobe and multiple chips (max 8).
     Note: on some notebooks the buffer address cannot be detected
     automatically, or causes hang-up during initialization.
-    In such a case, specify the buffer top address explicitly via
+    In such a case, specify the buffer top address explicity via
     buffer_top option.
     For example,
       Sony F250: buffer_top=0x25a800
@@ -966,6 +981,19 @@
     Module supports autoprobe and multiple chips (max 8).
     
     The power-management is supported.
+
+
+Configuring Non-ISAPNP Cards
+============================
+
+When the kernel is configured with ISA-PnP support, the modules
+supporting the isapnp cards will have module options "isapnp".
+If this option is set, *only* the ISA-PnP devices will be probed.
+For probing the non ISA-PnP cards, you have to pass "isapnp=0" option
+together with the proper i/o and irq configuration.
+
+When the kernel is configured without ISA-PnP support, isapnp option
+will be not built in.
 
 
 modprobe/kmod support
diff -Nru a/Documentation/sound/alsa/CMIPCI.txt b/Documentation/sound/alsa/CMIPCI.txt
--- a/Documentation/sound/alsa/CMIPCI.txt	Sat Feb  8 12:10:44 2003
+++ b/Documentation/sound/alsa/CMIPCI.txt	Tue Feb 25 05:46:04 2003
@@ -207,7 +207,7 @@
 ---------------
 
 The MPU401-UART interface is enabled as default only for the first
-(CMIPCI) card.  You need to set module option "snd_midi_port" properly
+(CMIPCI) card.  You need to set module option "midi_port" properly
 for the 2nd (CMIPCI) card.
 
 There is _no_ hardware wavetable function on this chip (except for
@@ -221,7 +221,7 @@
 --------------
 
 The FM OPL/3 is also enabled as default only for the first card.
-Set "snd_fm_port" module option for more cards.
+Set "fm_port" module option for more cards.
 
 The output quality of FM OPL/3 is, however, very weird.
 I don't know why..
diff -Nru a/Documentation/sound/alsa/ControlNames.txt b/Documentation/sound/alsa/ControlNames.txt
--- a/Documentation/sound/alsa/ControlNames.txt	Wed Dec 18 01:13:12 2002
+++ b/Documentation/sound/alsa/ControlNames.txt	Thu Mar 20 08:41:10 2003
@@ -80,3 +80,5 @@
   IEC958 [...] [Playback|Capture] Con Mask	/* consumer mask */
   IEC958 [...] [Playback|Capture] Pro Mask	/* professional mask */
   IEC958 [...] [Playback|Capture] PCM Stream	/* the settings assigned to a PCM stream */
+  IEC958 Q-subcode [Playback|Capture] Default	/* Q-subcode bits */
+  IEC958 Preamble [Playback|Capture] Default	/* burst preamble words (4*16bits) */
diff -Nru a/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl b/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl
--- a/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl	Mon Jan 27 11:00:11 2003
+++ b/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl	Thu Mar 20 08:41:10 2003
@@ -48,6 +48,8 @@
      <sect1><title>Memory Management Helpers</title>
 !Esound/core/memory.c
 !Iinclude/sound/sndmagic.h
+!Esound/core/memalloc.c
+!Esound/core/sgbuf.c
      </sect1>
   </chapter>
   <chapter><title>PCM API</title>
@@ -61,9 +63,6 @@
      </sect1>
      <sect1><title>PCM Memory Managment</title>
 !Esound/core/pcm_memory.c
-     </sect1>
-     <sect1><title>SG-Buffer Helpers</title>
-!Esound/core/pcm_sgbuf.c
      </sect1>
   </chapter>
   <chapter><title>Control/Mixer API</title>
diff -Nru a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl	Tue Mar 11 10:20:19 2003
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl	Thu Mar 20 08:41:10 2003
@@ -437,7 +437,7 @@
   // (see "Management of Cards and Components")
   static int __devinit snd_mychip_create(snd_card_t *card,
                                          struct pci_device *pci,
-                                         mychip_t *rchip)
+                                         mychip_t **rchip)
   {
           mychip_t *chip;
           int err;
@@ -1377,6 +1377,8 @@
 
   module_init(alsa_card_mychip_init)
   module_exit(alsa_card_mychip_exit)
+
+  EXPORT_NO_SYMBOLS; /* for old kernels only */
 ]]>
           </programlisting>
         </example>
@@ -1664,7 +1666,7 @@
   chip->iobase_phys = pci_resource_start(pci, 0);
   chip->iobase_virt = (unsigned long)
                       ioremap_nocache(chip->iobase_phys, 512);
-  if ((chip->res_port = request_mem_region(chip->port, 512,
+  if ((chip->res_port = request_mem_region(chip->iobase_phys, 512,
                                            "My Chip")) == NULL) {
           printk(KERN_ERR "cannot allocate the memory region\n");
           snd_mychip_free(chip);
@@ -2758,6 +2760,17 @@
         </para>
       </section>
 
+      <section id="pcm-interface-operators-ack">
+        <title>ack callback</title>
+        <para>
+          This callback is also not mandatory. This callback is called
+        when the appl_ptr is updated in read or write operations.
+        Some drivers like emu10k1-fx and cs46xx need to track the
+	current appl_ptr for the internal buffer, and this callback
+	is useful only for such a purpose.
+	</para>
+      </section>
+
       <section id="pcm-interface-operators-page-callback">
         <title>page callback</title>
 
@@ -2807,7 +2820,7 @@
         </para>
 
         <para>
-          If you acquire a spinlock in the interrupt handler, and the
+          If you aquire a spinlock in the interrupt handler, and the
         lock is used in other pcm callbacks, too, then you have to
         release the lock before calling
         <function>snd_pcm_period_elapsed()</function>, because
@@ -4467,8 +4480,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_pcm_sgbuf_t *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t,
-                              substream->dma_private, return -EINVAL);
+  snd_pcm_sgbuf_t *sgbuf = (snd_pcm_sgbuf_t*)substream->dma_private;
 ]]>
           </programlisting>
         </informalexample>
diff -Nru a/Documentation/sound/alsa/serial-u16550.txt b/Documentation/sound/alsa/serial-u16550.txt
--- a/Documentation/sound/alsa/serial-u16550.txt	Sun Sep 29 13:22:50 2002
+++ b/Documentation/sound/alsa/serial-u16550.txt	Tue Feb 25 05:46:04 2003
@@ -2,7 +2,7 @@
 			Serial UART 16450/16550 MIDI driver
 			===================================
 
-The snd_adaptor module parameter allows you to select either:
+The adaptor module parameter allows you to select either:
 
   0 - Roland Soundcanvas support (default)
   1 - Midiator MS-124T support (1)
@@ -24,37 +24,35 @@
 Usage example for simple serial converter:
 
 	/sbin/setserial /dev/ttyS0 none
-	/sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \
-			snd_speed=115200
+	/sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 speed=115200
 
 Usage example for Roland SoundCanvas with 4 MIDI ports:
 
 	/sbin/setserial /dev/ttyS0 none
-	/sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 snd_outs=4
+	/sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 outs=4
 
-In MS-124T mode, one raw MIDI substream is supported (midiCnD0); the snd_outs
+In MS-124T mode, one raw MIDI substream is supported (midiCnD0); the outs
 module parameter is automatically set to 1. The driver sends the same data to
-all four MIDI Out connectors.  Set the A-B switch and the snd_speed module
+all four MIDI Out connectors.  Set the A-B switch and the speed module
 parameter to match (A=19200, B=9600).
 
 Usage example for MS-124T, with A-B switch in A position:
 
 	/sbin/setserial /dev/ttyS0 none
-	/sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \
-			snd_adaptor=1 snd_speed=19200
+	/sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 adaptor=1 \
+			speed=19200
 
 In MS-124W S/A mode, one raw MIDI substream is supported (midiCnD0);
-the snd_outs module parameter is automatically set to 1. The driver sends
+the outs module parameter is automatically set to 1. The driver sends
 the same data to all four MIDI Out connectors at full MIDI speed.
 
 Usage example for S/A mode:
 
 	/sbin/setserial /dev/ttyS0 none
-	/sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \
-			snd_adaptor=2
+	/sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 adaptor=2
 
 In MS-124W M/B mode, the driver supports 16 ALSA raw MIDI substreams;
-the snd_outs module parameter is automatically set to 16.  The substream
+the outs module parameter is automatically set to 16.  The substream
 number gives a bitmask of which MIDI Out connectors the data should be
 sent to, with midiCnD1 sending to Out 1, midiCnD2 to Out 2, midiCnD4 to
 Out 3, and midiCnD8 to Out 4.  Thus midiCnD15 sends the data to all 4 ports.
@@ -67,8 +65,7 @@
 Usage example for M/B mode:
 
 	/sbin/setserial /dev/ttyS0 none
-	/sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \
-			snd_adaptor=3
+	/sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 adaptor=3
 
 The MS-124W hardware's M/A mode is currently not supported. This mode allows
 the MIDI Outs to act independently at double the aggregate throughput of M/B,
@@ -88,4 +85,4 @@
 serial port.  Similar to Roland Soundcanvas mode, F5 NN is used to select the
 appropriate input or output stream (depending on the data direction).
 Additionally, the CTS signal is used to regulate the data flow.  The number of
-inputs is specified by the snd_ins parameter.
+inputs is specified by the ins parameter.
diff -Nru a/Documentation/sysrq.txt b/Documentation/sysrq.txt
--- a/Documentation/sysrq.txt	Tue Feb 18 10:31:36 2003
+++ b/Documentation/sysrq.txt	Mon Mar 17 21:33:20 2003
@@ -36,6 +36,10 @@
 On other - If you know of the key combos for other architectures, please
            let me know so I can add them to this section.
 
+On all -  write a character to /proc/sysrq-trigger.  eg:
+
+		echo t > /proc/sysrq-trigger
+
 *  What are the 'command' keys?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 'r'     - Turns off keyboard raw mode and sets it to XLATE.
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	Thu Mar  6 09:07:03 2003
+++ b/MAINTAINERS	Sat Mar 22 20:13:39 2003
@@ -728,7 +728,7 @@
 
 GDT SCSI DISK ARRAY CONTROLLER DRIVER
 P:	Achim Leubner
-M:	achim@vortex.de
+M:	achim.leubner@intel.com
 L:	linux-scsi@vger.kernel.org
 W:	http://www.icp-vortex.com/
 S:	Supported
@@ -923,10 +923,11 @@
 S:	Supported
 
 INTEL PRO/1000 GIGABIT ETHERNET SUPPORT
-P:	Chris Leech
-M:	christopher.leech@intel.com
+P:	Jeb Cramer
+M:	cramerj@intel.com
 P:	Scott Feldman
 M:	scott.feldman@intel.com
+W:	http://sourceforge.net/projects/e1000/
 S:	Supported
 
 INTERMEZZO FILE SYSTEM
@@ -1610,6 +1611,12 @@
 L:	linux-net@vger.kernel.org
 S:	Supported
 
+SIS FRAMEBUFFER DRIVER
+P:	Thomas Winischhofer
+M:	thomas@winischhofer.net
+W:	http://www.winischhofer.net/linuxsisvga.shtml
+S:	Maintained	
+
 SMB FILESYSTEM
 P:	Urban Widmark
 M:	urban@teststation.com
@@ -2056,6 +2063,11 @@
 P:	Jeff Garzik
 L:	linux-via@gtf.org
 S:	Odd fixes
+
+VIA RHINE NETWORK DRIVER
+P:	Roger Luethi
+M:	rl@hellgate.ch
+S:	Maintained
 
 UCLINUX
 P:	Greg Ungerer
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Mon Mar 17 13:36:41 2003
+++ b/Makefile	Mon Mar 24 04:29:52 2003
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 65
-EXTRAVERSION =
+EXTRAVERSION = -bk5
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
@@ -164,6 +164,8 @@
 OBJCOPY		= $(CROSS_COMPILE)objcopy
 OBJDUMP		= $(CROSS_COMPILE)objdump
 AWK		= awk
+RPM 		:= $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
+		    	else echo rpm; fi)
 GENKSYMS	= scripts/genksyms/genksyms
 DEPMOD		= /sbin/depmod
 KALLSYMS	= scripts/kallsyms
@@ -768,9 +770,7 @@
 	rm $(KERNELPATH) ; \
 	cd $(TOPDIR) ; \
 	$(CONFIG_SHELL) $(srctree)/scripts/mkversion > .version ; \
-	RPM=`which rpmbuild`; \
-	if [ -z "$$RPM" ]; then RPM=rpm; fi; \
-	$$RPM -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
+	$(RPM) -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
 	rm $(TOPDIR)/../$(KERNELPATH).tar.gz
 
 # Brief documentation of the typical targets used
diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig
--- a/arch/arm/Kconfig	Sat Mar  8 14:50:37 2003
+++ b/arch/arm/Kconfig	Thu Mar 20 11:17:58 2003
@@ -546,9 +546,9 @@
 if (CPU_FREQ_SA1100 || CPU_FREQ_SA1110)
 
 config CPU_FREQ_GOV_USERSPACE
- 	bool
- 	depends on CPU_FREQ
- 	default y
+	tristate
+	depends on CPU_FREQ
+	default y
 
 config CPU_FREQ_24_API
 	bool
@@ -1027,9 +1027,6 @@
 
 endmenu
 
-#if [ "$CONFIG_ARCH_CLPS711X" = "y" ]; then
-#   source drivers/ssi/Config.in
-#fi
 source "drivers/ieee1394/Kconfig"
 
 source "drivers/message/i2o/Kconfig"
diff -Nru a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
--- a/arch/arm/boot/compressed/Makefile	Sun Mar  9 13:47:41 2003
+++ b/arch/arm/boot/compressed/Makefile	Sat Mar 22 12:34:23 2003
@@ -19,10 +19,6 @@
 CFLAGS_misc.o	:= -DPARAMS_PHYS=$(PARAMS_PHYS)
 endif
 
-ifeq ($(CONFIG_ARCH_NETWINDER),y)
-OBJS		+= head-netwinder.o
-endif
-
 ifeq ($(CONFIG_ARCH_SHARK),y)
 OBJS		+= head-shark.o ofw-shark.o
 endif
diff -Nru a/arch/arm/boot/compressed/head-netwinder.S b/arch/arm/boot/compressed/head-netwinder.S
--- a/arch/arm/boot/compressed/head-netwinder.S	Wed Apr 17 10:44:02 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,13 +0,0 @@
-/*
- *  linux/arch/arm/boot/compressed/head-netwinder.S
- *
- *  Copyright (C) 2000-2002 Russell King
- *
- * 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.
- */
-		.section	".start", "ax"
-
-		mov	r7, #5
-		mov	r8, #0
diff -Nru a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
--- a/arch/arm/kernel/bios32.c	Sun Mar 16 14:16:30 2003
+++ b/arch/arm/kernel/bios32.c	Tue Mar 18 13:42:00 2003
@@ -6,6 +6,7 @@
  *  Bits taken from various places.
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
@@ -61,7 +62,7 @@
  * Bug 3 is responsible for the sound DMA grinding to a halt.  We now
  * live with bug 2.
  */
-static void __init pci_fixup_83c553(struct pci_dev *dev)
+static void __devinit pci_fixup_83c553(struct pci_dev *dev)
 {
 	/*
 	 * Set memory region to start at address 0, and enable IO
@@ -112,7 +113,7 @@
 	outb(0x08, 0x4d1);
 }
 
-static void __init pci_fixup_unassign(struct pci_dev *dev)
+static void __devinit pci_fixup_unassign(struct pci_dev *dev)
 {
 	dev->resource[0].end -= dev->resource[0].start;
 	dev->resource[0].start = 0;
@@ -123,7 +124,7 @@
  * if it is the host bridge by marking it as such.  These resources are of
  * no consequence to the PCI layer (they are handled elsewhere).
  */
-static void __init pci_fixup_dec21285(struct pci_dev *dev)
+static void __devinit pci_fixup_dec21285(struct pci_dev *dev)
 {
 	int i;
 
@@ -141,7 +142,7 @@
 /*
  * PCI IDE controllers use non-standard I/O port decoding, respect it.
  */
-static void __init pci_fixup_ide_bases(struct pci_dev *dev)
+static void __devinit pci_fixup_ide_bases(struct pci_dev *dev)
 {
 	struct resource *r;
 	int i;
@@ -161,7 +162,7 @@
 /*
  * Put the DEC21142 to sleep
  */
-static void __init pci_fixup_dec21142(struct pci_dev *dev)
+static void __devinit pci_fixup_dec21142(struct pci_dev *dev)
 {
 	pci_write_config_dword(dev, 0x40, 0x80000000);
 }
@@ -182,7 +183,7 @@
  * functional.  However, The CY82C693U _does not work_ in bus
  * master mode without locking the PCI bus solid.
  */
-static void __init pci_fixup_cy82c693(struct pci_dev *dev)
+static void __devinit pci_fixup_cy82c693(struct pci_dev *dev)
 {
 	if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
 		u32 base0, base1;
@@ -511,6 +512,8 @@
 				panic("PCI: unable to scan bus!");
 
 			busnr = sys->bus->subordinate + 1;
+
+			list_add(&sys->node, &hw->buses);
 		} else {
 			kfree(sys);
 			if (ret < 0)
@@ -521,17 +524,36 @@
 
 void __init pci_common_init(struct hw_pci *hw)
 {
+	struct pci_sys_data *sys;
+
+	INIT_LIST_HEAD(&hw->buses);
+
 	if (hw->preinit)
 		hw->preinit();
 	pcibios_init_hw(hw);
 	if (hw->postinit)
 		hw->postinit();
 
-	/*
-	 * Assign any unassigned resources.
-	 */
-	pci_assign_unassigned_resources();
 	pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
+
+	list_for_each_entry(sys, &hw->buses, node) {
+		struct pci_bus *bus = sys->bus;
+
+		/*
+		 * Size the bridge windows.
+		 */
+		pci_bus_size_bridges(bus);
+
+		/*
+		 * Assign resources.
+		 */
+		pci_bus_assign_resources(bus);
+
+		/*
+		 * Tell drivers about devices found.
+		 */
+		pci_bus_add_devices(bus);
+	}
 }
 
 char * __init pcibios_setup(char *str)
diff -Nru a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
--- a/arch/arm/kernel/ecard.c	Thu Mar  6 05:14:05 2003
+++ b/arch/arm/kernel/ecard.c	Tue Mar 18 13:52:45 2003
@@ -562,7 +562,8 @@
 
 static void ecard_check_lockup(struct irqdesc *desc)
 {
-	static int last, lockup;
+	static unsigned long last;
+	static int lockup;
 	ecard_t *ec;
 
 	/*
diff -Nru a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
--- a/arch/arm/kernel/time.c	Thu Mar  6 05:40:54 2003
+++ b/arch/arm/kernel/time.c	Tue Mar 18 13:52:45 2003
@@ -89,7 +89,7 @@
 	}
 }
 
-static long next_rtc_update;
+static unsigned long next_rtc_update;
 
 /*
  * If we have an externally synchronized linux clock, then update
diff -Nru a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
--- a/arch/arm/kernel/traps.c	Thu Feb  6 11:28:41 2003
+++ b/arch/arm/kernel/traps.c	Sat Mar 22 17:29:51 2003
@@ -208,12 +208,13 @@
 NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
 {
 	struct task_struct *tsk = current;
+	static int die_counter;
 
 	console_verbose();
 	spin_lock_irq(&die_lock);
 	bust_spinlocks(1);
 
-	printk("Internal error: %s: %x\n", str, err);
+	printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
 	print_modules();
 	printk("CPU: %d\n", smp_processor_id());
 	show_regs(regs);
@@ -325,7 +326,7 @@
 	dump_mem(KERN_CRIT "Vectors: ", vectors, vectors + 0x40);
 	dump_mem(KERN_CRIT "Stubs: ", vectors + 0x200, vectors + 0x4b8);
 
-	die("Oops", regs, 0);
+	die("Oops - bad mode", regs, 0);
 	local_irq_disable();
 	panic("bad mode");
 }
@@ -353,7 +354,7 @@
 			 (thumb_mode(regs) ? 2 : 4);
 
 	force_sig_info(SIGILL, &info, current);
-	die_if_kernel("Oops", regs, n);
+	die_if_kernel("Oops - bad syscall", regs, n);
 	return regs->ARM_r0;
 }
 
@@ -471,7 +472,7 @@
 			 (thumb_mode(regs) ? 2 : 4);
 
 	force_sig_info(SIGILL, &info, current);
-	die_if_kernel("Oops", regs, no);
+	die_if_kernel("Oops - bad syscall(2)", regs, no);
 	return 0;
 }
 
diff -Nru a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
--- a/arch/arm/mach-clps7500/core.c	Tue Jun  4 16:19:01 2002
+++ b/arch/arm/mach-clps7500/core.c	Tue Mar 18 15:19:45 2003
@@ -8,19 +8,22 @@
  */
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 #include <linux/init.h>
 
+#include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <asm/mach/irq.h>
 
 #include <asm/hardware.h>
 #include <asm/hardware/iomd.h>
 #include <asm/io.h>
-#include <asm/page.h>
-#include <asm/proc/domain.h>
-#include <asm/setup.h>
+#include <asm/irq.h>
 #include <asm/mach-types.h>
 
-static void cl7500_mask_irq_ack_a(unsigned int irq)
+static void cl7500_ack_irq_a(unsigned int irq)
 {
 	unsigned int val, mask;
 
@@ -48,6 +51,12 @@
 	iomd_writeb(val | mask, IOMD_IRQMASKA);
 }
 
+static struct irqchip clps7500_a_chip = {
+	.ack	= cl7500_ack_irq_a,
+	.mask	= cl7500_mask_irq_a,
+	.unmask	= cl7500_unmask_irq_a,
+};
+
 static void cl7500_mask_irq_b(unsigned int irq)
 {
 	unsigned int val, mask;
@@ -66,6 +75,12 @@
 	iomd_writeb(val | mask, IOMD_IRQMASKB);
 }
 
+static struct irqchip clps7500_b_chip = {
+	.ack	= cl7500_mask_irq_b,
+	.mask	= cl7500_mask_irq_b,
+	.unmask	= cl7500_unmask_irq_b,
+};
+
 static void cl7500_mask_irq_c(unsigned int irq)
 {
 	unsigned int val, mask;
@@ -84,6 +99,11 @@
 	iomd_writeb(val | mask, IOMD_IRQMASKC);
 }
 
+static struct irqchip clps7500_c_chip = {
+	.ack	= cl7500_mask_irq_c,
+	.mask	= cl7500_mask_irq_c,
+	.unmask	= cl7500_unmask_irq_c,
+};
 
 static void cl7500_mask_irq_d(unsigned int irq)
 {
@@ -103,6 +123,12 @@
 	iomd_writeb(val | mask, IOMD_IRQMASKD);
 }
 
+static struct irqchip clps7500_d_chip = {
+	.ack	= cl7500_mask_irq_d,
+	.mask	= cl7500_mask_irq_d,
+	.unmask	= cl7500_unmask_irq_d,
+};
+
 static void cl7500_mask_irq_dma(unsigned int irq)
 {
 	unsigned int val, mask;
@@ -121,6 +147,12 @@
 	iomd_writeb(val | mask, IOMD_DMAMASK);
 }
 
+static struct irqchip clps7500_dma_chip = {
+	.ack	= cl7500_mask_irq_dma,
+	.mask	= cl7500_mask_irq_dma,
+	.unmask	= cl7500_unmask_irq_dma,
+};
+
 static void cl7500_mask_irq_fiq(unsigned int irq)
 {
 	unsigned int val, mask;
@@ -139,6 +171,22 @@
 	iomd_writeb(val | mask, IOMD_FIQMASK);
 }
 
+static struct irqchip clps7500_fiq_chip = {
+	.ack	= cl7500_mask_irq_fiq,
+	.mask	= cl7500_mask_irq_fiq,
+	.unmask	= cl7500_unmask_irq_fiq,
+};
+
+static void cl7500_no_action(unsigned int irq)
+{
+}
+
+static struct irqchip clps7500_no_chip = {
+	.ack	= cl7500_no_action,
+	.mask	= cl7500_no_action,
+	.unmask	= cl7500_no_action,
+};
+
 static void no_action(int cpl, void *dev_id, struct pt_regs *regs)
 {
 }
@@ -147,7 +195,7 @@
 
 static void __init clps7500_init_irq(void)
 {
-	int irq;
+	unsigned int irq, flags;
 
 	iomd_writeb(0, IOMD_IRQMASKA);
 	iomd_writeb(0, IOMD_IRQMASKB);
@@ -155,64 +203,58 @@
 	iomd_writeb(0, IOMD_DMAMASK);
 
 	for (irq = 0; irq < NR_IRQS; irq++) {
+		flags = IRQF_VALID;
+
+		if (irq <= 6 || (irq >= 9 && irq <= 15) ||
+		    (irq >= 48 && irq <= 55))
+			flags |= IRQF_PROBE;
+
 		switch (irq) {
-		case 0 ... 6:
-			irq_desc[irq].probe_ok = 1;
-		case 7:
-			irq_desc[irq].valid    = 1;
-			irq_desc[irq].mask_ack = cl7500_mask_irq_ack_a;
-			irq_desc[irq].mask     = cl7500_mask_irq_a;
-			irq_desc[irq].unmask   = cl7500_unmask_irq_a;
-			break;
-
-		case 9 ... 15:
-			irq_desc[irq].probe_ok = 1;
-		case 8:
-			irq_desc[irq].valid    = 1;
-			irq_desc[irq].mask_ack = cl7500_mask_irq_b;
-			irq_desc[irq].mask     = cl7500_mask_irq_b;
-			irq_desc[irq].unmask   = cl7500_unmask_irq_b;
+		case 0 ... 7:
+			set_irq_chip(irq, &clps7500_a_chip);
+			set_irq_handler(irq, do_level_IRQ);
+			set_irq_flags(irq, flags);
+			break;
+
+		case 8 ... 15:
+			set_irq_chip(irq, &clps7500_b_chip);
+			set_irq_handler(irq, do_level_IRQ);
+			set_irq_flags(irq, flags);
 			break;
 
 		case 16 ... 22:
-			irq_desc[irq].valid    = 1;
-			irq_desc[irq].mask_ack = cl7500_mask_irq_dma;
-			irq_desc[irq].mask     = cl7500_mask_irq_dma;
-			irq_desc[irq].unmask   = cl7500_unmask_irq_dma;
+			set_irq_chip(irq, &clps7500_dma_chip);
+			set_irq_handler(irq, do_level_IRQ);
+			set_irq_flags(irq, flags);
 			break;
 
 		case 24 ... 31:
-			irq_desc[irq].valid    = 1;
-			irq_desc[irq].mask_ack = cl7500_mask_irq_c;
-			irq_desc[irq].mask     = cl7500_mask_irq_c;
-			irq_desc[irq].unmask   = cl7500_unmask_irq_c;
+			set_irq_chip(irq, &clps7500_c_chip);
+			set_irq_handler(irq, do_level_IRQ);
+			set_irq_flags(irq, flags);
 			break;
 
 		case 40 ... 47:
-			irq_desc[irq].valid    = 1;
-			irq_desc[irq].mask_ack = cl7500_mask_irq_d;
-			irq_desc[irq].mask     = cl7500_mask_irq_d;
-			irq_desc[irq].unmask   = cl7500_unmask_irq_d;
+			set_irq_chip(irq, &clps7500_d_chip);
+			set_irq_handler(irq, do_level_IRQ);
+			set_irq_flags(irq, flags);
 			break;
 
 		case 48 ... 55:
-			irq_desc[irq].valid      = 1;
-			irq_desc[irq].probe_ok   = 1;
-			irq_desc[irq].mask_ack   = no_action;
-			irq_desc[irq].mask       = no_action;
-			irq_desc[irq].unmask     = no_action;
+			set_irq_chip(irq, &clps7500_no_chip);
+			set_irq_handler(irq, do_level_IRQ);
+			set_irq_flags(irq, flags);
 			break;
 
 		case 64 ... 72:
-			irq_desc[irq].valid    = 1;
-			irq_desc[irq].mask_ack = cl7500_mask_irq_fiq;
-			irq_desc[irq].mask     = cl7500_mask_irq_fiq;
-			irq_desc[irq].unmask   = cl7500_unmask_irq_fiq;
+			set_irq_chip(irq, &clps7500_fiq_chip);
+			set_irq_handler(irq, do_level_IRQ);
+			set_irq_flags(irq, flags);
 			break;
 		}
 	}
 
-	setup_arm_irq(IRQ_ISA, &irq_isa);
+	setup_irq(IRQ_ISA, &irq_isa);
 }
 
 static struct map_desc cl7500_io_desc[] __initdata = {
diff -Nru a/arch/arm/mach-sa1100/ssp.c b/arch/arm/mach-sa1100/ssp.c
--- a/arch/arm/mach-sa1100/ssp.c	Thu Mar  6 16:15:28 2003
+++ b/arch/arm/mach-sa1100/ssp.c	Tue Mar 18 15:32:28 2003
@@ -39,7 +39,8 @@
  * @data: 16-bit, MSB justified data to write.
  *
  * Wait for a free entry in the SSP transmit FIFO, and write a data
- * word to the SSP port.
+ * word to the SSP port.  Wait for the SSP port to start sending
+ * the data.
  *
  * The caller is expected to perform the necessary locking.
  *
@@ -53,6 +54,9 @@
 		cpu_relax();
 
 	Ser4SSDR = data;
+
+	while (!(Ser4SSSR & SSSR_BSY))
+		cpu_relax();
 
 	return 0;
 }
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig	Sat Mar  8 14:50:37 2003
+++ b/arch/i386/Kconfig	Mon Mar 17 21:33:21 2003
@@ -476,21 +476,6 @@
 	  This is purely to save memory - each supported CPU adds
 	  approximately eight kilobytes to the kernel image.
 
-# Common NUMA Features
-config NUMA
-	bool "Numa Memory Allocation Support"
-	depends on (HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT && ACPI && !ACPI_HT_ONLY))) || X86_PC
-
-config DISCONTIGMEM
-	bool
-	depends on NUMA
-	default y
-
-config HAVE_ARCH_BOOTMEM_NODE
-	bool
-	depends on NUMA
-	default y
-
 config X86_TSC
 	bool
 	depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2) && !X86_NUMAQ
@@ -678,6 +663,30 @@
 config X86_PAE
 	bool
 	depends on HIGHMEM64G
+	default y
+
+# Common NUMA Features
+config NUMA
+	bool "Numa Memory Allocation Support"
+	depends on SMP && HIGHMEM64G && (X86_PC || X86_NUMAQ || (X86_SUMMIT && ACPI && !ACPI_HT_ONLY))
+	default n if X86_PC
+	default y if (X86_NUMAQ || X86_SUMMIT)
+
+# Need comments to help the hapless user trying to turn on NUMA support
+comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support"
+	depends on X86_NUMAQ && (!HIGHMEM64G || !SMP)
+
+comment "NUMA (Summit) requires SMP, 64GB highmem support, full ACPI"
+	depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI || ACPI_HT_ONLY)
+
+config DISCONTIGMEM
+	bool
+	depends on NUMA
+	default y
+
+config HAVE_ARCH_BOOTMEM_NODE
+	bool
+	depends on NUMA
 	default y
 
 config HIGHPTE
diff -Nru a/arch/i386/boot98/Makefile b/arch/i386/boot98/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/boot98/Makefile	Sun Mar 23 08:36:08 2003
@@ -0,0 +1,103 @@
+#
+# arch/i386/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1994 by Linus Torvalds
+#
+
+# ROOT_DEV specifies the default root-device when making the image.
+# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
+# the default of FLOPPY is used by 'build'.
+
+ROOT_DEV := CURRENT
+
+# If you want to preset the SVGA mode, uncomment the next line and
+# set SVGA_MODE to whatever number you want.
+# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
+# The number is the same as you would ordinarily press at bootup.
+
+SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
+
+# If you want the RAM disk device, define this to be the size in blocks.
+
+#RAMDISK := -DRAMDISK=512
+
+targets		:= vmlinux.bin bootsect bootsect.o setup setup.o \
+		   zImage bzImage
+subdir- 	:= compressed
+
+host-progs	:= tools/build
+
+# ---------------------------------------------------------------------------
+
+$(obj)/zImage:  IMAGE_OFFSET := 0x1000
+$(obj)/zImage:  EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK)
+$(obj)/bzImage: IMAGE_OFFSET := 0x100000
+$(obj)/bzImage: EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
+$(obj)/bzImage: BUILDFLAGS   := -b
+
+quiet_cmd_image = BUILD   $@
+cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
+	    $(obj)/vmlinux.bin $(ROOT_DEV) > $@
+
+$(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
+			      $(obj)/vmlinux.bin $(obj)/tools/build FORCE
+	$(call if_changed,image)
+	@echo 'Kernel: $@ is ready'
+
+$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
+	$(call if_changed,objcopy)
+
+LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
+LDFLAGS_setup	 := -Ttext 0x0 -s --oformat binary -e begtext
+
+$(obj)/setup $(obj)/bootsect: %: %.o FORCE
+	$(call if_changed,ld)
+
+$(obj)/compressed/vmlinux: FORCE
+	$(Q)$(MAKE) -f scripts/Makefile.build obj=$(obj)/compressed \
+					IMAGE_OFFSET=$(IMAGE_OFFSET) $@
+
+# Set this if you want to pass append arguments to the zdisk/fdimage kernel
+FDARGS = 
+
+$(obj)/mtools.conf: $(src)/mtools.conf.in
+	sed -e 's|@OBJ@|$(obj)|g' < $< > $@
+
+# This requires write access to /dev/fd0
+zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
+	MTOOLSRC=$(obj)/mtools.conf mformat a:			; sync
+	syslinux /dev/fd0					; sync
+	echo 'default linux $(FDARGS)' | \
+		MTOOLSRC=$(src)/mtools.conf mcopy - a:syslinux.cfg
+	MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux	; sync
+
+# These require being root or having syslinux 2.02 or higher installed
+fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf
+	dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440
+	MTOOLSRC=$(obj)/mtools.conf mformat v:			; sync
+	syslinux $(obj)/fdimage					; sync
+	echo 'default linux $(FDARGS)' | \
+		MTOOLSRC=$(obj)/mtools.conf mcopy - v:syslinux.cfg
+	MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux	; sync
+
+fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf
+	dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880
+	MTOOLSRC=$(obj)/mtools.conf mformat w:			; sync
+	syslinux $(obj)/fdimage					; sync
+	echo 'default linux $(FDARGS)' | \
+		MTOOLSRC=$(obj)/mtools.conf mcopy - w:syslinux.cfg
+	MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux	; sync
+
+zlilo: $(BOOTIMAGE)
+	if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
+	if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
+	cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
+	cp System.map $(INSTALL_PATH)/
+	if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
+
+install: $(BOOTIMAGE)
+	sh $(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
diff -Nru a/arch/i386/boot98/bootsect.S b/arch/i386/boot98/bootsect.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/boot98/bootsect.S	Fri Feb 14 14:38:01 2003
@@ -0,0 +1,397 @@
+/*	
+ *	bootsect.S - boot sector for NEC PC-9800 series
+ *
+ *	Linux/98 project at Kyoto University Microcomputer Club (KMC)
+ *		    FUJITA Norimasa, TAKAI Kousuke  1997-1998
+ *	rewritten by TAKAI Kousuke (as86 -> gas), Nov 1999
+ *
+ * Based on:
+ *	bootsect.S		Copyright (C) 1991, 1992 Linus Torvalds
+ *	modified by Drew Eckhardt
+ *	modified by Bruce Evans (bde)
+ *
+ * bootsect.S is loaded at 0x1FC00 or 0x1FE00 by the bios-startup routines,
+ * and moves itself out of the way to address 0x90000, and jumps there.
+ *
+ * It then loads 'setup' directly after itself (0x90200), and the system
+ * at 0x10000, using BIOS interrupts. 
+ *
+ * NOTE! currently system is at most (8*65536-4096) bytes long. This should 
+ * be no problem, even in the future. I want to keep it simple. This 508 kB
+ * kernel size should be enough, especially as this doesn't contain the
+ * buffer cache as in minix (and especially now that the kernel is 
+ * compressed :-)
+ *
+ * The loader has been made as simple as possible, and continuous
+ * read errors will result in a unbreakable loop. Reboot by hand. It
+ * loads pretty fast by getting whole tracks at a time whenever possible.
+ */
+
+#include <linux/config.h>		/* for CONFIG_ROOT_RDONLY */
+#include <asm/boot.h>
+
+SETUPSECTS	= 4			/* default nr of setup-sectors */
+BOOTSEG		= 0x1FC0		/* original address of boot-sector */
+INITSEG		= DEF_INITSEG		/* we move boot here - out of the way */
+SETUPSEG	= DEF_SETUPSEG		/* setup starts here */
+SYSSEG		= DEF_SYSSEG		/* system loaded at 0x10000 (65536) */
+SYSSIZE		= DEF_SYSSIZE		/* system size: # of 16-byte clicks */
+					/* to be loaded */
+ROOT_DEV	= 0 			/* ROOT_DEV is now written by "build" */
+SWAP_DEV	= 0			/* SWAP_DEV is now written by "build" */
+
+#ifndef SVGA_MODE
+#define SVGA_MODE ASK_VGA
+#endif
+
+#ifndef RAMDISK
+#define RAMDISK 0
+#endif 
+
+#ifndef ROOT_RDONLY
+#define ROOT_RDONLY 1
+#endif
+
+/* normal/hireso text VRAM segments */
+#define NORMAL_TEXT	0xa000
+#define HIRESO_TEXT	0xe000
+
+/* bios work area addresses */
+#define EXPMMSZ		0x0401
+#define BIOS_FLAG	0x0501
+#define	DISK_BOOT	0x0584
+
+.code16
+.text
+
+.global _start
+_start:
+
+#if 0 /* hook for debugger, harmless unless BIOS is fussy (old HP) */
+	int	$0x3
+#endif
+	jmp	real_start
+	.ascii	"Linux 98"
+	.word	0
+real_start:
+	xorw	%di, %di		/* %di = 0 */
+	movw	%di, %ss		/* %ss = 0 */
+	movw	$0x03F0, %sp
+	pushw	%cx			/* for hint */
+
+	movw	$0x0A00, %ax		/* normal mode defaults (80x25) */
+
+	testb	$0x08, %ss:BIOS_FLAG	/* check hi-reso bit */
+	jnz	set_crt_mode
+/*
+ * Hi-Reso (high-resolution) machine.
+ *
+ * Some hi-reso machines have no RAMs on bank 8/A (0x080000 - 0x0BFFFF).
+ * On such machines we get two RAM banks from top of protect menory and
+ * map them on bank 8/A.
+ * These work-around must be done before moving myself on INITSEG (0x090000-).
+ */
+	movw	$(HIRESO_TEXT >> 8), %cs:(vram + 1)	/* text VRAM segment */
+
+	/* set memory window */
+	movb	$0x08, %al
+	outb	%al, $0x91		/* map native RAM (if any) */
+	movb	$0x0A, %al
+	outb	%al, $0x93
+
+	/* check bank ram A */
+	pushw	$0xA500
+	popw	%ds
+	movw	(%di), %cx		/* %si == 0 from entry */
+	notw	%cx
+	movw	%cx, (%di)
+
+	movw	$0x43F, %dx		/* cache flush for 486 and up. */
+	movb	$0xA0, %al
+	outb	%al, %dx
+	
+	cmpw	%cx, (%di)
+	je	hireso_done
+
+	/* 
+	 * Write test failed; we have no native RAM on 080000h - 0BFFFFh.
+	 * Take 256KB of RAM from top of protected memory.
+	 */
+	movb	%ss:EXPMMSZ, %al
+	subb	$2, %al			/* reduce 2 x 128KB */
+	movb	%al, %ss:EXPMMSZ
+	addb	%al, %al
+	addb	$0x10, %al
+	outb	%al, $0x91
+	addb	$2, %al
+	outb	%al, $0x93
+
+hireso_done:
+	movb	$0x10, %al		/* CRT mode 80x31, %ah still 0Ah */
+
+set_crt_mode:
+	int	$0x18			/* set CRT mode */
+
+	movb	$0x0C, %ah		/* turn on text displaying */
+	int	$0x18
+
+	xorw	%dx, %dx		/* position cursor to home */
+	movb	$0x13, %ah
+	int	$0x18
+
+	movb	$0x11, %ah		/* turn cursor displaying on */
+	int	$0x18
+
+	/* move 1 kilobytes from [BOOTSEG:0000h] to [INITSEG:0000h] */
+	cld
+	xorw	%si, %si
+	pushw	$INITSEG
+	popw	%es
+	movw	$512, %cx		/* %di == 0 from entry */
+	rep
+	cs
+	movsw
+
+	ljmp	$INITSEG, $go
+
+go:
+	pushw	%cs
+	popw	%ds		/* %ds = %cs */
+
+	popw	%dx		/* %dh = saved %ch passed from BIOS */
+	movb	%ss:DISK_BOOT, %al
+	andb	$0xf0, %al	/* %al = Device Address */
+	movb	$18, %ch	/* 18 secs/track,  512 b/sec (1440 KB) */
+	cmpb	$0x30, %al
+	je	try512
+	cmpb	$0x90, %al	/* 1 MB I/F, 1 MB floppy */
+	je	try1.2M
+	cmpb	$0xf0, %al	/* 640 KB I/F, 1 MB floppy */
+	je	try1.2M
+	movb	$9, %ch		/*  9 secs/track,  512 b/sec ( 720 KB) */
+	cmpb	$0x10, %al	/* 1 MB I/F, 640 KB floppy */
+	je	try512
+	cmpb	$0x70, %al	/* 640 KB I/F, 640 KB floppy */
+	jne	error		/* unknown device? */
+
+	/* XXX: Does it make sense to support 8 secs/track, 512 b/sec 
+		(640 KB) floppy? */
+
+try512:	movb	$2, %cl		/* 512 b/sec */
+lasttry:call	tryload
+/*
+ * Display error message and halt
+ */
+error:	movw	$error_msg, %si
+	call	print
+wait_reboot:
+	movb	$0x0, %ah
+	int	$0x18			/* wait keyboard input */
+1:	movb	$0, %al
+	outb	%al, $0xF0		/* reset CPU */
+	jmp	1b			/* just in case... */
+
+try1.2M:cmpb	$2, %dh
+	je	try2HC
+	movw	$0x0803, %cx	/*  8 secs/track, 1024 b/sec (1232 KB) */
+	call	tryload
+	movb	$15, %ch	/* 15 secs/track,  512 b/sec (1200 KB) */
+	jmp	try512
+try2HC:	movw	$0x0F02, %cx	/* 15 secs/track,  512 b/sec (1200 KB) */
+	call	tryload
+	movw	$0x0803, %cx	/*  8 secs/track, 1024 b/sec (1232 KB) */
+	jmp	lasttry
+
+/*
+ * Try to load SETUP and SYSTEM provided geometry information in %cx.
+ * This routine *will not* return on successful load...
+ */
+tryload:
+	movw	%cx, sectlen
+	movb	%ss:DISK_BOOT, %al
+	movb	$0x7, %ah		/* recalibrate the drive */
+	int	$0x1b
+	jc	error			/* recalibration should succeed */
+
+	/*
+	 * Load SETUP into memory. It is assumed that SETUP fits into
+	 * first cylinder (2 tracks, 9KB on 2DD, 15-18KB on 2HD).
+	 */
+	movb	$0, %bl
+	movb	setup_sects, %bh
+	incb	%bh
+	shlw	%bx			/* %bx = (setup_sects + 1) * 512 */
+	movw	$128, %bp
+	shlw	%cl, %bp		/* %bp = <sector size> */
+	subw	%bp, %bx		/* length to load */
+	movw	$0x0002, %dx		/* head 0, sector 2 */
+	movb	%cl, %ch		/* `N' for sector address */
+	movb	$0, %cl			/* cylinder 0 */
+	pushw	%cs
+	popw	%es			/* %es = %cs (= INITSEG) */
+	movb	$0xd6, %ah		/* read, multi-track, MFM */
+	int	$0x1b			/* load it! */
+	jc	read_error
+
+	movw	$loading_msg, %si
+	call	print
+
+	movw	$SYSSEG, %ax
+	movw	%ax, %es		/* %es = SYSSEG */
+
+/*
+ * This routine loads the system at address 0x10000, making sure
+ * no 64kB boundaries are crossed. We try to load it as fast as
+ * possible, loading whole tracks whenever we can.
+ *
+ * in:	es - starting address segment (normally 0x1000)
+ */
+	movb	%ch, %cl
+	addb	$7, %cl			/* %cl = log2 <sector_size> */
+	shrw	%cl, %bx		/* %bx = # of phys. sectors in SETUP */
+	addb	%bl, %dl		/* %dl = start sector # of SYSTEM */
+	decb	%dl			/* %dl is 0-based in below loop */
+
+rp_read_newseg:
+	xorw	%bp, %bp		/* = starting address within segment */
+#ifdef __BIG_KERNEL__
+	bootsect_kludge = 0x220		/* 0x200 (size of bootsector) + 0x20 (offset */
+	lcall	*bootsect_kludge	/* of bootsect_kludge in setup.S */
+#else
+	movw	%es, %ax
+	subw	$SYSSEG, %ax
+#endif
+	cmpw	syssize, %ax
+	ja	boot			/* done! */
+
+rp_read:
+	movb	sectors, %al
+	addb	%al, %al
+	movb	%al, %ch		/* # of sectors on both surface */
+	subb	%dl, %al		/* # of sectors left on this track */
+	movb	$0, %ah
+	shlw	%cl, %ax		/* # of bytes left on this track */
+	movw	%ax, %bx		/* transfer length */
+	addw	%bp, %ax		/* cross 64K boundary? */
+	jnc	1f			/* ok. */
+	jz	1f			/* also ok. */
+	/*
+	 * Oops, we are crossing 64K boundary...
+	 * Adjust transfer length to make transfer fit in the boundary.
+	 *
+	 * Note: sector size is assumed to be a measure of 65536.
+	 */
+	xorw	%bx, %bx
+	subw	%bp, %bx
+1:	pushw	%dx
+	movw	$dot_msg, %si		/* give progress message */
+	call	print
+	xchgw	%ax, %dx
+	movb	$0, %ah
+	divb	sectors
+	xchgb	%al, %ah
+	xchgw	%ax, %dx		/* %dh = head # / %dl = sector # */
+	incb	%dl			/* fix %dl to 1-based */
+	pushw	%cx
+	movw	cylinder, %cx
+	movb	$0xd6, %ah		/* read, multi-track, seek, MFM */
+	movb	%ss:DISK_BOOT, %al
+	int	$0x1b
+	popw	%cx
+	popw	%dx
+	jc	read_error
+	movw	%bx, %ax		/* # of bytes just read */
+	shrw	%cl, %ax		/* %ax = # of sectors just read */
+	addb	%al, %dl		/* advance sector # */
+	cmpb	%ch, %dl		/* %ch = # of sectors/cylinder */
+	jb	2f
+	incb	cylinder		/* next cylinder */
+	xorb	%dl, %dl		/* sector 0 */
+2:	addw	%bx, %bp		/* advance offset pointer */
+	jnc	rp_read
+	/* offset pointer wrapped; advance segment pointer. */
+	movw	%es, %ax
+	addw	$0x1000, %ax
+	movw	%ax, %es
+	jmp	rp_read_newseg
+
+read_error:
+	ret
+
+boot:	movw	%cs, %ax		/* = INITSEG */
+	/* movw	%ax, %ds */
+	movw	%ax, %ss
+	movw	$0x4000, %sp		/* 0x4000 is arbitrary value >=
+					 * length of bootsect + length of
+					 * setup + room for stack;
+					 * PC-9800 never have BIOS workareas
+					 * on high memory.
+					 */
+/*
+ * After that we check which root-device to use. If the device is
+ * not defined, /dev/fd0 (2, 0) will be used.
+ */
+	cmpw	$0, root_dev
+	jne	3f
+	movb	$2, root_dev+1
+3:
+
+/*
+ * After that (everything loaded), we jump to the setup-routine
+ * loaded directly after the bootblock:
+ */
+	ljmp	$SETUPSEG, $0
+
+/*
+ * Subroutine for print string on console.
+ *	%cs:%si	- pointer to message
+ */
+print:
+	pushaw
+	pushw	%ds
+	pushw	%es
+	pushw	%cs
+	popw	%ds
+	lesw	curpos, %di		/* %es:%di = current text VRAM addr. */
+1:	xorw	%ax, %ax
+	lodsb
+	testb	%al, %al
+	jz	2f			/* end of string */
+	stosw					/* character code */
+	movb	$0xE1, %es:0x2000-2(%di)	/* character attribute */
+	jmp	1b
+2:	movw	%di, %dx
+	movb	$0x13, %ah
+	int	$0x18			/* move cursor to current point */
+	popw	%es
+	popw	%ds
+	popaw
+	ret
+
+loading_msg:
+	.string	"Loading"
+dot_msg:
+	.string	"."
+error_msg:
+	.string	"Read Error!"
+
+	.org	490
+
+curpos:	.word	160		/* current cursor position */
+vram:	.word	NORMAL_TEXT	/* text VRAM segment */
+
+cylinder:	.byte	0	/* current cylinder (lower byte)	*/
+sectlen:	.byte	0	/* (log2 of <sector size>) - 7		*/
+sectors:	.byte	0x0F	/* default is 2HD (15 sector/track)	*/
+
+# XXX: This is a fairly snug fit.
+
+.org 497
+setup_sects:	.byte SETUPSECTS
+root_flags:	.word ROOT_RDONLY
+syssize:	.word SYSSIZE
+swap_dev:	.word SWAP_DEV
+ram_size:	.word RAMDISK
+vid_mode:	.word SVGA_MODE
+root_dev:	.word ROOT_DEV
+boot_flag:	.word 0xAA55
diff -Nru a/arch/i386/boot98/compressed/Makefile b/arch/i386/boot98/compressed/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/boot98/compressed/Makefile	Sun Mar 23 08:36:08 2003
@@ -0,0 +1,25 @@
+#
+# linux/arch/i386/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+targets		:= vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
+EXTRA_AFLAGS	:= -traditional
+
+LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32
+
+$(obj)/vmlinux: $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
+	$(call if_changed,ld)
+	@:
+
+$(obj)/vmlinux.bin: vmlinux FORCE
+	$(call if_changed,objcopy)
+
+$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,gzip)
+
+LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+	$(call if_changed,ld)
diff -Nru a/arch/i386/boot98/compressed/head.S b/arch/i386/boot98/compressed/head.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/boot98/compressed/head.S	Fri Feb 14 14:38:01 2003
@@ -0,0 +1,128 @@
+/*
+ *  linux/boot/head.S
+ *
+ *  Copyright (C) 1991, 1992, 1993  Linus Torvalds
+ */
+
+/*
+ *  head.S contains the 32-bit startup code.
+ *
+ * NOTE!!! Startup happens at absolute address 0x00001000, which is also where
+ * the page directory will exist. The startup code will be overwritten by
+ * the page directory. [According to comments etc elsewhere on a compressed
+ * kernel it will end up at 0x1000 + 1Mb I hope so as I assume this. - AC]
+ *
+ * Page 0 is deliberately kept safe, since System Management Mode code in 
+ * laptops may need to access the BIOS data stored there.  This is also
+ * useful for future device drivers that either access the BIOS via VM86 
+ * mode.
+ */
+
+/*
+ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+ */
+.text
+
+#include <linux/linkage.h>
+#include <asm/segment.h>
+
+	.globl startup_32
+	
+startup_32:
+	cld
+	cli
+	movl $(__BOOT_DS),%eax
+	movl %eax,%ds
+	movl %eax,%es
+	movl %eax,%fs
+	movl %eax,%gs
+
+	lss stack_start,%esp
+	xorl %eax,%eax
+1:	incl %eax		# check that A20 really IS enabled
+	movl %eax,0x000000	# loop forever if it isn't
+	cmpl %eax,0x100000
+	je 1b
+
+/*
+ * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
+ * confuse the debugger if this code is traced.
+ * XXX - best to initialize before switching to protected mode.
+ */
+	pushl $0
+	popfl
+/*
+ * Clear BSS
+ */
+	xorl %eax,%eax
+	movl $_edata,%edi
+	movl $_end,%ecx
+	subl %edi,%ecx
+	cld
+	rep
+	stosb
+/*
+ * Do the decompression, and jump to the new kernel..
+ */
+	subl $16,%esp	# place for structure on the stack
+	movl %esp,%eax
+	pushl %esi	# real mode pointer as second arg
+	pushl %eax	# address of structure as first arg
+	call decompress_kernel
+	orl  %eax,%eax 
+	jnz  3f
+	popl %esi	# discard address
+	popl %esi	# real mode pointer
+	xorl %ebx,%ebx
+	ljmp $(__BOOT_CS), $0x100000
+
+/*
+ * We come here, if we were loaded high.
+ * We need to move the move-in-place routine down to 0x1000
+ * and then start it with the buffer addresses in registers,
+ * which we got from the stack.
+ */
+3:
+	movl $move_routine_start,%esi
+	movl $0x1000,%edi
+	movl $move_routine_end,%ecx
+	subl %esi,%ecx
+	addl $3,%ecx
+	shrl $2,%ecx
+	cld
+	rep
+	movsl
+
+	popl %esi	# discard the address
+	popl %ebx	# real mode pointer
+	popl %esi	# low_buffer_start
+	popl %ecx	# lcount
+	popl %edx	# high_buffer_start
+	popl %eax	# hcount
+	movl $0x100000,%edi
+	cli		# make sure we don't get interrupted
+	ljmp $(__BOOT_CS), $0x1000 # and jump to the move routine
+
+/*
+ * Routine (template) for moving the decompressed kernel in place,
+ * if we were high loaded. This _must_ PIC-code !
+ */
+move_routine_start:
+	movl %ecx,%ebp
+	shrl $2,%ecx
+	rep
+	movsl
+	movl %ebp,%ecx
+	andl $3,%ecx
+	rep
+	movsb
+	movl %edx,%esi
+	movl %eax,%ecx	# NOTE: rep movsb won't move if %ecx == 0
+	addl $3,%ecx
+	shrl $2,%ecx
+	rep
+	movsl
+	movl %ebx,%esi	# Restore setup pointer
+	xorl %ebx,%ebx
+	ljmp $(__BOOT_CS), $0x100000
+move_routine_end:
diff -Nru a/arch/i386/boot98/compressed/misc.c b/arch/i386/boot98/compressed/misc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/boot98/compressed/misc.c	Fri Feb 14 14:38:01 2003
@@ -0,0 +1,379 @@
+/*
+ * misc.c
+ * 
+ * This is a collection of several routines from gzip-1.0.3 
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ * puts by Nick Holloway 1993, better puts by Martin Mares 1995
+ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+ */
+
+#include <linux/linkage.h>
+#include <linux/vmalloc.h>
+#include <linux/tty.h>
+#include <asm/io.h>
+#ifdef STANDARD_MEMORY_BIOS_CALL
+#undef STANDARD_MEMORY_BIOS_CALL
+#endif
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+#define STATIC static
+
+#undef memset
+#undef memcpy
+
+/*
+ * Why do we do this? Don't ask me..
+ *
+ * Incomprehensible are the ways of bootloaders.
+ */
+static void* memset(void *, int, size_t);
+static void* memcpy(void *, __const void *, size_t);
+#define memzero(s, n)     memset ((s), 0, (n))
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define WSIZE 0x8000		/* Window size must be at least 32k, */
+				/* and a power of two */
+
+static uch *inbuf;	     /* input buffer */
+static uch window[WSIZE];    /* Sliding window buffer */
+
+static unsigned insize = 0;  /* valid bytes in inbuf */
+static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
+static unsigned outcnt = 0;  /* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
+#define RESERVED     0xC0 /* bit 6,7:   reserved */
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+		
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) {if(!(cond)) error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+static int  fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+  
+/*
+ * This is set up by the setup-routine at boot-time
+ */
+static unsigned char *real_mode; /* Pointer to real-mode data */
+
+#define EXT_MEM_K   (*(unsigned short *)(real_mode + 0x2))
+#ifndef STANDARD_MEMORY_BIOS_CALL
+#define ALT_MEM_K   (*(unsigned long *)(real_mode + 0x1e0))
+#endif
+#define SCREEN_INFO (*(struct screen_info *)(real_mode+0))
+
+extern char input_data[];
+extern int input_len;
+
+static long bytes_out = 0;
+static uch *output_data;
+static unsigned long output_ptr = 0;
+
+static void *malloc(int size);
+static void free(void *where);
+
+static void puts(const char *);
+
+extern int end;
+static long free_mem_ptr = (long)&end;
+static long free_mem_end_ptr;
+
+#define INPLACE_MOVE_ROUTINE  0x1000
+#define LOW_BUFFER_START      0x2000
+#define LOW_BUFFER_MAX       0x90000
+#define HEAP_SIZE             0x3000
+static unsigned int low_buffer_end, low_buffer_size;
+static int high_loaded =0;
+static uch *high_buffer_start /* = (uch *)(((ulg)&end) + HEAP_SIZE)*/;
+
+static char *vidmem = (char *)0xa0000;
+static int lines, cols;
+
+#ifdef CONFIG_X86_NUMAQ
+static void * xquad_portio = NULL;
+#endif
+
+#include "../../../../lib/inflate.c"
+
+static void *malloc(int size)
+{
+	void *p;
+
+	if (size <0) error("Malloc error\n");
+	if (free_mem_ptr <= 0) error("Memory error\n");
+
+	free_mem_ptr = (free_mem_ptr + 3) & ~3;	/* Align */
+
+	p = (void *)free_mem_ptr;
+	free_mem_ptr += size;
+
+	if (free_mem_ptr >= free_mem_end_ptr)
+		error("\nOut of memory\n");
+
+	return p;
+}
+
+static void free(void *where)
+{	/* Don't care */
+}
+
+static void gzip_mark(void **ptr)
+{
+	*ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+	free_mem_ptr = (long) *ptr;
+}
+ 
+static void scroll(void)
+{
+	int i;
+
+	memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
+	for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
+		vidmem[i] = ' ';
+}
+
+static void puts(const char *s)
+{
+	int x,y,pos;
+	char c;
+
+	x = SCREEN_INFO.orig_x;
+	y = SCREEN_INFO.orig_y;
+
+	while ( ( c = *s++ ) != '\0' ) {
+		if ( c == '\n' ) {
+			x = 0;
+			if ( ++y >= lines ) {
+				scroll();
+				y--;
+			}
+		} else {
+			vidmem [ ( x + cols * y ) * 2 ] = c; 
+			if ( ++x >= cols ) {
+				x = 0;
+				if ( ++y >= lines ) {
+					scroll();
+					y--;
+				}
+			}
+		}
+	}
+
+	SCREEN_INFO.orig_x = x;
+	SCREEN_INFO.orig_y = y;
+
+	pos = x + cols * y;	/* Update cursor position */
+	while (!(inb_p(0x60) & 4));
+	outb_p(0x49, 0x62);
+	outb_p(pos & 0xff, 0x60);
+	outb_p((pos >> 8) & 0xff, 0x60);
+}
+
+static void* memset(void* s, int c, size_t n)
+{
+	int i;
+	char *ss = (char*)s;
+
+	for (i=0;i<n;i++) ss[i] = c;
+	return s;
+}
+
+static void* memcpy(void* __dest, __const void* __src,
+			    size_t __n)
+{
+	int i;
+	char *d = (char *)__dest, *s = (char *)__src;
+
+	for (i=0;i<__n;i++) d[i] = s[i];
+	return __dest;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf(void)
+{
+	if (insize != 0) {
+		error("ran out of input data\n");
+	}
+
+	inbuf = input_data;
+	insize = input_len;
+	inptr = 1;
+	return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window_low(void)
+{
+    ulg c = crc;         /* temporary variable */
+    unsigned n;
+    uch *in, *out, ch;
+    
+    in = window;
+    out = &output_data[output_ptr]; 
+    for (n = 0; n < outcnt; n++) {
+	    ch = *out++ = *in++;
+	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+    }
+    crc = c;
+    bytes_out += (ulg)outcnt;
+    output_ptr += (ulg)outcnt;
+    outcnt = 0;
+}
+
+static void flush_window_high(void)
+{
+    ulg c = crc;         /* temporary variable */
+    unsigned n;
+    uch *in,  ch;
+    in = window;
+    for (n = 0; n < outcnt; n++) {
+	ch = *output_data++ = *in++;
+	if ((ulg)output_data == low_buffer_end) output_data=high_buffer_start;
+	c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+    }
+    crc = c;
+    bytes_out += (ulg)outcnt;
+    outcnt = 0;
+}
+
+static void flush_window(void)
+{
+	if (high_loaded) flush_window_high();
+	else flush_window_low();
+}
+
+static void error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	while(1);	/* Halt */
+}
+
+#define STACK_SIZE (4096)
+
+long user_stack [STACK_SIZE];
+
+struct {
+	long * a;
+	short b;
+	} stack_start = { & user_stack [STACK_SIZE] , __BOOT_DS };
+
+static void setup_normal_output_buffer(void)
+{
+#ifdef STANDARD_MEMORY_BIOS_CALL
+	if (EXT_MEM_K < 1024) error("Less than 2MB of memory.\n");
+#else
+	if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory.\n");
+#endif
+	output_data = (char *)0x100000; /* Points to 1M */
+	free_mem_end_ptr = (long)real_mode;
+}
+
+struct moveparams {
+	uch *low_buffer_start;  int lcount;
+	uch *high_buffer_start; int hcount;
+};
+
+static void setup_output_buffer_if_we_run_high(struct moveparams *mv)
+{
+	high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE);
+#ifdef STANDARD_MEMORY_BIOS_CALL
+	if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory.\n");
+#else
+	if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory.\n");
+#endif	
+	mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
+	low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX
+	  ? LOW_BUFFER_MAX : (unsigned int)real_mode) & ~0xfff;
+	low_buffer_size = low_buffer_end - LOW_BUFFER_START;
+	high_loaded = 1;
+	free_mem_end_ptr = (long)high_buffer_start;
+	if ( (0x100000 + low_buffer_size) > ((ulg)high_buffer_start)) {
+		high_buffer_start = (uch *)(0x100000 + low_buffer_size);
+		mv->hcount = 0; /* say: we need not to move high_buffer */
+	}
+	else mv->hcount = -1;
+	mv->high_buffer_start = high_buffer_start;
+}
+
+static void close_output_buffer_if_we_run_high(struct moveparams *mv)
+{
+	if (bytes_out > low_buffer_size) {
+		mv->lcount = low_buffer_size;
+		if (mv->hcount)
+			mv->hcount = bytes_out - low_buffer_size;
+	} else {
+		mv->lcount = bytes_out;
+		mv->hcount = 0;
+	}
+}
+
+
+asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode)
+{
+	real_mode = rmode;
+
+	vidmem = (char *)(((unsigned int)SCREEN_INFO.orig_video_page) << 4);
+
+	lines = SCREEN_INFO.orig_video_lines;
+	cols = SCREEN_INFO.orig_video_cols;
+
+	if (free_mem_ptr < 0x100000) setup_normal_output_buffer();
+	else setup_output_buffer_if_we_run_high(mv);
+
+	makecrc();
+	puts("Uncompressing Linux... ");
+	gunzip();
+	puts("Ok, booting the kernel.\n");
+	if (high_loaded) close_output_buffer_if_we_run_high(mv);
+	return high_loaded;
+}
+
+/* We don't actually check for stack overflows this early. */
+__asm__(".globl mcount ; mcount: ret\n");
+
diff -Nru a/arch/i386/boot98/compressed/vmlinux.scr b/arch/i386/boot98/compressed/vmlinux.scr
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/boot98/compressed/vmlinux.scr	Fri Feb 14 14:38:01 2003
@@ -0,0 +1,9 @@
+SECTIONS
+{
+  .data : { 
+	input_len = .;
+	LONG(input_data_end - input_data) input_data = .; 
+	*(.data) 
+	input_data_end = .; 
+	}
+}
diff -Nru a/arch/i386/boot98/install.sh b/arch/i386/boot98/install.sh
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/boot98/install.sh	Fri Feb 14 14:38:01 2003
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# arch/i386/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+#
+# "make install" script for i386 architecture
+#
+# Arguments:
+#   $1 - kernel version
+#   $2 - kernel image file
+#   $3 - kernel map file
+#   $4 - default install path (blank if root directory)
+#
+
+# User may have a custom install script
+
+if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
+if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
+
+# Default install - same as make zlilo
+
+if [ -f $4/vmlinuz ]; then
+	mv $4/vmlinuz $4/vmlinuz.old
+fi
+
+if [ -f $4/System.map ]; then
+	mv $4/System.map $4/System.old
+fi
+
+cat $2 > $4/vmlinuz
+cp $3 $4/System.map
+
+if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
diff -Nru a/arch/i386/boot98/mtools.conf.in b/arch/i386/boot98/mtools.conf.in
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/boot98/mtools.conf.in	Sun Mar 23 08:36:08 2003
@@ -0,0 +1,17 @@
+#
+# mtools configuration file for "make (b)zdisk"
+#
+
+# Actual floppy drive
+drive a:
+  file="/dev/fd0"
+
+# 1.44 MB floppy disk image
+drive v:
+  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=18 filter
+
+# 2.88 MB floppy disk image (mostly for virtual uses)
+drive w:
+  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=36 filter
+
+
diff -Nru a/arch/i386/boot98/setup.S b/arch/i386/boot98/setup.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/boot98/setup.S	Thu Mar 20 10:43:51 2003
@@ -0,0 +1,961 @@
+/*
+ *	setup.S		Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * setup.s is responsible for getting the system data from the BIOS,
+ * and putting them into the appropriate places in system memory.
+ * both setup.s and system has been loaded by the bootblock.
+ *
+ * This code asks the bios for memory/disk/other parameters, and
+ * puts them in a "safe" place: 0x90000-0x901FF, ie where the
+ * boot-block used to be. It is then up to the protected mode
+ * system to read them from there before the area is overwritten
+ * for buffer-blocks.
+ *
+ * Move PS/2 aux init code to psaux.c
+ * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
+ *
+ * some changes and additional features by Christoph Niemann,
+ * March 1993/June 1994 (Christoph.Niemann@linux.org)
+ *
+ * add APM BIOS checking by Stephen Rothwell, May 1994
+ * (sfr@canb.auug.org.au)
+ *
+ * High load stuff, initrd support and position independency
+ * by Hans Lermen & Werner Almesberger, February 1996
+ * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
+ *
+ * Video handling moved to video.S by Martin Mares, March 1996
+ * <mj@k332.feld.cvut.cz>
+ *
+ * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
+ * parsons) to avoid loadlin confusion, July 1997
+ *
+ * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
+ * <stiker@northlink.com>
+ *
+ * Fix to work around buggy BIOSes which dont use carry bit correctly
+ * and/or report extended memory in CX/DX for e801h memory size detection 
+ * call.  As a result the kernel got wrong figures.  The int15/e801h docs
+ * from Ralf Brown interrupt list seem to indicate AX/BX should be used
+ * anyway.  So to avoid breaking many machines (presumably there was a reason
+ * to orginally use CX/DX instead of AX/BX), we do a kludge to see
+ * if CX/DX have been changed in the e801 call and if so use AX/BX .
+ * Michael Miller, April 2001 <michaelm@mjmm.org>
+ *
+ * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes
+ * by Robert Schwebel, December 2001 <robert@schwebel.de>
+ *
+ * Heavily modified for NEC PC-9800 series by Kyoto University Microcomputer
+ * Club (KMC) Linux/98 project <seraphim@kmc.kyoto-u.ac.jp>, 1997-1999
+ */
+
+#include <linux/config.h>
+#include <asm/segment.h>
+#include <linux/version.h>
+#include <linux/compile.h>
+#include <asm/boot.h>
+#include <asm/e820.h>
+#include <asm/page.h>
+	
+/* Signature words to ensure LILO loaded us right */
+#define SIG1	0xAA55
+#define SIG2	0x5A5A
+
+#define HIRESO_TEXT	0xe000
+#define NORMAL_TEXT	0xa000
+
+#define BIOS_FLAG2	0x0400
+#define BIOS_FLAG5	0x0458
+#define RDISK_EQUIP	0x0488
+#define BIOS_FLAG	0x0501
+#define KB_SHFT_STS	0x053a
+#define DISK_EQUIP	0x055c
+
+INITSEG  = DEF_INITSEG		# 0x9000, we move boot here, out of the way
+SYSSEG   = DEF_SYSSEG		# 0x1000, system loaded at 0x10000 (65536).
+SETUPSEG = DEF_SETUPSEG		# 0x9020, this is the current segment
+				# ... and the former contents of CS
+
+DELTA_INITSEG = SETUPSEG - INITSEG	# 0x0020
+
+.code16
+.globl begtext, begdata, begbss, endtext, enddata, endbss
+
+.text
+begtext:
+.data
+begdata:
+.bss
+begbss:
+.text
+
+start:
+	jmp	trampoline
+
+# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
+
+		.ascii	"HdrS"		# header signature
+		.word	0x0203		# header version number (>= 0x0105)
+					# or else old loadlin-1.5 will fail)
+realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
+start_sys_seg:	.word	SYSSEG
+		.word	kernel_version	# pointing to kernel version string
+					# above section of header is compatible
+					# with loadlin-1.5 (header v1.5). Don't
+					# change it.
+
+type_of_loader:	.byte	0		# = 0, old one (LILO, Loadlin,
+					#      Bootlin, SYSLX, bootsect...)
+					# See Documentation/i386/boot.txt for
+					# assigned ids
+	
+# flags, unused bits must be zero (RFU) bit within loadflags
+loadflags:
+LOADED_HIGH	= 1			# If set, the kernel is loaded high
+CAN_USE_HEAP	= 0x80			# If set, the loader also has set
+					# heap_end_ptr to tell how much
+					# space behind setup.S can be used for
+					# heap purposes.
+					# Only the loader knows what is free
+#ifndef __BIG_KERNEL__
+		.byte	0
+#else
+		.byte	LOADED_HIGH
+#endif
+
+setup_move_size: .word  0x8000		# size to move, when setup is not
+					# loaded at 0x90000. We will move setup 
+					# to 0x90000 then just before jumping
+					# into the kernel. However, only the
+					# loader knows how much data behind
+					# us also needs to be loaded.
+
+code32_start:				# here loaders can put a different
+					# start address for 32-bit code.
+#ifndef __BIG_KERNEL__
+		.long	0x1000		#   0x1000 = default for zImage
+#else
+		.long	0x100000	# 0x100000 = default for big kernel
+#endif
+
+ramdisk_image:	.long	0		# address of loaded ramdisk image
+					# Here the loader puts the 32-bit
+					# address where it loaded the image.
+					# This only will be read by the kernel.
+
+ramdisk_size:	.long	0		# its size in bytes
+
+bootsect_kludge:
+		.word  bootsect_helper, SETUPSEG
+
+heap_end_ptr:	.word	modelist+1024	# (Header version 0x0201 or later)
+					# space from here (exclusive) down to
+					# end of setup code can be used by setup
+					# for local heap purposes.
+
+pad1:		.word	0
+cmd_line_ptr:	.long 0			# (Header version 0x0202 or later)
+					# If nonzero, a 32-bit pointer
+					# to the kernel command line.
+					# The command line should be
+					# located between the start of
+					# setup and the end of low
+					# memory (0xa0000), or it may
+					# get overwritten before it
+					# gets read.  If this field is
+					# used, there is no longer
+					# anything magical about the
+					# 0x90000 segment; the setup
+					# can be located anywhere in
+					# low memory 0x10000 or higher.
+
+ramdisk_max:	.long __MAXMEM-1	# (Header version 0x0203 or later)
+					# The highest safe address for
+					# the contents of an initrd
+
+trampoline:	call	start_of_setup
+		.space	1024
+# End of setup header #####################################################
+
+start_of_setup:
+# Set %ds = %cs, we know that SETUPSEG = %cs at this point
+	movw	%cs, %ax		# aka SETUPSEG
+	movw	%ax, %ds
+# Check signature at end of setup
+	cmpw	$SIG1, setup_sig1
+	jne	bad_sig
+
+	cmpw	$SIG2, setup_sig2
+	jne	bad_sig
+
+	jmp	good_sig1
+
+# Routine to print asciiz string at ds:si
+prtstr:
+	lodsb
+	andb	%al, %al
+	jz	fin
+
+	call	prtchr
+	jmp	prtstr
+
+fin:	ret
+
+no_sig_mess: .string	"No setup signature found ..."
+
+good_sig1:
+	jmp	good_sig
+
+# We now have to find the rest of the setup code/data
+bad_sig:
+	movw	%cs, %ax			# SETUPSEG
+	subw	$DELTA_INITSEG, %ax		# INITSEG
+	movw	%ax, %ds
+	xorb	%bh, %bh
+	movb	(497), %bl			# get setup sect from bootsect
+	subw	$4, %bx				# LILO loads 4 sectors of setup
+	shlw	$8, %bx				# convert to words (1sect=2^8 words)
+	movw	%bx, %cx
+	shrw	$3, %bx				# convert to segment
+	addw	$SYSSEG, %bx
+	movw	%bx, %cs:start_sys_seg
+# Move rest of setup code/data to here
+	movw	$2048, %di			# four sectors loaded by LILO
+	subw	%si, %si
+	pushw	%cs
+	popw	%es
+	movw	$SYSSEG, %ax
+	movw	%ax, %ds
+	rep
+	movsw
+	movw	%cs, %ax			# aka SETUPSEG
+	movw	%ax, %ds
+	cmpw	$SIG1, setup_sig1
+	jne	no_sig
+
+	cmpw	$SIG2, setup_sig2
+	jne	no_sig
+
+	jmp	good_sig
+
+no_sig:
+	lea	no_sig_mess, %si
+	call	prtstr
+
+no_sig_loop:
+	hlt
+	jmp	no_sig_loop
+
+good_sig:
+	movw	%cs, %ax			# aka SETUPSEG
+	subw	$DELTA_INITSEG, %ax 		# aka INITSEG
+	movw	%ax, %ds
+# Check if an old loader tries to load a big-kernel
+	testb	$LOADED_HIGH, %cs:loadflags	# Do we have a big kernel?
+	jz	loader_ok			# No, no danger for old loaders.
+
+	cmpb	$0, %cs:type_of_loader 		# Do we have a loader that
+						# can deal with us?
+	jnz	loader_ok			# Yes, continue.
+
+	pushw	%cs				# No, we have an old loader,
+	popw	%ds				# die. 
+	lea	loader_panic_mess, %si
+	call	prtstr
+
+	jmp	no_sig_loop
+
+loader_panic_mess: .string "Wrong loader, giving up..."
+
+loader_ok:
+# Get memory size (extended mem, kB)
+
+# On PC-9800, memory size detection is done completely in 32-bit
+# kernel initialize code (kernel/setup.c).
+	pushw	%es
+	xorl	%eax, %eax
+	movw	%ax, %es
+	movb	%al, (E820NR)		# PC-9800 has no E820
+	movb	%es:(0x401), %al
+	shll	$7, %eax
+	addw	$1024, %ax
+	movw	%ax, (2)
+	movl	%eax, (0x1e0)
+	movw	%es:(0x594), %ax
+	shll	$10, %eax
+	addl	%eax, (0x1e0)
+	popw	%es
+
+# Check for video adapter and its parameters and allow the
+# user to browse video modes.
+	call	video				# NOTE: we need %ds pointing
+						# to bootsector
+
+# Get text video mode
+	movb	$0x0B, %ah
+	int	$0x18		# CRT mode sense
+	movw	$(20 << 8) + 40, %cx
+	testb	$0x10, %al
+	jnz	3f
+	movb	$20, %ch
+	testb	$0x01, %al
+	jnz	1f
+	movb	$25, %ch
+	jmp	1f
+3:	# If bit 4 was 1, it means either 1) 31 lines for hi-reso mode,
+	# or 2) 30 lines for PC-9821.
+	movb	$31, %ch	# hireso mode value
+	pushw	$0
+	popw	%es
+	testb	$0x08, %es:BIOS_FLAG
+	jnz	1f
+	movb	$30, %ch
+1:	# Now we got # of rows in %ch
+	movb	%ch, (14)
+
+	testb	$0x02, %al
+	jnz	2f
+	movb	$80, %cl
+2:	# Now we got # of columns in %cl
+	movb	%cl, (7)
+
+	# Next, get horizontal frequency if supported
+	movw	$0x3100, %ax
+	int	$0x18		# Call CRT bios
+	movb	%al, (6)	# If 31h is unsupported, %al remains 0
+
+# Get hd0-3 data...
+	pushw	%ds				# aka INITSEG
+	popw	%es
+	xorw	%ax, %ax
+	movw	%ax, %ds
+	cld
+	movw	$0x0080, %di
+	movb	DISK_EQUIP+1, %ah
+	movb	$0x80, %al
+
+get_hd_info:
+	shrb	%ah
+	pushw	%ax
+	jnc	1f
+	movb	$0x84, %ah
+	int	$0x1b
+	jnc	2f				# Success
+1:	xorw	%cx, %cx			# `0 cylinders' means no drive
+2:	# Attention! Work area (drive_info) is arranged for PC-9800.
+	movw	%cx, %ax			# # of cylinders
+	stosw
+	movw	%dx, %ax			# # of sectors / # of heads
+	stosw
+	movw	%bx, %ax			# sector size in bytes
+	stosw
+	popw	%ax
+	incb	%al
+	cmpb	$0x84, %al
+	jb	get_hd_info
+
+# Get fd data...
+	movw	DISK_EQUIP, %ax
+	andw	$0xf00f, %ax
+	orb	%al, %ah
+	movb	RDISK_EQUIP, %al
+	notb	%al
+	andb	%al, %ah			# ignore all `RAM drive'
+
+	movb	$0x30, %al
+
+get_fd_info:
+	shrb	%ah
+	pushw	%ax
+	jnc	1f
+	movb	$0xc4, %ah
+	int	$0x1b
+	movb	%ah, %al
+	andb	$4, %al				# 1.44MB support flag
+	shrb	%al
+	addb	$2, %al				# %al = 2 (1.2MB) or 4 (1.44MB)
+	jmp	2f
+1:	movb	$0, %al				# no drive
+2:	stosb
+	popw	%ax
+	incb	%al
+	testb	$0x04, %al
+	jz	get_fd_info
+
+	addb	$(0xb0 - 0x34), %al
+	jnc	get_fd_info			# check FDs on 640KB I/F
+
+	pushw	%es
+	popw	%ds				# %ds got bootsector again
+#if 0
+	mov	$0, (0x1ff)			# default is no pointing device
+#endif
+
+#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
+# Then check for an APM BIOS...
+						# %ds points to the bootsector
+	movw	$0, 0x40			# version = 0 means no APM BIOS
+	movw	$0x09a00, %ax			# APM BIOS installation check
+	xorw	%bx, %bx
+	int	$0x1f
+	jc	done_apm_bios			# Nope, no APM BIOS
+
+	cmpw	$0x0504d, %bx			# Check for "PM" signature
+	jne	done_apm_bios			# No signature, no APM BIOS
+
+	testb	$0x02, %cl			# Is 32 bit supported?
+	je	done_apm_bios			# No 32-bit, no (good) APM BIOS
+
+	movw	$0x09a04, %ax			# Disconnect first just in case
+	xorw	%bx, %bx
+	int	$0x1f				# ignore return code
+	movw	$0x09a03, %ax			# 32 bit connect
+	xorl	%ebx, %ebx
+	int	$0x1f
+	jc	no_32_apm_bios			# Ack, error.
+
+	movw	%ax,  (66)			# BIOS code segment
+	movl	%ebx, (68)			# BIOS entry point offset
+	movw	%cx,  (72)			# BIOS 16 bit code segment
+	movw	%dx,  (74)			# BIOS data segment
+	movl	%esi, (78)			# BIOS code segment length
+	movw	%di,  (82)			# BIOS data segment length
+# Redo the installation check as the 32 bit connect
+# modifies the flags returned on some BIOSs
+	movw	$0x09a00, %ax			# APM BIOS installation check
+	xorw	%bx, %bx
+	int	$0x1f
+	jc	apm_disconnect			# error -> shouldn't happen
+
+	cmpw	$0x0504d, %bx			# check for "PM" signature
+	jne	apm_disconnect			# no sig -> shouldn't happen
+
+	movw	%ax, (64)			# record the APM BIOS version
+	movw	%cx, (76)			# and flags
+	jmp	done_apm_bios
+
+apm_disconnect:					# Tidy up
+	movw	$0x09a04, %ax			# Disconnect
+	xorw	%bx, %bx
+	int	$0x1f				# ignore return code
+
+	jmp	done_apm_bios
+
+no_32_apm_bios:
+	andw	$0xfffd, (76)			# remove 32 bit support bit
+done_apm_bios:
+#endif
+
+# Pass cursor position to kernel...
+	movw	%cs:cursor_address, %ax
+	shrw	%ax		# cursor_address is 2 bytes unit
+	movb	$80, %cl
+	divb	%cl
+	xchgb	%al, %ah	# (0) = %al = X, (1) = %ah = Y
+	movw	%ax, (0)
+
+#if 0
+	movw	$msg_cpos, %si
+	call	prtstr_cs
+	call	prthex
+	call	prtstr_cs
+	movw	%ds, %ax
+	call	prthex
+	call	prtstr_cs
+	movb	$0x11, %ah
+	int	$0x18
+	movb	$0, %ah
+	int	$0x18
+	.section .rodata, "a"
+msg_cpos:	.string	"Cursor position: 0x"
+		.string	", %ds:0x"
+		.string	"\r\n"
+	.previous
+#endif
+
+# Now we want to move to protected mode ...
+	cmpw	$0, %cs:realmode_swtch
+	jz	rmodeswtch_normal
+
+	lcall	*%cs:realmode_swtch
+
+	jmp	rmodeswtch_end
+
+rmodeswtch_normal:
+        pushw	%cs
+	call	default_switch
+
+rmodeswtch_end:
+# we get the code32 start address and modify the below 'jmpi'
+# (loader may have changed it)
+	movl	%cs:code32_start, %eax
+	movl	%eax, %cs:code32
+
+# Now we move the system to its rightful place ... but we check if we have a
+# big-kernel. In that case we *must* not move it ...
+	testb	$LOADED_HIGH, %cs:loadflags
+	jz	do_move0			# .. then we have a normal low
+						# loaded zImage
+						# .. or else we have a high
+						# loaded bzImage
+	jmp	end_move			# ... and we skip moving
+
+do_move0:
+	movw	$0x100, %ax			# start of destination segment
+	movw	%cs, %bp			# aka SETUPSEG
+	subw	$DELTA_INITSEG, %bp		# aka INITSEG
+	movw	%cs:start_sys_seg, %bx		# start of source segment
+	cld
+do_move:
+	movw	%ax, %es			# destination segment
+	incb	%ah				# instead of add ax,#0x100
+	movw	%bx, %ds			# source segment
+	addw	$0x100, %bx
+	subw	%di, %di
+	subw	%si, %si
+	movw 	$0x800, %cx
+	rep
+	movsw
+	cmpw	%bp, %bx			# assume start_sys_seg > 0x200,
+						# so we will perhaps read one
+						# page more than needed, but
+						# never overwrite INITSEG
+						# because destination is a
+						# minimum one page below source
+	jb	do_move
+
+end_move:
+# then we load the segment descriptors
+	movw	%cs, %ax			# aka SETUPSEG
+	movw	%ax, %ds
+               
+# Check whether we need to be downward compatible with version <=201
+	cmpl	$0, cmd_line_ptr
+	jne	end_move_self		# loader uses version >=202 features
+	cmpb	$0x20, type_of_loader
+	je	end_move_self		# bootsect loader, we know of it
+ 
+# Boot loader does not support boot protocol version 2.02.
+# If we have our code not at 0x90000, we need to move it there now.
+# We also then need to move the params behind it (commandline)
+# Because we would overwrite the code on the current IP, we move
+# it in two steps, jumping high after the first one.
+	movw	%cs, %ax
+	cmpw	$SETUPSEG, %ax
+	je	end_move_self
+
+	cli					# make sure we really have
+						# interrupts disabled !
+						# because after this the stack
+						# should not be used
+	subw	$DELTA_INITSEG, %ax		# aka INITSEG
+	movw	%ss, %dx
+	cmpw	%ax, %dx
+	jb	move_self_1
+
+	addw	$INITSEG, %dx
+	subw	%ax, %dx			# this will go into %ss after
+						# the move
+move_self_1:
+	movw	%ax, %ds
+	movw	$INITSEG, %ax			# real INITSEG
+	movw	%ax, %es
+	movw	%cs:setup_move_size, %cx
+	std					# we have to move up, so we use
+						# direction down because the
+						# areas may overlap
+	movw	%cx, %di
+	decw	%di
+	movw	%di, %si
+	subw	$move_self_here+0x200, %cx
+	rep
+	movsb
+	ljmp	$SETUPSEG, $move_self_here
+
+move_self_here:
+	movw	$move_self_here+0x200, %cx
+	rep
+	movsb
+	movw	$SETUPSEG, %ax
+	movw	%ax, %ds
+	movw	%dx, %ss
+
+end_move_self:					# now we are at the right place
+	lidt	idt_48				# load idt with 0,0
+	xorl	%eax, %eax			# Compute gdt_base
+	movw	%ds, %ax			# (Convert %ds:gdt to a linear ptr)
+	shll	$4, %eax
+	addl	$gdt, %eax
+	movl	%eax, (gdt_48+2)
+	lgdt	gdt_48				# load gdt with whatever is
+						# appropriate
+
+# that was painless, now we enable A20
+
+	outb	%al, $0xf2			# A20 on
+	movb	$0x02, %al
+	outb	%al, $0xf6			# also A20 on; making ITF's
+						# way our model
+
+	# PC-9800 seems to enable A20 at the moment of `outb';
+	# so we don't wait unlike IBM PCs (see ../setup.S).
+
+# enable DMA to access memory over 0x100000 (1MB).
+
+	movw	$0x439, %dx
+	inb	%dx, %al
+	andb	$(~4), %al
+	outb	%al, %dx
+
+# Set DMA to increment its bank address automatically at 16MB boundary.
+# Initial setting is 64KB boundary mode so that we can't run DMA crossing
+# physical address 0xXXXXFFFF.
+
+	movb	$0x0c, %al
+	outb	%al, $0x29			# ch. 0
+	movb	$0x0d, %al
+	outb	%al, $0x29			# ch. 1
+	movb	$0x0e, %al
+	outb	%al, $0x29			# ch. 2
+	movb	$0x0f, %al
+	outb	%al, $0x29			# ch. 3
+	movb	$0x50, %al
+	outb	%al, $0x11			# reinitialize DMAC
+
+# make sure any possible coprocessor is properly reset..
+	movb	$0, %al
+	outb	%al, $0xf8
+	outb	%al, $0x5f			# delay
+
+# well, that went ok, I hope. Now we mask all interrupts - the rest
+# is done in init_IRQ().
+	movb	$0xFF, %al			# mask all interrupts for now
+	outb	%al, $0x0A
+	outb	%al, $0x5f			# delay
+	
+	movb	$0x7F, %al			# mask all irq's but irq7 which
+	outb	%al, $0x02			# is cascaded
+
+# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
+# need no steenking BIOS anyway (except for the initial loading :-).
+# The BIOS-routine wants lots of unnecessary data, and it's less
+# "interesting" anyway. This is how REAL programmers do it.
+#
+# Well, now's the time to actually move into protected mode. To make
+# things as simple as possible, we do no register set-up or anything,
+# we let the gnu-compiled 32-bit programs do that. We just jump to
+# absolute address 0x1000 (or the loader supplied one),
+# in 32-bit protected mode.
+#
+# Note that the short jump isn't strictly needed, although there are
+# reasons why it might be a good idea. It won't hurt in any case.
+	movw	$1, %ax				# protected mode (PE) bit
+	lmsw	%ax				# This is it!
+	jmp	flush_instr
+
+flush_instr:
+	xorw	%bx, %bx			# Flag to indicate a boot
+	xorl	%esi, %esi			# Pointer to real-mode code
+	movw	%cs, %si
+	subw	$DELTA_INITSEG, %si
+	shll	$4, %esi			# Convert to 32-bit pointer
+# NOTE: For high loaded big kernels we need a
+#	jmpi    0x100000,__BOOT_CS
+#
+#	but we yet haven't reloaded the CS register, so the default size 
+#	of the target offset still is 16 bit.
+#       However, using an operand prefix (0x66), the CPU will properly
+#	take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
+#	Manual, Mixing 16-bit and 32-bit code, page 16-6)
+
+	.byte 0x66, 0xea			# prefix + jmpi-opcode
+code32:	.long	0x1000				# will be set to 0x100000
+						# for big kernels
+	.word	__BOOT_CS
+
+# Here's a bunch of information about your current kernel..
+kernel_version:	.ascii	UTS_RELEASE
+		.ascii	" ("
+		.ascii	LINUX_COMPILE_BY
+		.ascii	"@"
+		.ascii	LINUX_COMPILE_HOST
+		.ascii	") "
+		.ascii	UTS_VERSION
+		.byte	0
+
+# This is the default real mode switch routine.
+# to be called just before protected mode transition
+default_switch:
+	cli					# no interrupts allowed !
+	outb	%al, $0x50			# disable NMI for bootup
+						# sequence
+	lret
+
+# This routine only gets called, if we get loaded by the simple
+# bootsect loader _and_ have a bzImage to load.
+# Because there is no place left in the 512 bytes of the boot sector,
+# we must emigrate to code space here.
+bootsect_helper:
+	cmpw	$0, %cs:bootsect_es
+	jnz	bootsect_second
+
+	movb	$0x20, %cs:type_of_loader
+	movw	%es, %ax
+	shrw	$4, %ax
+	movb	%ah, %cs:bootsect_src_base+2
+	movw	%es, %ax
+	movw	%ax, %cs:bootsect_es
+	subw	$SYSSEG, %ax
+	lret					# nothing else to do for now
+
+bootsect_second:
+	pushw	%bx
+	pushw	%cx
+	pushw	%si
+	pushw	%di
+	testw	%bp, %bp			# 64K full ?
+	jne	bootsect_ex
+
+	xorw	%cx, %cx			# zero means full 64K
+	pushw	%cs
+	popw	%es
+	movw	$bootsect_gdt, %bx
+	xorw	%si, %si			# source address
+	xorw	%di, %di			# destination address
+	movb	$0x90, %ah
+	int	$0x1f
+	jc	bootsect_panic			# this, if INT1F fails
+
+	movw	%cs:bootsect_es, %es		# we reset %es to always point
+	incb	%cs:bootsect_dst_base+2		# to 0x10000
+bootsect_ex:
+	movb	%cs:bootsect_dst_base+2, %ah
+	shlb	$4, %ah				# we now have the number of
+						# moved frames in %ax
+	xorb	%al, %al
+	popw	%di
+	popw	%si
+	popw	%cx
+	popw	%bx
+	lret
+
+bootsect_gdt:
+	.word	0, 0, 0, 0
+	.word	0, 0, 0, 0
+
+bootsect_src:
+	.word	0xffff
+
+bootsect_src_base:
+	.byte	0x00, 0x00, 0x01		# base = 0x010000
+	.byte	0x93				# typbyte
+	.word	0				# limit16,base24 =0
+
+bootsect_dst:
+	.word	0xffff
+
+bootsect_dst_base:
+	.byte	0x00, 0x00, 0x10		# base = 0x100000
+	.byte	0x93				# typbyte
+	.word	0				# limit16,base24 =0
+	.word	0, 0, 0, 0			# BIOS CS
+	.word	0, 0, 0, 0			# BIOS DS
+
+bootsect_es:
+	.word	0
+
+bootsect_panic:
+	pushw	%cs
+	popw	%ds
+	cld
+	leaw	bootsect_panic_mess, %si
+	call	prtstr
+
+bootsect_panic_loop:
+	jmp	bootsect_panic_loop
+
+bootsect_panic_mess:
+	.string	"INT1F refuses to access high mem, giving up."
+
+# This routine prints one character (in %al) on console.
+# PC-9800 doesn't have BIOS-function to do it like IBM PC's INT 10h - 0Eh,
+# so we hardcode `prtchr' subroutine here.
+prtchr:
+	pushaw
+	pushw	%es
+	cmpb	$0, %cs:prtchr_initialized
+	jnz	prtchr_ok
+	xorw	%cx, %cx
+	movw	%cx, %es
+	testb	$0x8, %es:BIOS_FLAG
+	jz	1f
+	movb	$(HIRESO_TEXT >> 8), %cs:cursor_address+3
+	movw	$(80 * 31 * 2), %cs:max_cursor_offset
+1:	pushw	%ax
+	call	get_cursor_position
+	movw	%ax, %cs:cursor_address
+	popw	%ax
+	movb	$1, %cs:prtchr_initialized
+prtchr_ok:
+	lesw	%cs:cursor_address, %di
+	movw	$160, %bx
+	movb	$0, %ah
+	cmpb	$13, %al
+	je	do_cr
+	cmpb	$10, %al
+	je	do_lf
+
+	# normal (printable) character
+	stosw
+	movb	$0xe1, %es:0x2000-2(%di)
+	jmp	1f
+
+do_cr:	movw	%di, %ax
+	divb	%bl				# %al = Y, %ah = X * 2
+	mulb	%bl
+	movw	%ax, %dx
+	jmp	2f
+
+do_lf:	addw	%bx, %di
+1:	movw	%cs:max_cursor_offset, %cx
+	cmpw	%cx, %di
+	movw	%di, %dx
+	jb	2f
+	# cursor reaches bottom of screen; scroll it
+	subw	%bx, %dx
+	xorw	%di, %di
+	movw	%bx, %si
+	cld
+	subw	%bx, %cx
+	shrw	%cx
+	pushw	%cx
+	rep; es; movsw
+	movb	$32, %al			# clear bottom line characters
+	movb	$80, %cl
+	rep; stosw
+	movw	$0x2000, %di
+	popw	%cx
+	leaw	(%bx,%di), %si
+	rep; es; movsw
+	movb	$0xe1, %al			# clear bottom line attributes
+	movb	$80, %cl
+	rep; stosw
+2:	movw	%dx, %cs:cursor_address
+	movb	$0x13, %ah			# move cursor to right position
+	int	$0x18
+	popw	%es
+	popaw
+	ret
+
+cursor_address:
+	.word	0
+	.word	NORMAL_TEXT
+max_cursor_offset:
+	.word	80 * 25 * 2			# for normal 80x25 mode
+
+# putstr may called without running through start_of_setup (via bootsect_panic)
+# so we should initialize ourselves on demand.
+prtchr_initialized:
+	.byte	0
+
+# This routine queries GDC (graphic display controller) for current cursor
+# position. Cursor position is returned in %ax (CPU offset address).
+get_cursor_position:
+1:	inb	$0x60, %al
+	outb	%al, $0x5f			# delay
+	outb	%al, $0x5f			# delay
+	testb	$0x04, %al			# Is FIFO empty?
+	jz	1b				# no -> wait until empty
+
+	movb	$0xe0, %al			# CSRR command
+	outb	%al, $0x62			# command write
+	outb	%al, $0x5f			# delay
+	outb	%al, $0x5f			# delay
+
+2:	inb	$0x60, %al
+	outb	%al, $0x5f			# delay
+	outb	%al, $0x5f			# delay
+	testb	$0x01, %al			# Is DATA READY?
+	jz	2b				# no -> wait until ready
+
+	inb	$0x62, %al			# read xAD (L)
+	outb	%al, $0x5f			# delay
+	outb	%al, $0x5f			# delay
+	movb	%al, %ah
+	inb	$0x62, %al			# read xAD (H)
+	outb	%al, $0x5f			# delay
+	outb	%al, $0x5f			# delay
+	xchgb	%al, %ah			# correct byte order
+	pushw	%ax
+	inb	$0x62, %al			# read yAD (L)
+	outb	%al, $0x5f			# delay
+	outb	%al, $0x5f			# delay
+	inb	$0x62, %al			# read yAD (M)
+	outb	%al, $0x5f			# delay
+	outb	%al, $0x5f			# delay
+	inb	$0x62, %al			# read yAD (H)
+						# yAD is not our interest,
+						# so discard it.
+	popw	%ax
+	addw	%ax, %ax			# convert to CPU address
+	ret
+
+# Descriptor tables
+#
+# NOTE: The intel manual says gdt should be sixteen bytes aligned for
+# efficiency reasons.  However, there are machines which are known not
+# to boot with misaligned GDTs, so alter this at your peril!  If you alter
+# GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two
+# empty GDT entries (one for NULL and one reserved).
+#
+# NOTE:	On some CPUs, the GDT must be 8 byte aligned.  This is
+# true for the Voyager Quad CPU card which will not boot without
+# This directive.  16 byte aligment is recommended by intel.
+#
+	.align 16
+gdt:
+	.fill GDT_ENTRY_BOOT_CS,8,0
+
+	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
+	.word	0				# base address = 0
+	.word	0x9A00				# code read/exec
+	.word	0x00CF				# granularity = 4096, 386
+						#  (+5th nibble of limit)
+
+	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
+	.word	0				# base address = 0
+	.word	0x9200				# data read/write
+	.word	0x00CF				# granularity = 4096, 386
+						#  (+5th nibble of limit)
+gdt_end:
+	.align	4
+	
+	.word	0				# alignment byte
+idt_48:
+	.word	0				# idt limit = 0
+	.word	0, 0				# idt base = 0L
+
+	.word	0				# alignment byte
+gdt_48:
+	.word	gdt_end - gdt - 1		# gdt limit
+	.word	0, 0				# gdt base (filled in later)
+
+# Include video setup & detection code
+
+#include "video.S"
+
+# Setup signature -- must be last
+setup_sig1:	.word	SIG1
+setup_sig2:	.word	SIG2
+
+# After this point, there is some free space which is used by the video mode
+# handling code to store the temporary mode table (not used by the kernel).
+
+modelist:
+
+.text
+endtext:
+.data
+enddata:
+.bss
+endbss:
diff -Nru a/arch/i386/boot98/tools/build.c b/arch/i386/boot98/tools/build.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/boot98/tools/build.c	Sun Mar 23 08:36:08 2003
@@ -0,0 +1,185 @@
+/*
+ *  $Id: build.c,v 1.5 1997/05/19 12:29:58 mj Exp $
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 1997 Martin Mares
+ */
+
+/*
+ * This file builds a disk-image from three different files:
+ *
+ * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest
+ * - setup: 8086 machine code, sets up system parm
+ * - system: 80386 code for actual system
+ *
+ * It does some checking that all files are of the correct type, and
+ * just writes the result to stdout, removing headers and padding to
+ * the right amount. It also writes some system data to stderr.
+ */
+
+/*
+ * Changes by tytso to allow root device specification
+ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+ * Cross compiling fixes by Gertjan van Wingerde, July 1996
+ * Rewritten by Martin Mares, April 1997
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <asm/boot.h>
+
+typedef unsigned char byte;
+typedef unsigned short word;
+typedef unsigned long u32;
+
+#define DEFAULT_MAJOR_ROOT 0
+#define DEFAULT_MINOR_ROOT 0
+
+/* Minimal number of setup sectors (see also bootsect.S) */
+#define SETUP_SECTS 4
+
+byte buf[1024];
+int fd;
+int is_big_kernel;
+
+void die(const char * str, ...)
+{
+	va_list args;
+	va_start(args, str);
+	vfprintf(stderr, str, args);
+	fputc('\n', stderr);
+	exit(1);
+}
+
+void file_open(const char *name)
+{
+	if ((fd = open(name, O_RDONLY, 0)) < 0)
+		die("Unable to open `%s': %m", name);
+}
+
+void usage(void)
+{
+	die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
+}
+
+int main(int argc, char ** argv)
+{
+	unsigned int i, c, sz, setup_sectors;
+	u32 sys_size;
+	byte major_root, minor_root;
+	struct stat sb;
+
+	if (argc > 2 && !strcmp(argv[1], "-b"))
+	  {
+	    is_big_kernel = 1;
+	    argc--, argv++;
+	  }
+	if ((argc < 4) || (argc > 5))
+		usage();
+	if (argc > 4) {
+		if (!strcmp(argv[4], "CURRENT")) {
+			if (stat("/", &sb)) {
+				perror("/");
+				die("Couldn't stat /");
+			}
+			major_root = major(sb.st_dev);
+			minor_root = minor(sb.st_dev);
+		} else if (strcmp(argv[4], "FLOPPY")) {
+			if (stat(argv[4], &sb)) {
+				perror(argv[4]);
+				die("Couldn't stat root device.");
+			}
+			major_root = major(sb.st_rdev);
+			minor_root = minor(sb.st_rdev);
+		} else {
+			major_root = 0;
+			minor_root = 0;
+		}
+	} else {
+		major_root = DEFAULT_MAJOR_ROOT;
+		minor_root = DEFAULT_MINOR_ROOT;
+	}
+	fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
+
+	file_open(argv[1]);
+	i = read(fd, buf, sizeof(buf));
+	fprintf(stderr,"Boot sector %d bytes.\n",i);
+	if (i != 512)
+		die("Boot block must be exactly 512 bytes");
+	if (buf[510] != 0x55 || buf[511] != 0xaa)
+		die("Boot block hasn't got boot flag (0xAA55)");
+	buf[508] = minor_root;
+	buf[509] = major_root;
+	if (write(1, buf, 512) != 512)
+		die("Write call failed");
+	close (fd);
+
+	file_open(argv[2]);				    /* Copy the setup code */
+	for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
+		if (write(1, buf, c) != c)
+			die("Write call failed");
+	if (c != 0)
+		die("read-error on `setup'");
+	close (fd);
+
+	setup_sectors = (i + 511) / 512;	/* Pad unused space with zeros */
+	if (!(setup_sectors & 1))
+		setup_sectors++;    /* setup_sectors must be odd on NEC PC-9800 */
+	fprintf(stderr, "Setup is %d bytes.\n", i);
+	memset(buf, 0, sizeof(buf));
+	while (i < setup_sectors * 512) {
+		c = setup_sectors * 512 - i;
+		if (c > sizeof(buf))
+			c = sizeof(buf);
+		if (write(1, buf, c) != c)
+			die("Write call failed");
+		i += c;
+	}
+
+	file_open(argv[3]);
+	if (fstat (fd, &sb))
+		die("Unable to stat `%s': %m", argv[3]);
+	sz = sb.st_size;
+	fprintf (stderr, "System is %d kB\n", sz/1024);
+	sys_size = (sz + 15) / 16;
+	/* 0x40000*16 = 4.0 MB, reasonable estimate for the current maximum */
+	if (sys_size > (is_big_kernel ? 0x40000 : DEF_SYSSIZE))
+		die("System is too big. Try using %smodules.",
+			is_big_kernel ? "" : "bzImage or ");
+	while (sz > 0) {
+		int l, n;
+
+		l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
+		if ((n=read(fd, buf, l)) != l) {
+			if (n < 0)
+				die("Error reading %s: %m", argv[3]);
+			else
+				die("%s: Unexpected EOF", argv[3]);
+		}
+		if (write(1, buf, l) != l)
+			die("Write failed");
+		sz -= l;
+	}
+	close(fd);
+
+	if (lseek(1, 497, SEEK_SET) != 497)		    /* Write sizes to the bootsector */
+		die("Output: seek failed");
+	buf[0] = setup_sectors;
+	if (write(1, buf, 1) != 1)
+		die("Write of setup sector count failed");
+	if (lseek(1, 500, SEEK_SET) != 500)
+		die("Output: seek failed");
+	buf[0] = (sys_size & 0xff);
+	buf[1] = ((sys_size >> 8) & 0xff);
+	if (write(1, buf, 2) != 2)
+		die("Write of image length failed");
+
+	return 0;					    /* Everything is OK */
+}
diff -Nru a/arch/i386/boot98/video.S b/arch/i386/boot98/video.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/boot98/video.S	Fri Feb 14 14:38:01 2003
@@ -0,0 +1,262 @@
+/*	video.S
+ *
+ *  Video mode setup, etc. for NEC PC-9800 series.
+ *
+ *  Copyright (C) 1997,98,99  Linux/98 project  <seraphim@kmc.kyoto-u.ac.jp>
+ *
+ *  Based on the video.S for IBM PC:
+ *	copyright (C) Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+
+/* Positions of various video parameters passed to the kernel */
+/* (see also include/linux/tty.h) */
+#define PARAM_CURSOR_POS	0x00
+#define PARAM_VIDEO_PAGE	0x04
+#define PARAM_VIDEO_MODE	0x06
+#define PARAM_VIDEO_COLS	0x07
+#define PARAM_VIDEO_EGA_BX	0x0a
+#define PARAM_VIDEO_LINES	0x0e
+#define PARAM_HAVE_VGA		0x0f
+#define PARAM_FONT_POINTS	0x10
+
+#define PARAM_VIDEO98_COMPAT	0x0a
+#define PARAM_VIDEO98_HIRESO	0x0b
+#define PARAM_VIDEO98_MACHTYPE	0x0c
+#define PARAM_VIDEO98_LINES	0x0e
+#define PARAM_VIDEO98_COLS	0x0f
+
+# PARAM_LFB_* and PARAM_VESAPM_* are unused on PC-9800.
+
+# This is the main entry point called by setup.S
+# %ds *must* be pointing to the bootsector
+video:	xorw	%ax, %ax
+	movw	%ax, %es			# %es = 0
+
+	movb	%es:BIOS_FLAG, %al
+	movb	%al, PARAM_VIDEO_MODE
+
+	movb	$0, PARAM_VIDEO98_HIRESO	# 0 = normal
+	movw	$NORMAL_TEXT, PARAM_VIDEO_PAGE
+	testb	$0x8, %al
+	movw	$(80 * 256 + 25), %ax
+	jz	1f
+	# hireso machine.
+	movb	$1, PARAM_VIDEO98_HIRESO	# !0 = hi-reso
+	movb	$(HIRESO_TEXT >> 8), PARAM_VIDEO_PAGE + 1
+	movw	$(80 * 256 + 31), %ax
+1:	movw	%ax, PARAM_VIDEO98_LINES	# also sets VIDEO98_COLS
+
+	movb	$0xc0, %ch			# 400-line graphic mode
+	movb	$0x42, %ah
+	int	$0x18
+
+	movw	$80, PARAM_VIDEO_COLS
+
+	movw	$msg_probing, %si
+	call	prtstr_cs
+
+# Check vendor from font pattern of `A'...
+
+1:	inb	$0x60, %al			# wait V-sync
+	testb	$0x20, %al
+	jnz	1b
+2:	inb	$0x60, %al
+	testb	$0x20, %al
+	jz	2b
+
+	movb	$0x00, %al			# select font of `A'
+	outb	%al, $0xa1
+	movb	$0x41, %al
+	outb	%al, $0xa3
+
+	movw	$8, %cx
+	movw	PARAM_VIDEO_PAGE, %ax
+	cmpw	$NORMAL_TEXT, %ax
+	je	3f
+	movb	$24, %cl			# for hi-reso machine
+3:	addw	$0x400, %ax			# %ax = CG window segment
+	pushw	%ds
+	movw	%ax, %ds
+	xorw	%dx, %dx			# get sum of `A' pattern...
+	xorw	%si, %si
+4:	lodsw
+	addw	%ax, %dx
+	loop	4b
+	popw	%ds
+
+	movw	%dx, %ax
+	movw	$msg_nec, %si
+	xorw	%bx, %bx			# vendor info will go into %bx
+	testb	$8, %es:BIOS_FLAG
+	jnz	check_hireso_vendor
+	cmpw	$0xc7f8, %ax
+	je	5f
+	jmp	6f
+check_hireso_vendor:
+	cmpw	$0x9639, %ax			# XXX: NOT VERIFIED!!!
+	je	5f
+6:	incw	%bx				# compatible machine
+	movw	$msg_compat, %si
+5:	movb	%bl, PARAM_VIDEO98_COMPAT
+	call	prtstr_cs
+
+	movw	$msg_fontdata, %si
+	call	prtstr_cs			# " (CG sum of A = 0x"
+	movw	%dx, %ax
+	call	prthex
+	call	prtstr_cs			# ") PC-98"
+
+	movb	$'0', %al
+	pushw	%ds
+	pushw	$0xf8e8
+	popw	%ds
+	cmpw	$0x2198, (0)
+	popw	%ds
+	jne	7f
+	movb	$'2', %al
+7:	call	prtchr
+	call	prtstr_cs			# "1 "
+
+	movb	$0, PARAM_VIDEO98_MACHTYPE
+#if 0	/* XXX - This check is bogus? [0000:BIOS_FLAG2]-bit7 does NOT
+		 indicate whether it is a note machine, but merely indicates
+		 whether it has ``RAM drive''. */
+# check note machine
+	testb	$0x80, %es:BIOS_FLAG2
+	jnz	is_note
+	pushw	%ds
+	pushw	$0xfd80
+	popw	%ds
+	movb	(4), %al
+	popw	%ds
+	cmpb	$0x20, %al			# EPSON note A
+	je	epson_note
+	cmpb	$0x22, %al			# EPSON note W
+	je	epson_note
+	cmpb	$0x27, %al			# EPSON note AE
+	je	epson_note
+	cmpb	$0x2a, %al			# EPSON note WR
+	jne	note_done
+epson_note:
+	movb	$1, PARAM_VIDEO98_MACHTYPE
+	movw	$msg_note, %si
+	call	prtstr_cs
+note_done:
+#endif
+	
+# print h98 ? (only NEC)
+	cmpb	$0, PARAM_VIDEO98_COMPAT
+	jnz	8f				# not NEC -> not H98
+
+	testb	$0x80, %es:BIOS_FLAG5
+	jz	8f				# have NESA bus -> H98
+	movw	$msg_h98, %si
+	call	prtstr_cs
+	orb	$2, PARAM_VIDEO98_MACHTYPE
+8:	testb	$0x40, %es:BIOS_FLAG5
+	jz	9f
+	movw	$msg_gs, %si
+	call	prtstr_cs			# only prints it :-)
+9:
+	movw	$msg_normal, %si		# "normal"
+	testb	$0x8, %es:BIOS_FLAG
+	jz	1f
+	movw	$msg_hireso, %si
+1:	call	prtstr_cs
+
+	movw	$msg_sysclk, %si
+	call	prtstr_cs
+	movb	$'5', %al
+	testb	$0x80, %es:BIOS_FLAG
+	jz	2f
+	movb	$'8', %al
+2:	call	prtchr
+	call	prtstr_cs
+
+#if 0
+	testb	$0x40, %es:(0x45c)
+	jz	no_30line			# no 30-line support
+
+	movb	%es:KB_SHFT_STS, %al
+	testb	$0x01, %al			# is SHIFT key pressed?
+	jz	no_30line
+
+	testb	$0x10, %al			# is CTRL key pressed?
+	jnz	line40
+
+	# switch to 30-line mode
+	movb	$30, PARAM_VIDEO98_LINES
+	movw	$msg_30line, %si
+	jmp	3f
+
+line40:
+	movb	$37, PARAM_VIDEO98_LINES
+	movw	$40, PARAM_VIDEO_LINES
+	movw	$msg_40line, %si
+3:	call	prtstr_cs
+
+	movb	$0x32, %bh
+	movw	$0x300c, %ax
+	int	$0x18				# switch video mode
+	movb	$0x0c, %ah
+	int	$0x18				# turn on text plane
+	movw	%cs:cursor_address, %dx
+	movb	$0x13, %ah
+	int	$0x18				# move cursor to correct place
+	mov	$0x11, %ah
+	int	$0x18				# turn on text plane
+
+	call	prtstr_cs			# "Ok.\r\n"
+no_30line:
+#endif
+	ret
+
+prtstr_cs:
+	pushw	%ds
+	pushw	%cs
+	popw	%ds
+	call	prtstr
+	popw	%ds
+	ret
+
+# prthex is for debugging purposes, and prints %ax in hexadecimal.
+prthex:	pushw	%cx
+	movw	$4, %cx
+1:	rolw	$4, %ax
+	pushw	%ax
+	andb	$0xf, %al
+	cmpb	$10, %al
+	sbbb	$0x69, %al
+	das
+	call	prtchr
+	popw	%ax
+	loop	1b
+	popw	%cx
+	ret
+
+msg_probing:	.string	"Probing machine: "
+
+msg_nec:	.string	"NEC"
+msg_compat:	.string	"compatible"
+
+msg_fontdata:	.string	" (CG sum of A = 0x"
+		.string	") PC-98"
+		.string	"1 "
+
+msg_gs:		.string	"(GS) "
+msg_h98:	.string	"(H98) "
+
+msg_normal:	.string	"normal"
+msg_hireso:	.string	"Hi-reso"
+
+msg_sysclk:	.string	" mode, system clock "
+		.string	"MHz\r\n"
+
+#if 0
+msg_40line:	# cpp will concat following lines, so the assembler can deal.
+		.ascii	"\
+Video mode will be adjusted to 37-line (so-called ``40-line'') mode later.\r\n\
+THIS MODE MAY DAMAGE YOUR MONITOR PHYSICALLY. USE AT YOUR OWN RISK.\r\n"
+msg_30line:	.string	"Switching video mode to 30-line (640x480) mode... "
+		.string	"Ok.\r\n"
+#endif
diff -Nru a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c	Tue Mar 11 17:20:59 2003
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c	Mon Mar 17 05:50:14 2003
@@ -525,9 +525,6 @@
 {
 	struct cpuinfo_x86 *c = cpu_data;
 
-	if ((c->x86_vendor != X86_VENDOR_CENTAUR) || (c->x86 !=6) )
-		return -ENODEV;
-
 	switch (c->x86_model) {
 	case 6:		/* VIA C3 Samuel C5A */
 		longhaul=1;
diff -Nru a/arch/i386/kernel/cpu/cpufreq/longrun.c b/arch/i386/kernel/cpu/cpufreq/longrun.c
--- a/arch/i386/kernel/cpu/cpufreq/longrun.c	Sat Mar  8 01:37:35 2003
+++ b/arch/i386/kernel/cpu/cpufreq/longrun.c	Mon Mar 17 05:54:38 2003
@@ -229,9 +229,6 @@
 	/* capability check */
 	if (policy->cpu != 0)
 		return -ENODEV;
-	if (c->x86_vendor != X86_VENDOR_TRANSMETA || 
-	    !cpu_has(c, X86_FEATURE_LONGRUN))
-		return -ENODEV;
 
 	/* detect low and high frequency */
 	result = longrun_determine_freqs(&longrun_low_freq, &longrun_high_freq);
diff -Nru a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	Sat Mar  8 01:39:17 2003
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	Mon Mar 17 05:57:02 2003
@@ -180,13 +180,6 @@
 	int cpuid = 0;
 	unsigned int i;
 
-	/* capability check */
-	if (c->x86_vendor != X86_VENDOR_INTEL)
-		return -ENODEV;
-	if (!test_bit(X86_FEATURE_ACPI, c->x86_capability) ||
-	    !test_bit(X86_FEATURE_ACC, c->x86_capability))
-		return -ENODEV;
-	
 	/* Errata workaround */
 	cpuid = (c->x86 << 8) | (c->x86_model << 4) | c->x86_mask;
 	switch (cpuid) {
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c	Sat Mar  8 01:37:35 2003
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c	Mon Mar 17 05:53:03 2003
@@ -145,10 +145,6 @@
 	struct cpuinfo_x86 *c = cpu_data;
 	unsigned int i;
 
-	/* capability check */
-	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
-	    ((c->x86_model != 12) && (c->x86_model != 13)))
-		return -ENODEV;
 	if (policy->cpu != 0)
 		return -ENODEV;
 
diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
--- a/arch/i386/kernel/dmi_scan.c	Thu Mar 13 12:16:41 2003
+++ b/arch/i386/kernel/dmi_scan.c	Thu Mar 20 16:00:01 2003
@@ -499,6 +499,19 @@
 	return 0;
 }
 
+/*
+ *	Exploding PnPBIOS. Don't yet know if its the BIOS or us for
+ *	some entries
+ */
+
+static __init int exploding_pnp_bios(struct dmi_blacklist *d)
+{
+	printk(KERN_WARNING "%s detected. Disabling PnPBIOS\n", d->ident);
+	dmi_broken |= BROKEN_PNP_BIOS;
+	return 0;
+}
+
+
 
 /*
  *	Simple "print if true" callback
@@ -686,6 +699,13 @@
 			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
 			MATCH(DMI_BIOS_VERSION, "WXPO1Z3"),
 			MATCH(DMI_BIOS_DATE, "10/26/01"), NO_MATCH
+			} },
+			
+	{ exploding_pnp_bios, "Higraded P14H", {	/* BIOSPnP problem */
+			MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
+			MATCH(DMI_BIOS_VERSION, "07.00T"),
+			MATCH(DMI_SYS_VENDOR, "Higraded"),
+			MATCH(DMI_PRODUCT_NAME, "P14H")
 			} },
 
 	/* Machines which have problems handling enabled local APICs */
diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
--- a/arch/i386/kernel/entry.S	Mon Mar 10 14:41:23 2003
+++ b/arch/i386/kernel/entry.S	Thu Mar 20 21:43:55 2003
@@ -73,10 +73,10 @@
 VM_MASK		= 0x00020000
 
 /*
- * ESP0 is at offset 4. 0x100 is the size of the TSS, and
+ * ESP0 is at offset 4. 0x200 is the size of the TSS, and
  * also thus the top-of-stack pointer offset of SYSENTER_ESP
  */
-TSS_ESP0_OFFSET = (4 - 0x100)
+TSS_ESP0_OFFSET = (4 - 0x200)
 
 #ifdef CONFIG_PREEMPT
 #define preempt_stop		cli
@@ -479,23 +479,32 @@
  * by hand onto the new stack - while updating the return eip past
  * the instruction that would have done it for sysenter.
  */
-#define CHECK_SYSENTER_EIP			\
-	cmpl $sysenter_entry,(%esp);		\
-	jne 1f;					\
-	movl TSS_ESP0_OFFSET+12(%esp),%esp;	\
+#define FIX_STACK(offset, ok, label)		\
+	cmpw $__KERNEL_CS,4(%esp);		\
+	jne ok;					\
+label:						\
+	movl TSS_ESP0_OFFSET+offset(%esp),%esp;	\
 	pushfl;					\
 	pushl $__KERNEL_CS;			\
-	pushl $sysenter_past_esp;		\
-1:
+	pushl $sysenter_past_esp
 
 ENTRY(debug)
-	CHECK_SYSENTER_EIP
+	cmpl $sysenter_entry,(%esp)
+	jne debug_stack_correct
+	FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
+debug_stack_correct:
 	pushl $0
 	pushl $do_debug
 	jmp error_code
 
 ENTRY(nmi)
-	CHECK_SYSENTER_EIP
+	cmpl $sysenter_entry,(%esp)
+	je nmi_stack_fixup
+	cmpl $debug - 1,(%esp)
+	jle nmi_stack_correct
+	cmpl $debug_esp_fix_insn,(%esp)
+	jle nmi_debug_stack_fixup
+nmi_stack_correct:
 	pushl %eax
 	SAVE_ALL
 	movl %esp, %edx
@@ -504,6 +513,13 @@
 	call do_nmi
 	addl $8, %esp
 	RESTORE_ALL
+
+nmi_stack_fixup:
+	FIX_STACK(12,nmi_stack_correct, 1)
+	jmp nmi_stack_correct
+nmi_debug_stack_fixup:
+	FIX_STACK(24,nmi_stack_correct, 1)
+	jmp nmi_stack_correct
 
 ENTRY(int3)
 	pushl $0
diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c	Sat Mar  8 14:50:47 2003
+++ b/arch/i386/kernel/io_apic.c	Thu Mar 20 03:11:41 2003
@@ -116,40 +116,84 @@
 	}
 }
 
-#define __DO_ACTION(R, ACTION, FINAL)					\
-									\
-{									\
-	int pin;							\
-	struct irq_pin_list *entry = irq_2_pin + irq;			\
-									\
-	for (;;) {							\
-		unsigned int reg;					\
-		pin = entry->pin;					\
-		if (pin == -1)						\
-			break;						\
-		reg = io_apic_read(entry->apic, 0x10 + R + pin*2);	\
-		reg ACTION;						\
-		io_apic_modify(entry->apic, 0x10 + R + pin*2, reg);	\
-		if (!entry->next)					\
-			break;						\
-		entry = irq_2_pin + entry->next;			\
-	}								\
-	FINAL;								\
-}
-
-#define DO_ACTION(name,R,ACTION, FINAL)					\
-									\
-	static void name##_IO_APIC_irq (unsigned int irq)		\
-	__DO_ACTION(R, ACTION, FINAL)
-
-DO_ACTION( __mask,             0, |= 0x00010000, io_apic_sync(entry->apic) )
-						/* mask = 1 */
-DO_ACTION( __unmask,           0, &= 0xfffeffff, )
-						/* mask = 0 */
-DO_ACTION( __mask_and_edge,    0, = (reg & 0xffff7fff) | 0x00010000, )
-						/* mask = 1, trigger = 0 */
-DO_ACTION( __unmask_and_level, 0, = (reg & 0xfffeffff) | 0x00008000, )
-						/* mask = 0, trigger = 1 */
+/* mask = 1 */
+static void __mask_IO_APIC_irq (unsigned int irq)
+{
+	int pin;
+	struct irq_pin_list *entry = irq_2_pin + irq;
+
+	for (;;) {
+		unsigned int reg;
+		pin = entry->pin;
+		if (pin == -1)
+			break;
+		reg = io_apic_read(entry->apic, 0x10 + pin*2);
+		io_apic_modify(entry->apic, 0x10 + pin*2, reg |= 0x00010000);
+		if (!entry->next)
+			break;
+		entry = irq_2_pin + entry->next;
+	}
+	io_apic_sync(entry->apic);
+}
+
+/* mask = 0 */
+static void __unmask_IO_APIC_irq (unsigned int irq)
+{
+	int pin;
+	struct irq_pin_list *entry = irq_2_pin + irq;
+
+	for (;;) {
+		unsigned int reg;
+		pin = entry->pin;
+		if (pin == -1)
+			break;
+		reg = io_apic_read(entry->apic, 0x10 + pin*2);
+		io_apic_modify(entry->apic, 0x10 + pin*2, reg &= 0xfffeffff);
+		if (!entry->next)
+			break;
+		entry = irq_2_pin + entry->next;
+	}
+}
+
+/* mask = 1, trigger = 0 */
+static void __mask_and_edge_IO_APIC_irq (unsigned int irq)
+{
+	int pin;
+	struct irq_pin_list *entry = irq_2_pin + irq;
+
+	for (;;) {
+		unsigned int reg;
+		pin = entry->pin;
+		if (pin == -1)
+			break;
+		reg = io_apic_read(entry->apic, 0x10 + pin*2);
+		reg = (reg & 0xffff7fff) | 0x00010000;
+		io_apic_modify(entry->apic, 0x10 + pin*2, reg);
+		if (!entry->next)
+			break;
+		entry = irq_2_pin + entry->next;
+	}
+}
+
+/* mask = 0, trigger = 1 */
+static void __unmask_and_level_IO_APIC_irq (unsigned int irq)
+{
+	int pin;
+	struct irq_pin_list *entry = irq_2_pin + irq;
+
+	for (;;) {
+		unsigned int reg;
+		pin = entry->pin;
+		if (pin == -1)
+			break;
+		reg = io_apic_read(entry->apic, 0x10 + pin*2);
+		reg = (reg & 0xfffeffff) | 0x00008000;
+		io_apic_modify(entry->apic, 0x10 + pin*2, reg);
+		if (!entry->next)
+			break;
+		entry = irq_2_pin + entry->next;
+	}
+}
 
 static void mask_IO_APIC_irq (unsigned int irq)
 {
@@ -197,13 +241,23 @@
 static void set_ioapic_affinity (unsigned int irq, unsigned long mask)
 {
 	unsigned long flags;
+	int pin;
+	struct irq_pin_list *entry = irq_2_pin + irq;
 
 	/*
 	 * Only the first 8 bits are valid.
 	 */
 	mask = mask << 24;
 	spin_lock_irqsave(&ioapic_lock, flags);
-	__DO_ACTION(1, = mask, )
+	for (;;) {
+		pin = entry->pin;
+		if (pin == -1)
+			break;
+		io_apic_write(entry->apic, 0x10 + 1 + pin*2, mask);
+		if (!entry->next)
+			break;
+		entry = irq_2_pin + entry->next;
+	}
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
@@ -743,6 +797,30 @@
 }
 
 /*
+ * This function currently is only a helper for the i386 smp boot process where 
+ * we need to reprogram the ioredtbls to cater for the cpus which have come online
+ * so mask in all cases should simply be TARGET_CPUS
+ */
+void __init setup_ioapic_dest (unsigned long mask)
+{
+	int pin, ioapic, irq, irq_entry;
+
+	if (skip_ioapic_setup == 1)
+		return;
+
+	for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
+		for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
+			irq_entry = find_irq_entry(ioapic, pin, mp_INT);
+			if (irq_entry == -1)
+				continue;
+			irq = pin_2_irq(irq_entry, ioapic, pin);
+			set_ioapic_affinity(irq, mask);
+		}
+
+	}
+}
+
+/*
  * EISA Edge/Level control register, ELCR
  */
 static int __init EISA_ELCR(unsigned int irq)
@@ -2003,7 +2081,7 @@
 	}
 	printk(" failed.\n");
 
-	if (nmi_watchdog) {
+	if (nmi_watchdog == NMI_IO_APIC) {
 		printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
 		nmi_watchdog = 0;
 	}
diff -Nru a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
--- a/arch/i386/kernel/irq.c	Sat Mar  8 14:50:44 2003
+++ b/arch/i386/kernel/irq.c	Thu Mar 20 03:11:45 2003
@@ -744,6 +744,8 @@
 	struct irqaction *old, **p;
 	irq_desc_t *desc = irq_desc + irq;
 
+	if (desc->handler == &no_irq_type)
+		return -ENOSYS;
 	/*
 	 * Some drivers like serial.c use request_irq() heavily,
 	 * so we have to be careful not to interfere with a
diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
--- a/arch/i386/kernel/process.c	Mon Mar 10 10:20:30 2003
+++ b/arch/i386/kernel/process.c	Mon Mar 17 21:32:03 2003
@@ -290,6 +290,7 @@
 {
 	struct pt_regs * childregs;
 	struct task_struct *tsk;
+	int err;
 
 	childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
 	struct_cpy(childregs, regs);
@@ -322,20 +323,27 @@
 		struct user_desc info;
 		int idx;
 
+		err = -EFAULT;
 		if (copy_from_user(&info, (void *)childregs->esi, sizeof(info)))
-			return -EFAULT;
+			goto out;
+		err = -EINVAL;
 		if (LDT_empty(&info))
-			return -EINVAL;
+			goto out;
 
 		idx = info.entry_number;
 		if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
-			return -EINVAL;
+			goto out;
 
 		desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
 		desc->a = LDT_entry_a(&info);
 		desc->b = LDT_entry_b(&info);
 	}
-	return 0;
+
+	err = 0;
+ out:
+	if (err && p->thread.ts_io_bitmap)
+		kfree(p->thread.ts_io_bitmap);
+	return err;
 }
 
 /*
diff -Nru a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
--- a/arch/i386/kernel/reboot.c	Tue Oct  8 15:19:22 2002
+++ b/arch/i386/kernel/reboot.c	Fri Feb 14 14:48:47 2003
@@ -8,6 +8,7 @@
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
 #include <asm/uaccess.h>
+#include "mach_reboot.h"
 
 /*
  * Power off function, if any
@@ -125,15 +126,6 @@
 	0xea, 0x00, 0x00, 0xff, 0xff		/*    ljmp  $0xffff,$0x0000  */
 };
 
-static inline void kb_wait(void)
-{
-	int i;
-
-	for (i=0; i<0x10000; i++)
-		if ((inb_p(0x64) & 0x02) == 0)
-			break;
-}
-
 /*
  * Switch to real mode and then execute the code
  * specified by the code and length parameters.
@@ -264,13 +256,7 @@
 		/* rebooting needs to touch the page at absolute addr 0 */
 		*((unsigned short *)__va(0x472)) = reboot_mode;
 		for (;;) {
-			int i;
-			for (i=0; i<100; i++) {
-				kb_wait();
-				udelay(50);
-				outb(0xfe,0x64);         /* pulse reset low */
-				udelay(50);
-			}
+			mach_reboot();
 			/* That didn't work - force a triple fault.. */
 			__asm__ __volatile__("lidt %0": :"m" (no_idt));
 			__asm__ __volatile__("int3");
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c	Tue Mar  4 23:41:54 2003
+++ b/arch/i386/kernel/smpboot.c	Mon Mar 17 21:31:45 2003
@@ -1155,6 +1155,7 @@
 
 void __init smp_cpus_done(unsigned int max_cpus)
 {
+	setup_ioapic_dest(TARGET_CPUS);
 	zap_low_mappings();
 }
 
diff -Nru a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
--- a/arch/i386/kernel/timers/timer_tsc.c	Sun Mar  2 18:14:23 2003
+++ b/arch/i386/kernel/timers/timer_tsc.c	Thu Mar 20 03:11:42 2003
@@ -213,6 +213,7 @@
 {
 	struct cpufreq_freqs *freq = data;
 
+	write_seqlock(&xtime_lock);
 	if (!ref_freq) {
 		ref_freq = freq->old;
 		loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy;
@@ -232,6 +233,7 @@
 		}
 #endif
 	}
+	write_sequnlock(&xtime_lock);
 
 	return 0;
 }
diff -Nru a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
--- a/arch/i386/kernel/traps.c	Mon Mar 10 10:20:30 2003
+++ b/arch/i386/kernel/traps.c	Mon Mar 17 21:33:07 2003
@@ -247,11 +247,13 @@
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
+	static int die_counter;
+
 	console_verbose();
 	spin_lock_irq(&die_lock);
 	bust_spinlocks(1);
 	handle_BUG(regs);
-	printk("%s: %04lx\n", str, err & 0xffff);
+	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
 	show_registers(regs);
 	bust_spinlocks(0);
 	spin_unlock_irq(&die_lock);
diff -Nru a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c
--- a/arch/i386/lib/usercopy.c	Mon Jan  6 14:58:30 2003
+++ b/arch/i386/lib/usercopy.c	Sat Mar 22 12:06:31 2003
@@ -50,6 +50,26 @@
 		: "memory");						   \
 } while (0)
 
+/**
+ * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
+ * @dst:   Destination address, in kernel space.  This buffer must be at
+ *         least @count bytes long.
+ * @src:   Source address, in user space.
+ * @count: Maximum number of bytes to copy, including the trailing NUL.
+ * 
+ * Copies a NUL-terminated string from userspace to kernel space.
+ * Caller must check the specified block with access_ok() before calling
+ * this function.
+ *
+ * On success, returns the length of the string (not including the trailing
+ * NUL).
+ *
+ * If access to userspace fails, returns -EFAULT (some data may have been
+ * copied).
+ *
+ * If @count is smaller than the length of the string, copies @count bytes
+ * and returns @count.
+ */
 long
 __strncpy_from_user(char *dst, const char *src, long count)
 {
@@ -58,6 +78,24 @@
 	return res;
 }
 
+/**
+ * strncpy_from_user: - Copy a NUL terminated string from userspace.
+ * @dst:   Destination address, in kernel space.  This buffer must be at
+ *         least @count bytes long.
+ * @src:   Source address, in user space.
+ * @count: Maximum number of bytes to copy, including the trailing NUL.
+ * 
+ * Copies a NUL-terminated string from userspace to kernel space.
+ *
+ * On success, returns the length of the string (not including the trailing
+ * NUL).
+ *
+ * If access to userspace fails, returns -EFAULT (some data may have been
+ * copied).
+ *
+ * If @count is smaller than the length of the string, copies @count bytes
+ * and returns @count.
+ */
 long
 strncpy_from_user(char *dst, const char *src, long count)
 {
@@ -93,6 +131,16 @@
 		: "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));	\
 } while (0)
 
+/**
+ * clear_user: - Zero a block of memory in user space.
+ * @to:   Destination address, in user space.
+ * @n:    Number of bytes to zero.
+ *
+ * Zero a block of memory in user space.
+ *
+ * Returns number of bytes that could not be cleared.
+ * On success, this will be zero.
+ */
 unsigned long
 clear_user(void *to, unsigned long n)
 {
@@ -101,6 +149,17 @@
 	return n;
 }
 
+/**
+ * __clear_user: - Zero a block of memory in user space, with less checking.
+ * @to:   Destination address, in user space.
+ * @n:    Number of bytes to zero.
+ *
+ * Zero a block of memory in user space.  Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be cleared.
+ * On success, this will be zero.
+ */
 unsigned long
 __clear_user(void *to, unsigned long n)
 {
@@ -108,12 +167,17 @@
 	return n;
 }
 
-/*
- * Return the size of a string (including the ending 0)
+/**
+ * strlen_user: - Get the size of a string in user space.
+ * @s: The string to measure.
+ * @n: The maximum valid length
  *
- * Return 0 on exception, a value greater than N if too long
+ * Get the size of a NUL-terminated string in user space.
+ *
+ * Returns the size of the string INCLUDING the terminating NUL.
+ * On exception, returns 0.
+ * If the string is too long, returns a value greater than @n.
  */
-
 long strnlen_user(const char *s, long n)
 {
 	unsigned long mask = -__addr_ok(s);
diff -Nru a/arch/i386/mach-pc9800/Makefile b/arch/i386/mach-pc9800/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/mach-pc9800/Makefile	Thu Feb 20 08:28:14 2003
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+#
+
+EXTRA_CFLAGS	+= -I../kernel
+
+obj-y				:= setup.o topology.o
diff -Nru a/arch/i386/mach-pc9800/setup.c b/arch/i386/mach-pc9800/setup.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/mach-pc9800/setup.c	Thu Mar 20 10:43:51 2003
@@ -0,0 +1,117 @@
+/*
+ *	Machine specific setup for pc9800
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/apm_bios.h>
+#include <asm/setup.h>
+#include <asm/arch_hooks.h>
+
+struct sys_desc_table_struct {
+	unsigned short length;
+	unsigned char table[0];
+};
+
+/**
+ * pre_intr_init_hook - initialisation prior to setting up interrupt vectors
+ *
+ * Description:
+ *	Perform any necessary interrupt initialisation prior to setting up
+ *	the "ordinary" interrupt call gates.  For legacy reasons, the ISA
+ *	interrupts should be initialised here if the machine emulates a PC
+ *	in any way.
+ **/
+void __init pre_intr_init_hook(void)
+{
+	init_ISA_irqs();
+}
+
+/*
+ * IRQ7 is cascade interrupt to second interrupt controller
+ */
+static struct irqaction irq7 = { no_action, 0, 0, "cascade", NULL, NULL};
+
+/**
+ * intr_init_hook - post gate setup interrupt initialisation
+ *
+ * Description:
+ *	Fill in any interrupts that may have been left out by the general
+ *	init_IRQ() routine.  interrupts having to do with the machine rather
+ *	than the devices on the I/O bus (like APIC interrupts in intel MP
+ *	systems) are started here.
+ **/
+void __init intr_init_hook(void)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	apic_intr_init();
+#endif
+
+	setup_irq(7, &irq7);
+}
+
+/**
+ * pre_setup_arch_hook - hook called prior to any setup_arch() execution
+ *
+ * Description:
+ *	generally used to activate any machine specific identification
+ *	routines that may be needed before setup_arch() runs.  On VISWS
+ *	this is used to get the board revision and type.
+ **/
+void __init pre_setup_arch_hook(void)
+{
+	SYS_DESC_TABLE.length = 0;
+	MCA_bus = 0;
+	/* In PC-9800, APM BIOS version is written in BCD...?? */
+	APM_BIOS_INFO.version = (APM_BIOS_INFO.version & 0xff00)
+				| ((APM_BIOS_INFO.version & 0x00f0) >> 4);
+}
+
+/**
+ * trap_init_hook - initialise system specific traps
+ *
+ * Description:
+ *	Called as the final act of trap_init().  Used in VISWS to initialise
+ *	the various board specific APIC traps.
+ **/
+void __init trap_init_hook(void)
+{
+}
+
+static struct irqaction irq0  = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
+
+/**
+ * time_init_hook - do any specific initialisations for the system timer.
+ *
+ * Description:
+ *	Must plug the system timer interrupt source at HZ into the IRQ listed
+ *	in irq_vectors.h:TIMER_IRQ
+ **/
+void __init time_init_hook(void)
+{
+	setup_irq(0, &irq0);
+}
+
+#ifdef CONFIG_MCA
+/**
+ * mca_nmi_hook - hook into MCA specific NMI chain
+ *
+ * Description:
+ *	The MCA (Microchannel Architecture) has an NMI chain for NMI sources
+ *	along the MCA bus.  Use this to hook into that chain if you will need
+ *	it.
+ **/
+void __init mca_nmi_hook(void)
+{
+	/* If I recall correctly, there's a whole bunch of other things that
+	 * we can do to check for NMI problems, but that's all I know about
+	 * at the moment.
+	 */
+
+	printk("NMI generated from unknown source!\n");
+}
+#endif
diff -Nru a/arch/i386/mach-pc9800/topology.c b/arch/i386/mach-pc9800/topology.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/mach-pc9800/topology.c	Thu Mar 13 17:21:57 2003
@@ -0,0 +1,44 @@
+/*
+ * arch/i386/mach-pc9800/topology.c - Populate driverfs with topology information
+ *
+ * Written by: Matthew Dobson, IBM Corporation
+ * Original Code: Paul Dorwin, IBM Corporation, Patrick Mochel, OSDL
+ *
+ * Copyright (C) 2002, IBM Corp.
+ *
+ * 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 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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.
+ *
+ * Modify for PC-9800 by Osamu Tomita <tomita@cinet.co.jp>
+ *
+ */
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <asm/cpu.h>
+
+struct i386_cpu cpu_devices[NR_CPUS];
+
+static int __init topology_init(void)
+{
+	int i;
+
+	for (i = 0; i < NR_CPUS; i++)
+		if (cpu_possible(i)) arch_register_cpu(i);
+	return 0;
+}
+
+subsys_initcall(topology_init);
diff -Nru a/arch/i386/pci/common.c b/arch/i386/pci/common.c
--- a/arch/i386/pci/common.c	Sun Mar 16 13:55:55 2003
+++ b/arch/i386/pci/common.c	Sat Mar 22 07:22:30 2003
@@ -120,12 +120,27 @@
 	return pci_scan_bus(busnum, pci_root_ops, NULL);
 }
 
+extern u8 pci_cache_line_size;
+
 static int __init pcibios_init(void)
 {
+	struct cpuinfo_x86 *c = &boot_cpu_data;
+
 	if (!pci_root_ops) {
 		printk("PCI: System does not support PCI\n");
 		return 0;
 	}
+
+	/*
+	 * Assume PCI cacheline size of 32 bytes for all x86s except K7/K8
+	 * and P4. It's also good for 386/486s (which actually have 16)
+	 * as quite a few PCI devices do not support smaller values.
+	 */
+	pci_cache_line_size = 32 >> 2;
+	if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD)
+		pci_cache_line_size = 64 >> 2;	/* K7 & K8 */
+	else if (c->x86 > 6)
+		pci_cache_line_size = 128 >> 2;	/* P4 */
 
 	pcibios_resource_survey();
 
diff -Nru a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c
--- a/arch/i386/pci/pcbios.c	Fri Aug 30 07:00:01 2002
+++ b/arch/i386/pci/pcbios.c	Fri Feb 14 15:04:05 2003
@@ -5,21 +5,8 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include "pci.h"
+#include "pci-functions.h"
 
-
-#define PCIBIOS_PCI_FUNCTION_ID 	0xb1XX
-#define PCIBIOS_PCI_BIOS_PRESENT 	0xb101
-#define PCIBIOS_FIND_PCI_DEVICE		0xb102
-#define PCIBIOS_FIND_PCI_CLASS_CODE	0xb103
-#define PCIBIOS_GENERATE_SPECIAL_CYCLE	0xb106
-#define PCIBIOS_READ_CONFIG_BYTE	0xb108
-#define PCIBIOS_READ_CONFIG_WORD	0xb109
-#define PCIBIOS_READ_CONFIG_DWORD	0xb10a
-#define PCIBIOS_WRITE_CONFIG_BYTE	0xb10b
-#define PCIBIOS_WRITE_CONFIG_WORD	0xb10c
-#define PCIBIOS_WRITE_CONFIG_DWORD	0xb10d
-#define PCIBIOS_GET_ROUTING_OPTIONS	0xb10e
-#define PCIBIOS_SET_PCI_HW_INT		0xb10f
 
 /* BIOS32 signature: "_32_" */
 #define BIOS32_SIGNATURE	(('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
diff -Nru a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
--- a/arch/ia64/ia32/sys_ia32.c	Sat Mar  8 11:30:11 2003
+++ b/arch/ia64/ia32/sys_ia32.c	Sun Mar 23 14:36:29 2003
@@ -3124,38 +3124,17 @@
 	compat_gid_t	ex32_anon_gid;
 };
 
-struct nfsctl_uidmap32 {
-	u32			ug32_ident;   /* char * */
-	compat_uid_t	ug32_uidbase;
-	s32			ug32_uidlen;
-	u32			ug32_udimap;  /* uid_t * */
-	compat_uid_t	ug32_gidbase;
-	s32			ug32_gidlen;
-	u32			ug32_gdimap;  /* gid_t * */
-};
-
-struct nfsctl_fhparm32 {
-	struct sockaddr		gf32_addr;
-	compat_dev_t	gf32_dev;
-	compat_ino_t	gf32_ino;
-	s32			gf32_version;
-};
-
 struct nfsctl_arg32 {
 	s32			ca32_version;	/* safeguard */
 	union {
 		struct nfsctl_svc32	u32_svc;
 		struct nfsctl_client32	u32_client;
 		struct nfsctl_export32	u32_export;
-		struct nfsctl_uidmap32	u32_umap;
-		struct nfsctl_fhparm32	u32_getfh;
 		u32			u32_debug;
 	} u;
 #define ca32_svc	u.u32_svc
 #define ca32_client	u.u32_client
 #define ca32_export	u.u32_export
-#define ca32_umap	u.u32_umap
-#define ca32_getfh	u.u32_getfh
 #define ca32_authd	u.u32_authd
 #define ca32_debug	u.u32_debug
 };
@@ -3227,75 +3206,6 @@
 }
 
 static int
-nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
-{
-	u32 uaddr;
-	int i;
-	int err;
-
-	memset(karg, 0, sizeof(*karg));
-	if(__get_user(karg->ca_version, &arg32->ca32_version))
-		return -EFAULT;
-	karg->ca_umap.ug_ident = (char *)get_zeroed_page(GFP_USER);
-	if(!karg->ca_umap.ug_ident)
-		return -ENOMEM;
-	err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
-	if(strncpy_from_user(karg->ca_umap.ug_ident,
-			     (char *)A(uaddr), PAGE_SIZE) <= 0)
-		return -EFAULT;
-	err |= __get_user(karg->ca_umap.ug_uidbase,
-		      &arg32->ca32_umap.ug32_uidbase);
-	err |= __get_user(karg->ca_umap.ug_uidlen,
-		      &arg32->ca32_umap.ug32_uidlen);
-	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
-	if (err)
-		return -EFAULT;
-	karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) *
-					   karg->ca_umap.ug_uidlen),
-					  GFP_USER);
-	if(!karg->ca_umap.ug_udimap)
-		return -ENOMEM;
-	for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
-		err |= __get_user(karg->ca_umap.ug_udimap[i],
-			      &(((compat_uid_t *)A(uaddr))[i]));
-	err |= __get_user(karg->ca_umap.ug_gidbase,
-		      &arg32->ca32_umap.ug32_gidbase);
-	err |= __get_user(karg->ca_umap.ug_uidlen,
-		      &arg32->ca32_umap.ug32_gidlen);
-	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
-	if (err)
-		return -EFAULT;
-	karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) *
-					   karg->ca_umap.ug_uidlen),
-					  GFP_USER);
-	if(!karg->ca_umap.ug_gdimap)
-		return -ENOMEM;
-	for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
-		err |= __get_user(karg->ca_umap.ug_gdimap[i],
-			      &(((compat_gid_t *)A(uaddr))[i]));
-
-	return err;
-}
-
-static int
-nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
-{
-	int err;
-
-	err = __get_user(karg->ca_version, &arg32->ca32_version);
-	err |= copy_from_user(&karg->ca_getfh.gf_addr,
-			  &arg32->ca32_getfh.gf32_addr,
-			  (sizeof(struct sockaddr)));
-	err |= __get_user(karg->ca_getfh.gf_dev,
-		      &arg32->ca32_getfh.gf32_dev);
-	err |= __get_user(karg->ca_getfh.gf_ino,
-		      &arg32->ca32_getfh.gf32_ino);
-	err |= __get_user(karg->ca_getfh.gf_version,
-		      &arg32->ca32_getfh.gf32_version);
-	return err;
-}
-
-static int
 nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
 {
 	int err;
@@ -3340,13 +3250,6 @@
 	case NFSCTL_EXPORT:
 		err = nfs_exp32_trans(karg, arg32);
 		break;
-	/* This one is unimplemented, be we're ready for it. */
-	case NFSCTL_UGIDUPDATE:
-		err = nfs_uud32_trans(karg, arg32);
-		break;
-	case NFSCTL_GETFH:
-		err = nfs_getfh32_trans(karg, arg32);
-		break;
 	default:
 		err = -EINVAL;
 		break;
@@ -3358,21 +3261,12 @@
 	err = sys_nfsservctl(cmd, karg, kres);
 	set_fs(oldfs);
 
-	if(!err && cmd == NFSCTL_GETFH)
+	if(!err && cmd == NFSCTL_GETFS)
 		err = nfs_getfh32_res_trans(kres, res32);
 
 done:
-	if(karg) {
-		if(cmd == NFSCTL_UGIDUPDATE) {
-			if(karg->ca_umap.ug_ident)
-				kfree(karg->ca_umap.ug_ident);
-			if(karg->ca_umap.ug_udimap)
-				kfree(karg->ca_umap.ug_udimap);
-			if(karg->ca_umap.ug_gdimap)
-				kfree(karg->ca_umap.ug_gdimap);
-		}
+	if(karg)
 		kfree(karg);
-	}
 	if(kres)
 		kfree(kres);
 	return err;
diff -Nru a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
--- a/arch/ia64/kernel/traps.c	Thu Mar  6 13:42:08 2003
+++ b/arch/ia64/kernel/traps.c	Mon Mar 17 21:32:24 2003
@@ -101,6 +101,7 @@
 		.lock_owner =		-1,
 		.lock_owner_depth =	0
 	};
+	static int die_counter;
 
 	if (die.lock_owner != smp_processor_id()) {
 		console_verbose();
@@ -111,7 +112,8 @@
 	}
 
 	if (++die.lock_owner_depth < 3) {
-		printk("%s[%d]: %s %ld\n", current->comm, current->pid, str, err);
+		printk("%s[%d]: %s %ld [%d]\n",
+			current->comm, current->pid, str, err, ++die_counter);
 		show_regs(regs);
   	} else
 		printk(KERN_ERR "Recursive die() failure, output suppressed\n");
diff -Nru a/arch/m68k/Kconfig b/arch/m68k/Kconfig
--- a/arch/m68k/Kconfig	Sat Mar  8 14:50:37 2003
+++ b/arch/m68k/Kconfig	Thu Feb 27 08:02:04 2003
@@ -499,8 +499,8 @@
 	  uses.
 
 config HEARTBEAT
-	bool "Use power LED as a heartbeat" if AMIGA || ATARI || Q40
-	default y if !AMIGA && !ATARI && !Q40 && HP300
+	bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40
+	default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300
 	help
 	  Use the power-on LED on your machine as a load meter.  The exact
 	  behavior is platform-dependent, but normally the flash frequency is
diff -Nru a/arch/m68k/amiga/amisound.c b/arch/m68k/amiga/amisound.c
--- a/arch/m68k/amiga/amisound.c	Tue Nov  5 06:25:32 2002
+++ b/arch/m68k/amiga/amisound.c	Wed Feb 26 04:06:15 2003
@@ -12,6 +12,7 @@
 #include <linux/jiffies.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/string.h>
 
 #include <asm/system.h>
 #include <asm/amigahw.h>
diff -Nru a/arch/m68k/amiga/chipram.c b/arch/m68k/amiga/chipram.c
--- a/arch/m68k/amiga/chipram.c	Tue Jan 15 12:00:01 2002
+++ b/arch/m68k/amiga/chipram.c	Wed Feb 26 04:05:56 2003
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 #include <asm/page.h>
 #include <asm/amigahw.h>
 
diff -Nru a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
--- a/arch/m68k/amiga/config.c	Mon Nov 18 07:03:02 2002
+++ b/arch/m68k/amiga/config.c	Thu Mar 13 05:27:40 2003
@@ -21,6 +21,7 @@
 #include <linux/rtc.h>
 #include <linux/init.h>
 #include <linux/vt_kern.h>
+#include <linux/delay.h>
 #include <linux/interrupt.h>
 #ifdef CONFIG_ZORRO
 #include <linux/zorro.h>
@@ -89,6 +90,7 @@
 static int a3000_hwclk (int, struct rtc_time *);
 static int a2000_hwclk (int, struct rtc_time *);
 static int amiga_set_clock_mmss (unsigned long);
+static unsigned int amiga_get_ss (void);
 extern void amiga_mksound( unsigned int count, unsigned int ticks );
 #ifdef CONFIG_AMIGA_FLOPPY
 extern void amiga_floppy_setup(char *, int *);
@@ -403,6 +405,7 @@
 				      */
 
   mach_set_clock_mmss  = amiga_set_clock_mmss;
+  mach_get_ss          = amiga_get_ss; 
 #ifdef CONFIG_AMIGA_FLOPPY
   mach_floppy_setup    = amiga_floppy_setup;
 #endif
@@ -545,96 +548,101 @@
 
 static int a3000_hwclk(int op, struct rtc_time *t)
 {
-	volatile struct tod3000 *tod = TOD_3000;
-
-	tod->cntrl1 = TOD3000_CNTRL1_HOLD;
+	tod_3000.cntrl1 = TOD3000_CNTRL1_HOLD;
 
 	if (!op) { /* read */
-		t->tm_sec  = tod->second1 * 10 + tod->second2;
-		t->tm_min  = tod->minute1 * 10 + tod->minute2;
-		t->tm_hour = tod->hour1   * 10 + tod->hour2;
-		t->tm_mday = tod->day1    * 10 + tod->day2;
-		t->tm_wday = tod->weekday;
-		t->tm_mon  = tod->month1  * 10 + tod->month2 - 1;
-		t->tm_year = tod->year1   * 10 + tod->year2;
+		t->tm_sec  = tod_3000.second1 * 10 + tod_3000.second2;
+		t->tm_min  = tod_3000.minute1 * 10 + tod_3000.minute2;
+		t->tm_hour = tod_3000.hour1   * 10 + tod_3000.hour2;
+		t->tm_mday = tod_3000.day1    * 10 + tod_3000.day2;
+		t->tm_wday = tod_3000.weekday;
+		t->tm_mon  = tod_3000.month1  * 10 + tod_3000.month2 - 1;
+		t->tm_year = tod_3000.year1   * 10 + tod_3000.year2;
 		if (t->tm_year <= 69)
 			t->tm_year += 100;
 	} else {
-		tod->second1 = t->tm_sec / 10;
-		tod->second2 = t->tm_sec % 10;
-		tod->minute1 = t->tm_min / 10;
-		tod->minute2 = t->tm_min % 10;
-		tod->hour1   = t->tm_hour / 10;
-		tod->hour2   = t->tm_hour % 10;
-		tod->day1    = t->tm_mday / 10;
-		tod->day2    = t->tm_mday % 10;
+		tod_3000.second1 = t->tm_sec / 10;
+		tod_3000.second2 = t->tm_sec % 10;
+		tod_3000.minute1 = t->tm_min / 10;
+		tod_3000.minute2 = t->tm_min % 10;
+		tod_3000.hour1   = t->tm_hour / 10;
+		tod_3000.hour2   = t->tm_hour % 10;
+		tod_3000.day1    = t->tm_mday / 10;
+		tod_3000.day2    = t->tm_mday % 10;
 		if (t->tm_wday != -1)
-			tod->weekday = t->tm_wday;
-		tod->month1  = (t->tm_mon + 1) / 10;
-		tod->month2  = (t->tm_mon + 1) % 10;
+			tod_3000.weekday = t->tm_wday;
+		tod_3000.month1  = (t->tm_mon + 1) / 10;
+		tod_3000.month2  = (t->tm_mon + 1) % 10;
 		if (t->tm_year >= 100)
 			t->tm_year -= 100;
-		tod->year1   = t->tm_year / 10;
-		tod->year2   = t->tm_year % 10;
+		tod_3000.year1   = t->tm_year / 10;
+		tod_3000.year2   = t->tm_year % 10;
 	}
 
-	tod->cntrl1 = TOD3000_CNTRL1_FREE;
+	tod_3000.cntrl1 = TOD3000_CNTRL1_FREE;
 
 	return 0;
 }
 
 static int a2000_hwclk(int op, struct rtc_time *t)
 {
-	volatile struct tod2000 *tod = TOD_2000;
+	int cnt = 5;
+
+	tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD;
 
-	tod->cntrl1 = TOD2000_CNTRL1_HOLD;
+	while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--)
+	{
+	        tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
+	        udelay(70);
+	        tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
+	}
 
-	while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
-		;
+	if (!cnt)
+		printk(KERN_INFO "hwclk: timed out waiting for RTC (0x%x)\n", tod_2000.cntrl1);
 
 	if (!op) { /* read */
-		t->tm_sec  = tod->second1     * 10 + tod->second2;
-		t->tm_min  = tod->minute1     * 10 + tod->minute2;
-		t->tm_hour = (tod->hour1 & 3) * 10 + tod->hour2;
-		t->tm_mday = tod->day1        * 10 + tod->day2;
-		t->tm_wday = tod->weekday;
-		t->tm_mon  = tod->month1      * 10 + tod->month2 - 1;
-		t->tm_year = tod->year1       * 10 + tod->year2;
+		t->tm_sec  = tod_2000.second1     * 10 + tod_2000.second2;
+		t->tm_min  = tod_2000.minute1     * 10 + tod_2000.minute2;
+		t->tm_hour = (tod_2000.hour1 & 3) * 10 + tod_2000.hour2;
+		t->tm_mday = tod_2000.day1        * 10 + tod_2000.day2;
+		t->tm_wday = tod_2000.weekday;
+		t->tm_mon  = tod_2000.month1      * 10 + tod_2000.month2 - 1;
+		t->tm_year = tod_2000.year1       * 10 + tod_2000.year2;
 		if (t->tm_year <= 69)
 			t->tm_year += 100;
 
-		if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){
-			if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12)
+		if (!(tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)){
+			if (!(tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12)
 				t->tm_hour = 0;
-			else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12)
+			else if ((tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12)
 				t->tm_hour += 12;
 		}
 	} else {
-		tod->second1 = t->tm_sec / 10;
-		tod->second2 = t->tm_sec % 10;
-		tod->minute1 = t->tm_min / 10;
-		tod->minute2 = t->tm_min % 10;
-		if (tod->cntrl3 & TOD2000_CNTRL3_24HMODE)
-			tod->hour1 = t->tm_hour / 10;
+		tod_2000.second1 = t->tm_sec / 10;
+		tod_2000.second2 = t->tm_sec % 10;
+		tod_2000.minute1 = t->tm_min / 10;
+		tod_2000.minute2 = t->tm_min % 10;
+		if (tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)
+			tod_2000.hour1 = t->tm_hour / 10;
 		else if (t->tm_hour >= 12)
-			tod->hour1 = TOD2000_HOUR1_PM +
+			tod_2000.hour1 = TOD2000_HOUR1_PM +
 				(t->tm_hour - 12) / 10;
 		else
-			tod->hour1 = t->tm_hour / 10;
-		tod->hour2   = t->tm_hour % 10;
-		tod->day1    = t->tm_mday / 10;
-		tod->day2    = t->tm_mday % 10;
+			tod_2000.hour1 = t->tm_hour / 10;
+		tod_2000.hour2   = t->tm_hour % 10;
+		tod_2000.day1    = t->tm_mday / 10;
+		tod_2000.day2    = t->tm_mday % 10;
 		if (t->tm_wday != -1)
-			tod->weekday = t->tm_wday;
-		tod->month1  = (t->tm_mon + 1) / 10;
-		tod->month2  = (t->tm_mon + 1) % 10;
+			tod_2000.weekday = t->tm_wday;
+		tod_2000.month1  = (t->tm_mon + 1) / 10;
+		tod_2000.month2  = (t->tm_mon + 1) % 10;
 		if (t->tm_year >= 100)
 			t->tm_year -= 100;
-		tod->year1   = t->tm_year / 10;
-		tod->year2   = t->tm_year % 10;
+		tod_2000.year1   = t->tm_year / 10;
+		tod_2000.year2   = t->tm_year % 10;
 	}
 
-	tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
+	tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
 
 	return 0;
 }
@@ -644,33 +652,52 @@
 	short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
 
 	if (AMIGAHW_PRESENT(A3000_CLK)) {
-		volatile struct tod3000 *tod = TOD_3000;
-
-		tod->cntrl1 = TOD3000_CNTRL1_HOLD;
+		tod_3000.cntrl1 = TOD3000_CNTRL1_HOLD;
 
-		tod->second1 = real_seconds / 10;
-		tod->second2 = real_seconds % 10;
-		tod->minute1 = real_minutes / 10;
-		tod->minute2 = real_minutes % 10;
+		tod_3000.second1 = real_seconds / 10;
+		tod_3000.second2 = real_seconds % 10;
+		tod_3000.minute1 = real_minutes / 10;
+		tod_3000.minute2 = real_minutes % 10;
 		
-		tod->cntrl1 = TOD3000_CNTRL1_FREE;
+		tod_3000.cntrl1 = TOD3000_CNTRL1_FREE;
 	} else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ {
-		volatile struct tod2000 *tod = TOD_2000;
+		int cnt = 5;
+
+		tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
+		
+		while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--)
+		{
+			tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
+			udelay(70);
+			tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
+		}
 
-		tod->cntrl1 = TOD2000_CNTRL1_HOLD;
-	    
-		while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
-			;
-
-		tod->second1 = real_seconds / 10;
-		tod->second2 = real_seconds % 10;
-		tod->minute1 = real_minutes / 10;
-		tod->minute2 = real_minutes % 10;
+		if (!cnt)
+			printk(KERN_INFO "set_clock_mmss: timed out waiting for RTC (0x%x)\n", tod_2000.cntrl1);
 
-		tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
+		tod_2000.second1 = real_seconds / 10;
+		tod_2000.second2 = real_seconds % 10;
+		tod_2000.minute1 = real_minutes / 10;
+		tod_2000.minute2 = real_minutes % 10;
+
+		tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
 	}
 
 	return 0;
+}
+
+static unsigned int amiga_get_ss( void )
+{
+	unsigned int s;
+
+	if (AMIGAHW_PRESENT(A3000_CLK)) {
+		tod_3000.cntrl1 = TOD3000_CNTRL1_HOLD;
+		s = tod_3000.second1 * 10 + tod_3000.second2;
+		tod_3000.cntrl1 = TOD3000_CNTRL1_FREE;
+	} else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ { 
+		s = tod_2000.second1 * 10 + tod_2000.second2;
+	}
+	return s;
 }
 
 static NORET_TYPE void amiga_reset( void )
diff -Nru a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c
--- a/arch/m68k/apollo/config.c	Mon Nov 18 09:37:20 2002
+++ b/arch/m68k/apollo/config.c	Thu Feb 27 07:56:03 2003
@@ -48,7 +48,6 @@
 static void dn_timer_int(int irq,void *, struct pt_regs *);
 static void (*sched_timer_handler)(int, void *, struct pt_regs *)=NULL;
 static void dn_get_model(char *model);
-static int dn_cpuctrl=0xff00;
 static const char *apollo_models[] = {
 	"DN3000 (Otter)",
 	"DN3010 (Otter)",
@@ -290,6 +289,8 @@
 }
 
 #ifdef CONFIG_HEARTBEAT
+static int dn_cpuctrl=0xff00;
+
 static void dn_heartbeat(int on) {
 
 	if(on) { 
diff -Nru a/arch/m68k/apollo/dma.c b/arch/m68k/apollo/dma.c
--- a/arch/m68k/apollo/dma.c	Tue Feb  5 09:40:28 2002
+++ b/arch/m68k/apollo/dma.c	Thu Feb 27 07:26:52 2003
@@ -10,6 +10,7 @@
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/apollodma.h>
+#include <asm/io.h>
 
 /* note only works for 16 Bit 1 page DMA's */
 
@@ -27,7 +28,7 @@
 #if 0
 		printk("phys_addr: %x, page_aligned_addr: %x, start_map_addr: %x\n",phys_addr,page_aligned_addr,start_map_addr+i);
 #endif
-		outw(start_map_addr+i, xlat_map_entry);
+		out_be16(xlat_map_entry, start_map_addr+i);
 	}
 
 	next_free_xlat_entry+=2;
diff -Nru a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
--- a/arch/m68k/atari/ataints.c	Thu Nov  7 14:02:56 2002
+++ b/arch/m68k/atari/ataints.c	Wed Feb 26 06:10:15 2003
@@ -273,29 +273,29 @@
 /* Dummy function to allow asm with operands.  */
 void atari_fast_prio_irq_dummy (void) {
 __asm__ (__ALIGN_STR "\n"
-"atari_fast_irq_handler:
-	orw 	#0x700,%%sr		/* disable all interrupts */
-atari_prio_irq_handler:\t
-	addl	%3,%2\n"		/* preempt_count() += HARDIRQ_OFFSET */
-	SAVE_ALL_INT "\n"
-	GET_CURRENT(%%d0) "
+"atari_fast_irq_handler:\n\t"
+	"orw 	#0x700,%%sr\n"		/* disable all interrupts */
+"atari_prio_irq_handler:\n\t"
+	"addl	%3,%2\n\t"		/* preempt_count() += HARDIRQ_OFFSET */
+	SAVE_ALL_INT "\n\t"
+	GET_CURRENT(%%d0) "\n\t"
 	/* get vector number from stack frame and convert to source */
-	bfextu	%%sp@(%c1){#4,#10},%%d0
-	subw	#(0x40-8),%%d0
-	jpl 	1f
-	addw	#(0x40-8-0x18),%%d0
-1:	lea	%a0,%%a0
-	addql	#1,%%a0@(%%d0:l:4)
-	lea	irq_handler,%%a0
-	lea	%%a0@(%%d0:l:8),%%a0
-	pea 	%%sp@			/* push frame address */
-	movel	%%a0@(4),%%sp@-		/* push handler data */
-	movel	%%d0,%%sp@-		/* push int number */
-	movel	%%a0@,%%a0
-	jsr	%%a0@			/* and call the handler */
-	addql	#8,%%sp
-	addql	#4,%%sp
-	jbra	ret_from_interrupt"
+	"bfextu	%%sp@(%c1){#4,#10},%%d0\n\t"
+	"subw	#(0x40-8),%%d0\n\t"
+	"jpl 	1f\n\t"
+	"addw	#(0x40-8-0x18),%%d0\n"
+    "1:\tlea	%a0,%%a0\n\t"
+	"addql	#1,%%a0@(%%d0:l:4)\n\t"
+	"lea	irq_handler,%%a0\n\t"
+	"lea	%%a0@(%%d0:l:8),%%a0\n\t"
+	"pea 	%%sp@\n\t"		/* push frame address */
+	"movel	%%a0@(4),%%sp@-\n\t"	/* push handler data */
+	"movel	%%d0,%%sp@-\n\t"	/* push int number */
+	"movel	%%a0@,%%a0\n\t"
+	"jsr	%%a0@\n\t"		/* and call the handler */
+	"addql	#8,%%sp\n\t"
+	"addql	#4,%%sp\n\t"
+	"jbra	ret_from_interrupt"
 	 : : "i" (&kstat_cpu(0).irqs), "n" (PT_OFF_FORMATVEC),
 	     "m" (preempt_count()), "di" (HARDIRQ_OFFSET)
 );
@@ -308,10 +308,10 @@
  */
 asmlinkage void falcon_hblhandler(void);
 asm(".text\n"
-__ALIGN_STR "\n"
-"falcon_hblhandler:
-	orw	#0x200,%sp@	/* set saved ipl to 2 */
-	rte");
+__ALIGN_STR "\n\t"
+"falcon_hblhandler:\n\t"
+	"orw	#0x200,%sp@\n\t"	/* set saved ipl to 2 */
+	"rte");
 
 /* Defined in entry.S; only increments 'num_spurious' */
 asmlinkage void bad_interrupt(void);
diff -Nru a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
--- a/arch/m68k/atari/stram.c	Sat Mar  8 14:50:21 2003
+++ b/arch/m68k/atari/stram.c	Wed Mar 12 07:16:13 2003
@@ -146,7 +146,7 @@
 
 /* The following two numbers define the maximum fraction of ST-RAM in total
  * memory, below that the kernel would automatically use ST-RAM as swap
- * space. This decision can be overriden with stram_swap= */
+ * space. This decision can be overridden with stram_swap= */
 #define MAX_STRAM_FRACTION_NOM		1
 #define MAX_STRAM_FRACTION_DENOM	3
 
@@ -347,7 +347,7 @@
 		/*
 		 * If the whole ST-RAM is used for swapping, there are no allocatable
 		 * dma pages left. But unfortunately, some shared parts of the kernel
-		 * (particularily the SCSI mid-level) call __get_dma_pages()
+		 * (particularly the SCSI mid-level) call __get_dma_pages()
 		 * unconditionally :-( These calls then fail, and scsi.c even doesn't
 		 * check for NULL return values and just crashes. The quick fix for
 		 * this (instead of doing much clean up work in the SCSI code) is to
diff -Nru a/arch/m68k/ifpsp060/fskeleton.S b/arch/m68k/ifpsp060/fskeleton.S
--- a/arch/m68k/ifpsp060/fskeleton.S	Thu Oct 10 10:51:24 2002
+++ b/arch/m68k/ifpsp060/fskeleton.S	Thu Feb 27 09:19:53 2003
@@ -302,7 +302,6 @@
 
 | The size of this section MUST be 128 bytes!!!
 
-	.global	_FP_CALL_TOP
 _FP_CALL_TOP:
 	.long	_060_real_bsun		- _FP_CALL_TOP
 	.long	_060_real_snan		- _FP_CALL_TOP
diff -Nru a/arch/m68k/ifpsp060/iskeleton.S b/arch/m68k/ifpsp060/iskeleton.S
--- a/arch/m68k/ifpsp060/iskeleton.S	Thu Oct 10 10:51:24 2002
+++ b/arch/m68k/ifpsp060/iskeleton.S	Thu Feb 27 09:20:37 2003
@@ -270,7 +270,6 @@
 
 | The size of this section MUST be 128 bytes!!!
 
-	.global	_I_CALL_TOP
 _I_CALL_TOP:
 	.long	_060_real_chk		- _I_CALL_TOP
 	.long	_060_real_divbyzero	- _I_CALL_TOP
diff -Nru a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
--- a/arch/m68k/kernel/entry.S	Thu Dec 26 10:39:55 2002
+++ b/arch/m68k/kernel/entry.S	Tue Feb 25 07:35:49 2003
@@ -33,7 +33,6 @@
  *		 for 68040
  */
 
-#include <linux/sys.h>
 #include <linux/config.h>
 #include <linux/linkage.h>
 #include <asm/entry.h>
@@ -41,6 +40,7 @@
 #include <asm/setup.h>
 #include <asm/segment.h>
 #include <asm/traps.h>
+#include <asm/unistd.h>
 
 #include "m68k_defs.h"
 
@@ -661,7 +661,3 @@
 	.long sys_lremovexattr
 	.long sys_fremovexattr
 	.long sys_futex		/* 235 */
-
-	.rept NR_syscalls-(.-sys_call_table)/4
-		.long sys_ni_syscall
-	.endr
diff -Nru a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S
--- a/arch/m68k/kernel/head.S	Tue Feb 25 11:05:23 2003
+++ b/arch/m68k/kernel/head.S	Wed Mar 12 07:16:16 2003
@@ -190,7 +190,7 @@
  *
  * options
  * -------
- *	There are many options availble in a build of this file.  I've
+ *	There are many options available in a build of this file.  I've
  * taken the time to describe them here to save you the time of searching
  * for them and trying to understand what they mean.
  *
diff -Nru a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c
--- a/arch/m68k/kernel/m68k_ksyms.c	Fri Jan  3 08:13:04 2003
+++ b/arch/m68k/kernel/m68k_ksyms.c	Wed Mar  5 07:55:57 2003
@@ -53,11 +53,15 @@
 EXPORT_SYMBOL(mach_get_ss);
 EXPORT_SYMBOL(mach_get_rtc_pll);
 EXPORT_SYMBOL(mach_set_rtc_pll);
+#ifdef CONFIG_INPUT_M68K_BEEP_MODULE
+EXPORT_SYMBOL(mach_beep);
+#endif
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(strrchr);
 EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strpbrk);
 EXPORT_SYMBOL(enable_irq);
 EXPORT_SYMBOL(disable_irq);
 EXPORT_SYMBOL(kernel_thread);
diff -Nru a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
--- a/arch/m68k/kernel/process.c	Tue Nov 26 06:45:59 2002
+++ b/arch/m68k/kernel/process.c	Tue Feb 11 05:08:30 2003
@@ -42,6 +42,7 @@
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
 struct mm_struct init_mm = INIT_MM(init_mm);
 
 union thread_union init_thread_union
diff -Nru a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
--- a/arch/m68k/kernel/signal.c	Thu Feb 13 09:34:46 2003
+++ b/arch/m68k/kernel/signal.c	Wed Mar 12 07:16:15 2003
@@ -16,7 +16,7 @@
  * 1997-12-01  Modified for POSIX.1b signals by Andreas Schwab
  *
  * mathemu support by Roman Zippel
- *  (Note: fpstate in the signal context is completly ignored for the emulator
+ *  (Note: fpstate in the signal context is completely ignored for the emulator
  *         and the internal floating point format is put on stack)
  */
 
@@ -1019,7 +1019,7 @@
 				/* Restart the system call the same way as
 				   if the process were not traced.  */
 				struct k_sigaction *ka =
-					&current->sig->action[signr-1];
+					&current->sighand->action[signr-1];
 				int has_handler =
 					(ka->sa.sa_handler != SIG_IGN &&
 					 ka->sa.sa_handler != SIG_DFL);
@@ -1060,7 +1060,7 @@
 			}
 		}
 
-		ka = &current->sig->action[signr-1];
+		ka = &current->sighand->action[signr-1];
 		if (ka->sa.sa_handler == SIG_IGN) {
 			if (signr != SIGCHLD)
 				continue;
@@ -1087,11 +1087,11 @@
 				/* FALLTHRU */
 
 			case SIGSTOP: {
-				struct signal_struct *sig;
+				struct sighand_struct *sighand;
 				current->state = TASK_STOPPED;
 				current->exit_code = signr;
-				sig = current->parent->sig;
-				if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags 
+				sighand = current->parent->sighand;
+				if (sighand && !(sighand->action[SIGCHLD-1].sa.sa_flags 
 					     & SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
@@ -1106,7 +1106,7 @@
 				/* FALLTHRU */
 
 			default:
-				sig_exit(signr, exit_code, &info);
+				do_group_exit(signr);
 				/* NOTREACHED */
 			}
 		}
diff -Nru a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
--- a/arch/m68k/kernel/time.c	Mon Feb 24 23:13:09 2003
+++ b/arch/m68k/kernel/time.c	Wed Mar  5 02:26:04 2003
@@ -59,35 +59,11 @@
  */
 static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
 {
-	/* last time the cmos clock got updated */
-	static long last_rtc_update=0;
-
 	do_timer(regs);
 
 	if (!user_mode(regs))
 		do_profile(regs->pc);
 
-	/*
-	 * If we have an externally synchronized 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.
-	 */
-	/*
-	 * This code hopefully becomes obsolete in 2.5 or earlier
-	 * Should it ever be reenabled it must be serialized with
-	 * genrtc.c operation
-	 */
-#if 0
-	if ((time_status & STA_UNSYNC) == 0 &&
-	    xtime.tv_sec > last_rtc_update + 660 &&
-	    (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) tick) / 2 &&
-	    (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) tick) / 2) {
-	  if (set_rtc_mmss(xtime.tv_sec) == 0)
-	    last_rtc_update = xtime.tv_sec;
-	  else
-	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
-	}
-#endif
 #ifdef CONFIG_HEARTBEAT
 	/* use power LED as a heartbeat instead -- much more useful
 	   for debugging -- based on the version for PReP by Cort */
diff -Nru a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
--- a/arch/m68k/kernel/traps.c	Sat Feb 15 19:30:17 2003
+++ b/arch/m68k/kernel/traps.c	Wed Mar 12 07:16:16 2003
@@ -303,7 +303,7 @@
 	return res;
 }
 
-/* after an exception in a writeback the stack frame coresponding
+/* after an exception in a writeback the stack frame corresponding
  * to that exception is discarded, set a few bits in the old frame 
  * to simulate what it should look like
  */
@@ -333,7 +333,7 @@
 			fp->un.fmt7.wb2s = 0;
 	}
 
-	/* do the 2nd wb only if the first one was succesful (except for a kernel wb) */
+	/* do the 2nd wb only if the first one was successful (except for a kernel wb) */
 	if (fp->un.fmt7.wb3s & WBV_040 && (!res || fp->un.fmt7.wb3s & 4)) {
 		res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a,
 				       fp->un.fmt7.wb3d);
diff -Nru a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c
--- a/arch/m68k/mac/baboon.c	Fri Jun  7 04:06:40 2002
+++ b/arch/m68k/mac/baboon.c	Wed Mar 12 07:16:11 2003
@@ -1,5 +1,5 @@
 /*
- * Baboon Custom IC Managment
+ * Baboon Custom IC Management
  *
  * The Baboon custom IC controls the IDE, PCMCIA and media bay on the
  * PowerBook 190. It multiplexes multiple interrupt sources onto the
diff -Nru a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c
--- a/arch/m68k/mac/iop.c	Tue Dec  3 13:17:27 2002
+++ b/arch/m68k/mac/iop.c	Wed Mar 12 07:16:11 2003
@@ -236,7 +236,7 @@
 
 /*
  * This is called by the startup code before anything else. Its purpose
- * is to find and initalize the IOPs early in the boot sequence, so that
+ * is to find and initialize the IOPs early in the boot sequence, so that
  * the serial IOP can be placed into bypass mode _before_ we try to
  * initialize the serial console.
  */
diff -Nru a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
--- a/arch/m68k/mac/macints.c	Fri Feb  7 00:20:36 2003
+++ b/arch/m68k/mac/macints.c	Wed Mar 12 07:16:11 2003
@@ -30,7 +30,7 @@
  *		  - slot 0: SCSI interrupt
  *		  - slot 1: Sound interrupt
  *
- * Levels 3-6 vary by machine type. For VIA or RBV Macintohes:
+ * Levels 3-6 vary by machine type. For VIA or RBV Macintoshes:
  *
  *	3	- unused (?)
  *
@@ -494,7 +494,7 @@
  * Add an interrupt service routine to an interrupt source.
  * Returns 0 on success.
  *
- * FIXME: You can register interrupts on nonexistant source (ie PSC4 on a
+ * FIXME: You can register interrupts on nonexistent source (ie PSC4 on a
  *        non-PSC machine). We should return -EINVAL in those cases.
  */
  
diff -Nru a/arch/m68k/math-emu/fp_arith.c b/arch/m68k/math-emu/fp_arith.c
--- a/arch/m68k/math-emu/fp_arith.c	Tue Feb  5 09:40:28 2002
+++ b/arch/m68k/math-emu/fp_arith.c	Wed Mar 12 07:16:13 2003
@@ -113,7 +113,7 @@
 	return dest;
 }
 
-/* fp_fsub: Implementes the kernel of the FSUB, FSSUB, and FDSUB
+/* fp_fsub: Implements the kernel of the FSUB, FSSUB, and FDSUB
    instructions.
 
    Remember that the arguments are in assembler-syntax order! */
diff -Nru a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c
--- a/arch/m68k/mm/memory.c	Sat Oct 12 12:29:15 2002
+++ b/arch/m68k/mm/memory.c	Fri Feb  7 14:01:38 2003
@@ -33,7 +33,7 @@
 typedef struct list_head ptable_desc;
 static LIST_HEAD(ptable_list);
 
-#define PD_PTABLE(page) ((ptable_desc *)virt_to_page(page))
+#define PD_PTABLE(page) ((ptable_desc *)&(virt_to_page(page)->list))
 #define PD_PAGE(ptable) (list_entry(ptable, struct page, list))
 #define PD_MARKBITS(dp) (*(unsigned char *)&PD_PAGE(dp)->index)
 
diff -Nru a/arch/m68k/mm/sun3mmu.c b/arch/m68k/mm/sun3mmu.c
--- a/arch/m68k/mm/sun3mmu.c	Sun May 26 04:25:49 2002
+++ b/arch/m68k/mm/sun3mmu.c	Fri Feb  7 14:01:38 2003
@@ -92,13 +92,12 @@
 	}
 
 	mmu_emu_init(bootmem_end);
-	
+
 	current->mm = NULL;
 
 	/* memory sizing is a hack stolen from motorola.c..  hope it works for us */
-	zones_size[1] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
-	zones_size[0] = zones_size[1]/2;
-	zones_size[1] -= zones_size[0];
+	zones_size[0] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
+	zones_size[1] = 0;
 	
 	free_area_init(zones_size);
 
diff -Nru a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c
--- a/arch/m68k/q40/q40ints.c	Sun Jan  5 04:44:44 2003
+++ b/arch/m68k/q40/q40ints.c	Wed Mar 12 07:16:10 2003
@@ -7,7 +7,7 @@
  * License.  See the file COPYING in the main directory of this archive
  * for more details.
  *
- * .. used to be losely based on bvme6000ints.c
+ * .. used to be loosely based on bvme6000ints.c
  *
  */
 
@@ -127,6 +127,7 @@
 	    printk("warning IRQ 10 and 11 not distinguishable\n");
 	    irq=10;
 	  default:
+	    ;
 	  }
 
 	if (irq<Q40_IRQ_SAMPLE)
@@ -174,6 +175,7 @@
 	    return;
 	  case 11: irq=10;
 	  default:
+	    ;
 	  }
 	
 	if (irq<Q40_IRQ_SAMPLE)
@@ -315,7 +317,7 @@
   unsigned mir, mer;
   int irq,i;
 
- repeat:
+//repeat:
   mir=master_inb(IIRQ_REG);
   if (mir&Q40_IRQ_FRAME_MASK) {
 	  irq_tab[Q40_IRQ_FRAME].count++;
@@ -342,7 +344,7 @@
 				  continue; /* ignore uninited INTs :-( */
 			  }
 			  if ( irq_tab[irq].state & IRQ_INPROGRESS ) {
-				  /* some handlers do sti() for irq latency reasons, */
+				  /* some handlers do local_irq_enable() for irq latency reasons, */
 				  /* however reentering an active irq handler is not permitted */
 #ifdef IP_USE_DISABLE
 				  /* in theory this is the better way to do it because it still */
@@ -439,7 +441,7 @@
 {
   /* disable ISA iqs : only do something if the driver has been
    * verified to be Q40 "compatible" - right now IDE, NE2K
-   * Any driver should not attempt to sleep accross disable_irq !!
+   * Any driver should not attempt to sleep across disable_irq !!
    */
 
   if ( irq>=5 && irq<=15 ) {
diff -Nru a/arch/m68k/sun3/sun3dvma.c b/arch/m68k/sun3/sun3dvma.c
--- a/arch/m68k/sun3/sun3dvma.c	Sun Apr  7 03:56:14 2002
+++ b/arch/m68k/sun3/sun3dvma.c	Wed Feb 26 06:04:37 2003
@@ -97,7 +97,7 @@
 	printk("end of hole listing...\n");
 	
 }
-#endif DVMA_DEBUG
+#endif /* DVMA_DEBUG */
 
 static inline int refill(void)
 {
diff -Nru a/arch/m68k/vmlinux-sun3.lds b/arch/m68k/vmlinux-sun3.lds
--- a/arch/m68k/vmlinux-sun3.lds	Fri Feb 14 15:09:22 2003
+++ b/arch/m68k/vmlinux-sun3.lds	Fri Feb  7 14:01:36 2003
@@ -16,11 +16,12 @@
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x4e75
+	RODATA
 
   _etext = .;			/* End of text section */
 
   .data : {			/* Data */
-	RODATA
+	*(.data)
 	CONSTRUCTORS
   	. = ALIGN(16);		/* Exception table */
   	__start___ex_table = .;
diff -Nru a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
--- a/arch/mips/kernel/traps.c	Tue Feb 25 10:47:06 2003
+++ b/arch/mips/kernel/traps.c	Mon Mar 17 21:32:24 2003
@@ -191,12 +191,13 @@
 extern void __die(const char * str, struct pt_regs * regs, const char *where,
                   unsigned long line)
 {
+	static int die_counter;
 	console_verbose();
 	spin_lock_irq(&die_lock);
 	printk("%s", str);
 	if (where)
 		printk(" in %s, line %ld", where, line);
-	printk(":\n");
+	printk("[#%d]:\n", ++die_counter);
 	show_regs(regs);
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
 		current->comm, current->pid, (unsigned long) current);
diff -Nru a/arch/mips64/Kconfig b/arch/mips64/Kconfig
--- a/arch/mips64/Kconfig	Sat Mar  8 14:50:37 2003
+++ b/arch/mips64/Kconfig	Sat Mar  8 21:41:49 2003
@@ -5,6 +5,10 @@
 
 mainmenu "Linux Kernel Configuration"
 
+config MIPS64
+	bool
+	default y
+
 config MMU
 	bool
 	default y
diff -Nru a/arch/mips64/kernel/traps.c b/arch/mips64/kernel/traps.c
--- a/arch/mips64/kernel/traps.c	Tue Feb 25 10:47:06 2003
+++ b/arch/mips64/kernel/traps.c	Mon Mar 17 21:32:24 2003
@@ -161,12 +161,13 @@
 
 void die(const char * str, struct pt_regs * regs, unsigned long err)
 {
+	static int die_counter;
 	if (user_mode(regs))	/* Just return if in user mode.  */
 		return;
 
 	console_verbose();
 	spin_lock_irq(&die_lock);
-	printk("%s: %04lx\n", str, err & 0xffff);
+	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
 	show_regs(regs);
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
 		current->comm, current->pid, (unsigned long) current);
diff -Nru a/arch/parisc/Makefile b/arch/parisc/Makefile
--- a/arch/parisc/Makefile	Fri Mar  7 13:28:49 2003
+++ b/arch/parisc/Makefile	Mon Mar 17 09:56:44 2003
@@ -93,7 +93,8 @@
 include/asm-parisc/offsets.h: arch/parisc/kernel/asm-offsets.s
 	$(call filechk,gen-asm-offsets)
 
-CLEAN_FILES	+= palo.conf lifimage include/asm-parisc/offsets.h
+CLEAN_FILES	+= lifimage include/asm-parisc/offsets.h
+MRPROPER_FILES	+= palo.conf
 
 define archhelp
 	@echo  '* vmlinux	- Uncompressed kernel image (./vmlinux)'
diff -Nru a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
--- a/arch/parisc/kernel/Makefile	Sun Mar  9 14:15:54 2003
+++ b/arch/parisc/kernel/Makefile	Mon Mar 17 10:33:22 2003
@@ -4,7 +4,7 @@
 
 head-y			:= head.o
 head-$(CONFIG_PARISC64)	:= head64.o
-extra-y			:= init_task.o pdc_cons.o process.o
+extra-y			:= init_task.o pdc_cons.o process.o \
 			   unaligned.o $(head-y)
 
 AFLAGS_entry.o	:= -traditional
diff -Nru a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c
--- a/arch/parisc/kernel/binfmt_elf32.c	Mon Feb 10 17:21:29 2003
+++ b/arch/parisc/kernel/binfmt_elf32.c	Tue Mar 11 16:21:06 2003
@@ -12,6 +12,26 @@
 
 #define ELF_CLASS	ELFCLASS32
 
+#define ELF_CORE_COPY_REGS(dst, pt)	\
+	memset(dst, 0, sizeof(dst));	/* don't leak any "random" bits */ \
+	{	int i; \
+		for (i = 0; i < 32; i++) dst[i] = (elf_greg_t) pt->gr[i]; \
+		for (i = 0; i < 8; i++) dst[32 + i] = (elf_greg_t) pt->sr[i]; \
+	} \
+	dst[40] = (elf_greg_t) pt->iaoq[0]; dst[41] = (elf_greg_t) pt->iaoq[1]; \
+	dst[42] = (elf_greg_t) pt->iasq[0]; dst[43] = (elf_greg_t) pt->iasq[1]; \
+	dst[44] = (elf_greg_t) pt->sar;   dst[45] = (elf_greg_t) pt->iir; \
+	dst[46] = (elf_greg_t) pt->isr;   dst[47] = (elf_greg_t) pt->ior; \
+	dst[48] = (elf_greg_t) mfctl(22); dst[49] = (elf_greg_t) mfctl(0); \
+	dst[50] = (elf_greg_t) mfctl(24); dst[51] = (elf_greg_t) mfctl(25); \
+	dst[52] = (elf_greg_t) mfctl(26); dst[53] = (elf_greg_t) mfctl(27); \
+	dst[54] = (elf_greg_t) mfctl(28); dst[55] = (elf_greg_t) mfctl(29); \
+	dst[56] = (elf_greg_t) mfctl(30); dst[57] = (elf_greg_t) mfctl(31); \
+	dst[58] = (elf_greg_t) mfctl( 8); dst[59] = (elf_greg_t) mfctl( 9); \
+	dst[60] = (elf_greg_t) mfctl(12); dst[61] = (elf_greg_t) mfctl(13); \
+	dst[62] = (elf_greg_t) mfctl(10); dst[63] = (elf_greg_t) mfctl(15);
+
+
 typedef unsigned int elf_greg_t;
 
 #include <linux/spinlock.h>
@@ -60,25 +80,6 @@
 #define init_elf_binfmt init_elf32_binfmt
 
 #define ELF_PLATFORM  ("PARISC32\0")
-
-#define ELF_CORE_COPY_REGS(dst, pt)	\
-	memset(dst, 0, sizeof(dst));	/* don't leak any "random" bits */ \
-	{	int i; \
-		for (i = 0; i < 32; i++) dst[i] = (elf_greg_t) pt->gr[i]; \
-		for (i = 0; i < 8; i++) dst[32 + i] = (elf_greg_t) pt->sr[i]; \
-	} \
-	dst[40] = (elf_greg_t) pt->iaoq[0]; dst[41] = (elf_greg_t) pt->iaoq[1]; \
-	dst[42] = (elf_greg_t) pt->iasq[0]; dst[43] = (elf_greg_t) pt->iasq[1]; \
-	dst[44] = (elf_greg_t) pt->sar;   dst[45] = (elf_greg_t) pt->iir; \
-	dst[46] = (elf_greg_t) pt->isr;   dst[47] = (elf_greg_t) pt->ior; \
-	dst[48] = (elf_greg_t) mfctl(22); dst[49] = (elf_greg_t) mfctl(0); \
-	dst[50] = (elf_greg_t) mfctl(24); dst[51] = (elf_greg_t) mfctl(25); \
-	dst[52] = (elf_greg_t) mfctl(26); dst[53] = (elf_greg_t) mfctl(27); \
-	dst[54] = (elf_greg_t) mfctl(28); dst[55] = (elf_greg_t) mfctl(29); \
-	dst[56] = (elf_greg_t) mfctl(30); dst[57] = (elf_greg_t) mfctl(31); \
-	dst[58] = (elf_greg_t) mfctl( 8); dst[59] = (elf_greg_t) mfctl( 9); \
-	dst[60] = (elf_greg_t) mfctl(12); dst[61] = (elf_greg_t) mfctl(13); \
-	dst[62] = (elf_greg_t) mfctl(10); dst[63] = (elf_greg_t) mfctl(15);
 
 /*
  * We should probably use this macro to set a flag somewhere to indicate
diff -Nru a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
--- a/arch/parisc/kernel/cache.c	Sun Mar  2 18:13:32 2003
+++ b/arch/parisc/kernel/cache.c	Sat Mar  8 12:01:30 2003
@@ -114,7 +114,7 @@
 void __init 
 parisc_cache_init(void)
 {
-	if(pdc_cache_info(&cache_info)<0)
+	if (pdc_cache_info(&cache_info) < 0)
 		panic("parisc_cache_init: pdc_cache_info failed");
 
 #if 0
@@ -167,25 +167,25 @@
 
 	split_tlb = 0;
 	if (cache_info.dt_conf.tc_sh == 0 || cache_info.dt_conf.tc_sh == 2) {
-
-	    if (cache_info.dt_conf.tc_sh == 2)
-		printk(KERN_WARNING "Unexpected TLB configuration. "
+		if (cache_info.dt_conf.tc_sh == 2)
+			printk(KERN_WARNING "Unexpected TLB configuration. "
 			"Will flush I/D separately (could be optimized).\n");
 
-	    split_tlb = 1;
+		split_tlb = 1;
 	}
 
-	dcache_stride = ( (1<<(cache_info.dc_conf.cc_block+3)) *
-			 cache_info.dc_conf.cc_line );
-	icache_stride = ( (1<<(cache_info.ic_conf.cc_block+3)) *
-			 cache_info.ic_conf.cc_line );
+	dcache_stride = (1 << (cache_info.dc_conf.cc_block + 3)) *
+						cache_info.dc_conf.cc_line;
+	icache_stride = (1 << (cache_info.ic_conf.cc_block + 3)) *
+						cache_info.ic_conf.cc_line;
 #ifndef CONFIG_PA20
-	if(pdc_btlb_info(&btlb_info)<0) {
+	if (pdc_btlb_info(&btlb_info) < 0) {
 		memset(&btlb_info, 0, sizeof btlb_info);
 	}
 #endif
 
-	if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) == PDC_MODEL_NVA_UNSUPPORTED) {
+	if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) ==
+						PDC_MODEL_NVA_UNSUPPORTED) {
 		printk(KERN_WARNING "Only equivalent aliasing supported\n");
 #ifndef CONFIG_SMP
 		panic("SMP kernel required to avoid non-equivalent aliasing");
@@ -195,31 +195,69 @@
 
 void disable_sr_hashing(void)
 {
-    int srhash_type;
+	int srhash_type;
+
+	switch (boot_cpu_data.cpu_type) {
+	case pcx: /* We shouldn't get this far.  setup.c should prevent it. */
+		BUG();
+		return;
+
+	case pcxs:
+	case pcxt:
+	case pcxt_:
+		srhash_type = SRHASH_PCXST;
+		break;
+
+	case pcxl:
+		srhash_type = SRHASH_PCXL;
+		break;
+
+	case pcxl2: /* pcxl2 doesn't support space register hashing */
+		return;
+
+	default: /* Currently all PA2.0 machines use the same ins. sequence */
+		srhash_type = SRHASH_PA20;
+		break;
+	}
 
-    if (boot_cpu_data.cpu_type == pcxl2)
-	return; /* pcxl2 doesn't support space register hashing */
+	disable_sr_hashing_asm(srhash_type);
+}
+
+void __flush_dcache_page(struct page *page)
+{
+	struct mm_struct *mm = current->active_mm;
+	struct list_head *l;
 
-    switch (boot_cpu_data.cpu_type) {
+	flush_kernel_dcache_page(page_address(page));
 
-    case pcx:
-	BUG(); /* We shouldn't get here. code in setup.c should prevent it */
-	return;
+	if (!page->mapping)
+		return;
 
-    case pcxs:
-    case pcxt:
-    case pcxt_:
-	srhash_type = SRHASH_PCXST;
-	break;
+	list_for_each(l, &page->mapping->i_mmap_shared) {
+		struct vm_area_struct *mpnt;
+		unsigned long off;
 
-    case pcxl:
-	srhash_type = SRHASH_PCXL;
-	break;
+		mpnt = list_entry(l, struct vm_area_struct, shared);
 
-    default: /* Currently all PA2.0 machines use the same ins. sequence */
-	srhash_type = SRHASH_PA20;
-	break;
-    }
+		/*
+		 * If this VMA is not in our MM, we can ignore it.
+		 */
+		if (mpnt->vm_mm != mm)
+			continue;
 
-    disable_sr_hashing_asm(srhash_type);
+		if (page->index < mpnt->vm_pgoff)
+			continue;
+
+		off = page->index - mpnt->vm_pgoff;
+		if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT)
+			continue;
+
+		flush_cache_page(mpnt, mpnt->vm_start + (off << PAGE_SHIFT));
+
+		/* All user shared mappings should be equivalently mapped,
+		 * so once we've flushed one we should be ok
+		 */
+		break;
+	}
 }
+
diff -Nru a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
--- a/arch/parisc/kernel/entry.S	Fri Feb  7 00:20:33 2003
+++ b/arch/parisc/kernel/entry.S	Wed Mar  5 13:21:51 2003
@@ -558,11 +558,9 @@
 	.export	ret_from_kernel_thread
 ret_from_kernel_thread:
 
-#if CONFIG_PREEMPT || CONFIG_SMP
 	/* Call schedule_tail first though */
 	bl	schedule_tail, %r2
 	nop
-#endif
 
 	LDREG	TI_TASK-THREAD_SZ_ALGN(%r30), %r1
 	LDREG	TASK_PT_GR25(%r1), %r26
@@ -2014,10 +2012,8 @@
 
 	/* Set the return value for the child */
 child_return:
-#if CONFIG_SMP || CONFIG_PREEMPT
 	bl	schedule_tail, %r2
 	nop
-#endif
 
 	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1
 	LDREG	TASK_PT_GR19(%r1),%r2
diff -Nru a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c
--- a/arch/parisc/kernel/hardware.c	Sat Nov  2 12:27:46 2002
+++ b/arch/parisc/kernel/hardware.c	Fri Feb  7 05:29:04 2003
@@ -99,8 +99,8 @@
 	{HPHW_NPROC,0x481,0x4,0x81,"Wilbur (E25)"},
 	{HPHW_NPROC,0x482,0x4,0x81,"WB-80 (E35)"},
 	{HPHW_NPROC,0x483,0x4,0x81,"WB-96 (E45)"},
-	{HPHW_NPROC,0x48,0x4,0x81,"UL Proc L-100 (811/D210,D310)"},
-	{HPHW_NPROC,0x48,0x4,0x81,"UL Proc L-75 (801/D200)"},
+	{HPHW_NPROC,0x484,0x4,0x81,"UL Proc L-100 (811/D210,D310)"},
+	{HPHW_NPROC,0x485,0x4,0x81,"UL Proc L-75 (801/D200)"},
 	{HPHW_NPROC,0x501,0x4,0x81,"Merlin L2 132 (9000/778/B132L)"},
 	{HPHW_NPROC,0x502,0x4,0x81,"Merlin L2 160 (9000/778/B160L)"},
 	{HPHW_NPROC,0x503,0x4,0x81,"Merlin L2+ 132 (9000/778/B132L)"},
diff -Nru a/arch/parisc/kernel/init_task.c b/arch/parisc/kernel/init_task.c
--- a/arch/parisc/kernel/init_task.c	Tue Oct  8 17:14:52 2002
+++ b/arch/parisc/kernel/init_task.c	Mon Feb 10 09:49:16 2003
@@ -10,6 +10,7 @@
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
 struct mm_struct init_mm = INIT_MM(init_mm);
 
 /*
diff -Nru a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c
--- a/arch/parisc/kernel/ioctl32.c	Tue Feb 18 10:25:13 2003
+++ b/arch/parisc/kernel/ioctl32.c	Mon Mar  3 16:52:27 2003
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.6 2002/10/21 16:13:22 varenet Exp $
+/* $Id: ioctl32.c,v 1.5 2002/10/18 00:21:43 varenet Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
@@ -66,6 +66,9 @@
 #define __KERNEL__
 #include <scsi/sg.h>
 
+#include <linux/raid/md_u.h>
+#include <linux/dm-ioctl.h>
+
 #include <asm/types.h>
 #include <asm/uaccess.h>
 #include <asm/perf.h>
@@ -2824,6 +2827,27 @@
 	return err;
 }
 
+/* Fix sizeof(sizeof()) breakage */
+#define BLKBSZGET_32	_IOR(0x12,112,int)
+#define BLKBSZSET_32	_IOW(0x12,113,int)
+#define BLKGETSIZE64_32	_IOR(0x12,114,int)
+
+static int do_blkbszget(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return sys_ioctl(fd, BLKBSZGET, arg);
+}
+
+static int do_blkbszset(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return sys_ioctl(fd, BLKBSZSET, arg);
+}
+
+static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
+			   unsigned long arg)
+{
+	return sys_ioctl(fd, BLKGETSIZE64, arg);
+}
+
 static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
 	return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
@@ -2997,14 +3021,13 @@
 COMPATIBLE_IOCTL(BLKRRPART)
 COMPATIBLE_IOCTL(BLKFLSBUF)
 COMPATIBLE_IOCTL(BLKSECTSET)
-COMPATIBLE_IOCTL(BLKSSZGET)
-COMPATIBLE_IOCTL(BLKBSZGET)
 
 /* RAID */
 COMPATIBLE_IOCTL(RAID_VERSION)
 COMPATIBLE_IOCTL(GET_ARRAY_INFO)
 COMPATIBLE_IOCTL(GET_DISK_INFO)
 COMPATIBLE_IOCTL(PRINT_RAID_DEBUG)
+COMPATIBLE_IOCTL(RAID_AUTORUN)
 COMPATIBLE_IOCTL(CLEAR_ARRAY)
 COMPATIBLE_IOCTL(ADD_NEW_DISK)
 COMPATIBLE_IOCTL(HOT_REMOVE_DISK)
@@ -3015,12 +3038,26 @@
 COMPATIBLE_IOCTL(PROTECT_ARRAY)
 COMPATIBLE_IOCTL(HOT_ADD_DISK)
 COMPATIBLE_IOCTL(SET_DISK_FAULTY)
+COMPATIBLE_IOCTL(HOT_GENERATE_ERROR)
 COMPATIBLE_IOCTL(RUN_ARRAY)
 COMPATIBLE_IOCTL(START_ARRAY)
 COMPATIBLE_IOCTL(STOP_ARRAY)
 COMPATIBLE_IOCTL(STOP_ARRAY_RO)
 COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
 
+/* DM */
+COMPATIBLE_IOCTL(DM_VERSION)
+COMPATIBLE_IOCTL(DM_REMOVE_ALL)
+COMPATIBLE_IOCTL(DM_DEV_CREATE)
+COMPATIBLE_IOCTL(DM_DEV_REMOVE)
+COMPATIBLE_IOCTL(DM_DEV_RELOAD)
+COMPATIBLE_IOCTL(DM_DEV_SUSPEND)
+COMPATIBLE_IOCTL(DM_DEV_RENAME)
+COMPATIBLE_IOCTL(DM_DEV_DEPS)
+COMPATIBLE_IOCTL(DM_DEV_STATUS)
+COMPATIBLE_IOCTL(DM_TARGET_STATUS)
+COMPATIBLE_IOCTL(DM_TARGET_WAIT)
+
 /* Big K */
 COMPATIBLE_IOCTL(PIO_FONT)
 COMPATIBLE_IOCTL(GIO_FONT)
@@ -3570,6 +3607,11 @@
 HANDLE_IOCTL(0x1260, broken_blkgetsize)
 HANDLE_IOCTL(BLKSECTGET, w_long)
 HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
+/* take care of sizeof(sizeof()) breakage */
+/* block stuff */
+HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget)
+HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset)
+HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64)
 
 HANDLE_IOCTL(FBIOGET_FSCREENINFO, fb_ioctl_trans)
 HANDLE_IOCTL(FBIOGETCMAP, fb_ioctl_trans)
diff -Nru a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
--- a/arch/parisc/kernel/module.c	Mon Feb  3 21:32:54 2003
+++ b/arch/parisc/kernel/module.c	Sun Mar  2 15:58:28 2003
@@ -562,10 +562,8 @@
 #ifdef __LP64__
 	me->init = (void *)get_fdesc(me, (Elf_Addr)me->init);
 #ifdef CONFIG_MODULE_UNLOAD
-	if (me->cleanup)
-		me->cleanup = (void *)get_fdesc(me, (Elf_Addr)me->cleanup);
-	if (me->destroy)
-		me->destroy = (void *)get_fdesc(me, (Elf_Addr)me->destroy);
+	if (me->exit)
+		me->exit = (void *)get_fdesc(me, (Elf_Addr)me->exit);
 #endif
 #endif
 	return 0;
diff -Nru a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
--- a/arch/parisc/kernel/pci.c	Sun Mar 16 14:16:32 2003
+++ b/arch/parisc/kernel/pci.c	Mon Mar 17 09:56:45 2003
@@ -83,16 +83,9 @@
 u##size in##type (int addr) \
 { \
 	int b = PCI_PORT_HBA(addr); \
-	u##size d = (u##size) -1; \
 	EISA_IN(size); \
-	ASSERT(pci_port); /* make sure services are defined */ \
-	ASSERT(parisc_pci_hba[b]); /* make sure ioaddr are "fixed up" */ \
-	if (parisc_pci_hba[b] == NULL) { \
-		printk(KERN_WARNING "\nPCI or EISA Host Bus Adapter %d not registered. in" #size "(0x%x) returning -1\n", b, addr); \
-	} else { \
-		d = pci_port->in##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr)); \
-	} \
-	return d; \
+	if (!parisc_pci_hba[b]) return (u##size) -1; \
+	return pci_port->in##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr)); \
 }
 
 PCI_PORT_IN(b,  8)
@@ -105,7 +98,7 @@
 { \
 	int b = PCI_PORT_HBA(addr); \
 	EISA_OUT(size); \
-	ASSERT(pci_port); \
+	if (!parisc_pci_hba[b]) return; \
 	pci_port->out##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr), d); \
 }
 
@@ -318,9 +311,6 @@
 EXPORT_SYMBOL(pcibios_resource_to_bus);
 #endif
 
-#define MAX(val1, val2)   ((val1) > (val2) ? (val1) : (val2))
-
-
 /*
 ** pcibios align resources() is called everytime generic PCI code
 ** wants to generate a new address. The process of looking for
@@ -349,7 +339,7 @@
 	align = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
 
 	/* Align to largest of MIN or input size */
-	mask = MAX(alignment, align) - 1;
+	mask = max(alignment, align) - 1;
 	res->start += mask;
 	res->start &= ~mask;
 
diff -Nru a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
--- a/arch/parisc/kernel/process.c	Fri Nov 29 02:53:55 2002
+++ b/arch/parisc/kernel/process.c	Tue Mar 11 16:21:06 2003
@@ -205,7 +205,16 @@
 
 int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
 {
+	if (regs == NULL)
+		return 0;
+
 	memcpy(r, regs->fr, sizeof *r);
+	return 1;
+}
+
+int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
+{
+	memcpy(r, tsk->thread.regs.fr, sizeof(*r));
 	return 1;
 }
 
diff -Nru a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
--- a/arch/parisc/kernel/signal.c	Mon Feb 10 17:21:29 2003
+++ b/arch/parisc/kernel/signal.c	Sun Feb 16 03:10:20 2003
@@ -310,7 +310,7 @@
 #endif
 
 #if CACHE_FLUSHING_IS_NOT_BROKEN
-	flush_icache_range((unsigned long) &frame->tramp[0],
+	flush_user_icache_range((unsigned long) &frame->tramp[0],
 			   (unsigned long) &frame->tramp[4]);
 #else
 	/* It should *always* be cache line-aligned, but the compiler
@@ -395,7 +395,7 @@
 handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
 	      struct pt_regs *regs, int in_syscall)
 {
-	struct k_sigaction *ka = &current->sig->action[sig-1];
+	struct k_sigaction *ka = &current->sighand->action[sig-1];
 
 	DBG(("handle_signal(sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p)\n",
 	       sig, ka, info, oldset, regs));
@@ -451,7 +451,7 @@
 		oldset->sig[0], oldset->sig[1]));
 
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		/* Restart a system call if necessary. */
 		if (in_syscall) {
@@ -463,7 +463,7 @@
 				break;
 
 			case -ERESTARTSYS:
-				ka = &current->sig->action[signr-1];
+				ka = &current->sighand->action[signr-1];
 				if (!(ka->sa.sa_flags & SA_RESTART)) {
 					DBG(("ERESTARTSYS: putting -EINTR\n"));
 					regs->gr[28] = -EINTR;
diff -Nru a/arch/parisc/kernel/sys32.h b/arch/parisc/kernel/sys32.h
--- a/arch/parisc/kernel/sys32.h	Mon Feb 10 17:21:29 2003
+++ b/arch/parisc/kernel/sys32.h	Sun Mar  2 15:58:28 2003
@@ -1,6 +1,8 @@
 #ifndef _PARISC64_KERNEL_SYS32_H
 #define _PARISC64_KERNEL_SYS32_H
 
+#include <linux/compat.h>
+
 /* Call a kernel syscall which will use kernel space instead of user
  * space for its copy_to/from_user.
  */
@@ -12,6 +14,8 @@
     set_fs (old_fs); \
 }
 
+#ifdef CONFIG_COMPAT
+
 typedef __u32 __sighandler_t32;
 
 struct sigaction32 {
@@ -19,5 +23,7 @@
 	unsigned int sa_flags;
 	compat_sigset_t sa_mask;		/* mask last for extensibility */
 };
+
+#endif
 
 #endif
diff -Nru a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
--- a/arch/parisc/kernel/sys_parisc.c	Wed Nov 27 01:13:35 2002
+++ b/arch/parisc/kernel/sys_parisc.c	Mon Mar 17 17:15:27 2003
@@ -309,25 +309,6 @@
 	return -ENOSYS;
 }
 
-/*
- * Set a given TLS descriptor:
- */
-asmlinkage int sys_set_thread_area(struct user_desc *u_info)
-{
-	return -ENOSYS;
-}
-
-
-/*
- * Get the current Thread-Local Storage area:
- */
-
-asmlinkage int sys_get_thread_area(struct user_desc *u_info)
-{
-	return -ENOSYS;
-}
-
-
 asmlinkage unsigned long sys_alloc_hugepages(int key, unsigned long addr, unsigned long len, int prot, int flag)
 {
 	return -ENOMEM;
diff -Nru a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
--- a/arch/parisc/kernel/sys_parisc32.c	Sun Mar  9 01:34:44 2003
+++ b/arch/parisc/kernel/sys_parisc32.c	Sun Mar 23 14:31:56 2003
@@ -1282,25 +1282,6 @@
 	__kernel_gid_t	ex_anon_gid;
 };
 
-/* GETFH */
-struct nfsctl_fhparm32 {
-	struct sockaddr	gf_addr;
-	__kernel_dev_t	gf_dev;
-	compat_ino_t	gf_ino;
-	int		gf_version;
-};
-
-/* UGIDUPDATE */
-struct nfsctl_uidmap32 {
-	compat_caddr_t	ug_ident;
-	__kernel_uid_t	ug_uidbase;
-	int		ug_uidlen;
-	compat_caddr_t	ug_udimap;
-	__kernel_gid_t	ug_gidbase;
-	int		ug_gidlen;
-	compat_caddr_t	ug_gdimap;
-};
-
 struct nfsctl_arg32 {
 	int			ca_version;	/* safeguard */
 	/* wide kernel places this union on 8-byte boundary, narrow on 4 */
@@ -1308,8 +1289,6 @@
 		struct nfsctl_svc	u_svc;
 		struct nfsctl_client	u_client;
 		struct nfsctl_export32	u_export;
-		struct nfsctl_uidmap32	u_umap;
-		struct nfsctl_fhparm32	u_getfh;
 		struct nfsctl_fdparm	u_getfd;
 		struct nfsctl_fsparm	u_getfs;
 	} u;
@@ -1346,29 +1325,6 @@
 		ret = copy_from_user(&n.u, argp, sizeof n.u.u_getfs);
 		break;
 
-	case NFSCTL_GETFH:		/* nfsctl_fhparm */
-		ret = copy_from_user(&n32.u, argp, sizeof n32.u.u_getfh);
-#undef CP
-#define CP(x)	n.u.u_getfh.gf_##x = n32.u.u_getfh.gf_##x
-		CP(addr);
-		CP(dev);
-		CP(ino);
-		CP(version);
-		break;
-
-	case NFSCTL_UGIDUPDATE:		/* nfsctl_uidmap */
-		ret = copy_from_user(&n32.u, argp, sizeof n32.u.u_umap);
-#undef CP
-#define CP(x)	n.u.u_umap.ug_##x = n32.u.u_umap.ug_##x
-		n.u.u_umap.ug_ident = (char *)(u_long)n32.u.u_umap.ug_ident;
-		CP(uidbase);
-		CP(uidlen);
-		n.u.u_umap.ug_udimap = (__kernel_uid_t *)(u_long)n32.u.u_umap.ug_udimap;
-		CP(gidbase);
-		CP(gidlen);
-		n.u.u_umap.ug_gdimap = (__kernel_gid_t *)(u_long)n32.u.u_umap.ug_gdimap;
-		break;
-
 	case NFSCTL_UNEXPORT:		/* nfsctl_export */
 	case NFSCTL_EXPORT:		/* nfsctl_export */
 		ret = copy_from_user(&n32.u, argp, sizeof n32.u.u_export);
@@ -1393,7 +1349,7 @@
 	if (ret == 0) {
 		unsigned char rbuf[NFS_FHSIZE + sizeof (struct knfsd_fh)];
 		KERNEL_SYSCALL(ret, sys_nfsservctl, cmd, &n, &rbuf);
-		if (cmd == NFSCTL_GETFH || cmd == NFSCTL_GETFD) {
+		if (cmd == NFSCTL_GETFD) {
 			ret = copy_to_user(resp, rbuf, NFS_FHSIZE);
 		} else if (cmd == NFSCTL_GETFS) {
 			ret = copy_to_user(resp, rbuf, sizeof (struct knfsd_fh));
diff -Nru a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
--- a/arch/parisc/kernel/syscall.S	Sun Mar  9 01:34:44 2003
+++ b/arch/parisc/kernel/syscall.S	Mon Mar 17 17:15:27 2003
@@ -567,10 +567,10 @@
 	ENTRY_SAME(rt_sigsuspend_wrapper) /* not really SAME -- see the code */
 	ENTRY_SAME(chown)		/* 180 */
 	/* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */
-	ENTRY_DIFF(setsockopt)
+	ENTRY_COMP(setsockopt)
 	ENTRY_SAME(getsockopt)
-	ENTRY_DIFF(sendmsg)
-	ENTRY_DIFF(recvmsg)
+	ENTRY_COMP(sendmsg)
+	ENTRY_COMP(recvmsg)
 	ENTRY_SAME(semop)		/* 185 */
 	ENTRY_SAME(semget)
 	ENTRY_DIFF(semctl_broken)
@@ -600,8 +600,8 @@
 	ENTRY_COMP(futex)		/* 210 */
 	ENTRY_SAME(sched_setaffinity)
 	ENTRY_SAME(sched_getaffinity)
-	ENTRY_SAME(set_thread_area)
-	ENTRY_SAME(get_thread_area)
+	ENTRY_SAME(ni_syscall)
+	ENTRY_SAME(ni_syscall)
 	ENTRY_SAME(io_setup)		/* 215 */
 	ENTRY_SAME(io_destroy)
 	ENTRY_SAME(io_getevents)
diff -Nru a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
--- a/arch/parisc/kernel/traps.c	Mon Jan 13 22:57:43 2003
+++ b/arch/parisc/kernel/traps.c	Fri Feb 14 00:46:27 2003
@@ -27,6 +27,7 @@
 #include <linux/console.h>
 #include <linux/kallsyms.h>
 
+#include <asm/assembly.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -165,9 +166,11 @@
 
 	startstack = (unsigned long *)((unsigned long)stack & ~(THREAD_SIZE - 1));
 	i = 1;
+	stack = (long *)((long)(stack + 32) &~ (FRAME_SIZE-1)); /* Align */
 	printk("Kernel addresses on the stack:\n");
-	while (stack >= startstack) {
-		addr = *stack--;
+	while (stack > startstack) {
+		stack -= 16;	/* Stack frames are a multiple of 16 words */
+		addr = stack[16 - RP_OFFSET / sizeof(long)];
 		/*
 		 * If the address is either in the text segment of the
 		 * kernel, or in the region which contains vmalloc'ed
diff -Nru a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c
--- a/arch/ppc/8260_io/enet.c	Sun Sep 15 21:51:56 2002
+++ b/arch/ppc/8260_io/enet.c	Sat Mar 22 17:18:48 2003
@@ -807,7 +807,7 @@
 
 	/* Install our interrupt handler.
 	*/
-	request_8xxirq(SIU_INT_ENET, scc_enet_interrupt, 0, "enet", dev);
+	request_irq(SIU_INT_ENET, scc_enet_interrupt, 0, "enet", dev);
 
 	/* Set GSMR_H to enable all normal operating modes.
 	 * Set GSMR_L to enable Ethernet to MC68160.
diff -Nru a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c
--- a/arch/ppc/8260_io/fcc_enet.c	Sun Sep 15 21:51:56 2002
+++ b/arch/ppc/8260_io/fcc_enet.c	Sat Mar 22 17:18:48 2003
@@ -1705,12 +1705,12 @@
 
 	/* Install our interrupt handler.
 	*/
-	if (request_8xxirq(fip->fc_interrupt, fcc_enet_interrupt, 0,
+	if (request_irq(fip->fc_interrupt, fcc_enet_interrupt, 0,
 							"fenet", dev) < 0)
 		printk("Can't get FCC IRQ %d\n", fip->fc_interrupt);
 
 #ifdef	CONFIG_USE_MDIO
-	if (request_8xxirq(PHY_INTERRUPT, mii_link_interrupt, 0,
+	if (request_irq(PHY_INTERRUPT, mii_link_interrupt, 0,
 							"mii", dev) < 0)
 		printk("Can't get MII IRQ %d\n", fip->fc_interrupt);
 #endif	/* CONFIG_USE_MDIO */
diff -Nru a/arch/ppc/8260_io/uart.c b/arch/ppc/8260_io/uart.c
--- a/arch/ppc/8260_io/uart.c	Mon Feb  3 05:47:46 2003
+++ b/arch/ppc/8260_io/uart.c	Sat Mar 22 17:18:48 2003
@@ -3,6 +3,8 @@
  *  Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
  *  Copyright (c) 2000 MontaVista Software, Inc. (source@mvista.com)
  *	2.3.99 updates
+ *  Copyright (c) 2002 Allen Curtis, Ones and Zeros, Inc. (acurtis@onz.com)
+ *	2.5.50 updates
  *
  * I used the 8xx uart.c driver as the framework for this driver.
  * The original code was written for the EST8260 board.  I tried to make
@@ -28,6 +30,7 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
+#include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
@@ -69,9 +72,7 @@
 #define TX_WAKEUP	ASYNC_SHARE_IRQ
 
 static char *serial_name = "CPM UART driver";
-static char *serial_version = "0.01";
-
-static DECLARE_TASK_QUEUE(tq_serial);
+static char *serial_version = "0.02";
 
 static struct tty_driver serial_driver, callout_driver;
 static int serial_refcount;
@@ -201,8 +202,8 @@
 	int			blocked_open; /* # of blocked opens */
 	long			session; /* Session of opening process */
 	long			pgrp; /* pgrp of opening process */
-	struct tq_struct	tqueue;
-	struct tq_struct	tqueue_hangup;
+	struct work_struct	tqueue;
+	struct work_struct	tqueue_hangup;
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
 
@@ -331,8 +332,7 @@
 				  int event)
 {
 	info->event |= 1 << event;
-	queue_task(&info->tqueue, &tq_serial);
-	mark_bh(SERIAL_BH);
+	schedule_work(&info->tqueue);
 }
 
 static _INLINE_ void receive_chars(ser_info_t *info)
@@ -479,7 +479,7 @@
 
 	info->rx_cur = (cbd_t *)bdp;
 
-	queue_task(&tty->flip.tqueue, &tq_timer);
+	schedule_delayed_work(&tty->flip.work, 1);
 }
 
 static _INLINE_ void transmit_chars(ser_info_t *info)
@@ -537,7 +537,7 @@
 			printk("scheduling hangup...");
 #endif
 			MOD_INC_USE_COUNT;
-			if (schedule_task(&info->tqueue_hangup) == 0)
+			if (schedule_work(&info->tqueue_hangup) == 0)
 				MOD_DEC_USE_COUNT;
 		}
 	}
@@ -628,11 +628,6 @@
  * 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_)
 {
 	ser_info_t	*info = (ser_info_t *) private_;
@@ -651,7 +646,7 @@
 }
 
 /*
- * This routine is called from the scheduler tqueue when the interrupt
+ * This routine is called from the scheduler work queue when the interrupt
  * routine has signalled that a hangup has occurred.  The path of
  * hangup processing is:
  *
@@ -1308,7 +1303,7 @@
 {
 	volatile cpm8260_t *cp;
 	uint	page, sblock;
-	ushort	num;
+	int	num;
 
 	cp = cpmp;
 
@@ -1352,7 +1347,7 @@
 {
 	volatile cpm8260_t *cp;
 	uint	page, sblock;
-	ushort	num;
+	int	num;
 
 	cp = cpmp;
 
@@ -1756,7 +1751,7 @@
 	 */
 	char_time = 1;
 	if (timeout)
-		char_time = min(char_time, timeout);
+		char_time = min(char_time, (unsigned long)timeout);
 #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
 	printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
 	printk("jiff=%lu...", jiffies);
@@ -1980,7 +1975,7 @@
 	ser_info_t	*info;
 	int 		retval, line;
 
-	line = MINOR(tty->device) - tty->driver.minor_start;
+	line = minor(tty->device) - tty->driver.minor_start;
 	if ((line < 0) || (line >= NR_PORTS))
 		return -ENODEV;
 	retval = get_async_struct(line, &info);
@@ -2455,7 +2450,7 @@
 
 static kdev_t serial_console_device(struct console *c)
 {
-	return MKDEV(TTY_MAJOR, 64 + c->index);
+	return mk_kdev(TTY_MAJOR, 64 + c->index);
 }
 
 
@@ -2503,8 +2498,6 @@
 	volatile	immap_t		*immap;
 	volatile	iop8260_t	*io;
 	
-	init_bh(SERIAL_BH, do_serial_bh);
-
 	show_serial_version();
 
 	/* Initialize the tty_driver structure */
@@ -2680,10 +2673,8 @@
 			init_waitqueue_head(&info->close_wait);
 			info->magic = SERIAL_MAGIC;
 			info->flags = state->flags;
-			info->tqueue.routine = do_softint;
-			info->tqueue.data = info;
-			info->tqueue_hangup.routine = do_serial_hangup;
-			info->tqueue_hangup.data = info;
+			INIT_WORK(&info->tqueue, do_softint, info);
+			INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info);
 			info->line = i;
 			info->state = state;
 			state->info = (struct async_struct *)info;
@@ -2874,7 +2865,7 @@
 
 			/* Install interrupt handler.
 			*/
-			request_8xxirq(state->irq, rs_8xx_interrupt, 0, "uart", info);
+			request_irq(state->irq, rs_8xx_interrupt, 0, "uart", info);
 
 			/* Set up the baud rate generator.
 			*/
diff -Nru a/arch/ppc/Makefile b/arch/ppc/Makefile
--- a/arch/ppc/Makefile	Fri Mar  7 13:28:49 2003
+++ b/arch/ppc/Makefile	Wed Mar 19 21:01:42 2003
@@ -1,7 +1,5 @@
 # This file is included by the global makefile so that you can add your own
-# architecture-specific flags and dependencies. Remember to do have actions
-# for "archclean" and "archdep" for cleaning up and making dependencies for
-# this architecture
+# architecture-specific flags and dependencies.
 #
 # This file is subject to the terms and conditions of the GNU General Public
 # License.  See the file "COPYING" in the main directory of this archive
@@ -17,24 +15,20 @@
 
 LDFLAGS_BLOB	:= --format binary --oformat elf32-powerpc
 LDFLAGS_vmlinux	= -Ttext $(KERNELLOAD) -Bstatic
-CPPFLAGS	:= $(CPPFLAGS) -I$(TOPDIR)/arch/$(ARCH)
-AFLAGS		:= $(AFLAGS) -I$(TOPDIR)/arch/$(ARCH)
-CFLAGS		:= $(CFLAGS) -I$(TOPDIR)/arch/$(ARCH) -msoft-float -pipe \
+CPPFLAGS	+= -Iarch/$(ARCH)
+AFLAGS		+= -Iarch/$(ARCH)
+cflags-y	+= -Iarch/$(ARCH) -msoft-float -pipe \
 		-ffixed-r2 -Wno-uninitialized -mmultiple -mstring
 CPP		= $(CC) -E $(CFLAGS)
 
-ifdef CONFIG_4xx
-CFLAGS := $(CFLAGS) -Wa,-m405
-endif
+cflags-$(CONFIG_4xx)		+= -Wa,-m405
+cflags-$(CONFIG_PPC64BRIDGE)	+= -Wa,-mppc64bridge
+# Use sed to remove the quotes.
+cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \
+	$(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
 
-ifdef CONFIG_PPC64BRIDGE
-CFLAGS := $(CFLAGS) -Wa,-mppc64bridge
-endif
+CFLAGS += $(cflags-y)
 
-ifdef CONFIG_MORE_COMPILE_OPTIONS
-# Use sed to remove the quotes.
-  CFLAGS += $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
-endif
 
 head-y				:= arch/ppc/kernel/head.o
 head-$(CONFIG_8xx)		:= arch/ppc/kernel/head_8xx.o
diff -Nru a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile
--- a/arch/ppc/boot/Makefile	Sat Jan  4 02:51:06 2003
+++ b/arch/ppc/boot/Makefile	Wed Mar 19 21:01:42 2003
@@ -10,8 +10,8 @@
 # modified by Cort (cort@cs.nmt.edu)
 #
 
-CFLAGS	+= -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include
-HOSTCFLAGS += -I$(TOPDIR)/arch/$(ARCH)/boot/include
+CFLAGS	 	+= -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include
+HOSTCFLAGS	+= -Iarch/$(ARCH)/boot/include
 
 BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd
 
@@ -21,7 +21,7 @@
 subdir-$(CONFIG_ALL_PPC)	+= of1275
 
 # for cleaning
-subdir-				+= simple openfirmware prep
+subdir-				+= simple/ openfirmware/ prep/
 
 tools-$(CONFIG_ALL_PPC)		:= addnote mknote hack-coff mkprep
 tools-$(CONFIG_PPLUS)		:= mkbugboot mkprep
@@ -33,8 +33,6 @@
 tools-$(CONFIG_PRPMC750)	:= mkbugboot mkprep
 tools-$(CONFIG_PRPMC800)	:= mkbugboot mkprep
 tools-$(CONFIG_SPRUCE)		:= mktree
-
-all-tools := addnote mknote hack-coff mkprep mkbugboot mktree
 
 host-progs			:= $(addprefix utils/,$(tools-y))
 
diff -Nru a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile
--- a/arch/ppc/boot/images/Makefile	Sun Mar  9 13:47:41 2003
+++ b/arch/ppc/boot/images/Makefile	Wed Mar 19 21:01:42 2003
@@ -2,7 +2,7 @@
 # This dir holds all of the images for PPC machines.
 # Tom Rini	January 2001
 
-targets		:= vmlinux.gz
+extra-y		:= vmlinux.gz
 GZIP_FLAGS	:= -v9f
 
 $(obj)/vmlinux.gz: vmlinux
diff -Nru a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile
--- a/arch/ppc/boot/openfirmware/Makefile	Sat Jan  4 02:51:06 2003
+++ b/arch/ppc/boot/openfirmware/Makefile	Wed Mar 19 21:01:42 2003
@@ -26,10 +26,15 @@
 CHRP_LD_ARGS = -T $(boot)/ld.script -e _start -Ttext 0x00800000
 NEWWORLD_LD_ARGS = -T $(boot)/ld.script -e _start -Ttext 0x01000000
 
-COMMONOBJS = $(obj)/start.o $(obj)/misc.o $(obj)/common.o
-COFFOBJS = $(obj)/coffcrt0.o $(COMMONOBJS) $(obj)/coffmain.o
-CHRPOBJS = $(obj)/crt0.o $(COMMONOBJS) $(obj)/chrpmain.o
-NEWWORLDOBJS = $(obj)/crt0.o $(COMMONOBJS) $(obj)/newworldmain.o
+COMMONOBJS	:= start.o misc.o common.o
+COFFOBJS	:= coffcrt0.o $(COMMONOBJS) coffmain.o
+CHRPOBJS	:= crt0.o $(COMMONOBJS) chrpmain.o
+NEWWORLDOBJS	:= crt0.o $(COMMONOBJS) newworldmain.o
+
+EXTRA_TARGETS := $(COFFOBJS) $(CHRPOBJS) $(NEWWORLDOBJS)
+COFFOBJS	:= $(addprefix $(obj)/, $(COFFOBJS))
+CHRPOBJS	:= $(addprefix $(obj)/, $(CHRPOBJS))
+NEWWORLDOBJS	:= $(addprefix $(obj)/, $(NEWWORLDOBJS))
 
 LIBS = lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a
 
diff -Nru a/arch/ppc/boot/prep/Makefile b/arch/ppc/boot/prep/Makefile
--- a/arch/ppc/boot/prep/Makefile	Wed Nov 20 03:10:01 2002
+++ b/arch/ppc/boot/prep/Makefile	Wed Mar 19 21:01:42 2003
@@ -35,7 +35,8 @@
 images := $(boot)/images
 simple := $(boot)/simple
 
-OBJS	:= $(addprefix $(obj)/,$(boot-y)) $(simple)/legacy.o 
+EXTRA_TARGETS	:= $(boot-y) ../simple/legacy.o
+OBJS		:= $(addprefix $(obj)/,$(boot-y)) $(simple)/legacy.o 
 
 # Tools
 MKPREP				:= $(utils)/mkprep
diff -Nru a/arch/ppc/boot/simple/embed_config.c b/arch/ppc/boot/simple/embed_config.c
--- a/arch/ppc/boot/simple/embed_config.c	Sat Jan  4 02:51:06 2003
+++ b/arch/ppc/boot/simple/embed_config.c	Sat Mar 22 17:18:48 2003
@@ -431,7 +431,7 @@
 }
 #endif
 
-#ifdef CONFIG_EST8260
+#if defined(CONFIG_EST8260) || defined(CONFIG_TQM8260)
 void
 embed_config(bd_t **bdp)
 {
diff -Nru a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
--- a/arch/ppc/kernel/Makefile	Sun Mar  9 14:15:54 2003
+++ b/arch/ppc/kernel/Makefile	Wed Mar 19 21:01:42 2003
@@ -28,11 +28,8 @@
 obj-$(CONFIG_KGDB)		+= ppc-stub.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_TAU)		+= temp.o
-ifeq ($(CONFIG_8xx),y)
-ifneq ($(CONFIG_MATH_EMULATION),n)
-obj-y				+= softemu8xx.o
-endif
+
+ifdef CONFIG_MATH_EMULATION
+obj-$(CONFIG_8xx)		+= softemu8xx.o
 endif
 
-find_name : find_name.c
-	$(HOSTCC) $(HOSTCFLAGS) -o find_name find_name.c
diff -Nru a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
--- a/arch/ppc/kernel/pci.c	Sun Mar 16 14:16:32 2003
+++ b/arch/ppc/kernel/pci.c	Wed Mar 19 18:45:17 2003
@@ -176,6 +176,21 @@
 }
 #endif /* CONFIG_ALL_PPC */
 
+void
+pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+			struct resource *res)
+{
+	unsigned long offset = 0;
+	struct pci_controller *hose = dev->sysdata;
+
+	if (hose && res->flags & IORESOURCE_IO)
+		offset = (unsigned long)hose->io_base_virt - isa_io_base;
+	else if (hose && res->flags & IORESOURCE_MEM)
+		offset = hose->pci_mem_offset;
+	region->start = res->start - offset;
+	region->end = res->end - offset;
+}
+
 /*
  * We need to avoid collisions with `mirrored' VGA ports
  * and other strange ISA hardware, so we always want the
@@ -579,8 +594,10 @@
 			 */
 			if ((r->flags & IORESOURCE_UNSET) && r->end &&
 			    (!ppc_md.pcibios_enable_device_hook ||
-			     !ppc_md.pcibios_enable_device_hook(dev, 1)))
+			     !ppc_md.pcibios_enable_device_hook(dev, 1))) {
+				r->flags &= ~IORESOURCE_UNSET;
 				pci_assign_resource(dev, idx);
+			}
 		}
 
 #if 0 /* don't assign ROMs */
diff -Nru a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
--- a/arch/ppc/kernel/ppc_ksyms.c	Fri Feb 14 01:58:30 2003
+++ b/arch/ppc/kernel/ppc_ksyms.c	Sat Mar 22 17:18:48 2003
@@ -337,7 +337,7 @@
 #if defined(CONFIG_8xx) || defined(CONFIG_4xx)
 EXPORT_SYMBOL(__res);
 #endif
-#if defined(CONFIG_8xx) || defined(CONFIG_8260)
+#if defined(CONFIG_8xx)
 EXPORT_SYMBOL(request_8xxirq);
 #endif
 
diff -Nru a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
--- a/arch/ppc/kernel/traps.c	Wed Jan 15 20:09:48 2003
+++ b/arch/ppc/kernel/traps.c	Mon Mar 17 21:32:24 2003
@@ -86,13 +86,14 @@
 
 void die(const char * str, struct pt_regs * fp, long err)
 {
+	static int die_counter;
 	console_verbose();
 	spin_lock_irq(&die_lock);
 #ifdef CONFIG_PMAC_BACKLIGHT
 	set_backlight_enable(1);
 	set_backlight_level(BACKLIGHT_MAX);
 #endif
-	printk("Oops: %s, sig: %ld\n", str, err);
+	printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
 	show_regs(fp);
 	spin_unlock_irq(&die_lock);
 	/* do_exit() should take care of panic'ing from an interrupt
diff -Nru a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
--- a/arch/ppc/platforms/Makefile	Mon Feb  3 14:19:36 2003
+++ b/arch/ppc/platforms/Makefile	Sat Mar 22 17:18:48 2003
@@ -10,7 +10,7 @@
 endif
 
 # Extra CFLAGS so we don't have to do relative includes
-CFLAGS_pmac_setup.o	+= -I$(TOPDIR)/arch/$(ARCH)/mm
+CFLAGS_pmac_setup.o	+= -Iarch/$(ARCH)/mm
 
 obj-$(CONFIG_APUS)		+= apus_setup.o
 ifeq ($(CONFIG_APUS),y)
@@ -28,6 +28,8 @@
 obj-$(CONFIG_PPC_RTAS)		+= error_log.o proc_rtas.o
 obj-$(CONFIG_PREP_RESIDUAL)	+= residual.o
 obj-$(CONFIG_ADIR)		+= adir_setup.o adir_pic.o adir_pci.o
+obj-$(CONFIG_EST8260)		+= est8260_setup.o
+obj-$(CONFIG_TQM8260)		+= tqm8260_setup.o
 obj-$(CONFIG_EV64260)		+= ev64260_setup.o
 obj-$(CONFIG_GEMINI)		+= gemini_pci.o gemini_setup.o gemini_prom.o
 obj-$(CONFIG_K2)		+= k2_setup.o k2_pci.o
diff -Nru a/arch/ppc/platforms/est8260.h b/arch/ppc/platforms/est8260.h
--- a/arch/ppc/platforms/est8260.h	Sun Sep 15 21:52:01 2002
+++ b/arch/ppc/platforms/est8260.h	Sat Mar 22 17:18:48 2003
@@ -3,8 +3,12 @@
  * will soon be removed.  All of the clock values are computed from
  * the configuration SCMR and the Power-On-Reset word.
  */
+#ifndef __EST8260_PLATFORM
+#define __EST8260_PLATFORM
 
-#define IMAP_ADDR	((uint)0xf0000000)
+#define IMAP_ADDR		((uint)0xf0000000)
+
+#define BOOTROM_RESTART_ADDR	((uint)0xff000104)
 
 
 /* A Board Information structure that is given to a program when
@@ -25,3 +29,4 @@
 
 extern bd_t m8xx_board_info;
 
+#endif 	/* __EST8260_PLATFORM */
diff -Nru a/arch/ppc/platforms/est8260_setup.c b/arch/ppc/platforms/est8260_setup.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc/platforms/est8260_setup.c	Sat Mar 22 17:12:56 2003
@@ -0,0 +1,65 @@
+/*
+ * arch/ppc/platforms/est8260_setup.c
+ * 
+ * EST8260 platform support
+ *
+ * Author: Allen Curtis <acurtis@onz.com>
+ * Derived from: m8260_setup.c by Dan Malek, MVista
+ *
+ * Copyright 2002 Ones and Zeros, 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.
+ */
+
+#include <linux/config.h>
+#include <linux/seq_file.h>
+
+#include <asm/mpc8260.h>
+#include <asm/machdep.h>
+
+static void (*callback_setup_arch)(void);
+
+extern unsigned char __res[sizeof(bd_t)];
+
+extern void m8260_init(unsigned long r3, unsigned long r4, 
+	unsigned long r5, unsigned long r6, unsigned long r7);
+
+static int
+est8260_show_cpuinfo(struct seq_file *m)
+{
+	bd_t	*binfo = (bd_t *)__res;
+
+	seq_printf(m, "vendor\t\t: EST Corporation\n"
+		      "machine\t\t: SBC8260 PowerPC\n"
+		      "\n"
+		      "mem size\t\t: 0x%08x\n"
+		      "console baud\t\t: %d\n"
+		      "\n",
+		      binfo->bi_memsize,
+		      binfo->bi_baudrate);
+	return 0;
+}
+
+static void __init
+est8260_setup_arch(void)
+{
+	printk("EST SBC8260 Port\n");
+	callback_setup_arch();
+}
+
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	      unsigned long r6, unsigned long r7)
+{
+	/* Generic 8260 platform initialization */
+	m8260_init(r3, r4, r5, r6, r7);
+
+	/* Anything special for this platform */
+	ppc_md.show_cpuinfo	= est8260_show_cpuinfo;
+
+	callback_setup_arch	= ppc_md.setup_arch;
+	ppc_md.setup_arch	= est8260_setup_arch;
+}
diff -Nru a/arch/ppc/platforms/k2_setup.c b/arch/ppc/platforms/k2_setup.c
--- a/arch/ppc/platforms/k2_setup.c	Tue Feb 11 15:48:53 2003
+++ b/arch/ppc/platforms/k2_setup.c	Sat Mar 22 16:59:59 2003
@@ -56,10 +56,10 @@
 /* IDE functions */
 
 static void __init
-k2_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port,
-		ide_ioreg_t ctrl_port, int *irq)
+k2_ide_init_hwif_ports (hw_regs_t *hw, unsigned long data_port,
+		unsigned long ctrl_port, int *irq)
 {
-	ide_ioreg_t reg = data_port;
+	unsigned long reg = data_port;
 	int i = 8;
 
 	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
diff -Nru a/arch/ppc/platforms/lopec_setup.c b/arch/ppc/platforms/lopec_setup.c
--- a/arch/ppc/platforms/lopec_setup.c	Mon Mar 10 14:16:12 2003
+++ b/arch/ppc/platforms/lopec_setup.c	Sat Mar 22 16:59:59 2003
@@ -104,9 +104,9 @@
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
 int lopec_ide_ports_known = 0;
-static ide_ioreg_t lopec_ide_regbase[MAX_HWIFS];
-static ide_ioreg_t lopec_ide_ctl_regbase[MAX_HWIFS];
-static ide_ioreg_t lopec_idedma_regbase;
+static unsigned long lopec_ide_regbase[MAX_HWIFS];
+static unsigned long lopec_ide_ctl_regbase[MAX_HWIFS];
+static unsigned long lopec_idedma_regbase;
 
 static void
 lopec_ide_probe(void)
@@ -126,7 +126,7 @@
 }
 
 static int
-lopec_ide_default_irq(ide_ioreg_t base)
+lopec_ide_default_irq(unsigned long base)
 {
 	if (lopec_ide_ports_known == 0)
 		lopec_ide_probe();
@@ -139,7 +139,7 @@
 		return 0;
 }
 
-static ide_ioreg_t
+static unsigned long
 lopec_ide_default_io_base(int index)
 {
 	if (lopec_ide_ports_known == 0)
@@ -148,10 +148,10 @@
 }
 
 static void __init
-lopec_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data,
-			  ide_ioreg_t ctl, int *irq)
+lopec_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data,
+			  unsigned long ctl, int *irq)
 {
-	ide_ioreg_t reg = data;
+	unsigned long reg = data;
 	uint alt_status_base;
 	int i;
 
diff -Nru a/arch/ppc/platforms/mcpn765_setup.c b/arch/ppc/platforms/mcpn765_setup.c
--- a/arch/ppc/platforms/mcpn765_setup.c	Tue Feb 11 15:48:53 2003
+++ b/arch/ppc/platforms/mcpn765_setup.c	Sat Mar 22 16:59:59 2003
@@ -274,9 +274,9 @@
  * IDE support.
  */
 static int		mcpn765_ide_ports_known = 0;
-static ide_ioreg_t	mcpn765_ide_regbase[MAX_HWIFS];
-static ide_ioreg_t	mcpn765_ide_ctl_regbase[MAX_HWIFS];
-static ide_ioreg_t	mcpn765_idedma_regbase;
+static unsigned long	mcpn765_ide_regbase[MAX_HWIFS];
+static unsigned long	mcpn765_ide_ctl_regbase[MAX_HWIFS];
+static unsigned long	mcpn765_idedma_regbase;
 
 static void
 mcpn765_ide_probe(void)
@@ -298,7 +298,7 @@
 }
 
 static int
-mcpn765_ide_default_irq(ide_ioreg_t base)
+mcpn765_ide_default_irq(unsigned long base)
 {
         if (mcpn765_ide_ports_known == 0)
 	        mcpn765_ide_probe();
@@ -311,7 +311,7 @@
 		return 0;
 }
 
-static ide_ioreg_t
+static unsigned long
 mcpn765_ide_default_io_base(int index)
 {
         if (mcpn765_ide_ports_known == 0)
@@ -321,10 +321,10 @@
 }
 
 static void __init
-mcpn765_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
-			      ide_ioreg_t ctrl_port, int *irq)
+mcpn765_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
+			      unsigned long ctrl_port, int *irq)
 {
-	ide_ioreg_t reg = data_port;
+	unsigned long reg = data_port;
 	uint	alt_status_base;
 	int	i;
 
diff -Nru a/arch/ppc/platforms/menf1_setup.c b/arch/ppc/platforms/menf1_setup.c
--- a/arch/ppc/platforms/menf1_setup.c	Tue Feb 11 15:48:53 2003
+++ b/arch/ppc/platforms/menf1_setup.c	Sat Mar 22 16:59:59 2003
@@ -194,10 +194,10 @@
 /* IDE functions */
 
 static void __init
-menf1_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port,
-		ide_ioreg_t ctrl_port, int *irq)
+menf1_ide_init_hwif_ports (hw_regs_t *hw, unsigned long data_port,
+		unsigned long ctrl_port, int *irq)
 {
-	ide_ioreg_t reg = data_port;
+	unsigned long reg = data_port;
 	int i = 8;
 
 	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
@@ -215,7 +215,7 @@
 }
 
 static int
-menf1_ide_default_irq(ide_ioreg_t base)
+menf1_ide_default_irq(unsigned long base)
 {
 	if (base == MENF1_IDE0_BASE_ADDR)
 		return 14;
@@ -225,7 +225,7 @@
 		return 0;
 }
 
-static ide_ioreg_t
+static unsigned long
 menf1_ide_default_io_base(int index)
 {
 	if (index == 0)
diff -Nru a/arch/ppc/platforms/mpc82xx.h b/arch/ppc/platforms/mpc82xx.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc/platforms/mpc82xx.h	Sat Mar 22 17:12:47 2003
@@ -0,0 +1,42 @@
+/*
+ * arch/ppc/platforms/mpc82xx.h
+ * 
+ * Board specific support for various 82xx platforms.
+ *
+ * Author: Allen Curtis <acurtis@onz.com>
+ *
+ * Copyright 2002 Ones and Zeros, 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.
+ */
+#ifndef __CONFIG_82XX_PLATFORMS
+#define __CONFIG_82XX_PLATFORMS
+
+#ifdef CONFIG_8260
+
+#ifdef CONFIG_EST8260
+#include <platforms/est8260.h>
+#endif
+
+#ifdef CONFIG_SBS8260
+#include <platforms/sbs8260.h>
+#endif
+
+#ifdef CONFIG_RPX6
+#include <platforms/rpxsuper.h>
+#endif
+
+#ifdef CONFIG_WILLOW
+#include <platforms/willow.h>
+#endif
+
+#ifdef CONFIG_TQM8260
+#include <platforms/tqm8260.h>
+#endif
+
+#endif	/* CONFIG_8260 */
+
+#endif
diff -Nru a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c
--- a/arch/ppc/platforms/pmac_setup.c	Thu Nov  7 03:10:38 2002
+++ b/arch/ppc/platforms/pmac_setup.c	Sat Mar 22 17:21:25 2003
@@ -81,8 +81,9 @@
 extern void pmac_calibrate_decr(void);
 extern void pmac_pcibios_fixup(void);
 extern void pmac_find_bridges(void);
-extern int pmac_ide_check_base(ide_ioreg_t base);
-extern ide_ioreg_t pmac_ide_get_base(int index);
+extern unsigned long pmac_ide_get_base(int index);
+extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
+	unsigned long data_port, unsigned long ctrl_port, int *irq);
 
 extern void pmac_nvram_update(void);
 extern unsigned char pmac_nvram_read_byte(int addr);
@@ -629,6 +630,13 @@
 	ppc_md.find_end_of_memory = pmac_find_end_of_memory;
 
 	ppc_md.feature_call   = pmac_do_feature_call;
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
+        ppc_ide_md.ide_init_hwif	= pmac_ide_init_hwif_ports;
+        ppc_ide_md.default_io_base	= pmac_ide_get_base;
+#endif /* CONFIG_BLK_DEV_IDE_PMAC */
+#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
 
 #ifdef CONFIG_BOOTX_TEXT
 	ppc_md.progress = pmac_progress;
diff -Nru a/arch/ppc/platforms/pplus_setup.c b/arch/ppc/platforms/pplus_setup.c
--- a/arch/ppc/platforms/pplus_setup.c	Tue Feb 11 15:48:53 2003
+++ b/arch/ppc/platforms/pplus_setup.c	Sat Mar 22 16:59:59 2003
@@ -235,7 +235,7 @@
  * IDE stuff.
  */
 static int 
-pplus_ide_default_irq(ide_ioreg_t base)
+pplus_ide_default_irq(unsigned long base)
 {
 	switch (base) {
 		case 0x1f0: return 14;
@@ -244,7 +244,7 @@
 	}
 }
 
-static ide_ioreg_t 
+static unsigned long 
 pplus_ide_default_io_base(int index)
 {
 	switch (index) {
@@ -256,9 +256,9 @@
 }
 
 static void __init
-pplus_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+pplus_ide_init_hwif_ports (hw_regs_t *hw, unsigned long data_port, unsigned long ctrl_port, int *irq)
 {
-	ide_ioreg_t reg = data_port;
+	unsigned long reg = data_port;
 	int i;
 
 	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
diff -Nru a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
--- a/arch/ppc/platforms/prep_setup.c	Tue Jan  7 07:52:34 2003
+++ b/arch/ppc/platforms/prep_setup.c	Sat Mar 22 16:59:59 2003
@@ -1017,7 +1017,7 @@
  * IDE stuff.
  */
 static int __prep
-prep_ide_default_irq(ide_ioreg_t base)
+prep_ide_default_irq(unsigned long base)
 {
 	switch (base) {
 		case 0x1f0: return 13;
@@ -1030,7 +1030,7 @@
 	}
 }
 
-static ide_ioreg_t __prep
+static unsigned long __prep
 prep_ide_default_io_base(int index)
 {
 	switch (index) {
diff -Nru a/arch/ppc/platforms/sandpoint_setup.c b/arch/ppc/platforms/sandpoint_setup.c
--- a/arch/ppc/platforms/sandpoint_setup.c	Tue Feb 11 15:48:53 2003
+++ b/arch/ppc/platforms/sandpoint_setup.c	Sat Mar 22 16:59:59 2003
@@ -433,9 +433,9 @@
  * IDE support.
  */
 static int		sandpoint_ide_ports_known = 0;
-static ide_ioreg_t	sandpoint_ide_regbase[MAX_HWIFS];
-static ide_ioreg_t	sandpoint_ide_ctl_regbase[MAX_HWIFS];
-static ide_ioreg_t	sandpoint_idedma_regbase;
+static unsigned long	sandpoint_ide_regbase[MAX_HWIFS];
+static unsigned long	sandpoint_ide_ctl_regbase[MAX_HWIFS];
+static unsigned long	sandpoint_idedma_regbase;
 
 static void
 sandpoint_ide_probe(void)
@@ -457,7 +457,7 @@
 }
 
 static int
-sandpoint_ide_default_irq(ide_ioreg_t base)
+sandpoint_ide_default_irq(unsigned long base)
 {
         if (sandpoint_ide_ports_known == 0)
 	        sandpoint_ide_probe();
@@ -470,7 +470,7 @@
 		return 0;
 }
 
-static ide_ioreg_t
+static unsigned long
 sandpoint_ide_default_io_base(int index)
 {
         if (sandpoint_ide_ports_known == 0)
@@ -480,10 +480,10 @@
 }
 
 static void __init
-sandpoint_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
-			      ide_ioreg_t ctrl_port, int *irq)
+sandpoint_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
+			      unsigned long ctrl_port, int *irq)
 {
-	ide_ioreg_t reg = data_port;
+	unsigned long reg = data_port;
 	uint	alt_status_base;
 	int	i;
 
diff -Nru a/arch/ppc/platforms/tqm8260.h b/arch/ppc/platforms/tqm8260.h
--- a/arch/ppc/platforms/tqm8260.h	Sun Feb 10 03:21:52 2002
+++ b/arch/ppc/platforms/tqm8260.h	Sat Mar 22 17:18:48 2003
@@ -4,8 +4,8 @@
  * Copyright (c) 2001 Wolfgang Denk (wd@denx.de)
  */
 
-#ifndef __MACH_TQM8260_H
-#define __MACH_TQM8260_H
+#ifndef __TQM8260_PLATFORM
+#define __TQM8260_PLATFORM
 
 #include <linux/config.h>
  
@@ -14,4 +14,6 @@
 #define IMAP_ADDR		((uint)0xFFF00000)
 #define PHY_INTERRUPT		25
 
-#endif	/* __MACH_TQM8260_H */
+#define BOOTROM_RESTART_ADDR	((uint)0x40000104)
+
+#endif	/* __TQM8260_PLATFORM */
diff -Nru a/arch/ppc/platforms/tqm8260_setup.c b/arch/ppc/platforms/tqm8260_setup.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc/platforms/tqm8260_setup.c	Sat Mar 22 17:12:27 2003
@@ -0,0 +1,79 @@
+/*
+ * arch/ppc/platforms/tqm8260_setup.c
+ * 
+ * TQM8260 platform support
+ *
+ * Author: Allen Curtis <acurtis@onz.com>
+ * Derived from: m8260_setup.c by Dan Malek, MVista
+ *
+ * Copyright 2002 Ones and Zeros, 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.
+ */
+
+#include <linux/config.h>
+#include <linux/seq_file.h>
+
+#include <asm/immap_8260.h>
+#include <asm/mpc8260.h>
+#include <asm/machdep.h>
+
+static void (*callback_setup_arch)(void);
+
+extern unsigned char __res[sizeof(bd_t)];
+
+extern void m8260_init(unsigned long r3, unsigned long r4, 
+	unsigned long r5, unsigned long r6, unsigned long r7);
+
+static int
+tqm8260_show_cpuinfo(struct seq_file *m)
+{
+	bd_t	*binfo = (bd_t *)__res;
+
+	seq_printf(m, "vendor\t\t: IN2 Systems\n"
+		      "machine\t\t: TQM8260 PowerPC\n"
+		      "mem size\t\t: 0x%08x\n"
+		      "\n",
+		      binfo->bi_memsize);
+	return 0;
+}
+
+static int
+tqm8260_set_rtc_time(unsigned long time)
+{
+	((immap_t *)IMAP_ADDR)->im_sit.sit_tmcnt = time;
+	((immap_t *)IMAP_ADDR)->im_sit.sit_tmcntsc = 0x3;
+
+	return(0);
+}
+
+static unsigned long
+tqm8260_get_rtc_time(void)
+{
+	return ((immap_t *)IMAP_ADDR)->im_sit.sit_tmcnt;
+}
+
+static void __init
+tqm8260_setup_arch(void)
+{
+	printk("IN2 Systems TQM8260 port\n");
+	callback_setup_arch();
+}
+
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	      unsigned long r6, unsigned long r7)
+{
+	/* Generic 8260 platform initialization */
+	m8260_init(r3, r4, r5, r6, r7);
+
+	/* Anything special for this platform */
+	ppc_md.show_cpuinfo	= tqm8260_show_cpuinfo;
+	ppc_md.set_rtc_time	= tqm8260_set_rtc_time;
+	ppc_md.get_rtc_time	= tqm8260_get_rtc_time;
+
+	callback_setup_arch	= ppc_md.setup_arch;
+	ppc_md.setup_arch	= tqm8260_setup_arch;
diff -Nru a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
--- a/arch/ppc/syslib/Makefile	Mon Feb  3 14:19:36 2003
+++ b/arch/ppc/syslib/Makefile	Wed Mar 19 21:01:42 2003
@@ -64,5 +64,3 @@
 obj-$(CONFIG_8260)		+= m8260_setup.o ppc8260_pic.o
 obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
 
-find_name : find_name.c
-	$(HOSTCC) $(HOSTCFLAGS) -o find_name find_name.c
diff -Nru a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
--- a/arch/ppc/syslib/m8260_setup.c	Tue Nov  5 13:53:07 2002
+++ b/arch/ppc/syslib/m8260_setup.c	Sat Mar 22 17:18:48 2003
@@ -63,16 +63,6 @@
 	m8260_cpm_reset();
 }
 
-static void
-abort(void)
-{
-#ifdef CONFIG_XMON
-	extern void xmon(void *);
-	xmon(0);
-#endif
-	machine_restart(NULL);
-}
-
 /* The decrementer counts at the system (internal) clock frequency
  * divided by four.
  */
@@ -93,30 +83,27 @@
  */
 static uint rtc_time;
 
-static static int
+static int
 m8260_set_rtc_time(unsigned long time)
 {
-#ifdef CONFIG_TQM8260
-	((immap_t *)IMAP_ADDR)->im_sit.sit_tmcnt = time;
-	((immap_t *)IMAP_ADDR)->im_sit.sit_tmcntsc = 0x3;
-#else
 	rtc_time = time;
-#endif
+
 	return(0);
 }
 
 static unsigned long
 m8260_get_rtc_time(void)
 {
-#ifdef CONFIG_TQM8260
-	return ((immap_t *)IMAP_ADDR)->im_sit.sit_tmcnt;
-#else
 	/* Get time from the RTC.
 	*/
 	return((unsigned long)rtc_time);
-#endif
 }
 
+#ifndef BOOTROM_RESTART_ADDR
+#warning "Using default BOOTROM_RESTART_ADDR!"
+#define BOOTROM_RESTART_ADDR	0xff000104
+#endif
+
 static void
 m8260_restart(char *cmd)
 {
@@ -127,32 +114,28 @@
 	 * of the reset vector.  If that doesn't work for you, change this
 	 * or the reboot program to send a proper address.
 	 */
-#ifdef CONFIG_TQM8260
-	startaddr = 0x40000104;
-#else
-	startaddr = 0xff000104;
-#endif
+	startaddr = BOOTROM_RESTART_ADDR;
 	if (cmd != NULL) {
 		if (!strncmp(cmd, "startaddr=", 10))
 			startaddr = simple_strtoul(&cmd[10], NULL, 0);
 	}
 
-	m8260_gorom((unsigned int)__pa(__res), startaddr);
+	m8260_gorom((void*)__pa(__res), startaddr);
 }
 
 static void
-m8260_power_off(void)
+m8260_halt(void)
 {
-   m8260_restart(NULL);
+	local_irq_disable();
+	while (1);
 }
 
 static void
-m8260_halt(void)
+m8260_power_off(void)
 {
-   m8260_restart(NULL);
+	m8260_halt();
 }
 
-
 static int
 m8260_show_percpuinfo(struct seq_file *m, int i)
 {
@@ -181,9 +164,6 @@
 	int i;
 	void cpm_interrupt_init(void);
 
-#if 0
-        ppc8260_pic.irq_offset = 0;
-#endif
         for ( i = 0 ; i < NR_SIU_INTS ; i++ )
                 irq_desc[i].handler = &ppc8260_pic;
 
@@ -194,7 +174,6 @@
 	immr->im_intctl.ic_siprr = 0x05309770;
 	immr->im_intctl.ic_scprrh = 0x05309770;
 	immr->im_intctl.ic_scprrl = 0x05309770;
-
 }
 
 /*
@@ -219,12 +198,29 @@
 static void __init
 m8260_map_io(void)
 {
-	io_block_mapping(0xf0000000, 0xf0000000, 0x10000000, _PAGE_IO);
-	io_block_mapping(0xe0000000, 0xe0000000, 0x10000000, _PAGE_IO);
-}
+	uint addr;
 
+	/* Map IMMR region to a 256MB BAT */
+	addr = (immr != NULL) ? (uint)immr : IMAP_ADDR;
+	io_block_mapping(addr, addr, 0x10000000, _PAGE_IO);
+
+	/* Map I/O region to a 256MB BAT */
+	io_block_mapping(IO_VIRT_ADDR, IO_PHYS_ADDR, 0x10000000, _PAGE_IO);
+}
+
+/* Inputs:
+ *   r3 - Optional pointer to a board information structure.
+ *   r4 - Optional pointer to the physical starting address of the init RAM
+ *        disk.
+ *   r5 - Optional pointer to the physical ending address of the init RAM
+ *        disk.
+ *   r6 - Optional pointer to the physical starting address of any kernel
+ *        command-line parameters.
+ *   r7 - Optional pointer to the physical ending address of any kernel
+ *        command-line parameters.
+ */
 void __init
-platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+m8260_init(unsigned long r3, unsigned long r4, unsigned long r5,
 	      unsigned long r6, unsigned long r7)
 {
 	parse_bootinfo(find_bootinfo());
@@ -265,11 +261,3 @@
 	ppc_md.setup_io_mappings	= m8260_map_io;
 }
 
-/* Mainly for ksyms.
-*/
-int
-request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
-		       unsigned long flag, const char *naem, void *dev)
-{
-	panic("request IRQ\n");
-}
diff -Nru a/arch/ppc/syslib/ppc4xx_setup.c b/arch/ppc/syslib/ppc4xx_setup.c
--- a/arch/ppc/syslib/ppc4xx_setup.c	Wed Jan  8 02:27:01 2003
+++ b/arch/ppc/syslib/ppc4xx_setup.c	Sat Mar 22 16:59:59 2003
@@ -228,8 +228,8 @@
  */
 #if defined(CONFIG_PCI) && defined(CONFIG_IDE)
 static void
-ppc4xx_ide_init_hwif_ports(hw_regs_t * hw, ide_ioreg_t data_port,
-			   ide_ioreg_t ctrl_port, int *irq)
+ppc4xx_ide_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
+			   unsigned long ctrl_port, int *irq)
 {
 	int i;
 
diff -Nru a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c
--- a/arch/ppc/syslib/prom.c	Tue Nov  5 14:59:43 2002
+++ b/arch/ppc/syslib/prom.c	Thu Feb 13 18:50:29 2003
@@ -37,9 +37,6 @@
 #include <asm/pci-bridge.h>
 #include <asm/open_pic.h>
 
-#ifdef CONFIG_FB
-#include <asm/linux_logo.h>
-#endif
 
 struct pci_address {
 	unsigned a_hi;
diff -Nru a/arch/ppc/syslib/prom_init.c b/arch/ppc/syslib/prom_init.c
--- a/arch/ppc/syslib/prom_init.c	Sat Jan  4 03:35:07 2003
+++ b/arch/ppc/syslib/prom_init.c	Thu Feb 13 18:50:29 2003
@@ -34,8 +34,9 @@
 #include <asm/open_pic.h>
 #include <asm/cacheflush.h>
 
-#ifdef CONFIG_FB
-#include <asm/linux_logo.h>
+#ifdef CONFIG_LOGO_LINUX_CLUT224
+#include <linux/linux_logo.h>
+extern const struct linux_logo logo_linux_clut224;
 #endif
 
 /*
@@ -294,6 +295,7 @@
 		0xff, 0xff, 0x55,
 		0xff, 0xff, 0xff
 	};
+	const unsigned char *clut;
 
 	prom_disp_node = 0;
 
@@ -360,20 +362,20 @@
 			 * method is available.
 			 * Should update this to use set-colors.
 			 */
-			for (i = 0; i < 32; i++)
-				if (prom_set_color(ih, i, default_colors[i*3],
-						   default_colors[i*3+1],
-						   default_colors[i*3+2]) != 0)
+			clut = default_colors;
+			for (i = 0; i < 32; i++, clut += 3)
+				if (prom_set_color(ih, i, clut[0], clut[1],
+						   clut[2]) != 0)
 					break;
 
-#ifdef CONFIG_FRAMEBUFFER_CONSOLE
-			for (i = 0; i < LINUX_LOGO_COLORS; i++)
-				if (prom_set_color(ih, i + 32,
-						   linux_logo_red[i],
-						   linux_logo_green[i],
-						   linux_logo_blue[i]) != 0)
+#ifdef CONFIG_LOGO_LINUX_CLUT224
+			clut = logo_linux_clut224.clut;
+			for (i = 0; i < logo_linux_clut224.clutsize;
+			     i++, clut += 3)
+				if (prom_set_color(ih, i + 32, clut[0],
+						   clut[1], clut[2]) != 0)
 					break;
-#endif /* CONFIG_FRAMEBUFFER_CONSOLE */
+#endif /* CONFIG_LOGO_LINUX_CLUT224 */
 		}
 	}
 
diff -Nru a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
--- a/arch/ppc64/kernel/prom.c	Sun Mar  2 19:21:25 2003
+++ b/arch/ppc64/kernel/prom.c	Sun Mar 16 15:51:49 2003
@@ -49,8 +49,9 @@
 #include <asm/ppcdebug.h>
 #include "open_pic.h"
 
-#ifdef CONFIG_FB
-#include <asm/linux_logo.h>
+#ifdef CONFIG_LOGO_LINUX_CLUT224
+#include <linux/linux_logo.h>
+extern const struct linux_logo logo_linux_clut224;
 #endif
 
 /*
@@ -1232,6 +1233,7 @@
 		0xff, 0xff, 0x55,
 		0xff, 0xff, 0xff
 	};
+	const unsigned char *clut;
 
 	_prom->disp_node = 0;
 
@@ -1261,20 +1263,19 @@
 
 		/* Setup a useable color table when the appropriate
 		 * method is available. Should update this to set-colors */
-		for (i = 0; i < 32; i++)
-			if (prom_set_color(ih, i, RELOC(default_colors)[i*3],
-					   RELOC(default_colors)[i*3+1],
-					   RELOC(default_colors)[i*3+2]) != 0)
+		clut = RELOC(default_colors);
+		for (i = 0; i < 32; i++, clut += 3)
+			if (prom_set_color(ih, i, clut[0], clut[1],
+					   clut[2]) != 0)
 				break;
 
-#ifdef CONFIG_FRAMEBUFFER_CONSOLE
-		for (i = 0; i < LINUX_LOGO_COLORS; i++)
-			if (prom_set_color(ih, i + 32,
-					   RELOC(linux_logo_red)[i],
-					   RELOC(linux_logo_green)[i],
-					   RELOC(linux_logo_blue)[i]) != 0)
+#ifdef CONFIG_LOGO_LINUX_CLUT224
+		clut = RELOC(RELOC(&logo_linux_clut224)->clut);
+		for (i = 0; i < logo_linux_clut224.clutsize; i++, clut += 3)
+			if (prom_set_color(ih, i + 32, clut[0], clut[1],
+					   clut[2]) != 0)
 				break;
-#endif /* CONFIG_FRAMEBUFFER_CONSOLE */
+#endif /* CONFIG_LOGO_LINUX_CLUT224 */
 
 		/*
 		 * If this display is the device that OF is using for stdout,
diff -Nru a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
--- a/arch/ppc64/kernel/sys_ppc32.c	Sat Mar 15 10:25:46 2003
+++ b/arch/ppc64/kernel/sys_ppc32.c	Sun Mar 23 14:38:47 2003
@@ -884,23 +884,6 @@
 	compat_gid_t	ex32_anon_gid;
 };
 
-struct nfsctl_uidmap32 {
-	u32			ug32_ident;   /* char * */
-	compat_uid_t	ug32_uidbase;
-	s32			ug32_uidlen;
-	u32			ug32_udimap;  /* uid_t * */
-	compat_uid_t	ug32_gidbase;
-	s32			ug32_gidlen;
-	u32			ug32_gdimap;  /* gid_t * */
-};
-
-struct nfsctl_fhparm32 {
-	struct sockaddr		gf32_addr;
-	compat_dev_t	gf32_dev;
-	compat_ino_t	gf32_ino;
-	s32			gf32_version;
-};
-
 struct nfsctl_fdparm32 {
 	struct sockaddr		gd32_addr;
 	s8			gd32_path[NFS_MAXPATHLEN+1];
@@ -919,16 +902,12 @@
 		struct nfsctl_svc32	u32_svc;
 		struct nfsctl_client32	u32_client;
 		struct nfsctl_export32	u32_export;
-		struct nfsctl_uidmap32	u32_umap;
-		struct nfsctl_fhparm32	u32_getfh;
 		struct nfsctl_fdparm32	u32_getfd;
 		struct nfsctl_fsparm32	u32_getfs;
 	} u;
 #define ca32_svc	u.u32_svc
 #define ca32_client	u.u32_client
 #define ca32_export	u.u32_export
-#define ca32_umap	u.u32_umap
-#define ca32_getfh	u.u32_getfh
 #define ca32_getfd	u.u32_getfd
 #define ca32_getfs	u.u32_getfs
 #define ca32_authd	u.u32_authd
@@ -1001,73 +980,6 @@
 	return 0;
 }
 
-static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
-{
-	u32 uaddr;
-	int i;
-	int err;
-
-	memset(karg, 0, sizeof(*karg));
-	if(__get_user(karg->ca_version, &arg32->ca32_version))
-		return -EFAULT;
-	karg->ca_umap.ug_ident = (char *)get_zeroed_page(GFP_USER);
-	if(!karg->ca_umap.ug_ident)
-		return -ENOMEM;
-	err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
-	if(strncpy_from_user(karg->ca_umap.ug_ident,
-			     (char *)A(uaddr), PAGE_SIZE) <= 0)
-		return -EFAULT;
-	err |= __get_user(karg->ca_umap.ug_uidbase,
-		      &arg32->ca32_umap.ug32_uidbase);
-	err |= __get_user(karg->ca_umap.ug_uidlen,
-		      &arg32->ca32_umap.ug32_uidlen);
-	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
-	if (err)
-		return -EFAULT;
-	karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
-					  GFP_USER);
-	if(!karg->ca_umap.ug_udimap)
-		return -ENOMEM;
-	for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
-		err |= __get_user(karg->ca_umap.ug_udimap[i],
-			      &(((compat_uid_t *)A(uaddr))[i]));
-	err |= __get_user(karg->ca_umap.ug_gidbase,
-		      &arg32->ca32_umap.ug32_gidbase);
-	err |= __get_user(karg->ca_umap.ug_uidlen,
-		      &arg32->ca32_umap.ug32_gidlen);
-	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
-	if (err)
-		return -EFAULT;
-	karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
-					  GFP_USER);
-	if(!karg->ca_umap.ug_gdimap)
-		return -ENOMEM;
-	for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
-		err |= __get_user(karg->ca_umap.ug_gdimap[i],
-			      &(((compat_gid_t *)A(uaddr))[i]));
-
-	return err;
-}
-
-static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
-{
-	int err;
-	
-	err = __get_user(karg->ca_version, &arg32->ca32_version);
-	err |= copy_from_user(&karg->ca_getfh.gf_addr,
-			  &arg32->ca32_getfh.gf32_addr,
-			  (sizeof(struct sockaddr)));
-	err |= __get_user(karg->ca_getfh.gf_dev,
-		      &arg32->ca32_getfh.gf32_dev);
-	err |= __get_user(karg->ca_getfh.gf_ino,
-		      &arg32->ca32_getfh.gf32_ino);
-	err |= __get_user(karg->ca_getfh.gf_version,
-		      &arg32->ca32_getfh.gf32_version);
-
-	if(err) return -EFAULT;
-	return 0;
-}
-
 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
 {
 	int err;
@@ -1154,13 +1066,6 @@
 	case NFSCTL_UNEXPORT:
 		err = nfs_exp32_trans(karg, arg32);
 		break;
-	/* This one is unimplemented, be we're ready for it. */
-	case NFSCTL_UGIDUPDATE:
-		err = nfs_uud32_trans(karg, arg32);
-		break;
-	case NFSCTL_GETFH:
-		err = nfs_getfh32_trans(karg, arg32);
-		break;
 	case NFSCTL_GETFD:
 		err = nfs_getfd32_trans(karg, arg32);
 		break;
@@ -1181,23 +1086,13 @@
 	if (err)
 		goto done;
 
-	if((cmd == NFSCTL_GETFH) ||
-	   (cmd == NFSCTL_GETFD) ||
+	if((cmd == NFSCTL_GETFD) ||
 	   (cmd == NFSCTL_GETFS))
 		err = nfs_getfh32_res_trans(kres, res32);
 
 done:
-	if(karg) {
-		if(cmd == NFSCTL_UGIDUPDATE) {
-			if(karg->ca_umap.ug_ident)
-				kfree(karg->ca_umap.ug_ident);
-			if(karg->ca_umap.ug_udimap)
-				kfree(karg->ca_umap.ug_udimap);
-			if(karg->ca_umap.ug_gdimap)
-				kfree(karg->ca_umap.ug_gdimap);
-		}
+	if(karg)
 		kfree(karg);
-	}
 	if(kres)
 		kfree(kres);
 	return err;
diff -Nru a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
--- a/arch/ppc64/kernel/traps.c	Tue Feb 11 04:15:56 2003
+++ b/arch/ppc64/kernel/traps.c	Mon Mar 17 21:32:24 2003
@@ -62,10 +62,11 @@
 
 void die(const char *str, struct pt_regs *regs, long err)
 {
+	static int die_counter;
 	console_verbose();
 	spin_lock_irq(&die_lock);
 	bust_spinlocks(1);
-	printk("Oops: %s, sig: %ld\n", str, err);
+	printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
 	show_regs(regs);
 	bust_spinlocks(0);
 	spin_unlock_irq(&die_lock);
diff -Nru a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
--- a/arch/s390/kernel/traps.c	Mon Feb 24 10:24:13 2003
+++ b/arch/s390/kernel/traps.c	Mon Mar 17 21:32:24 2003
@@ -226,10 +226,11 @@
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
+	static int die_counter;
         console_verbose();
         spin_lock_irq(&die_lock);
 	bust_spinlocks(1);
-        printk("%s: %04lx\n", str, err & 0xffff);
+	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
         show_regs(regs);
 	bust_spinlocks(0);
         spin_unlock_irq(&die_lock);
diff -Nru a/arch/s390x/kernel/binfmt_elf32.c b/arch/s390x/kernel/binfmt_elf32.c
--- a/arch/s390x/kernel/binfmt_elf32.c	Mon Feb 24 10:25:00 2003
+++ b/arch/s390x/kernel/binfmt_elf32.c	Mon Mar 17 21:31:50 2003
@@ -36,7 +36,7 @@
 
 /* For SVR4/S390 the function pointer to be registered with `atexit` is
    passed in R14. */
-#define ELF_PLAT_INIT(_r) \
+#define ELF_PLAT_INIT(_r, load_addr) \
 	do { \
 	_r->gprs[14] = 0; \
 	set_thread_flag(TIF_31BIT); \
diff -Nru a/arch/s390x/kernel/exec32.c b/arch/s390x/kernel/exec32.c
--- a/arch/s390x/kernel/exec32.c	Sun Mar  2 18:12:49 2003
+++ b/arch/s390x/kernel/exec32.c	Thu Mar 13 16:52:15 2003
@@ -21,7 +21,6 @@
 #include <linux/highmem.h>
 #include <linux/spinlock.h>
 #include <linux/binfmts.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 
 #include <asm/uaccess.h>
diff -Nru a/arch/s390x/kernel/linux32.c b/arch/s390x/kernel/linux32.c
--- a/arch/s390x/kernel/linux32.c	Sun Mar  9 01:34:44 2003
+++ b/arch/s390x/kernel/linux32.c	Sun Mar 23 14:35:08 2003
@@ -2092,23 +2092,6 @@
 	compat_gid_t	ex32_anon_gid;
 };
 
-struct nfsctl_uidmap32 {
-	u32			ug32_ident;   /* char * */
-	compat_uid_t	ug32_uidbase;
-	s32			ug32_uidlen;
-	u32			ug32_udimap;  /* uid_t * */
-	compat_uid_t	ug32_gidbase;
-	s32			ug32_gidlen;
-	u32			ug32_gdimap;  /* gid_t * */
-};
-
-struct nfsctl_fhparm32 {
-	struct sockaddr		gf32_addr;
-	compat_dev_t	gf32_dev;
-	compat_ino_t	gf32_ino;
-	s32			gf32_version;
-};
-
 struct nfsctl_fdparm32 {
 	struct sockaddr		gd32_addr;
 	s8			gd32_path[NFS_MAXPATHLEN+1];
@@ -2127,16 +2110,12 @@
 		struct nfsctl_svc32	u32_svc;
 		struct nfsctl_client32	u32_client;
 		struct nfsctl_export32	u32_export;
-		struct nfsctl_uidmap32	u32_umap;
-		struct nfsctl_fhparm32	u32_getfh;
 		struct nfsctl_fdparm32	u32_getfd;
 		struct nfsctl_fsparm32	u32_getfs;
 	} u;
 #define ca32_svc	u.u32_svc
 #define ca32_client	u.u32_client
 #define ca32_export	u.u32_export
-#define ca32_umap	u.u32_umap
-#define ca32_getfh	u.u32_getfh
 #define ca32_getfd	u.u32_getfd
 #define ca32_getfs	u.u32_getfs
 #define ca32_authd	u.u32_authd
@@ -2205,71 +2184,6 @@
 	return err;
 }
 
-static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
-{
-	u32 uaddr;
-	int i;
-	int err;
-
-	memset(karg, 0, sizeof(*karg));
-	if(__get_user(karg->ca_version, &arg32->ca32_version))
-		return -EFAULT;
-	karg->ca_umap.ug_ident = (char *)get_zeroed_page(GFP_USER);
-	if(!karg->ca_umap.ug_ident)
-		return -ENOMEM;
-	err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
-	if(strncpy_from_user(karg->ca_umap.ug_ident,
-			     (char *)A(uaddr), PAGE_SIZE) <= 0)
-		return -EFAULT;
-	err |= __get_user(karg->ca_umap.ug_uidbase,
-		      &arg32->ca32_umap.ug32_uidbase);
-	err |= __get_user(karg->ca_umap.ug_uidlen,
-		      &arg32->ca32_umap.ug32_uidlen);
-	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
-	if (err)
-		return -EFAULT;
-	karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
-					  GFP_USER);
-	if(!karg->ca_umap.ug_udimap)
-		return -ENOMEM;
-	for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
-		err |= __get_user(karg->ca_umap.ug_udimap[i],
-			      &(((compat_uid_t *)A(uaddr))[i]));
-	err |= __get_user(karg->ca_umap.ug_gidbase,
-		      &arg32->ca32_umap.ug32_gidbase);
-	err |= __get_user(karg->ca_umap.ug_uidlen,
-		      &arg32->ca32_umap.ug32_gidlen);
-	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
-	if (err)
-		return -EFAULT;
-	karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
-					  GFP_USER);
-	if(!karg->ca_umap.ug_gdimap)
-		return -ENOMEM;
-	for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
-		err |= __get_user(karg->ca_umap.ug_gdimap[i],
-			      &(((compat_gid_t *)A(uaddr))[i]));
-
-	return err;
-}
-
-static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
-{
-	int err;
-	
-	err = __get_user(karg->ca_version, &arg32->ca32_version);
-	err |= copy_from_user(&karg->ca_getfh.gf_addr,
-			  &arg32->ca32_getfh.gf32_addr,
-			  (sizeof(struct sockaddr)));
-	err |= __get_user(karg->ca_getfh.gf_dev,
-		      &arg32->ca32_getfh.gf32_dev);
-	err |= __get_user(karg->ca_getfh.gf_ino,
-		      &arg32->ca32_getfh.gf32_ino);
-	err |= __get_user(karg->ca_getfh.gf_version,
-		      &arg32->ca32_getfh.gf32_version);
-	return err;
-}
-
 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
 {
 	int err;
@@ -2345,13 +2259,6 @@
 	case NFSCTL_UNEXPORT:
 		err = nfs_exp32_trans(karg, arg32);
 		break;
-	/* This one is unimplemented, be we're ready for it. */
-	case NFSCTL_UGIDUPDATE:
-		err = nfs_uud32_trans(karg, arg32);
-		break;
-	case NFSCTL_GETFH:
-		err = nfs_getfh32_trans(karg, arg32);
-		break;
 	case NFSCTL_GETFD:
 		err = nfs_getfd32_trans(karg, arg32);
 		break;
@@ -2372,23 +2279,13 @@
 	if (err)
 		goto done;
 
-	if((cmd == NFSCTL_GETFH) ||
-	   (cmd == NFSCTL_GETFD) ||
+	if((cmd == NFSCTL_GETFD) ||
 	   (cmd == NFSCTL_GETFS))
 		err = nfs_getfh32_res_trans(kres, res32);
 
 done:
-	if(karg) {
-		if(cmd == NFSCTL_UGIDUPDATE) {
-			if(karg->ca_umap.ug_ident)
-				kfree(karg->ca_umap.ug_ident);
-			if(karg->ca_umap.ug_udimap)
-				kfree(karg->ca_umap.ug_udimap);
-			if(karg->ca_umap.ug_gdimap)
-				kfree(karg->ca_umap.ug_gdimap);
-		}
+	if(karg)
 		kfree(karg);
-	}
 	if(kres)
 		kfree(kres);
 	return err;
diff -Nru a/arch/s390x/kernel/traps.c b/arch/s390x/kernel/traps.c
--- a/arch/s390x/kernel/traps.c	Mon Feb 24 10:24:13 2003
+++ b/arch/s390x/kernel/traps.c	Mon Mar 17 21:32:24 2003
@@ -228,10 +228,11 @@
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
+	static int die_counter;
         console_verbose();
         spin_lock_irq(&die_lock);
 	bust_spinlocks(1);
-        printk("%s: %04lx\n", str, err & 0xffff);
+	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
         show_regs(regs);
 	bust_spinlocks(0);
         spin_unlock_irq(&die_lock);
diff -Nru a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
--- a/arch/sh/kernel/traps.c	Tue Feb  5 07:24:41 2002
+++ b/arch/sh/kernel/traps.c	Mon Mar 17 21:32:24 2003
@@ -58,9 +58,10 @@
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
+	static int die_counter;
 	console_verbose();
 	spin_lock_irq(&die_lock);
-	printk("%s: %04lx\n", str, err & 0xffff);
+	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
 	show_regs(regs);
 	spin_unlock_irq(&die_lock);
 	do_exit(SIGSEGV);
diff -Nru a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c
--- a/arch/sparc/kernel/traps.c	Tue Jul 16 17:12:13 2002
+++ b/arch/sparc/kernel/traps.c	Wed Mar 19 22:55:52 2003
@@ -89,6 +89,7 @@
 
 void die_if_kernel(char *str, struct pt_regs *regs)
 {
+	static int die_counter;
 	int count = 0;
 
 	/* Amuse the user. */
@@ -98,7 +99,7 @@
 "              /_| \\__/ |_\\\n"
 "                 \\__U_/\n");
 
-	printk("%s(%d): %s\n", current->comm, current->pid, str);
+	printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
 	show_regs(regs);
 
 	__SAVE; __SAVE; __SAVE; __SAVE;
diff -Nru a/arch/sparc64/Makefile b/arch/sparc64/Makefile
--- a/arch/sparc64/Makefile	Sun Jan 26 11:13:05 2003
+++ b/arch/sparc64/Makefile	Sun Mar 23 00:38:52 2003
@@ -71,8 +71,10 @@
 # FIXME: is drivers- right?
 drivers-$(CONFIG_OPROFILE)	+= arch/sparc64/oprofile/
 
-tftpboot.img vmlinux.aout:
-	$(Q)$(MAKE) $(build)=arch/sparc64/boot arch/sparc64/boot/$@
+makeboot = $(Q)$(MAKE) -f scripts/Makefile.build obj=arch/$(ARCH)/boot $(1)
+
+image tftpboot.img vmlinux.aout: vmlinux
+	$(call makeboot,arch/sparc64/boot/$@)
 
 define archhelp
   echo  '* vmlinux       - Standard sparc64 kernel'
diff -Nru a/arch/sparc64/boot/Makefile b/arch/sparc64/boot/Makefile
--- a/arch/sparc64/boot/Makefile	Sun Mar  9 13:47:41 2003
+++ b/arch/sparc64/boot/Makefile	Sun Mar 23 00:38:52 2003
@@ -14,13 +14,21 @@
       cmd_elftoaout = $(ELFTOAOUT) vmlinux -o $@
 quiet_cmd_piggy     = PIGGY    $@
       cmd_piggy     = $(obj)/piggyback $@ System.map $(ROOT_IMG)
+quiet_cmd_strip     = STRIP $@
+      cmd_strip     = $(STRIP) -R .comment -R .note vmlinux -o $@
 
-$(obj)/tftpboot.img: $(obj)/piggyback System.map vmlinux $(ROOT_IMG) FORCE
+
+# Actual linking
+$(obj)/image: FORCE
+	$(call if_changed,strip)
+	@echo '  kernel: $@ is ready'
+
+$(obj)/tftpboot.img: $(obj)/piggyback System.map $(ROOT_IMG) FORCE
 	$(call if_changed,elftoaout)
 	$(call if_changed,piggy)
 	@echo '  kernel: $@ is ready'
 
-$(obj)/vmlinux.aout: vmlinux FORCE
+$(obj)/vmlinux.aout: FORCE
 	$(call if_changed,elftoaout)
 	@echo '  kernel: $@ is ready'
 
diff -Nru a/arch/sparc64/defconfig b/arch/sparc64/defconfig
--- a/arch/sparc64/defconfig	Fri Mar  7 19:26:39 2003
+++ b/arch/sparc64/defconfig	Sun Mar 23 00:43:03 2003
@@ -2,7 +2,6 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MMU=y
-CONFIG_SWAP=y
 
 #
 # Code maturity level options
@@ -12,6 +11,7 @@
 #
 # General setup
 #
+CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -88,7 +88,7 @@
 # Graphics support
 #
 CONFIG_FB=y
-# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
 # CONFIG_FB_IMSTT is not set
@@ -124,15 +124,23 @@
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_PCI_CONSOLE=y
-# CONFIG_FBCON_ADVANCED is not set
-CONFIG_FONT_SUN8x16=y
-# CONFIG_FONT_SUN12x22 is not set
 CONFIG_FONTS=y
 # CONFIG_FONT_8x8 is not set
 # CONFIG_FONT_8x16 is not set
 # CONFIG_FONT_6x11 is not set
 # CONFIG_FONT_PEARL_8x8 is not set
 # CONFIG_FONT_ACORN_8x8 is not set
+CONFIG_FONT_SUN8x16=y
+# CONFIG_FONT_SUN12x22 is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_LOGO_SUN_CLUT224=y
 
 #
 # Serial drivers
@@ -625,62 +633,78 @@
 #
 # File systems
 #
-# CONFIG_QUOTA is not set
-CONFIG_QUOTACTL=y
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-# CONFIG_REISERFS_FS is not set
-# CONFIG_ADFS_FS is not set
-CONFIG_AFFS_FS=m
-# CONFIG_HFS_FS is not set
-CONFIG_BEFS_FS=m
-# CONFIG_BEFS_DEBUG is not set
-CONFIG_BFS_FS=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT3_FS=m
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_EFS_FS=m
-# CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
 CONFIG_JFS_FS=m
 CONFIG_JFS_POSIX_ACL=y
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
 CONFIG_MINIX_FS=m
-# CONFIG_VXFS_FS is not set
+CONFIG_ROMFS_FS=m
+# CONFIG_QUOTA is not set
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
 # CONFIG_NTFS_FS is not set
-CONFIG_HPFS_FS=m
+
+#
+# Pseudo filesystems
+#
 CONFIG_PROC_FS=y
 # CONFIG_DEVFS_FS is not set
 CONFIG_DEVPTS_FS=y
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+# CONFIG_HFS_FS is not set
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
-CONFIG_ROMFS_FS=m
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_SYSV_FS=m
-CONFIG_UDF_FS=m
 CONFIG_UFS_FS=m
 CONFIG_UFS_FS_WRITE=y
-CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_POSIX_ACL=y
 
 #
 # Network File Systems
 #
-CONFIG_CODA_FS=m
-# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
@@ -688,18 +712,18 @@
 CONFIG_NFSD_V3=y
 CONFIG_NFSD_V4=y
 CONFIG_NFSD_TCP=y
-CONFIG_SUNRPC=m
-CONFIG_SUNRPC_GSS=m
-CONFIG_RPCSEC_GSS_KRB5=m
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
-CONFIG_CIFS=m
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
 # CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
 # CONFIG_NCP_FS is not set
+CONFIG_CODA_FS=m
+# CONFIG_INTERMEZZO_FS is not set
 # CONFIG_AFS_FS is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
 
 #
 # Partition Types
@@ -805,6 +829,7 @@
 CONFIG_SND_MAESTRO3=m
 CONFIG_SND_FM801=m
 CONFIG_SND_ICE1712=m
+# CONFIG_SND_ICE1724 is not set
 CONFIG_SND_INTEL8X0=m
 CONFIG_SND_SONICVIBES=m
 # CONFIG_SND_VIA82XX is not set
diff -Nru a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
--- a/arch/sparc64/kernel/head.S	Mon Nov 11 03:57:03 2002
+++ b/arch/sparc64/kernel/head.S	Tue Mar 18 18:26:20 2003
@@ -671,7 +671,9 @@
 #endif
 
 	/* Kill PROM timer */
-	wr	%g0, 0, %tick_cmpr
+	sethi	%hi(0x80000000), %g1
+	sllx	%g1, 32, %g1
+	wr	%g1, 0, %tick_cmpr
 
 	BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
 
diff -Nru a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
--- a/arch/sparc64/kernel/irq.c	Wed Feb 12 01:41:01 2003
+++ b/arch/sparc64/kernel/irq.c	Wed Mar 12 12:47:00 2003
@@ -719,12 +719,8 @@
 	 */
 	{
 		unsigned long clr_mask = 1 << irq;
-		unsigned long tick_mask;
+		unsigned long tick_mask = tick_ops->softint_mask;
 
-		if (SPARC64_USE_STICK)
-			tick_mask = (1UL << 16);
-		else
-			tick_mask = (1UL << 0);
 		if ((irq == 14) && (get_softint() & tick_mask)) {
 			irq = 0;
 			clr_mask = tick_mask;
@@ -944,113 +940,6 @@
 int probe_irq_off(unsigned long mask)
 {
 	return 0;
-}
-
-/* This is gets the master TICK_INT timer going. */
-void sparc64_init_timers(void (*cfunc)(int, void *, struct pt_regs *),
-			 unsigned long *clock)
-{
-	unsigned long pstate;
-	extern unsigned long timer_tick_offset;
-	int node, err;
-#ifdef CONFIG_SMP
-	extern void smp_tick_init(void);
-#endif
-
-	if (!SPARC64_USE_STICK) {
-		node = linux_cpus[0].prom_node;
-		*clock = prom_getint(node, "clock-frequency");
-	} else {
-		node = prom_root_node;
-		*clock = prom_getint(node, "stick-frequency");
-	}
-	timer_tick_offset = *clock / HZ;
-#ifdef CONFIG_SMP
-	smp_tick_init();
-#endif
-
-	/* Register IRQ handler. */
-	err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, SA_STATIC_ALLOC,
-			  "timer", NULL);
-
-	if (err) {
-		prom_printf("Serious problem, cannot register TICK_INT\n");
-		prom_halt();
-	}
-
-	/* Guarentee that the following sequences execute
-	 * uninterrupted.
-	 */
-	__asm__ __volatile__("rdpr	%%pstate, %0\n\t"
-			     "wrpr	%0, %1, %%pstate"
-			     : "=r" (pstate)
-			     : "i" (PSTATE_IE));
-
-	/* Set things up so user can access tick register for profiling
-	 * purposes.  Also workaround BB_ERRATA_1 by doing a dummy
-	 * read back of %tick after writing it.
-	 */
-	__asm__ __volatile__(
-	"	sethi	%%hi(0x80000000), %%g1\n"
-	"	ba,pt	%%xcc, 1f\n"
-	"	 sllx	%%g1, 32, %%g1\n"
-	"	.align	64\n"
-	"1:	rd	%%tick, %%g2\n"
-	"	add	%%g2, 6, %%g2\n"
-	"	andn	%%g2, %%g1, %%g2\n"
-	"	wrpr	%%g2, 0, %%tick\n"
-	"	rdpr	%%tick, %%g0"
-	: /* no outputs */
-	: /* no inputs */
-	: "g1", "g2");
-
-	/* Workaround for Spitfire Errata (#54 I think??), I discovered
-	 * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
-	 * number 103640.
-	 *
-	 * On Blackbird writes to %tick_cmpr can fail, the
-	 * workaround seems to be to execute the wr instruction
-	 * at the start of an I-cache line, and perform a dummy
-	 * read back from %tick_cmpr right after writing to it. -DaveM
-	 */
-	if (!SPARC64_USE_STICK) {
-	__asm__ __volatile__(
-	"	rd	%%tick, %%g1\n"
-	"	ba,pt	%%xcc, 1f\n"
-	"	 add	%%g1, %0, %%g1\n"
-	"	.align	64\n"
-	"1:	wr	%%g1, 0x0, %%tick_cmpr\n"
-	"	rd	%%tick_cmpr, %%g0"
-	: /* no outputs */
-	: "r" (timer_tick_offset)
-	: "g1");
-	} else {
-	/* Let the user get at STICK too. */
-	__asm__ __volatile__(
-	"	sethi	%%hi(0x80000000), %%g1\n"
-	"	sllx	%%g1, 32, %%g1\n"
-	"	rd	%%asr24, %%g2\n"
-	"	andn	%%g2, %%g1, %%g2\n"
-	"	wr	%%g2, 0, %%asr24"
-	: /* no outputs */
-	: /* no inputs */
-	: "g1", "g2");
-
-	__asm__ __volatile__(
-	"	rd	%%asr24, %%g1\n"
-	"	add	%%g1, %0, %%g1\n"
-	"	wr	%%g1, 0x0, %%asr25"
-	: /* no outputs */
-	: "r" (timer_tick_offset)
-	: "g1");
-	}
-
-	/* Restore PSTATE_IE. */
-	__asm__ __volatile__("wrpr	%0, 0x0, %%pstate"
-			     : /* no outputs */
-			     : "r" (pstate));
-
-	local_irq_enable();
 }
 
 #ifdef CONFIG_SMP
diff -Nru a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
--- a/arch/sparc64/kernel/smp.c	Sat Mar  8 07:52:56 2003
+++ b/arch/sparc64/kernel/smp.c	Tue Mar 18 17:11:38 2003
@@ -18,6 +18,7 @@
 #include <linux/fs.h>
 #include <linux/seq_file.h>
 #include <linux/cache.h>
+#include <linux/jiffies.h>
 
 #include <asm/head.h>
 #include <asm/ptrace.h>
@@ -115,7 +116,6 @@
 void __init smp_callin(void)
 {
 	int cpuid = hard_smp_processor_id();
-	unsigned long pstate;
 	extern int bigkernel;
 	extern unsigned long kern_locked_tte_data;
 
@@ -133,50 +133,6 @@
 
 	cpu_probe();
 
-	/* Guarentee that the following sequences execute
-	 * uninterrupted.
-	 */
-	__asm__ __volatile__("rdpr	%%pstate, %0\n\t"
-			     "wrpr	%0, %1, %%pstate"
-			     : "=r" (pstate)
-			     : "i" (PSTATE_IE));
-
-	/* Set things up so user can access tick register for profiling
-	 * purposes.  Also workaround BB_ERRATA_1 by doing a dummy
-	 * read back of %tick after writing it.
-	 */
-	__asm__ __volatile__(
-	"sethi	%%hi(0x80000000), %%g1\n\t"
-	"ba,pt	%%xcc, 1f\n\t"
-	" sllx	%%g1, 32, %%g1\n\t"
-	".align	64\n"
-"1:	rd	%%tick, %%g2\n\t"
-	"add	%%g2, 6, %%g2\n\t"
-	"andn	%%g2, %%g1, %%g2\n\t"
-	"wrpr	%%g2, 0, %%tick\n\t"
-	"rdpr	%%tick, %%g0"
-	: /* no outputs */
-	: /* no inputs */
-	: "g1", "g2");
-
-	if (SPARC64_USE_STICK) {
-		/* Let the user get at STICK too. */
-		__asm__ __volatile__(
-			"sethi	%%hi(0x80000000), %%g1\n\t"
-			"sllx	%%g1, 32, %%g1\n\t"
-			"rd	%%asr24, %%g2\n\t"
-			"andn	%%g2, %%g1, %%g2\n\t"
-			"wr	%%g2, 0, %%asr24"
-		: /* no outputs */
-		: /* no inputs */
-		: "g1", "g2");
-	}
-
-	/* Restore PSTATE_IE. */
-	__asm__ __volatile__("wrpr	%0, 0x0, %%pstate"
-			     : /* no outputs */
-			     : "r" (pstate));
-
 	smp_setup_percpu_timer();
 
 	local_irq_enable();
@@ -211,7 +167,7 @@
 
 static unsigned long current_tick_offset;
 
-/* This stick register synchronization scheme is taken entirely from
+/* This tick register synchronization scheme is taken entirely from
  * the ia64 port, see arch/ia64/kernel/smpboot.c for details and credit.
  *
  * The only change I've made is to rework it so that the master
@@ -227,16 +183,7 @@
 static spinlock_t itc_sync_lock = SPIN_LOCK_UNLOCKED;
 static unsigned long go[SLAVE + 1];
 
-#define DEBUG_STICK_SYNC	0
-
-static inline unsigned long get_stick(void)
-{
-	unsigned long val;
-
-	__asm__ __volatile__("rd	%%asr24, %0"
-			     : "=r" (val));
-	return val;
-}
+#define DEBUG_TICK_SYNC	0
 
 static inline long get_delta (long *rt, long *master)
 {
@@ -245,14 +192,14 @@
 	unsigned long i;
 
 	for (i = 0; i < NUM_ITERS; i++) {
-		t0 = get_stick();
+		t0 = tick_ops->get_tick();
 		go[MASTER] = 1;
 		membar("#StoreLoad");
 		while (!(tm = go[SLAVE]))
 			membar("#LoadLoad");
 		go[SLAVE] = 0;
 		membar("#StoreStore");
-		t1 = get_stick();
+		t1 = tick_ops->get_tick();
 
 		if (t1 - t0 < best_t1 - best_t0)
 			best_t0 = t0, best_t1 = t1, best_tm = tm;
@@ -268,32 +215,11 @@
 	return tcenter - best_tm;
 }
 
-static void adjust_stick(long adj)
-{
-	unsigned long tmp, pstate;
-
-	__asm__ __volatile__(
-		"rdpr	%%pstate, %0\n\t"
-		"ba,pt	%%xcc, 1f\n\t"
-		" wrpr	%0, %4, %%pstate\n\t"
-		".align	16\n\t"
-		"1:nop\n\t"
-		"rd	%%asr24, %1\n\t"
-		"add	%1, %2, %1\n\t"
-		"wr	%1, 0x0, %%asr24\n\t"
-		"add	%1, %3, %1\n\t"
-		"wr	%1, 0x0, %%asr25\n\t"
-		"wrpr	%0, 0x0, %%pstate"
-		: "=&r" (pstate), "=&r" (tmp)
-		: "r" (adj), "r" (current_tick_offset),
-		  "i" (PSTATE_IE));
-}
-
-void smp_synchronize_stick_client(void)
+void smp_synchronize_tick_client(void)
 {
 	long i, delta, adj, adjust_latency = 0, done = 0;
 	unsigned long flags, rt, master_time_stamp, bound;
-#if DEBUG_STICK_SYNC
+#if DEBUG_TICK_SYNC
 	struct {
 		long rt;	/* roundtrip time */
 		long master;	/* master's timestamp */
@@ -323,9 +249,9 @@
 				} else
 					adj = -delta;
 
-				adjust_stick(adj);
+				tick_ops->add_tick(adj, current_tick_offset);
 			}
-#if DEBUG_STICK_SYNC
+#if DEBUG_TICK_SYNC
 			t[i].rt = rt;
 			t[i].master = master_time_stamp;
 			t[i].diff = delta;
@@ -335,25 +261,25 @@
 	}
 	local_irq_restore(flags);
 
-#if DEBUG_STICK_SYNC
+#if DEBUG_TICK_SYNC
 	for (i = 0; i < NUM_ROUNDS; i++)
 		printk("rt=%5ld master=%5ld diff=%5ld adjlat=%5ld\n",
 		       t[i].rt, t[i].master, t[i].diff, t[i].lat);
 #endif
 
-	printk(KERN_INFO "CPU %d: synchronized STICK with master CPU (last diff %ld cycles,"
+	printk(KERN_INFO "CPU %d: synchronized TICK with master CPU (last diff %ld cycles,"
 	       "maxerr %lu cycles)\n", smp_processor_id(), delta, rt);
 }
 
-static void smp_start_sync_stick_client(int cpu);
+static void smp_start_sync_tick_client(int cpu);
 
-static void smp_synchronize_one_stick(int cpu)
+static void smp_synchronize_one_tick(int cpu)
 {
 	unsigned long flags, i;
 
 	go[MASTER] = 0;
 
-	smp_start_sync_stick_client(cpu);
+	smp_start_sync_tick_client(cpu);
 
 	/* wait for client to be ready */
 	while (!go[MASTER])
@@ -370,7 +296,7 @@
 				membar("#LoadLoad");
 			go[MASTER] = 0;
 			membar("#StoreStore");
-			go[SLAVE] = get_stick();
+			go[SLAVE] = tick_ops->get_tick();
 			membar("#StoreLoad");
 		}
 	}
@@ -638,11 +564,11 @@
 	/* NOTE: Caller runs local copy on master. */
 }
 
-extern unsigned long xcall_sync_stick;
+extern unsigned long xcall_sync_tick;
 
-static void smp_start_sync_stick_client(int cpu)
+static void smp_start_sync_tick_client(int cpu)
 {
-	smp_cross_call_masked(&xcall_sync_stick,
+	smp_cross_call_masked(&xcall_sync_tick,
 			      0, 0, 0,
 			      (1UL << cpu));
 }
@@ -1118,12 +1044,7 @@
 	 * Check for level 14 softint.
 	 */
 	{
-		unsigned long tick_mask;
-
-		if (SPARC64_USE_STICK)
-			tick_mask = (1UL << 16);
-		else
-			tick_mask = (1UL << 0);
+		unsigned long tick_mask = tick_ops->softint_mask;
 
 		if (!(get_softint() & tick_mask)) {
 			extern void handler_irq(int, struct pt_regs *);
@@ -1159,47 +1080,14 @@
 				     : "=r" (pstate)
 				     : "i" (PSTATE_IE));
 
-		/* Workaround for Spitfire Errata (#54 I think??), I discovered
-		 * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
-		 * number 103640.
-		 *
-		 * On Blackbird writes to %tick_cmpr can fail, the
-		 * workaround seems to be to execute the wr instruction
-		 * at the start of an I-cache line, and perform a dummy
-		 * read back from %tick_cmpr right after writing to it. -DaveM
-		 *
-		 * Just to be anal we add a workaround for Spitfire
-		 * Errata 50 by preventing pipeline bypasses on the
-		 * final read of the %tick register into a compare
-		 * instruction.  The Errata 50 description states
-		 * that %tick is not prone to this bug, but I am not
-		 * taking any chances.
-		 */
-		if (!SPARC64_USE_STICK) {
-		__asm__ __volatile__("rd	%%tick_cmpr, %0\n\t"
-				     "ba,pt	%%xcc, 1f\n\t"
-				     " add	%0, %2, %0\n\t"
-				     ".align	64\n"
-				  "1: wr	%0, 0x0, %%tick_cmpr\n\t"
-				     "rd	%%tick_cmpr, %%g0\n\t"
-				     "rd	%%tick, %1\n\t"
-				     "mov	%1, %1"
-				     : "=&r" (compare), "=r" (tick)
-				     : "r" (current_tick_offset));
-		} else {
-		__asm__ __volatile__("rd	%%asr25, %0\n\t"
-				     "add	%0, %2, %0\n\t"
-				     "wr	%0, 0x0, %%asr25\n\t"
-				     "rd	%%asr24, %1\n\t"
-				     : "=&r" (compare), "=r" (tick)
-				     : "r" (current_tick_offset));
-		}
+		compare = tick_ops->add_compare(current_tick_offset);
+		tick = tick_ops->get_tick();
 
 		/* Restore PSTATE_IE. */
 		__asm__ __volatile__("wrpr	%0, 0x0, %%pstate"
 				     : /* no outputs */
 				     : "r" (pstate));
-	} while (tick >= compare);
+	} while (time_after_eq(tick, compare));
 }
 
 static void __init smp_setup_percpu_timer(void)
@@ -1217,35 +1105,7 @@
 			     : "=r" (pstate)
 			     : "i" (PSTATE_IE));
 
-	/* Workaround for Spitfire Errata (#54 I think??), I discovered
-	 * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
-	 * number 103640.
-	 *
-	 * On Blackbird writes to %tick_cmpr can fail, the
-	 * workaround seems to be to execute the wr instruction
-	 * at the start of an I-cache line, and perform a dummy
-	 * read back from %tick_cmpr right after writing to it. -DaveM
-	 */
-	if (!SPARC64_USE_STICK) {
-	__asm__ __volatile__(
-		"rd	%%tick, %%g1\n\t"
-		"ba,pt	%%xcc, 1f\n\t"
-		" add	%%g1, %0, %%g1\n\t"
-		".align	64\n"
-	"1:	wr	%%g1, 0x0, %%tick_cmpr\n\t"
-		"rd	%%tick_cmpr, %%g0"
-	: /* no outputs */
-	: "r" (current_tick_offset)
-	: "g1");
-	} else {
-	__asm__ __volatile__(
-		"rd	%%asr24, %%g1\n\t"
-		"add	%%g1, %0, %%g1\n\t"
-		"wr	%%g1, 0x0, %%asr25"
-	: /* no outputs */
-	: "r" (current_tick_offset)
-	: "g1");
-	}
+	tick_ops->init_tick(current_tick_offset);
 
 	/* Restore PSTATE_IE. */
 	__asm__ __volatile__("wrpr	%0, 0x0, %%pstate"
@@ -1314,44 +1174,23 @@
 		     p += (64 / sizeof(unsigned long)))
 			*((volatile unsigned long *)p);
 
-		/* Now the real measurement. */
-		if (!SPARC64_USE_STICK) {
-		__asm__ __volatile__("b,pt	%%xcc, 1f\n\t"
-				     " rd	%%tick, %0\n\t"
-				     ".align	64\n"
-				     "1:\tldx	[%2 + 0x000], %%g1\n\t"
-				     "ldx	[%2 + 0x040], %%g2\n\t"
-				     "ldx	[%2 + 0x080], %%g3\n\t"
-				     "ldx	[%2 + 0x0c0], %%g5\n\t"
-				     "add	%2, 0x100, %2\n\t"
-				     "cmp	%2, %4\n\t"
-				     "bne,pt	%%xcc, 1b\n\t"
-				     " nop\n\t"
-				     "rd	%%tick, %1\n\t"
-				     : "=&r" (tick1), "=&r" (tick2),
-				       "=&r" (flush_base)
-				     : "2" (flush_base),
-				       "r" (flush_base + ecache_size)
-				     : "g1", "g2", "g3", "g5");
-		} else {
-		__asm__ __volatile__("b,pt	%%xcc, 1f\n\t"
-				     " rd	%%asr24, %0\n\t"
-				     ".align	64\n"
-				     "1:\tldx	[%2 + 0x000], %%g1\n\t"
-				     "ldx	[%2 + 0x040], %%g2\n\t"
-				     "ldx	[%2 + 0x080], %%g3\n\t"
-				     "ldx	[%2 + 0x0c0], %%g5\n\t"
-				     "add	%2, 0x100, %2\n\t"
-				     "cmp	%2, %4\n\t"
+		tick1 = tick_ops->get_tick();
+
+		__asm__ __volatile__("1:\n\t"
+				     "ldx	[%0 + 0x000], %%g1\n\t"
+				     "ldx	[%0 + 0x040], %%g2\n\t"
+				     "ldx	[%0 + 0x080], %%g3\n\t"
+				     "ldx	[%0 + 0x0c0], %%g5\n\t"
+				     "add	%0, 0x100, %0\n\t"
+				     "cmp	%0, %2\n\t"
 				     "bne,pt	%%xcc, 1b\n\t"
-				     " nop\n\t"
-				     "rd	%%asr24, %1\n\t"
-				     : "=&r" (tick1), "=&r" (tick2),
-				       "=&r" (flush_base)
-				     : "2" (flush_base),
+				     " nop"
+				     : "=&r" (flush_base)
+				     : "0" (flush_base),
 				       "r" (flush_base + ecache_size)
 				     : "g1", "g2", "g3", "g5");
-		}
+
+		tick2 = tick_ops->get_tick();
 
 		local_irq_restore(flags);
 
@@ -1370,6 +1209,8 @@
 report:
 	/* Convert ticks/sticks to jiffies. */
 	cache_decay_ticks = cacheflush_time / timer_tick_offset;
+	if (cache_decay_ticks < 1)
+		cache_decay_ticks = 1;
 
 	printk("Using heuristic of %ld cycles, %ld ticks.\n",
 	       cacheflush_time, cache_decay_ticks);
@@ -1438,8 +1279,7 @@
 		if (!test_bit(cpu, &cpu_online_map)) {
 			ret = -ENODEV;
 		} else {
-			if (SPARC64_USE_STICK)
-				smp_synchronize_one_stick(cpu);
+			smp_synchronize_one_tick(cpu);
 		}
 	}
 	return ret;
diff -Nru a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
--- a/arch/sparc64/kernel/sparc64_ksyms.c	Tue Mar 11 16:12:15 2003
+++ b/arch/sparc64/kernel/sparc64_ksyms.c	Sun Mar 23 22:06:53 2003
@@ -21,6 +21,7 @@
 #include <linux/fs_struct.h>
 #include <linux/mm.h>
 #include <linux/socket.h>
+#include <net/compat.h>
 
 #include <asm/oplib.h>
 #include <asm/delay.h>
@@ -128,20 +129,13 @@
 #endif
 
 /* Hard IRQ locking */
-#ifdef CONFIG_SMP
 EXPORT_SYMBOL(synchronize_irq);
-#endif
 
 #if defined(CONFIG_MCOUNT)
 extern void mcount(void);
 EXPORT_SYMBOL_NOVERS(mcount);
 #endif
 
-/* Uniprocessor clock frequency */
-#ifndef CONFIG_SMP
-EXPORT_SYMBOL(up_clock_tick);
-#endif
-
 /* Per-CPU information table */
 EXPORT_SYMBOL(cpu_data);
 
@@ -162,10 +156,13 @@
 EXPORT_SYMBOL(_do_write_unlock);
 #endif
 
-#ifdef CONFIG_SMP
 EXPORT_SYMBOL(smp_call_function);
-#endif
+#endif /* CONFIG_SMP */
 
+/* Uniprocessor clock frequency */
+#ifndef CONFIG_SMP
+extern unsigned long up_clock_tick;
+EXPORT_SYMBOL(up_clock_tick);
 #endif
 
 /* semaphores */
diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
--- a/arch/sparc64/kernel/sys_sparc32.c	Tue Mar 11 15:41:39 2003
+++ b/arch/sparc64/kernel/sys_sparc32.c	Sun Mar 23 14:38:05 2003
@@ -2234,23 +2234,6 @@
 	compat_gid_t	ex32_anon_gid;
 };
 
-struct nfsctl_uidmap32 {
-	u32			ug32_ident;   /* char * */
-	compat_uid_t	ug32_uidbase;
-	s32			ug32_uidlen;
-	u32			ug32_udimap;  /* uid_t * */
-	compat_uid_t	ug32_gidbase;
-	s32			ug32_gidlen;
-	u32			ug32_gdimap;  /* gid_t * */
-};
-
-struct nfsctl_fhparm32 {
-	struct sockaddr		gf32_addr;
-	compat_dev_t	gf32_dev;
-	compat_ino_t	gf32_ino;
-	s32			gf32_version;
-};
-
 struct nfsctl_fdparm32 {
 	struct sockaddr		gd32_addr;
 	s8			gd32_path[NFS_MAXPATHLEN+1];
@@ -2269,16 +2252,12 @@
 		struct nfsctl_svc32	u32_svc;
 		struct nfsctl_client32	u32_client;
 		struct nfsctl_export32	u32_export;
-		struct nfsctl_uidmap32	u32_umap;
-		struct nfsctl_fhparm32	u32_getfh;
 		struct nfsctl_fdparm32	u32_getfd;
 		struct nfsctl_fsparm32	u32_getfs;
 	} u;
 #define ca32_svc	u.u32_svc
 #define ca32_client	u.u32_client
 #define ca32_export	u.u32_export
-#define ca32_umap	u.u32_umap
-#define ca32_getfh	u.u32_getfh
 #define ca32_getfd	u.u32_getfd
 #define ca32_getfs	u.u32_getfs
 #define ca32_authd	u.u32_authd
@@ -2347,71 +2326,6 @@
 	return (err ? -EFAULT : 0);
 }
 
-static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
-{
-	u32 uaddr;
-	int i;
-	int err;
-
-	memset(karg, 0, sizeof(*karg));
-	if(__get_user(karg->ca_version, &arg32->ca32_version))
-		return -EFAULT;
-	karg->ca_umap.ug_ident = (char *)get_zeroed_page(GFP_USER);
-	if(!karg->ca_umap.ug_ident)
-		return -ENOMEM;
-	err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
-	if(strncpy_from_user(karg->ca_umap.ug_ident,
-			     (char *)A(uaddr), PAGE_SIZE) <= 0)
-		return -EFAULT;
-	err |= __get_user(karg->ca_umap.ug_uidbase,
-		      &arg32->ca32_umap.ug32_uidbase);
-	err |= __get_user(karg->ca_umap.ug_uidlen,
-		      &arg32->ca32_umap.ug32_uidlen);
-	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
-	if (err)
-		return -EFAULT;
-	karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
-					  GFP_USER);
-	if(!karg->ca_umap.ug_udimap)
-		return -ENOMEM;
-	for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
-		err |= __get_user(karg->ca_umap.ug_udimap[i],
-			      &(((compat_uid_t *)A(uaddr))[i]));
-	err |= __get_user(karg->ca_umap.ug_gidbase,
-		      &arg32->ca32_umap.ug32_gidbase);
-	err |= __get_user(karg->ca_umap.ug_uidlen,
-		      &arg32->ca32_umap.ug32_gidlen);
-	err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
-	if (err)
-		return -EFAULT;
-	karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
-					  GFP_USER);
-	if(!karg->ca_umap.ug_gdimap)
-		return -ENOMEM;
-	for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
-		err |= __get_user(karg->ca_umap.ug_gdimap[i],
-			      &(((compat_gid_t *)A(uaddr))[i]));
-
-	return (err ? -EFAULT : 0);
-}
-
-static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
-{
-	int err;
-	
-	err = __get_user(karg->ca_version, &arg32->ca32_version);
-	err |= copy_from_user(&karg->ca_getfh.gf_addr,
-			  &arg32->ca32_getfh.gf32_addr,
-			  (sizeof(struct sockaddr)));
-	err |= __get_user(karg->ca_getfh.gf_dev,
-		      &arg32->ca32_getfh.gf32_dev);
-	err |= __get_user(karg->ca_getfh.gf_ino,
-		      &arg32->ca32_getfh.gf32_ino);
-	err |= __get_user(karg->ca_getfh.gf_version,
-		      &arg32->ca32_getfh.gf32_version);
-	return (err ? -EFAULT : 0);
-}
-
 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
 {
 	int err;
@@ -2483,13 +2397,6 @@
 	case NFSCTL_UNEXPORT:
 		err = nfs_exp32_trans(karg, arg32);
 		break;
-	/* This one is unimplemented, be we're ready for it. */
-	case NFSCTL_UGIDUPDATE:
-		err = nfs_uud32_trans(karg, arg32);
-		break;
-	case NFSCTL_GETFH:
-		err = nfs_getfh32_trans(karg, arg32);
-		break;
 	case NFSCTL_GETFD:
 		err = nfs_getfd32_trans(karg, arg32);
 		break;
@@ -2510,23 +2417,13 @@
 	if (err)
 		goto done;
 
-	if((cmd == NFSCTL_GETFH) ||
-	   (cmd == NFSCTL_GETFD) ||
+	if((cmd == NFSCTL_GETFD) ||
 	   (cmd == NFSCTL_GETFS))
 		err = nfs_getfh32_res_trans(kres, res32);
 
 done:
-	if(karg) {
-		if(cmd == NFSCTL_UGIDUPDATE) {
-			if(karg->ca_umap.ug_ident)
-				kfree(karg->ca_umap.ug_ident);
-			if(karg->ca_umap.ug_udimap)
-				kfree(karg->ca_umap.ug_udimap);
-			if(karg->ca_umap.ug_gdimap)
-				kfree(karg->ca_umap.ug_gdimap);
-		}
+	if(karg)
 		kfree(karg);
-	}
 	if(kres)
 		kfree(kres);
 	return err;
diff -Nru a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
--- a/arch/sparc64/kernel/sys_sunos32.c	Sat Mar  8 11:39:01 2003
+++ b/arch/sparc64/kernel/sys_sunos32.c	Sun Mar 23 22:06:53 2003
@@ -56,6 +56,7 @@
 /* For SOCKET_I */
 #include <linux/socket.h>
 #include <net/sock.h>
+#include <net/compat.h>
 
 /* Use this to get at 32-bit user passed pointers. */
 #define A(__x)				\
diff -Nru a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
--- a/arch/sparc64/kernel/time.c	Mon Feb 24 23:13:09 2003
+++ b/arch/sparc64/kernel/time.c	Tue Mar 18 18:04:20 2003
@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/profile.h>
 #include <linux/bcd.h>
+#include <linux/jiffies.h>
 
 #include <asm/oplib.h>
 #include <asm/mostek.h>
@@ -37,6 +38,7 @@
 #include <asm/ebus.h>
 #include <asm/isa.h>
 #include <asm/starfire.h>
+#include <asm/smp.h>
 
 spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED;
 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
@@ -54,6 +56,352 @@
 
 static int set_rtc_mmss(unsigned long);
 
+struct sparc64_tick_ops *tick_ops;
+
+#define TICK_PRIV_BIT	(1UL << 63)
+
+static void tick_disable_protection(void)
+{
+	/* Set things up so user can access tick register for profiling
+	 * purposes.  Also workaround BB_ERRATA_1 by doing a dummy
+	 * read back of %tick after writing it.
+	 */
+	__asm__ __volatile__(
+	"	ba,pt	%%xcc, 1f\n"
+	"	 nop\n"
+	"	.align	64\n"
+	"1:	rd	%%tick, %%g2\n"
+	"	add	%%g2, 6, %%g2\n"
+	"	andn	%%g2, %0, %%g2\n"
+	"	wrpr	%%g2, 0, %%tick\n"
+	"	rdpr	%%tick, %%g0"
+	: /* no outputs */
+	: "r" (TICK_PRIV_BIT)
+	: "g2");
+}
+
+static void tick_init_tick(unsigned long offset)
+{
+	tick_disable_protection();
+
+	__asm__ __volatile__(
+	"	rd	%%tick, %%g1\n"
+	"	andn	%%g1, %1, %%g1\n"
+	"	ba,pt	%%xcc, 1f\n"
+	"	 add	%%g1, %0, %%g1\n"
+	"	.align	64\n"
+	"1:	wr	%%g1, 0x0, %%tick_cmpr\n"
+	"	rd	%%tick_cmpr, %%g0"
+	: /* no outputs */
+	: "r" (offset), "r" (TICK_PRIV_BIT)
+	: "g1");
+}
+
+static unsigned long tick_get_tick(void)
+{
+	unsigned long ret;
+
+	__asm__ __volatile__("rd	%%tick, %0\n\t"
+			     "mov	%0, %0"
+			     : "=r" (ret));
+
+	return ret & ~TICK_PRIV_BIT;
+}
+
+static unsigned long tick_get_compare(void)
+{
+	unsigned long ret;
+
+	__asm__ __volatile__("rd	%%tick_cmpr, %0\n\t"
+			     "mov	%0, %0"
+			     : "=r" (ret));
+
+	return ret;
+}
+
+static unsigned long tick_add_compare(unsigned long adj)
+{
+	unsigned long new_compare;
+
+	/* Workaround for Spitfire Errata (#54 I think??), I discovered
+	 * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
+	 * number 103640.
+	 *
+	 * On Blackbird writes to %tick_cmpr can fail, the
+	 * workaround seems to be to execute the wr instruction
+	 * at the start of an I-cache line, and perform a dummy
+	 * read back from %tick_cmpr right after writing to it. -DaveM
+	 */
+	__asm__ __volatile__("rd	%%tick_cmpr, %0\n\t"
+			     "ba,pt	%%xcc, 1f\n\t"
+			     " add	%0, %1, %0\n\t"
+			     ".align	64\n"
+			     "1:\n\t"
+			     "wr	%0, 0, %%tick_cmpr\n\t"
+			     "rd	%%tick_cmpr, %%g0"
+			     : "=&r" (new_compare)
+			     : "r" (adj));
+
+	return new_compare;
+}
+
+static unsigned long tick_add_tick(unsigned long adj, unsigned long offset)
+{
+	unsigned long new_tick, tmp;
+
+	/* Also need to handle Blackbird bug here too. */
+	__asm__ __volatile__("rd	%%tick, %0\n\t"
+			     "add	%0, %2, %0\n\t"
+			     "wrpr	%0, 0, %%tick\n\t"
+			     "andn	%0, %4, %1\n\t"
+			     "ba,pt	%%xcc, 1f\n\t"
+			     " add	%1, %3, %1\n\t"
+			     ".align	64\n"
+			     "1:\n\t"
+			     "wr	%1, 0, %%tick_cmpr\n\t"
+			     "rd	%%tick_cmpr, %%g0"
+			     : "=&r" (new_tick), "=&r" (tmp)
+			     : "r" (adj), "r" (offset), "r" (TICK_PRIV_BIT));
+
+	return new_tick;
+}
+
+static struct sparc64_tick_ops tick_operations = {
+	.init_tick	=	tick_init_tick,
+	.get_tick	=	tick_get_tick,
+	.get_compare	=	tick_get_compare,
+	.add_tick	=	tick_add_tick,
+	.add_compare	=	tick_add_compare,
+	.softint_mask	=	1UL << 0,
+};
+
+static void stick_init_tick(unsigned long offset)
+{
+	tick_disable_protection();
+
+	/* Let the user get at STICK too. */
+	__asm__ __volatile__(
+	"	rd	%%asr24, %%g2\n"
+	"	andn	%%g2, %0, %%g2\n"
+	"	wr	%%g2, 0, %%asr24"
+	: /* no outputs */
+	: "r" (TICK_PRIV_BIT)
+	: "g1", "g2");
+
+	__asm__ __volatile__(
+	"	rd	%%asr24, %%g1\n"
+	"	andn	%%g1, %1, %%g1\n"
+	"	add	%%g1, %0, %%g1\n"
+	"	wr	%%g1, 0x0, %%asr25"
+	: /* no outputs */
+	: "r" (offset), "r" (TICK_PRIV_BIT)
+	: "g1");
+}
+
+static unsigned long stick_get_tick(void)
+{
+	unsigned long ret;
+
+	__asm__ __volatile__("rd	%%asr24, %0"
+			     : "=r" (ret));
+
+	return ret & ~TICK_PRIV_BIT;
+}
+
+static unsigned long stick_get_compare(void)
+{
+	unsigned long ret;
+
+	__asm__ __volatile__("rd	%%asr25, %0"
+			     : "=r" (ret));
+
+	return ret;
+}
+
+static unsigned long stick_add_tick(unsigned long adj, unsigned long offset)
+{
+	unsigned long new_tick, tmp;
+
+	__asm__ __volatile__("rd	%%asr24, %0\n\t"
+			     "add	%0, %2, %0\n\t"
+			     "wr	%0, 0, %%asr24\n\t"
+			     "andn	%0, %4, %1\n\t"
+			     "add	%1, %3, %1\n\t"
+			     "wr	%1, 0, %%asr25"
+			     : "=&r" (new_tick), "=&r" (tmp)
+			     : "r" (adj), "r" (offset), "r" (TICK_PRIV_BIT));
+
+	return new_tick;
+}
+
+static unsigned long stick_add_compare(unsigned long adj)
+{
+	unsigned long new_compare;
+
+	__asm__ __volatile__("rd	%%asr25, %0\n\t"
+			     "add	%0, %1, %0\n\t"
+			     "wr	%0, 0, %%asr25"
+			     : "=&r" (new_compare)
+			     : "r" (adj));
+
+	return new_compare;
+}
+
+static struct sparc64_tick_ops stick_operations = {
+	.init_tick	=	stick_init_tick,
+	.get_tick	=	stick_get_tick,
+	.get_compare	=	stick_get_compare,
+	.add_tick	=	stick_add_tick,
+	.add_compare	=	stick_add_compare,
+	.softint_mask	=	1UL << 16,
+};
+
+/* On Hummingbird the STICK/STICK_CMPR register is implemented
+ * in I/O space.  There are two 64-bit registers each, the
+ * first holds the low 32-bits of the value and the second holds
+ * the high 32-bits.
+ *
+ * Since STICK is constantly updating, we have to access it carefully.
+ *
+ * The sequence we use to read is:
+ * 1) read low
+ * 2) read high
+ * 3) read low again, if it rolled over increment high by 1
+ *
+ * Writing STICK safely is also tricky:
+ * 1) write low to zero
+ * 2) write high
+ * 3) write low
+ */
+#define HBIRD_STICKCMP_ADDR	0x1fe0000f060UL
+#define HBIRD_STICK_ADDR	0x1fe0000f070UL
+
+static unsigned long __hbird_read_stick(void)
+{
+	unsigned long ret, tmp1, tmp2, tmp3;
+	unsigned long addr = HBIRD_STICK_ADDR;
+
+	__asm__ __volatile__("ldxa	[%1] %5, %2\n\t"
+			     "add	%1, 0x8, %1\n\t"
+			     "ldxa	[%1] %5, %3\n\t"
+			     "sub	%1, 0x8, %1\n\t"
+			     "ldxa	[%1] %5, %4\n\t"
+			     "cmp	%4, %2\n\t"
+			     "blu,a,pn	%%xcc, 1f\n\t"
+			     " add	%3, 1, %3\n"
+			     "1:\n\t"
+			     "sllx	%3, 32, %3\n\t"
+			     "or	%3, %4, %0\n\t"
+			     : "=&r" (ret), "=&r" (addr),
+			       "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3)
+			     : "i" (ASI_PHYS_BYPASS_EC_E), "1" (addr));
+
+	return ret;
+}
+
+static unsigned long __hbird_read_compare(void)
+{
+	unsigned long low, high;
+	unsigned long addr = HBIRD_STICKCMP_ADDR;
+
+	__asm__ __volatile__("ldxa	[%2] %3, %0\n\t"
+			     "add	%2, 0x8, %2\n\t"
+			     "ldxa	[%2] %3, %1"
+			     : "=&r" (low), "=&r" (high), "=&r" (addr)
+			     : "i" (ASI_PHYS_BYPASS_EC_E), "2" (addr));
+
+	return (high << 32UL) | low;
+}
+
+static void __hbird_write_stick(unsigned long val)
+{
+	unsigned long low = (val & 0xffffffffUL);
+	unsigned long high = (val >> 32UL);
+	unsigned long addr = HBIRD_STICK_ADDR;
+
+	__asm__ __volatile__("stxa	%%g0, [%0] %4\n\t"
+			     "add	%0, 0x8, %0\n\t"
+			     "stxa	%3, [%0] %4\n\t"
+			     "sub	%0, 0x8, %0\n\t"
+			     "stxa	%2, [%0] %4"
+			     : "=&r" (addr)
+			     : "0" (addr), "r" (low), "r" (high),
+			       "i" (ASI_PHYS_BYPASS_EC_E));
+}
+
+static void __hbird_write_compare(unsigned long val)
+{
+	unsigned long low = (val & 0xffffffffUL);
+	unsigned long high = (val >> 32UL);
+	unsigned long addr = HBIRD_STICKCMP_ADDR + 0x8UL;
+
+	__asm__ __volatile__("stxa	%3, [%0] %4\n\t"
+			     "sub	%0, 0x8, %0\n\t"
+			     "stxa	%2, [%0] %4"
+			     : "=&r" (addr)
+			     : "0" (addr), "r" (low), "r" (high),
+			       "i" (ASI_PHYS_BYPASS_EC_E));
+}
+
+static void hbtick_init_tick(unsigned long offset)
+{
+	unsigned long val;
+
+	tick_disable_protection();
+
+	/* XXX This seems to be necessary to 'jumpstart' Hummingbird
+	 * XXX into actually sending STICK interrupts.  I think because
+	 * XXX of how we store %tick_cmpr in head.S this somehow resets the
+	 * XXX {TICK + STICK} interrupt mux.  -DaveM
+	 */
+	__hbird_write_stick(__hbird_read_stick());
+
+	val = __hbird_read_stick() & ~TICK_PRIV_BIT;
+	__hbird_write_compare(val + offset);
+}
+
+static unsigned long hbtick_get_tick(void)
+{
+	return __hbird_read_stick() & ~TICK_PRIV_BIT;
+}
+
+static unsigned long hbtick_get_compare(void)
+{
+	return __hbird_read_compare();
+}
+
+static unsigned long hbtick_add_tick(unsigned long adj, unsigned long offset)
+{
+	unsigned long val;
+
+	val = __hbird_read_stick() + adj;
+	__hbird_write_stick(val);
+
+	val &= ~TICK_PRIV_BIT;
+	__hbird_write_compare(val + offset);
+
+	return val;
+}
+
+static unsigned long hbtick_add_compare(unsigned long adj)
+{
+	unsigned long val = __hbird_read_compare() + adj;
+
+	val &= ~TICK_PRIV_BIT;
+	__hbird_write_compare(val);
+
+	return val;
+}
+
+static struct sparc64_tick_ops hbtick_operations = {
+	.init_tick	=	hbtick_init_tick,
+	.get_tick	=	hbtick_get_tick,
+	.get_compare	=	hbtick_get_compare,
+	.add_tick	=	hbtick_add_tick,
+	.add_compare	=	hbtick_add_compare,
+	.softint_mask	=	1UL << 0,
+};
+
 /* timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  *
@@ -62,7 +410,8 @@
  */
 unsigned long timer_tick_offset;
 unsigned long timer_tick_compare;
-unsigned long timer_ticks_per_usec_quotient;
+
+static unsigned long timer_ticks_per_usec_quotient;
 
 #define TICK_SIZE (tick_nsec / 1000)
 
@@ -146,49 +495,14 @@
 				     : "=r" (pstate)
 				     : "i" (PSTATE_IE));
 
-		/* Workaround for Spitfire Errata (#54 I think??), I discovered
-		 * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
-		 * number 103640.
-		 *
-		 * On Blackbird writes to %tick_cmpr can fail, the
-		 * workaround seems to be to execute the wr instruction
-		 * at the start of an I-cache line, and perform a dummy
-		 * read back from %tick_cmpr right after writing to it. -DaveM
-		 *
-		 * Just to be anal we add a workaround for Spitfire
-		 * Errata 50 by preventing pipeline bypasses on the
-		 * final read of the %tick register into a compare
-		 * instruction.  The Errata 50 description states
-		 * that %tick is not prone to this bug, but I am not
-		 * taking any chances.
-		 */
-		if (!SPARC64_USE_STICK) {
-		__asm__ __volatile__(
-		"	rd	%%tick_cmpr, %0\n"
-		"	ba,pt	%%xcc, 1f\n"
-		"	 add	%0, %2, %0\n"
-		"	.align	64\n"
-		"1: 	wr	%0, 0, %%tick_cmpr\n"
-		"	rd	%%tick_cmpr, %%g0\n"
-		"	rd	%%tick, %1\n"
-		"	mov	%1, %1"
-			: "=&r" (timer_tick_compare), "=r" (ticks)
-			: "r" (timer_tick_offset));
-		} else {
-		__asm__ __volatile__(
-		"	rd	%%asr25, %0\n"
-		"	add	%0, %2, %0\n"
-		"	wr	%0, 0, %%asr25\n"
-		"	rd	%%asr24, %1"
-			: "=&r" (timer_tick_compare), "=r" (ticks)
-			: "r" (timer_tick_offset));
-		}
+		timer_tick_compare = tick_ops->add_compare(timer_tick_offset);
+		ticks = tick_ops->get_tick();
 
 		/* Restore PSTATE_IE. */
 		__asm__ __volatile__("wrpr	%0, 0x0, %%pstate"
 				     : /* no outputs */
 				     : "r" (pstate));
-	} while (ticks >= timer_tick_compare);
+	} while (time_after_eq(ticks, timer_tick_compare));
 
 	timer_check_rtc();
 
@@ -205,19 +519,7 @@
 	/*
 	 * Only keep timer_tick_offset uptodate, but don't set TICK_CMPR.
 	 */
-	if (!SPARC64_USE_STICK) {
-	__asm__ __volatile__(
-	"	rd	%%tick_cmpr, %0\n"
-	"	add	%0, %1, %0"
-		: "=&r" (timer_tick_compare)
-		: "r" (timer_tick_offset));
-	} else {
-	__asm__ __volatile__(
-	"	rd	%%asr25, %0\n"
-	"	add	%0, %1, %0"
-		: "=&r" (timer_tick_compare)
-		: "r" (timer_tick_offset));
-	}
+	timer_tick_compare = tick_ops->get_compare() + timer_tick_offset;
 
 	timer_check_rtc();
 
@@ -620,40 +922,90 @@
 	local_irq_restore(flags);
 }
 
-void __init time_init(void)
+/* This is gets the master TICK_INT timer going. */
+static unsigned long sparc64_init_timers(void (*cfunc)(int, void *, struct pt_regs *))
 {
-	/* clock_probe() is now done at end of [se]bus_init on sparc64
-	 * so that sbus, fhc and ebus bus information is probed and
-	 * available.
+	unsigned long pstate, clock;
+	int node, err;
+#ifdef CONFIG_SMP
+	extern void smp_tick_init(void);
+#endif
+
+	if (tlb_type == spitfire) {
+		unsigned long ver, manuf, impl;
+
+		__asm__ __volatile__ ("rdpr %%ver, %0"
+				      : "=&r" (ver));
+		manuf = ((ver >> 48) & 0xffff);
+		impl = ((ver >> 32) & 0xffff);
+		if (manuf == 0x17 && impl == 0x13) {
+			/* Hummingbird, aka Ultra-IIe */
+			tick_ops = &hbtick_operations;
+			node = prom_root_node;
+			clock = prom_getint(node, "stick-frequency");
+		} else {
+			tick_ops = &tick_operations;
+			node = linux_cpus[0].prom_node;
+			clock = prom_getint(node, "clock-frequency");
+		}
+	} else {
+		tick_ops = &stick_operations;
+		node = prom_root_node;
+		clock = prom_getint(node, "stick-frequency");
+	}
+	timer_tick_offset = clock / HZ;
+
+#ifdef CONFIG_SMP
+	smp_tick_init();
+#endif
+
+	/* Register IRQ handler. */
+	err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, SA_STATIC_ALLOC,
+			  "timer", NULL);
+
+	if (err) {
+		prom_printf("Serious problem, cannot register TICK_INT\n");
+		prom_halt();
+	}
+
+	/* Guarentee that the following sequences execute
+	 * uninterrupted.
 	 */
-	unsigned long clock;
+	__asm__ __volatile__("rdpr	%%pstate, %0\n\t"
+			     "wrpr	%0, %1, %%pstate"
+			     : "=r" (pstate)
+			     : "i" (PSTATE_IE));
+
+	tick_ops->init_tick(timer_tick_offset);
+
+	/* Restore PSTATE_IE. */
+	__asm__ __volatile__("wrpr	%0, 0x0, %%pstate"
+			     : /* no outputs */
+			     : "r" (pstate));
+
+	local_irq_enable();
 
-	sparc64_init_timers(timer_interrupt, &clock);
-	timer_ticks_per_usec_quotient = ((1UL<<32) / (clock / 1000020));
+	return clock;
+}
+
+/* The quotient formula is taken from the IA64 port. */
+void __init time_init(void)
+{
+	unsigned long clock = sparc64_init_timers(timer_interrupt);
+
+	timer_ticks_per_usec_quotient =
+		(((1000000UL << 30) +
+		  (clock / 2)) / clock);
 }
 
 static __inline__ unsigned long do_gettimeoffset(void)
 {
-	unsigned long ticks;
+	unsigned long ticks = tick_ops->get_tick();
 
-	if (!SPARC64_USE_STICK) {
-	__asm__ __volatile__(
-	"	rd	%%tick, %%g1\n"
-	"	add	%1, %%g1, %0\n"
-	"	sub	%0, %2, %0\n"
-		: "=r" (ticks)
-		: "r" (timer_tick_offset), "r" (timer_tick_compare)
-		: "g1", "g2");
-	} else {
-	__asm__ __volatile__("rd	%%asr24, %%g1\n\t"
-			     "add	%1, %%g1, %0\n\t"
-			     "sub	%0, %2, %0\n\t"
-			     : "=&r" (ticks)
-			     : "r" (timer_tick_offset), "r" (timer_tick_compare)
-			     : "g1");
-	}
+	ticks += timer_tick_offset;
+	ticks -= timer_tick_compare;
 
-	return (ticks * timer_ticks_per_usec_quotient) >> 32UL;
+	return (ticks * timer_ticks_per_usec_quotient) >> 30UL;
 }
 
 void do_settimeofday(struct timeval *tv)
diff -Nru a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
--- a/arch/sparc64/kernel/trampoline.S	Mon Aug 26 02:44:51 2002
+++ b/arch/sparc64/kernel/trampoline.S	Tue Mar 18 18:26:20 2003
@@ -85,7 +85,10 @@
 
 startup_continue:
 	wrpr		%g0, 15, %pil
-	wr		%g0, 0, %tick_cmpr
+
+	sethi		%hi(0x80000000), %g2
+	sllx		%g2, 32, %g2
+	wr		%g2, 0, %tick_cmpr
 
 	/* Call OBP by hand to lock KERNBASE into i/d tlbs. */
 	mov		%o0, %l0
diff -Nru a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
--- a/arch/sparc64/kernel/traps.c	Tue Feb 25 09:17:18 2003
+++ b/arch/sparc64/kernel/traps.c	Wed Mar 19 22:55:52 2003
@@ -33,6 +33,7 @@
 #include <asm/chafsr.h>
 #include <asm/psrcompat.h>
 #include <asm/processor.h>
+#include <asm/timer.h>
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
 #endif
@@ -588,7 +589,7 @@
 	flush_linesize = ecache_flush_linesize;
 	flush_size = ecache_flush_size >> 1;
 
-	__asm__ __volatile__("rd %%tick, %0" : "=r" (tick1));
+	tick1 = tick_ops->get_tick();
 
 	__asm__ __volatile__("1: subcc	%0, %4, %0\n\t"
 			     "   bne,pt	%%xcc, 1b\n\t"
@@ -597,7 +598,7 @@
 			     : "0" (flush_size), "r" (flush_base),
 			       "i" (ASI_PHYS_USE_EC), "r" (flush_linesize));
 
-	__asm__ __volatile__("rd %%tick, %0" : "=r" (tick2));
+	tick2 = tick_ops->get_tick();
 
 	raw = (tick2 - tick1);
 
@@ -1598,6 +1599,7 @@
 
 void die_if_kernel(char *str, struct pt_regs *regs)
 {
+	static int die_counter;
 	extern void __show_regs(struct pt_regs * regs);
 	extern void smp_report_regs(void);
 	int count = 0;
@@ -1610,7 +1612,7 @@
 "              /_| \\__/ |_\\\n"
 "                 \\__U_/\n");
 
-	printk("%s(%d): %s\n", current->comm, current->pid, str);
+	printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
 	__asm__ __volatile__("flushw");
 	__show_regs(regs);
 	if (regs->tstate & TSTATE_PRIV) {
diff -Nru a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S
--- a/arch/sparc64/mm/ultra.S	Sat Feb 22 00:03:07 2003
+++ b/arch/sparc64/mm/ultra.S	Wed Mar 12 12:47:00 2003
@@ -560,8 +560,8 @@
 	/* This runs in a very controlled environment, so we do
 	 * not need to worry about BH races etc.
 	 */
-	.globl		xcall_sync_stick
-xcall_sync_stick:
+	.globl		xcall_sync_tick
+xcall_sync_tick:
 	rdpr		%pstate, %g2
 	wrpr		%g2, PSTATE_IG | PSTATE_AG, %pstate
 	rdpr		%pil, %g2
@@ -569,7 +569,7 @@
 	sethi		%hi(109f), %g7
 	b,pt		%xcc, etrap_irq
 109:	 or		%g7, %lo(109b), %g7
-	call		smp_synchronize_stick_client
+	call		smp_synchronize_tick_client
 	 nop
 	clr		%l6
 	b		rtrap_xcall
diff -Nru a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c
--- a/arch/sparc64/solaris/socket.c	Thu Mar  6 12:08:45 2003
+++ b/arch/sparc64/solaris/socket.c	Sun Mar 23 22:06:53 2003
@@ -15,6 +15,7 @@
 #include <linux/file.h>
 #include <linux/net.h>
 #include <linux/compat.h>
+#include <net/compat.h>
 
 #include <asm/uaccess.h>
 #include <asm/string.h>
diff -Nru a/arch/um/drivers/line.c b/arch/um/drivers/line.c
--- a/arch/um/drivers/line.c	Wed Feb  5 20:16:01 2003
+++ b/arch/um/drivers/line.c	Sat Mar 22 07:37:12 2003
@@ -438,7 +438,7 @@
 
 	from = line_driver->symlink_from;
 	to = line_driver->symlink_to;
-	err = devfs_mk_symlink(NULL, from, 0, to, NULL, NULL);
+	err = devfs_mk_symlink(from, to);
 	if(err) printk("Symlink creation from /dev/%s to /dev/%s "
 		       "returned %d\n", from, to, err);
 
diff -Nru a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
--- a/arch/um/drivers/mmapper_kern.c	Sat Dec 28 12:28:00 2002
+++ b/arch/um/drivers/mmapper_kern.c	Sat Mar 22 07:37:12 2003
@@ -127,8 +127,7 @@
 	devfs_register (NULL, "mmapper", DEVFS_FL_DEFAULT, 
 			30, 0, S_IFCHR | S_IRUGO | S_IWUGO, 
 			&mmapper_fops, NULL); 
-	devfs_mk_symlink(NULL, "mmapper0", DEVFS_FL_DEFAULT, "mmapper",
-			 NULL, NULL);
+	devfs_mk_symlink("mmapper0", "mmapper");
 	return(0);
 }
 
diff -Nru a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
--- a/arch/um/drivers/ubd_kern.c	Sat Mar  8 14:50:21 2003
+++ b/arch/um/drivers/ubd_kern.c	Sat Mar 22 09:04:18 2003
@@ -488,7 +488,7 @@
 			struct gendisk **disk_out, devfs_handle_t dir_handle,
 			devfs_handle_t *handle_out)
 {
-	char devfs_name[sizeof("nnnnnn\0")];
+	char devfs_name[sizeof("ubd/nnnnnn\0")];
 	struct gendisk *disk;
 	int minor = unit << UBD_SHIFT;
 
@@ -505,9 +505,9 @@
 	*disk_out = disk;
 
 	/* /dev/ubd/N style names */
-	sprintf(devfs_name, "%d", unit);
-	*handle_out = devfs_register(dir_handle, devfs_name,
-				     DEVFS_FL_REMOVABLE, major, minor,
+	sprintf(devfs_name, "ubd/%d", unit);
+	*handle_out = devfs_register(NULL, devfs_name,
+				     0, major, minor,
 				     S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP |
 				     S_IWGRP, &ubd_blops, NULL);
 	disk->private_data = &ubd_dev[unit];
@@ -682,7 +682,7 @@
 {
         int i;
 
-	ubd_dir_handle = devfs_mk_dir(NULL, "ubd", NULL);
+	ubd_dir_handle = devfs_mk_dir("ubd");
 	if (register_blkdev(MAJOR_NR, "ubd"))
 		return -1;
 
@@ -693,7 +693,7 @@
 		char name[sizeof("ubd_nnn\0")];
 
 		snprintf(name, sizeof(name), "ubd_%d", fake_major);
-		ubd_fake_dir_handle = devfs_mk_dir(NULL, name, NULL);
+		ubd_fake_dir_handle = devfs_mk_dir(name);
 		if (register_blkdev(fake_major, "ubd"))
 			return -1;
 	}
diff -Nru a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
--- a/arch/x86_64/ia32/ia32_binfmt.c	Sun Jan  5 05:32:14 2003
+++ b/arch/x86_64/ia32/ia32_binfmt.c	Mon Mar 17 21:31:50 2003
@@ -217,7 +217,7 @@
 # define CONFIG_BINFMT_ELF_MODULE	CONFIG_BINFMT_ELF32_MODULE
 #endif
 
-#define ELF_PLAT_INIT(r)		elf32_init(r)
+#define ELF_PLAT_INIT(r, load_addr)	elf32_init(r)
 #define setup_arg_pages(bprm)		ia32_setup_arg_pages(bprm)
 int ia32_setup_arg_pages(struct linux_binprm *bprm);
 
diff -Nru a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
--- a/arch/x86_64/ia32/sys_ia32.c	Sun Mar  9 01:34:45 2003
+++ b/arch/x86_64/ia32/sys_ia32.c	Sun Mar 23 14:34:05 2003
@@ -1807,23 +1807,6 @@
 	compat_gid_t	ex32_anon_gid;
 };
 
-struct nfsctl_uidmap32 {
-	u32			ug32_ident;   /* char * */
-	compat_pid_t	ug32_uidbase;
-	s32			ug32_uidlen;
-	u32			ug32_udimap;  /* uid_t * */
-	compat_pid_t	ug32_gidbase;
-	s32			ug32_gidlen;
-	u32			ug32_gdimap;  /* gid_t * */
-};
-
-struct nfsctl_fhparm32 {
-	struct sockaddr		gf32_addr;
-	compat_dev_t	gf32_dev;
-	compat_ino_t	gf32_ino;
-	s32			gf32_version;
-};
-
 struct nfsctl_fdparm32 {
 	struct sockaddr		gd32_addr;
 	s8			gd32_path[NFS_MAXPATHLEN+1];
@@ -1842,16 +1825,12 @@
 		struct nfsctl_svc32	u32_svc;
 		struct nfsctl_client32	u32_client;
 		struct nfsctl_export32	u32_export;
-		struct nfsctl_uidmap32	u32_umap;
-		struct nfsctl_fhparm32	u32_getfh;
 		struct nfsctl_fdparm32	u32_getfd;
 		struct nfsctl_fsparm32	u32_getfs;
 	} u;
 #define ca32_svc	u.u32_svc
 #define ca32_client	u.u32_client
 #define ca32_export	u.u32_export
-#define ca32_umap	u.u32_umap
-#define ca32_getfh	u.u32_getfh
 #define ca32_getfd	u.u32_getfd
 #define ca32_getfs	u.u32_getfs
 #define ca32_authd	u.u32_authd
@@ -1920,22 +1899,6 @@
 	return err;
 }
 
-static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
-{
-	int err;
-	
-	err = get_user(karg->ca_version, &arg32->ca32_version);
-	err |= copy_from_user(&karg->ca_getfh.gf_addr,
-			  &arg32->ca32_getfh.gf32_addr,
-			  (sizeof(struct sockaddr)));
-	err |= __get_user(karg->ca_getfh.gf_dev,
-		      &arg32->ca32_getfh.gf32_dev);
-	err |= __get_user(karg->ca_getfh.gf_ino,
-		      &arg32->ca32_getfh.gf32_ino);
-	err |= __get_user(karg->ca_getfh.gf_version,
-		      &arg32->ca32_getfh.gf32_version);
-	return err;
-}
 
 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
 {
@@ -2008,9 +1971,6 @@
 	case NFSCTL_UNEXPORT:
 		err = nfs_exp32_trans(karg, arg32);
 		break;
-	case NFSCTL_GETFH:
-		err = nfs_getfh32_trans(karg, arg32);
-		break;
 	case NFSCTL_GETFD:
 		err = nfs_getfd32_trans(karg, arg32);
 		break;
@@ -2031,23 +1991,13 @@
 	if (err)
 		goto done;
 
-	if((cmd == NFSCTL_GETFH) ||
-	   (cmd == NFSCTL_GETFD) ||
+	if((cmd == NFSCTL_GETFD) ||
 	   (cmd == NFSCTL_GETFS))
 		err = nfs_getfh32_res_trans(kres, res32);
 
 done:
-	if(karg) {
-		if(cmd == NFSCTL_UGIDUPDATE) {
-			if(karg->ca_umap.ug_ident)
-				kfree(karg->ca_umap.ug_ident);
-			if(karg->ca_umap.ug_udimap)
-				kfree(karg->ca_umap.ug_udimap);
-			if(karg->ca_umap.ug_gdimap)
-				kfree(karg->ca_umap.ug_gdimap);
-		}
+	if(karg)
 		kfree(karg);
-	}
 	if(kres)
 		kfree(kres);
 	return err;
@@ -2071,8 +2021,8 @@
 	return -ENOSYS ;
 } 
 
-int sys_sched_getaffinity(pid_t pid, unsigned int len, unsigned long *new_mask_ptr); 
-int sys_sched_setaffinity(pid_t pid, unsigned int len, unsigned long *new_mask_ptr); 
+long sys_sched_getaffinity(pid_t pid, unsigned int len, unsigned long *new_mask_ptr); 
+long sys_sched_setaffinity(pid_t pid, unsigned int len, unsigned long *new_mask_ptr); 
 
 /* only works on LE */
 long sys32_sched_setaffinity(pid_t pid, unsigned int len,
diff -Nru a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
--- a/arch/x86_64/kernel/irq.c	Sat Mar  8 14:50:43 2003
+++ b/arch/x86_64/kernel/irq.c	Thu Mar 20 03:11:45 2003
@@ -732,6 +732,9 @@
 	struct irqaction *old, **p;
 	irq_desc_t *desc = irq_desc + irq;
 
+	if (desc->handler == &no_irq_type)
+		return -ENOSYS;
+
 	/*
 	 * Some drivers like serial.c use request_irq() heavily,
 	 * so we have to be careful not to interfere with a
diff -Nru a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
--- a/arch/x86_64/kernel/traps.c	Tue Feb 11 02:33:11 2003
+++ b/arch/x86_64/kernel/traps.c	Mon Mar 17 21:32:24 2003
@@ -325,11 +325,12 @@
 {
 	int cpu;
 	struct die_args args = { regs, str, err };
+	static int die_counter;
 	console_verbose();
 	notifier_call_chain(&die_chain,  DIE_DIE, &args); 
 	bust_spinlocks(1);
 	handle_BUG(regs); 
-	printk("%s: %04lx\n", str, err & 0xffff);
+	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
 	cpu = safe_smp_processor_id(); 
 	/* racy, but better than risking deadlock. */ 
 	local_irq_disable();
diff -Nru a/crypto/aes.c b/crypto/aes.c
--- a/crypto/aes.c	Thu Jan  9 23:07:16 2003
+++ b/crypto/aes.c	Thu Mar 20 23:52:22 2003
@@ -55,6 +55,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/errno.h>
 #include <linux/crypto.h>
 #include <asm/byteorder.h>
 
diff -Nru a/crypto/api.c b/crypto/api.c
--- a/crypto/api.c	Sat Mar  8 11:46:18 2003
+++ b/crypto/api.c	Sun Mar 23 21:47:05 2003
@@ -15,6 +15,7 @@
  */
 #include <linux/init.h>
 #include <linux/crypto.h>
+#include <linux/errno.h>
 #include <linux/rwsem.h>
 #include <linux/slab.h>
 #include "internal.h"
@@ -151,10 +152,7 @@
 
 void crypto_free_tfm(struct crypto_tfm *tfm)
 {
-	if (crypto_tfm_alg_type(tfm) == CRYPTO_ALG_TYPE_CIPHER)
-		if (tfm->crt_cipher.cit_iv)
-			kfree(tfm->crt_cipher.cit_iv);
-	
+	crypto_exit_ops(tfm);
 	crypto_alg_put(tfm->__crt_alg);
 	kfree(tfm);
 }
diff -Nru a/crypto/des.c b/crypto/des.c
--- a/crypto/des.c	Tue Jan 14 03:51:23 2003
+++ b/crypto/des.c	Thu Mar 20 23:52:22 2003
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <linux/errno.h>
 #include <asm/scatterlist.h>
 #include <linux/crypto.h>
 
diff -Nru a/crypto/digest.c b/crypto/digest.c
--- a/crypto/digest.c	Sat Mar  8 11:46:18 2003
+++ b/crypto/digest.c	Thu Mar 20 23:52:22 2003
@@ -13,6 +13,7 @@
  */
 #include <linux/crypto.h>
 #include <linux/mm.h>
+#include <linux/errno.h>
 #include <linux/highmem.h>
 #include <asm/scatterlist.h>
 #include "internal.h"
diff -Nru a/crypto/serpent.c b/crypto/serpent.c
--- a/crypto/serpent.c	Thu Dec  5 13:05:55 2002
+++ b/crypto/serpent.c	Thu Mar 20 23:52:22 2003
@@ -13,6 +13,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/errno.h>
 #include <asm/byteorder.h>
 #include <linux/crypto.h>
 
diff -Nru a/crypto/twofish.c b/crypto/twofish.c
--- a/crypto/twofish.c	Tue Nov 26 14:34:05 2002
+++ b/crypto/twofish.c	Thu Mar 20 23:52:22 2003
@@ -40,6 +40,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/errno.h>
 #include <linux/crypto.h>
 
 
diff -Nru a/drivers/acorn/scsi/acornscsi.c b/drivers/acorn/scsi/acornscsi.c
--- a/drivers/acorn/scsi/acornscsi.c	Fri Feb 14 16:23:44 2003
+++ b/drivers/acorn/scsi/acornscsi.c	Wed Mar 19 07:19:28 2003
@@ -2521,19 +2521,19 @@
  */
 int acornscsi_queuecmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
-    AS_Host *host = (AS_Host *)SCpnt->host->hostdata;
+    AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
 
     if (!done) {
 	/* there should be some way of rejecting errors like this without panicing... */
 	panic("scsi%d: queuecommand called with NULL done function [cmd=%p]",
-		SCpnt->host->host_no, SCpnt);
+		host->host->host_no, SCpnt);
 	return -EINVAL;
     }
 
 #if (DEBUG & DEBUG_NO_WRITE)
     if (acornscsi_cmdtype(SCpnt->cmnd[0]) == CMD_WRITE && (NO_WRITE & (1 << SCpnt->device->id))) {
 	printk(KERN_CRIT "scsi%d.%c: WRITE attempted with NO_WRITE flag set\n",
-	    SCpnt->host->host_no, '0' + SCpnt->device->id);
+	    host->host->host_no, '0' + SCpnt->device->id);
 	SCpnt->result = DID_NO_CONNECT << 16;
 	done(SCpnt);
 	return 0;
@@ -2695,7 +2695,7 @@
  */
 int acornscsi_abort(Scsi_Cmnd *SCpnt)
 {
-	AS_Host *host = (AS_Host *) SCpnt->host->hostdata;
+	AS_Host *host = (AS_Host *) SCpnt->device->host->hostdata;
 	int result;
 
 	host->stats.aborts += 1;
@@ -2782,7 +2782,7 @@
  */
 int acornscsi_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
 {
-    AS_Host *host = (AS_Host *)SCpnt->host->hostdata;
+    AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
     Scsi_Cmnd *SCptr;
     
     host->stats.resets += 1;
diff -Nru a/drivers/acorn/scsi/scsi.h b/drivers/acorn/scsi/scsi.h
--- a/drivers/acorn/scsi/scsi.h	Fri Feb 14 16:23:45 2003
+++ b/drivers/acorn/scsi/scsi.h	Wed Mar 19 07:19:28 2003
@@ -68,8 +68,7 @@
 
 static inline void init_SCp(Scsi_Cmnd *SCpnt)
 {
-	SCpnt->SCp.Message = 0;
-	SCpnt->SCp.Status = 0;
+	memset(&SCpnt->SCp, 0, sizeof(struct scsi_pointer));
 
 	if (SCpnt->use_sg) {
 		unsigned long len = 0;
@@ -97,8 +96,6 @@
 		SCpnt->request_bufflen = len;
 #endif
 	} else {
-		SCpnt->SCp.buffer = NULL;
-		SCpnt->SCp.buffers_residual = 0;
 		SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer;
 		SCpnt->SCp.this_residual = SCpnt->request_bufflen;
 	}
diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c
--- a/drivers/acpi/processor.c	Wed Feb 19 15:50:05 2003
+++ b/drivers/acpi/processor.c	Sat Feb 15 09:52:17 2003
@@ -1356,7 +1356,8 @@
         loff_t			*data)
 {
 	int			result = 0;
-	struct acpi_processor	*pr = (struct acpi_processor *) data;
+        struct seq_file 	*m = (struct seq_file *)file->private_data;
+	struct acpi_processor	*pr = (struct acpi_processor *)m->private;
 	char			state_string[12] = {'\0'};
 
 	ACPI_FUNCTION_TRACE("acpi_processor_write_throttling");
@@ -1418,7 +1419,8 @@
 	loff_t			*data)
 {
 	int			result = 0;
-	struct acpi_processor	*pr = (struct acpi_processor *) data;
+        struct seq_file 	*m = (struct seq_file *)file->private_data;
+	struct acpi_processor	*pr = (struct acpi_processor *)m->private;
 	char			limit_string[25] = {'\0'};
 	int			px = 0;
 	int			tx = 0;
diff -Nru a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c
--- a/drivers/atm/idt77105.c	Mon Nov  4 11:56:57 2002
+++ b/drivers/atm/idt77105.c	Sun Mar 23 01:08:29 2003
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/capability.h>
 #include <linux/atm_idt77105.h>
+#include <linux/spinlock.h>
 #include <asm/system.h>
 #include <asm/param.h>
 #include <asm/uaccess.h>
@@ -38,6 +39,7 @@
         unsigned char old_mcr;          /* storage of MCR reg while signal lost */
 };
 
+static spinlock_t idt77105_priv_lock = SPIN_LOCK_UNLOCKED;
 
 #define PRIV(dev) ((struct idt77105_priv *) dev->phy_data)
 
@@ -144,12 +146,11 @@
 	unsigned long flags;
 	struct idt77105_stats stats;
 
-	save_flags(flags);
-	cli();
+	spin_lock_irqsave(&idt77105_priv_lock, flags);
 	memcpy(&stats, &PRIV(dev)->stats, sizeof(struct idt77105_stats));
 	if (zero)
 		memset(&PRIV(dev)->stats, 0, sizeof(struct idt77105_stats));
-	restore_flags(flags);
+	spin_unlock_irqrestore(&idt77105_priv_lock, flags);
 	if (arg == NULL)
 		return 0;
 	return copy_to_user(arg, &PRIV(dev)->stats,
@@ -267,11 +268,10 @@
 	if (!(PRIV(dev) = kmalloc(sizeof(struct idt77105_priv),GFP_KERNEL)))
 		return -ENOMEM;
 	PRIV(dev)->dev = dev;
-	save_flags(flags);
-	cli();
+	spin_lock_irqsave(&idt77105_priv_lock, flags);
 	PRIV(dev)->next = idt77105_all;
 	idt77105_all = PRIV(dev);
-	restore_flags(flags);
+	spin_unlock_irqrestore(&idt77105_priv_lock, flags);
 	memset(&PRIV(dev)->stats,0,sizeof(struct idt77105_stats));
         
         /* initialise dev->signal from Good Signal Bit */
@@ -305,11 +305,9 @@
 	idt77105_stats_timer_func(0); /* clear 77105 counters */
 	(void) fetch_stats(dev,NULL,1); /* clear kernel counters */
         
-	cli();
-	if (!start_timer) restore_flags(flags);
-	else {
+	spin_lock_irqsave(&idt77105_priv_lock, flags);
+	if (start_timer) {
 		start_timer = 0;
-		restore_flags(flags);
                 
 		init_timer(&stats_timer);
 		stats_timer.expires = jiffies+IDT77105_STATS_TIMER_PERIOD;
@@ -321,32 +319,11 @@
 		restart_timer.function = idt77105_restart_timer_func;
 		add_timer(&restart_timer);
 	}
+	spin_unlock_irqrestore(&idt77105_priv_lock, flags);
 	return 0;
 }
 
 
-static const struct atmphy_ops idt77105_ops = {
-	idt77105_start,
-	idt77105_ioctl,
-	idt77105_int
-};
-
-
-int __init idt77105_init(struct atm_dev *dev)
-{
-	MOD_INC_USE_COUNT;
-
-	dev->phy = &idt77105_ops;
-	return 0;
-}
-
-
-/*
- * TODO: this function should be called through phy_ops
- * but that will not be possible for some time as there is
- * currently a freeze on modifying that structure
- * -- Greg Banks, 13 Sep 1999
- */
 int idt77105_stop(struct atm_dev *dev)
 {
 	struct idt77105_priv *walk, *prev;
@@ -372,30 +349,33 @@
             }
         }
 
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
 
+static const struct atmphy_ops idt77105_ops = {
+	.start = 	idt77105_start,
+	.ioctl =	idt77105_ioctl,
+	.interrupt =	idt77105_int,
+	.stop =		idt77105_stop,
+};
 
-EXPORT_SYMBOL(idt77105_init);
-EXPORT_SYMBOL(idt77105_stop);
-
-MODULE_LICENSE("GPL");
-
-#ifdef MODULE
 
-int init_module(void)
+int idt77105_init(struct atm_dev *dev)
 {
+	dev->phy = &idt77105_ops;
 	return 0;
 }
 
+EXPORT_SYMBOL(idt77105_init);
 
-void cleanup_module(void)
+static void __exit idt77105_exit(void)
 {
         /* turn off timers */
         del_timer(&stats_timer);
         del_timer(&restart_timer);
 }
 
-#endif
+module_exit(idt77105_exit);
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
--- a/drivers/atm/idt77252.c	Mon Nov 11 05:55:56 2002
+++ b/drivers/atm/idt77252.c	Thu Mar 20 00:45:11 2003
@@ -730,7 +730,7 @@
 		struct atm_vcc *vcc = vc->tx_vcc;
 
 		vc->estimator->cells += (skb->len + 47) / 48;
-		if (atomic_read(&vcc->tx_inuse) > (vcc->sk->sndbuf >> 1)) {
+		if (atomic_read(&vcc->sk->wmem_alloc) > (vcc->sk->sndbuf >> 1)) {
 			u32 cps = vc->estimator->maxcps;
 
 			vc->estimator->cps = cps;
@@ -2025,7 +2025,7 @@
 		atomic_inc(&vcc->stats->tx_err);
 		return -ENOMEM;
 	}
-	atomic_add(skb->truesize + ATM_PDU_OVHD, &vcc->tx_inuse);
+	atomic_add(skb->truesize + ATM_PDU_OVHD, &vcc->sk->wmem_alloc);
 	ATM_SKB(skb)->iovcnt = 0;
 
 	memcpy(skb_put(skb, 52), cell, 52);
diff -Nru a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
--- a/drivers/atm/nicstar.c	Thu Feb 13 22:34:50 2003
+++ b/drivers/atm/nicstar.c	Sun Mar 23 01:14:47 2003
@@ -354,11 +354,8 @@
 
       card = cards[i];
 
-#ifdef CONFIG_ATM_NICSTAR_USE_IDT77105
-      if (card->max_pcr == ATM_25_PCR) {
-        idt77105_stop(card->atmdev);
-      }
-#endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */
+      if (card->atmdev->phy && card->atmdev->phy->stop)
+        card->atmdev->phy->stop(card->atmdev);
 
       /* Stop everything */
       writel(0x00000000, card->membase + CFG);
@@ -490,11 +487,6 @@
    card->atmdev = NULL;
    card->pcidev = pcidev;
    card->membase = pci_resource_start(pcidev, 1);
-#ifdef __powerpc__
-   /* Compensate for different memory map between host CPU and PCI bus.
-      Shouldn't we use a macro for this? */
-   card->membase += KERNELBASE;
-#endif /* __powerpc__ */
    card->membase = (unsigned long) ioremap(card->membase, NS_IOREMAP_SIZE);
    if (card->membase == 0)
    {
@@ -905,22 +897,13 @@
    card->atmdev->phy = NULL;
 
 #ifdef CONFIG_ATM_NICSTAR_USE_SUNI
-   if (card->max_pcr == ATM_OC3_PCR) {
+   if (card->max_pcr == ATM_OC3_PCR)
       suni_init(card->atmdev);
-
-      MOD_INC_USE_COUNT;
-      /* Can't remove the nicstar driver or the suni driver would oops */
-   }
 #endif /* CONFIG_ATM_NICSTAR_USE_SUNI */
 
 #ifdef CONFIG_ATM_NICSTAR_USE_IDT77105
-   if (card->max_pcr == ATM_25_PCR) {
+   if (card->max_pcr == ATM_25_PCR)
       idt77105_init(card->atmdev);
-      /* Note that for the IDT77105 PHY we don't need the awful
-       * module count hack that the SUNI needs because we can
-       * stop the '105 when the nicstar module is cleaned up.
-       */
-   }
 #endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */
 
    if (card->atmdev->phy && card->atmdev->phy->start)
@@ -2327,6 +2310,7 @@
          {
             push_rxbufs(card, BUF_SM, (u32) skb, (u32) virt_to_bus(skb->data),
                         0, 0);
+            atomic_inc(&vcc->stats->rx_drop);
          }
          else
 	 {
@@ -2354,6 +2338,7 @@
             {
                push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data),
                            0, 0);
+               atomic_inc(&vcc->stats->rx_drop);
             }
             else
 	    {
@@ -2378,6 +2363,7 @@
             {
                push_rxbufs(card, BUF_LG, (u32) skb,
                            (u32) virt_to_bus(skb->data), 0, 0);
+               atomic_inc(&vcc->stats->rx_drop);
             }
             else
             {
@@ -2462,6 +2448,7 @@
             }
 	    else
 	       dev_kfree_skb_any(hb);
+	    atomic_inc(&vcc->stats->rx_drop);
          }
          else
 	 {
diff -Nru a/drivers/atm/suni.c b/drivers/atm/suni.c
--- a/drivers/atm/suni.c	Mon Mar  3 01:49:37 2003
+++ b/drivers/atm/suni.c	Sun Mar 23 01:16:19 2003
@@ -297,7 +297,7 @@
 	mri = GET(MRI); /* reset SUNI */
 	PUT(mri | SUNI_MRI_RESET,MRI);
 	PUT(mri,MRI);
-	PUT(0,MT); /* disable all tests */
+	PUT((GET(MT) & SUNI_MT_DS27_53),MT); /* disable all tests */
 	REG_CHANGE(SUNI_TPOP_APM_S,SUNI_TPOP_APM_S_SHIFT,SUNI_TPOP_S_SONET,
 	    TPOP_APM); /* use SONET */
 	REG_CHANGE(SUNI_TACP_IUCHP_CLP,0,SUNI_TACP_IUCHP_CLP,
@@ -307,24 +307,6 @@
 	return 0;
 }
 
-
 EXPORT_SYMBOL(suni_init);
 
-
 MODULE_LICENSE("GPL");
-
-#ifdef MODULE
-
-
-int init_module(void)
-{
-	return 0;
-}
-
-
-void cleanup_module(void)
-{
-	/* Nay */
-}
-
-#endif
diff -Nru a/drivers/atm/suni.h b/drivers/atm/suni.h
--- a/drivers/atm/suni.h	Tue Feb  5 09:40:18 2002
+++ b/drivers/atm/suni.h	Sun Mar 23 01:16:19 2003
@@ -198,6 +198,7 @@
 #define SUNI_MT_IOTST		0x04	/* RW, enable test mode */
 #define SUNI_MT_DBCTRL		0x08	/* W, control data bus by CSB pin */
 #define SUNI_MT_PMCTST		0x10	/* W, PMC test mode */
+#define SUNI_MT_DS27_53		0x80	/* RW, select between 8- or 16- bit */
 
 
 #define SUNI_IDLE_PATTERN       0x6a    /* idle pattern */
diff -Nru a/drivers/block/Kconfig b/drivers/block/Kconfig
--- a/drivers/block/Kconfig	Sun Feb  9 17:29:49 2003
+++ b/drivers/block/Kconfig	Thu Feb 20 08:28:56 2003
@@ -6,6 +6,7 @@
 
 config BLK_DEV_FD
 	tristate "Normal floppy disk support"
+	depends on !X86_PC9800
 	---help---
 	  If you want to use the floppy disk drive(s) of your PC under Linux,
 	  say Y. Information about this driver, especially important for IBM
diff -Nru a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
--- a/drivers/block/acsi_slm.c	Mon Nov 11 03:13:19 2002
+++ b/drivers/block/acsi_slm.c	Sat Mar 22 07:38:04 2003
@@ -1006,7 +1006,7 @@
 	BufferP = SLMBuffer;
 	SLMState = IDLE;
 	
-	devfs_mk_dir (NULL, "slm", NULL);
+	devfs_mk_dir("slm");
 	for (i = 0; i < MAX_SLM; i++) {
 		char name[16];
 		sprintf(name, "slm/%d", i);
diff -Nru a/drivers/block/amiflop.c b/drivers/block/amiflop.c
--- a/drivers/block/amiflop.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/block/amiflop.c	Sun Mar 16 04:35:16 2003
@@ -353,10 +353,8 @@
 		unit[nr].motor = 1;
 		fd_select(nr);
 
-		del_timer(&motor_on_timer);
 		motor_on_timer.data = nr;
-		motor_on_timer.expires = jiffies + HZ/2;
-		add_timer(&motor_on_timer);
+		mod_timer(&motor_on_timer, jiffies + HZ/2);
 
 		on_attempts = 10;
 		sleep_on (&motor_wait);
@@ -414,11 +412,9 @@
 	int drive;
 
 	drive = nr & 3;
-	del_timer(motor_off_timer + drive);
-	motor_off_timer[drive].expires = jiffies + 3*HZ;
 	/* called this way it is always from interrupt */
 	motor_off_timer[drive].data = nr | 0x80000000;
-	add_timer(motor_off_timer + nr);
+	mod_timer(motor_off_timer + drive, jiffies + 3*HZ);
 }
 
 static int fd_calibrate(int drive)
@@ -1429,10 +1425,7 @@
 
 			floppy->dirty = 1;
 		        /* reset the timer */
-		        del_timer (flush_track_timer + drive);
-			    
-			flush_track_timer[drive].expires = jiffies + 1;
-			add_timer (flush_track_timer + drive);
+			mod_timer (flush_track_timer + drive, jiffies + 1);
 			local_irq_restore(flags);
 			break;
 		}
diff -Nru a/drivers/block/cciss.c b/drivers/block/cciss.c
--- a/drivers/block/cciss.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/block/cciss.c	Tue Mar 18 14:13:40 2003
@@ -2623,12 +2623,8 @@
 {
 	printk(KERN_INFO DRIVER_NAME "\n");
 
-	/* Register for out PCI devices */
-	if (pci_register_driver(&cciss_pci_driver) > 0 )
-		return 0;
-	else 
-		return -ENODEV;
-
+	/* Register for our PCI devices */
+	return pci_register_driver(&cciss_pci_driver);
 }
 
 static int __init init_cciss_module(void)
diff -Nru a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
--- a/drivers/block/cpqarray.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/block/cpqarray.c	Sat Mar 22 07:38:04 2003
@@ -1679,9 +1679,8 @@
 
 				}
 				if (!disk->de) {
-					char txt[16];
-					sprintf(txt,"ida/c%dd%d",ctlr,log_unit);
-					disk->de = devfs_mk_dir(NULL,txt,NULL);
+					disk->de = devfs_mk_dir("ida/c%dd%d",
+							ctlr, log_unit);
 				}
 				info_p->phys_drives =
 				    sense_config_buf->ctlr_phys_drv;
diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c
--- a/drivers/block/floppy.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/block/floppy.c	Sat Mar 22 07:38:04 2003
@@ -3649,6 +3649,8 @@
 				name = default_drive_params[type].name;
 				allowed_drive_mask |= 1 << drive;
 			}
+			else
+				allowed_drive_mask &= ~(1 << drive);
 		} else {
 			params = &default_drive_params[0].params;
 			sprintf(temparea, "unknown type %d (usb?)", type);
@@ -4231,7 +4233,7 @@
 			goto Enomem;
 	}
 
-	devfs_mk_dir (NULL, "floppy", NULL);
+	devfs_mk_dir ("floppy");
 	if (register_blkdev(FLOPPY_MAJOR,"fd")) {
 		err = -EBUSY;
 		goto out;
diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c
--- a/drivers/block/genhd.c	Mon Mar 10 11:47:07 2003
+++ b/drivers/block/genhd.c	Sat Mar 22 22:14:13 2003
@@ -18,13 +18,19 @@
 
 static struct subsystem block_subsys;
 
-/* Can be merged with blk_probe or deleted altogether. Later. */
+/*
+ * Can be merged with blk_probe or deleted altogether. Later.
+ *
+ * Modified under both block_subsys.rwsem and major_names_lock.
+ */
 static struct blk_major_name {
 	struct blk_major_name *next;
 	int major;
 	char name[16];
 } *major_names[MAX_PROBE_HASH];
 
+static spinlock_t major_names_lock = SPIN_LOCK_UNLOCKED;
+
 static struct blk_probe {
 	struct blk_probe *next;
 	dev_t dev;
@@ -46,23 +52,26 @@
 	return major_to_index(MAJOR(dev));
 }
 
-const char *__bdevname(dev_t dev)
+/*
+ * __bdevname may be called from interrupts, and must be atomic
+ */
+const char *__bdevname(dev_t dev, char *buffer)
 {
-	static char buffer[40];
 	char *name = "unknown-block";
 	unsigned int major = MAJOR(dev);
 	unsigned int minor = MINOR(dev);
 	int index = major_to_index(major);
 	struct blk_major_name *n;
+	unsigned long flags;
 
-	down_read(&block_subsys.rwsem);
+	spin_lock_irqsave(&major_names_lock, flags);
 	for (n = major_names[index]; n; n = n->next)
 		if (n->major == major)
 			break;
 	if (n)
 		name = &(n->name[0]);
-	sprintf(buffer, "%s(%u,%u)", name, major, minor);
-	up_read(&block_subsys.rwsem);
+	snprintf(buffer, BDEVNAME_SIZE, "%s(%u,%u)", name, major, minor);
+	spin_unlock_irqrestore(&major_names_lock, flags);
 
 	return buffer;
 }
@@ -90,26 +99,32 @@
 {
 	struct blk_major_name **n, *p;
 	int index, ret = 0;
+	unsigned long flags;
+
+	down_write(&block_subsys.rwsem);
 
 	/* temporary */
 	if (major == 0) {
-		down_read(&block_subsys.rwsem);
-		for (index = ARRAY_SIZE(major_names)-1; index > 0; index--)
+		for (index = ARRAY_SIZE(major_names)-1; index > 0; index--) {
 			if (major_names[index] == NULL)
 				break;
-		up_read(&block_subsys.rwsem);
+		}
 
 		if (index == 0) {
 			printk("register_blkdev: failed to get major for %s\n",
 			       name);
-			return -EBUSY;
+			ret = -EBUSY;
+			goto out;
 		}
-		ret = major = index;
+		major = index;
+		ret = major;
 	}
 
 	p = kmalloc(sizeof(struct blk_major_name), GFP_KERNEL);
-	if (p == NULL)
-		return -ENOMEM;
+	if (p == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
 
 	p->major = major;
 	strncpy(p->name, name, sizeof(p->name)-1);
@@ -117,31 +132,38 @@
 	p->next = 0;
 	index = major_to_index(major);
 
-	down_write(&block_subsys.rwsem);
-	for (n = &major_names[index]; *n; n = &(*n)->next)
+	spin_lock_irqsave(&major_names_lock, flags);
+	for (n = &major_names[index]; *n; n = &(*n)->next) {
 		if ((*n)->major == major)
 			break;
+	}
 	if (!*n)
 		*n = p;
 	else
 		ret = -EBUSY;
-	up_write(&block_subsys.rwsem);
+	spin_unlock_irqrestore(&major_names_lock, flags);
 
-	if (ret < 0)
+	if (ret < 0) {
 		printk("register_blkdev: cannot get major %d for %s\n",
 		       major, name);
-
+		kfree(p);
+	}
+out:
+	up_write(&block_subsys.rwsem);
 	return ret;
 }
 
 /* todo: make void - error printk here */
 int unregister_blkdev(unsigned int major, const char *name)
 {
-	struct blk_major_name **n, *p;
+	struct blk_major_name **n;
+	struct blk_major_name *p = NULL;
 	int index = major_to_index(major);
+	unsigned long flags;
 	int ret = 0;
 
 	down_write(&block_subsys.rwsem);
+	spin_lock_irqsave(&major_names_lock, flags);
 	for (n = &major_names[index]; *n; n = &(*n)->next)
 		if ((*n)->major == major)
 			break;
@@ -150,9 +172,10 @@
 	else {
 		p = *n;
 		*n = p->next;
-		kfree(p);
 	}
+	spin_unlock_irqrestore(&major_names_lock, flags);
 	up_write(&block_subsys.rwsem);
+	kfree(p);
 
 	return ret;
 }
@@ -538,12 +561,20 @@
 struct gendisk *get_disk(struct gendisk *disk)
 {
 	struct module *owner;
+	struct kobject *kobj;
+
 	if (!disk->fops)
 		return NULL;
 	owner = disk->fops->owner;
 	if (owner && !try_module_get(owner))
 		return NULL;
-	return to_disk(kobject_get(&disk->kobj));
+	kobj = kobject_get(&disk->kobj);
+	if (kobj == NULL) {
+		module_put(owner);
+		return NULL;
+	}
+	return to_disk(kobj);
+
 }
 
 void put_disk(struct gendisk *disk)
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Tue Mar 11 07:04:00 2003
+++ b/drivers/block/ll_rw_blk.c	Sun Mar 23 17:56:03 2003
@@ -26,6 +26,7 @@
 #include <linux/bootmem.h>	/* for max_pfn/max_low_pfn */
 #include <linux/completion.h>
 #include <linux/slab.h>
+#include <linux/swap.h>
 
 static void blk_unplug_work(void *data);
 static void blk_unplug_timeout(unsigned long data);
@@ -56,11 +57,7 @@
 unsigned long blk_max_low_pfn, blk_max_pfn;
 int blk_nohighio = 0;
 
-static struct congestion_state {
-	wait_queue_head_t wqh;
-	atomic_t nr_congested_queues;
-	atomic_t nr_active_queues;
-} congestion_states[2];
+static wait_queue_head_t congestion_wqh[2];
 
 /*
  * Return the threshold (number of free requests) at which the queue is
@@ -98,14 +95,12 @@
 static void clear_queue_congested(request_queue_t *q, int rw)
 {
 	enum bdi_state bit;
-	struct congestion_state *cs = &congestion_states[rw];
+	wait_queue_head_t *wqh = &congestion_wqh[rw];
 
 	bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
-
-	if (test_and_clear_bit(bit, &q->backing_dev_info.state))
-		atomic_dec(&cs->nr_congested_queues);
-	if (waitqueue_active(&cs->wqh))
-		wake_up(&cs->wqh);
+	clear_bit(bit, &q->backing_dev_info.state);
+	if (waitqueue_active(wqh))
+		wake_up(wqh);
 }
 
 /*
@@ -117,37 +112,7 @@
 	enum bdi_state bit;
 
 	bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
-
-	if (!test_and_set_bit(bit, &q->backing_dev_info.state))
-		atomic_inc(&congestion_states[rw].nr_congested_queues);
-}
-
-/*
- * A queue has just put back its last read or write request and has fallen
- * idle.
- */
-static void clear_queue_active(request_queue_t *q, int rw)
-{
-	enum bdi_state bit;
-
-	bit = (rw == WRITE) ? BDI_write_active : BDI_read_active;
-
-	if (test_and_clear_bit(bit, &q->backing_dev_info.state))
-		atomic_dec(&congestion_states[rw].nr_active_queues);
-}
-
-/*
- * A queue has just taken its first read or write request and has become
- * active.
- */
-static void set_queue_active(request_queue_t *q, int rw)
-{
-	enum bdi_state bit;
-
-	bit = (rw == WRITE) ? BDI_write_active : BDI_read_active;
-
-	if (!test_and_set_bit(bit, &q->backing_dev_info.state))
-		atomic_inc(&congestion_states[rw].nr_active_queues);
+	set_bit(bit, &q->backing_dev_info.state);
 }
 
 /**
@@ -236,6 +201,7 @@
 	q->make_request_fn = mfn;
 	q->backing_dev_info.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
 	q->backing_dev_info.state = 0;
+	q->backing_dev_info.memory_backed = 0;
 	blk_queue_max_sectors(q, MAX_SECTORS);
 	blk_queue_hardsect_size(q, 512);
 	blk_queue_dma_alignment(q, 511);
@@ -1325,8 +1291,6 @@
 		rq = blkdev_free_rq(&rl->free);
 		list_del_init(&rq->queuelist);
 		rq->ref_count = 1;
-		if (rl->count == queue_nr_requests)
-			set_queue_active(q, rw);
 		rl->count--;
 		if (rl->count < queue_congestion_on_threshold())
 			set_queue_congested(q, rw);
@@ -1569,8 +1533,6 @@
 		rl->count++;
 		if (rl->count >= queue_congestion_off_threshold())
 			clear_queue_congested(q, rw);
-		if (rl->count == queue_nr_requests)
-			clear_queue_active(q, rw);
 		if (rl->count >= batch_requests && waitqueue_active(&rl->wait))
 			wake_up(&rl->wait);
 	}
@@ -1605,12 +1567,12 @@
 void blk_congestion_wait(int rw, long timeout)
 {
 	DEFINE_WAIT(wait);
-	struct congestion_state *cs = &congestion_states[rw];
+	wait_queue_head_t *wqh = &congestion_wqh[rw];
 
 	blk_run_queues();
-	prepare_to_wait(&cs->wqh, &wait, TASK_UNINTERRUPTIBLE);
+	prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
 	io_schedule_timeout(timeout);
-	finish_wait(&cs->wqh, &wait);
+	finish_wait(wqh, &wait);
 }
 
 /*
@@ -1932,13 +1894,14 @@
 
 		if (maxsector < nr_sectors ||
 		    maxsector - nr_sectors < sector) {
+			char b[BDEVNAME_SIZE];
 			/* This may well happen - the kernel calls
 			 * bread() without checking the size of the
 			 * device, e.g., when mounting a device. */
 			printk(KERN_INFO
 			       "attempt to access beyond end of device\n");
 			printk(KERN_INFO "%s: rw=%ld, want=%Lu, limit=%Lu\n",
-			       bdevname(bio->bi_bdev),
+			       bdevname(bio->bi_bdev, b),
 			       bio->bi_rw,
 			       (unsigned long long) sector + nr_sectors,
 			       (long long) maxsector);
@@ -1957,12 +1920,15 @@
 	 * Stacking drivers are expected to know what they are doing.
 	 */
 	do {
+		char b[BDEVNAME_SIZE];
+
 		q = bdev_get_queue(bio->bi_bdev);
 		if (!q) {
 			printk(KERN_ERR
-			       "generic_make_request: Trying to access nonexistent block-device %s (%Lu)\n",
-			       bdevname(bio->bi_bdev),
-			       (long long) bio->bi_sector);
+			       "generic_make_request: Trying to access "
+				"nonexistent block-device %s (%Lu)\n",
+				bdevname(bio->bi_bdev, b),
+				(long long) bio->bi_sector);
 end_io:
 			bio_endio(bio, bio->bi_size, -EIO);
 			break;
@@ -1970,9 +1936,9 @@
 
 		if (unlikely(bio_sectors(bio) > q->max_sectors)) {
 			printk("bio too big device %s (%u > %u)\n", 
-			       bdevname(bio->bi_bdev),
-			       bio_sectors(bio),
-			       q->max_sectors);
+				bdevname(bio->bi_bdev, b),
+				bio_sectors(bio),
+				q->max_sectors);
 			goto end_io;
 		}
 
@@ -2249,11 +2215,8 @@
 	blk_max_low_pfn = max_low_pfn;
 	blk_max_pfn = max_pfn;
 
-	for (i = 0; i < ARRAY_SIZE(congestion_states); i++) {
-		init_waitqueue_head(&congestion_states[i].wqh);
-		atomic_set(&congestion_states[i].nr_congested_queues, 0);
-		atomic_set(&congestion_states[i].nr_active_queues, 0);
-	}
+	for (i = 0; i < ARRAY_SIZE(congestion_wqh); i++)
+		init_waitqueue_head(&congestion_wqh[i]);
 	return 0;
 };
 
diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c
--- a/drivers/block/loop.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/block/loop.c	Sat Mar 22 07:38:05 2003
@@ -1020,7 +1020,7 @@
 	if (register_blkdev(LOOP_MAJOR, "loop"))
 		return -EIO;
 
-	devfs_mk_dir(NULL, "loop", NULL);
+	devfs_mk_dir("loop");
 
 	loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL);
 	if (!loop_dev)
diff -Nru a/drivers/block/nbd.c b/drivers/block/nbd.c
--- a/drivers/block/nbd.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/block/nbd.c	Sat Mar 22 07:38:04 2003
@@ -76,22 +76,15 @@
 {
 	int uptodate = (req->errors == 0) ? 1 : 0;
 	request_queue_t *q = req->q;
-	struct bio *bio;
-	unsigned nsect;
 	unsigned long flags;
 
 #ifdef PARANOIA
 	requests_out++;
 #endif
 	spin_lock_irqsave(q->queue_lock, flags);
-	while((bio = req->bio) != NULL) {
-		nsect = bio_sectors(bio);
-		blk_finished_io(nsect);
-		req->bio = bio->bi_next;
-		bio->bi_next = NULL;
-		bio_endio(bio, nsect << 9, uptodate ? 0 : -EIO);
+	if (!end_that_request_first(req, uptodate, req->nr_sectors)) {
+		end_that_request_last(req);
 	}
-	blk_put_request(req);
 	spin_unlock_irqrestore(q->queue_lock, flags);
 }
 
@@ -243,7 +236,7 @@
 		req = list_entry(tmp, struct request, queuelist);
 		if (req != xreq)
 			continue;
-		list_del(&req->queuelist);
+		list_del_init(&req->queuelist);
 		spin_unlock(&lo->queue_lock);
 		return req;
 	}
@@ -322,7 +315,7 @@
 		spin_lock(&lo->queue_lock);
 		if (!list_empty(&lo->queue_head)) {
 			req = list_entry(lo->queue_head.next, struct request, queuelist);
-			list_del(&req->queuelist);
+			list_del_init(&req->queuelist);
 		}
 		spin_unlock(&lo->queue_lock);
 		if (req) {
@@ -387,7 +380,7 @@
 		if (req->errors) {
 			printk(KERN_ERR "nbd: nbd_send_req failed\n");
 			spin_lock(&lo->queue_lock);
-			list_del(&req->queuelist);
+			list_del_init(&req->queuelist);
 			spin_unlock(&lo->queue_lock);
 			nbd_end_request(req);
 			spin_lock_irq(q->queue_lock);
@@ -572,7 +565,7 @@
 	printk("nbd: registered device at major %d\n", NBD_MAJOR);
 #endif
 	blk_init_queue(&nbd_queue, do_nbd_request, &nbd_lock);
-	devfs_mk_dir (NULL, "nbd", NULL);
+	devfs_mk_dir("nbd");
 	for (i = 0; i < MAX_NBD; i++) {
 		struct gendisk *disk = nbd_dev[i].disk;
 		char name[16];
@@ -590,6 +583,7 @@
 		disk->first_minor = i;
 		disk->fops = &nbd_fops;
 		disk->private_data = &nbd_dev[i];
+		disk->queue = &nbd_queue;
 		sprintf(disk->disk_name, "nbd%d", i);
 		set_capacity(disk, 0x3ffffe);
 		add_disk(disk);
diff -Nru a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
--- a/drivers/block/paride/pg.c	Tue Dec  3 09:46:30 2002
+++ b/drivers/block/paride/pg.c	Sat Mar 22 07:38:05 2003
@@ -642,7 +642,7 @@
 		  if (PG.present) pi_release(PI);
 		return -1;
 	}
-	devfs_mk_dir (NULL, "pg", NULL);
+	devfs_mk_dir ("pg");
 	for (unit=0; unit<PG_UNITS; unit++)
 		if (PG.present) {
 			char name[16];
diff -Nru a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
--- a/drivers/block/paride/pt.c	Tue Dec  3 09:46:30 2002
+++ b/drivers/block/paride/pt.c	Sat Mar 22 07:38:04 2003
@@ -913,7 +913,7 @@
 		return -1;
 	}
 
-	devfs_mk_dir (NULL, "pt", NULL);
+	devfs_mk_dir ("pt");
 	for (unit=0;unit<PT_UNITS;unit++)
 		if (PT.present) {
 			char name[16];
diff -Nru a/drivers/block/rd.c b/drivers/block/rd.c
--- a/drivers/block/rd.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/block/rd.c	Sat Mar 22 07:38:05 2003
@@ -416,7 +416,7 @@
 
 	blk_queue_make_request(&rd_queue, &rd_make_request);
 
-	devfs_mk_dir (NULL, "rd", NULL);
+	devfs_mk_dir("rd");
 
 	for (i = 0; i < NUM_RAMDISKS; i++) {
 		struct gendisk *disk = rd_disks[i];
diff -Nru a/drivers/block/swim3.c b/drivers/block/swim3.c
--- a/drivers/block/swim3.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/block/swim3.c	Sat Mar 22 09:04:07 2003
@@ -979,7 +979,7 @@
 	int err = -ENOMEM;
 	int i;
 
-	floppy_devfs_handle = devfs_mk_dir(NULL, "floppy", NULL);
+	floppy_devfs_handle = devfs_mk_dir("floppy");
 
 	swim = find_devices("floppy");
 	while (swim && (floppy_count < MAX_FLOPPIES))
@@ -1095,9 +1095,9 @@
 
 	printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count,
 		mediabay ? "in media bay" : "");
-	sprintf(floppy_name, "%s%d", floppy_devfs_handle ? "" : "floppy",
-			floppy_count);
-	floppy_handle = devfs_register(floppy_devfs_handle, floppy_name, 
+
+	sprintf(floppy_name, "floppy/%d", floppy_count);
+	floppy_handle = devfs_register(NULL, floppy_name, 
 			DEVFS_FL_DEFAULT, FLOPPY_MAJOR, floppy_count, 
 			S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP |S_IWGRP, 
 			&floppy_fops, NULL);
diff -Nru a/drivers/block/umem.c b/drivers/block/umem.c
--- a/drivers/block/umem.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/block/umem.c	Sat Mar 22 07:38:05 2003
@@ -1154,7 +1154,8 @@
 		if (!mm_gendisk[i])
 			goto out;
 	}
-	devfs_mk_dir(NULL, "umem", NULL);
+
+	devfs_mk_dir("umem");
 
 	for (i = 0; i < num_cards; i++) {
 		struct gendisk *disk = mm_gendisk[i];
diff -Nru a/drivers/block/xd.c b/drivers/block/xd.c
--- a/drivers/block/xd.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/block/xd.c	Sat Mar 22 07:38:05 2003
@@ -173,7 +173,7 @@
 	if (register_blkdev(XT_DISK_MAJOR, "xd"))
 		goto out1;
 
-	devfs_mk_dir(NULL, "xd", NULL);
+	devfs_mk_dir("xd");
 	blk_init_queue(&xd_queue, do_xd_request, &xd_lock);
 	if (xd_detect(&controller,&address)) {
 
diff -Nru a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
--- a/drivers/cdrom/cdrom.c	Sun Mar  2 23:30:08 2003
+++ b/drivers/cdrom/cdrom.c	Wed Mar 19 01:53:58 2003
@@ -1125,7 +1125,7 @@
 
 static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s)
 {
-	unsigned char buf[20], *base;
+	unsigned char buf[21], *base;
 	struct dvd_layer *layer;
 	struct cdrom_generic_command cgc;
 	struct cdrom_device_ops *cdo = cdi->ops;
diff -Nru a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
--- a/drivers/cdrom/cdu31a.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/cdrom/cdu31a.c	Tue Mar 18 12:15:50 2003
@@ -1375,9 +1375,9 @@
 			       readahead_buffer + (2048 -
 						   readahead_dataleft),
 			       readahead_dataleft);
-			readahead_dataleft = 0;
 			bytesleft -= readahead_dataleft;
 			offset += readahead_dataleft;
+			readahead_dataleft = 0;
 		} else {
 			/* The readahead will fill the whole buffer, get the data
 			   and return. */
diff -Nru a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c
--- a/drivers/cdrom/optcd.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/cdrom/optcd.c	Fri Mar 21 14:30:08 2003
@@ -1600,13 +1600,17 @@
 
 static int cdromread(unsigned long arg, int blocksize, int cmd)
 {
-	int status;
+	int status, ret = 0;
 	struct cdrom_msf msf;
-	char buf[CD_FRAMESIZE_RAWER];
+	char *buf;
 
 	if (copy_from_user(&msf, (void *) arg, sizeof msf))
 		return -EFAULT;
 
+	buf = kmalloc(CD_FRAMESIZE_RAWER, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
 	bin2bcd(&msf);
 	msf.cdmsf_min1 = 0;
 	msf.cdmsf_sec1 = 0;
@@ -1615,11 +1619,19 @@
 
 	DEBUG((DEBUG_VFS, "read cmd status 0x%x", status));
 
-	if (!sleep_flag_low(FL_DTEN, SLEEP_TIMEOUT))
-		return -EIO;
+	if (!sleep_flag_low(FL_DTEN, SLEEP_TIMEOUT)) {
+		ret = -EIO;
+		goto cdr_free;
+	}
+
 	fetch_data(buf, blocksize);
 
-	return copy_to_user((void *)arg, &buf, blocksize) ? -EFAULT : 0;
+	if (copy_to_user((void *)arg, &buf, blocksize))
+		ret = -EFAULT;
+
+cdr_free:
+	kfree(buf);
+	return ret;
 }
 
 
diff -Nru a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
--- a/drivers/cdrom/sbpcd.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/cdrom/sbpcd.c	Sat Mar 22 07:38:04 2003
@@ -5805,7 +5805,7 @@
 
 	blk_init_queue(&sbpcd_queue, do_sbpcd_request, &sbpcd_lock);
 
-	devfs_mk_dir (NULL, "sbp", NULL);
+	devfs_mk_dir("sbp");
 
 	for (j=0;j<NR_SBPCD;j++)
 	{
diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile	Thu Mar 13 15:24:01 2003
+++ b/drivers/char/Makefile	Tue Mar 18 08:57:58 2003
@@ -44,6 +44,7 @@
 
 obj-$(CONFIG_PRINTER) += lp.o
 obj-$(CONFIG_TIPAR) += tipar.o
+obj-$(CONFIG_PC9800_OLDLP) += lp_old98.o
 
 obj-$(CONFIG_BUSMOUSE) += busmouse.o
 obj-$(CONFIG_DTLK) += dtlk.o
diff -Nru a/drivers/char/amiserial.c b/drivers/char/amiserial.c
--- a/drivers/char/amiserial.c	Mon Mar  3 12:04:08 2003
+++ b/drivers/char/amiserial.c	Tue Mar 18 07:40:48 2003
@@ -102,8 +102,6 @@
 
 static char *serial_name = "Amiga-builtin serial driver";
 
-static DECLARE_TASK_QUEUE(tq_serial);
-
 static struct tty_driver serial_driver, callout_driver;
 static int serial_refcount;
 
@@ -276,8 +274,7 @@
 				  int event)
 {
 	info->event |= 1 << event;
-	queue_task(&info->tqueue, &tq_serial);
-	mark_bh(SERIAL_BH);
+	tasklet_schedule(&info->tlet);
 }
 
 static _INLINE_ void receive_chars(struct async_struct *info)
@@ -560,12 +557,8 @@
  * 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_)
+static void do_softint(unsigned long private_)
 {
 	struct async_struct	*info = (struct async_struct *) private_;
 	struct tty_struct	*tty;
@@ -1878,8 +1871,7 @@
 	info->flags = sstate->flags;
 	info->xmit_fifo_size = sstate->xmit_fifo_size;
 	info->line = line;
-	info->tqueue.routine = do_softint;
-	info->tqueue.data = info;
+	tasklet_init(&info->tlet, do_softint, (unsigned long)info);
 	info->state = sstate;
 	if (sstate->info) {
 		kfree(info);
@@ -2117,8 +2109,6 @@
 	if (!request_mem_region(CUSTOM_PHYSADDR+0x30, 4, "amiserial [Paula]"))
 		return -EBUSY;
 
-	init_bh(SERIAL_BH, do_serial_bh);
-
 	IRQ_ports = NULL;
 
 	show_serial_version();
@@ -2234,23 +2224,18 @@
 
 static __exit void rs_exit(void) 
 {
-	unsigned long flags;
 	int e1, e2;
-	struct async_struct *info;
+	struct async_struct *info = rs_table[0].info;
 
 	/* printk("Unloading %s: version %s\n", serial_name, serial_version); */
-	save_flags(flags);
-	cli();
-        remove_bh(SERIAL_BH);
+	tasklet_kill(&info->tlet);
 	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);
 
-	info = rs_table[0].info;
 	if (info) {
 	  rs_table[0].info = NULL;
 	  kfree(info);
@@ -2320,9 +2305,10 @@
 /*
  *	Register console.
  */
-static void __init amiserial_console_init(void)
+static int __init amiserial_console_init(void)
 {
 	register_console(&sercons);
+	return 0;
 }
 console_initcall(amiserial_console_init);
 #endif
diff -Nru a/drivers/char/console_macros.h b/drivers/char/console_macros.h
--- a/drivers/char/console_macros.h	Tue Feb  5 09:40:05 2002
+++ b/drivers/char/console_macros.h	Thu Mar 20 06:36:40 2003
@@ -1,4 +1,5 @@
 #define cons_num	(vc_cons[currcons].d->vc_num)
+#define video_scan_lines (vc_cons[currcons].d->vc_scan_lines)
 #define sw		(vc_cons[currcons].d->vc_sw)
 #define screenbuf	(vc_cons[currcons].d->vc_screenbuf)
 #define screenbuf_size	(vc_cons[currcons].d->vc_screenbuf_size)
diff -Nru a/drivers/char/decserial.c b/drivers/char/decserial.c
--- a/drivers/char/decserial.c	Fri Feb 14 15:14:03 2003
+++ b/drivers/char/decserial.c	Tue Mar 18 07:43:01 2003
@@ -75,7 +75,7 @@
 /* serial_console_init handles the special case of starting
  *   up the console on the serial port
  */
-static void __init decserial_console_init(void)
+static int __init decserial_console_init(void)
 {
 #if defined(CONFIG_ZS) && defined(CONFIG_DZ)
     if (IOASIC)
@@ -93,6 +93,7 @@
 #endif
 
 #endif
+    return 0;
 }
 console_initcall(decserial_console_init);
 
diff -Nru a/drivers/char/drm/ati_pcigart.h b/drivers/char/drm/ati_pcigart.h
--- a/drivers/char/drm/ati_pcigart.h	Tue Oct 29 14:29:19 2002
+++ b/drivers/char/drm/ati_pcigart.h	Thu Mar 13 16:52:15 2003
@@ -27,7 +27,6 @@
  *   Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 
 #if PAGE_SIZE == 65536
diff -Nru a/drivers/char/drm/drm_agpsupport.h b/drivers/char/drm/drm_agpsupport.h
--- a/drivers/char/drm/drm_agpsupport.h	Wed Dec 18 09:56:28 2002
+++ b/drivers/char/drm/drm_agpsupport.h	Thu Mar 13 16:52:15 2003
@@ -29,7 +29,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 #include <linux/module.h>
 
diff -Nru a/drivers/char/drm/drm_auth.h b/drivers/char/drm/drm_auth.h
--- a/drivers/char/drm/drm_auth.h	Tue Oct 29 14:29:19 2002
+++ b/drivers/char/drm/drm_auth.h	Thu Mar 13 16:52:15 2003
@@ -29,7 +29,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 
 static int DRM(hash_magic)(drm_magic_t magic)
diff -Nru a/drivers/char/drm/drm_bufs.h b/drivers/char/drm/drm_bufs.h
--- a/drivers/char/drm/drm_bufs.h	Tue Oct 29 14:29:19 2002
+++ b/drivers/char/drm/drm_bufs.h	Thu Mar 13 16:52:15 2003
@@ -29,7 +29,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include <linux/vmalloc.h>
 #include "drmP.h"
 
diff -Nru a/drivers/char/drm/drm_context.h b/drivers/char/drm/drm_context.h
--- a/drivers/char/drm/drm_context.h	Tue Oct 29 14:29:19 2002
+++ b/drivers/char/drm/drm_context.h	Thu Mar 13 16:52:15 2003
@@ -33,7 +33,6 @@
  *		needed by SiS driver's memory management.
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 
 #if __HAVE_CTX_BITMAP
diff -Nru a/drivers/char/drm/drm_dma.h b/drivers/char/drm/drm_dma.h
--- a/drivers/char/drm/drm_dma.h	Wed Dec 18 09:56:28 2002
+++ b/drivers/char/drm/drm_dma.h	Thu Mar 13 16:52:15 2003
@@ -29,7 +29,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 
 #include <linux/interrupt.h>	/* For task queue support */
diff -Nru a/drivers/char/drm/drm_drawable.h b/drivers/char/drm/drm_drawable.h
--- a/drivers/char/drm/drm_drawable.h	Tue Oct 29 14:29:20 2002
+++ b/drivers/char/drm/drm_drawable.h	Thu Mar 13 16:52:15 2003
@@ -29,7 +29,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 
 int DRM(adddraw)(struct inode *inode, struct file *filp,
diff -Nru a/drivers/char/drm/drm_fops.h b/drivers/char/drm/drm_fops.h
--- a/drivers/char/drm/drm_fops.h	Tue Oct 29 14:29:20 2002
+++ b/drivers/char/drm/drm_fops.h	Thu Mar 13 16:52:15 2003
@@ -30,7 +30,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 #include <linux/poll.h>
 
diff -Nru a/drivers/char/drm/drm_init.h b/drivers/char/drm/drm_init.h
--- a/drivers/char/drm/drm_init.h	Tue Oct 29 14:29:20 2002
+++ b/drivers/char/drm/drm_init.h	Thu Mar 13 16:52:15 2003
@@ -29,7 +29,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 
 #if 0
diff -Nru a/drivers/char/drm/drm_ioctl.h b/drivers/char/drm/drm_ioctl.h
--- a/drivers/char/drm/drm_ioctl.h	Tue Oct 29 14:29:20 2002
+++ b/drivers/char/drm/drm_ioctl.h	Thu Mar 13 16:52:15 2003
@@ -29,7 +29,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 
 
diff -Nru a/drivers/char/drm/drm_lists.h b/drivers/char/drm/drm_lists.h
--- a/drivers/char/drm/drm_lists.h	Tue Oct 29 14:29:20 2002
+++ b/drivers/char/drm/drm_lists.h	Thu Mar 13 16:52:15 2003
@@ -29,7 +29,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 
 #if __HAVE_DMA_WAITLIST
diff -Nru a/drivers/char/drm/drm_lock.h b/drivers/char/drm/drm_lock.h
--- a/drivers/char/drm/drm_lock.h	Tue Oct 29 14:29:20 2002
+++ b/drivers/char/drm/drm_lock.h	Thu Mar 13 16:52:15 2003
@@ -29,7 +29,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 
 int DRM(block)(struct inode *inode, struct file *filp, unsigned int cmd,
diff -Nru a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h
--- a/drivers/char/drm/drm_memory.h	Tue Oct 29 14:29:20 2002
+++ b/drivers/char/drm/drm_memory.h	Thu Mar 13 16:52:15 2003
@@ -29,7 +29,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include <linux/config.h>
 #include "drmP.h"
 #include <linux/wrapper.h>
diff -Nru a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
--- a/drivers/char/drm/drm_os_linux.h	Tue Oct 29 14:29:20 2002
+++ b/drivers/char/drm/drm_os_linux.h	Thu Mar 13 16:52:15 2003
@@ -1,4 +1,3 @@
-#define __NO_VERSION__
 
 #include <linux/interrupt.h>	/* For task queue support */
 #include <linux/delay.h>
diff -Nru a/drivers/char/drm/drm_proc.h b/drivers/char/drm/drm_proc.h
--- a/drivers/char/drm/drm_proc.h	Tue Oct 29 14:29:20 2002
+++ b/drivers/char/drm/drm_proc.h	Thu Mar 13 16:52:15 2003
@@ -33,7 +33,6 @@
  *    the problem with the proc files not outputting all their information.
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 
 static int	   DRM(name_info)(char *buf, char **start, off_t offset,
diff -Nru a/drivers/char/drm/drm_scatter.h b/drivers/char/drm/drm_scatter.h
--- a/drivers/char/drm/drm_scatter.h	Tue Oct 29 14:29:20 2002
+++ b/drivers/char/drm/drm_scatter.h	Thu Mar 13 16:52:15 2003
@@ -27,7 +27,6 @@
  *   Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include <linux/config.h>
 #include <linux/vmalloc.h>
 #include "drmP.h"
diff -Nru a/drivers/char/drm/drm_stub.h b/drivers/char/drm/drm_stub.h
--- a/drivers/char/drm/drm_stub.h	Tue Oct 29 14:29:20 2002
+++ b/drivers/char/drm/drm_stub.h	Thu Mar 13 16:52:15 2003
@@ -28,7 +28,6 @@
  *
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 
 #define DRM_STUB_MAXCARDS 16	/* Enough for one machine */
diff -Nru a/drivers/char/drm/drm_vm.h b/drivers/char/drm/drm_vm.h
--- a/drivers/char/drm/drm_vm.h	Tue Feb 25 11:05:27 2003
+++ b/drivers/char/drm/drm_vm.h	Thu Mar 13 16:52:15 2003
@@ -29,7 +29,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "drmP.h"
 
 struct vm_operations_struct   DRM(vm_ops) = {
diff -Nru a/drivers/char/drm/gamma_dma.c b/drivers/char/drm/gamma_dma.c
--- a/drivers/char/drm/gamma_dma.c	Tue Oct 29 14:29:20 2002
+++ b/drivers/char/drm/gamma_dma.c	Thu Mar 13 16:52:15 2003
@@ -29,7 +29,6 @@
  *
  */
 
-#define __NO_VERSION__
 #include "gamma.h"
 #include "drmP.h"
 #include "drm.h"
diff -Nru a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
--- a/drivers/char/drm/i810_dma.c	Sat Nov 16 17:33:53 2002
+++ b/drivers/char/drm/i810_dma.c	Thu Mar 13 16:52:15 2003
@@ -30,7 +30,6 @@
  *
  */
 
-#define __NO_VERSION__
 #include "i810.h"
 #include "drmP.h"
 #include "drm.h"
diff -Nru a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
--- a/drivers/char/drm/i830_dma.c	Thu Feb  6 07:33:47 2003
+++ b/drivers/char/drm/i830_dma.c	Thu Mar 13 16:52:15 2003
@@ -31,7 +31,6 @@
  *
  */
 
-#define __NO_VERSION__
 #include "i830.h"
 #include "drmP.h"
 #include "drm.h"
@@ -40,12 +39,6 @@
 #include <linux/interrupt.h>	/* For task queue support */
 #include <linux/delay.h>
 
-#ifdef DO_MUNMAP_4_ARGS
-#define DO_MUNMAP(m, a, l)	do_munmap(m, a, l, 1)
-#else
-#define DO_MUNMAP(m, a, l)	do_munmap(m, a, l)
-#endif
-
 #define I830_BUF_FREE		2
 #define I830_BUF_CLIENT		1
 #define I830_BUF_HARDWARE      	0
@@ -230,7 +223,7 @@
 		return -EINVAL;
 
 	down_write(&current->mm->mmap_sem);
-	retcode = DO_MUNMAP(current->mm,
+	retcode = do_munmap(current->mm,
 			    (unsigned long)buf_priv->virtual,
 			    (size_t) buf->total);
 	up_write(&current->mm->mmap_sem);
diff -Nru a/drivers/char/drm/mga_warp.c b/drivers/char/drm/mga_warp.c
--- a/drivers/char/drm/mga_warp.c	Tue Oct 29 14:29:21 2002
+++ b/drivers/char/drm/mga_warp.c	Thu Mar 13 16:52:15 2003
@@ -27,7 +27,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "mga.h"
 #include "drmP.h"
 #include "drm.h"
diff -Nru a/drivers/char/drm/sis_ds.c b/drivers/char/drm/sis_ds.c
--- a/drivers/char/drm/sis_ds.c	Tue Oct 29 14:29:24 2002
+++ b/drivers/char/drm/sis_ds.c	Thu Mar 13 16:52:15 2003
@@ -28,7 +28,6 @@
  * 
  */
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
diff -Nru a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
--- a/drivers/char/drm/sis_mm.c	Tue Oct 29 14:29:24 2002
+++ b/drivers/char/drm/sis_mm.c	Thu Mar 13 16:52:15 2003
@@ -28,7 +28,6 @@
  * 
  */
 
-#define __NO_VERSION__
 #include "sis.h"
 #include <linux/sisfb.h>
 #include "drmP.h"
diff -Nru a/drivers/char/ftape/lowlevel/ftape_syms.c b/drivers/char/ftape/lowlevel/ftape_syms.c
--- a/drivers/char/ftape/lowlevel/ftape_syms.c	Tue Feb 25 10:47:06 2003
+++ b/drivers/char/ftape/lowlevel/ftape_syms.c	Thu Mar 13 16:52:15 2003
@@ -26,7 +26,6 @@
  */
 
 #include <linux/config.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 
 #include <linux/ftape.h>
diff -Nru a/drivers/char/ftape/zftape/zftape-ctl.c b/drivers/char/ftape/zftape/zftape-ctl.c
--- a/drivers/char/ftape/zftape/zftape-ctl.c	Tue Feb 18 10:25:13 2003
+++ b/drivers/char/ftape/zftape/zftape-ctl.c	Thu Mar 13 16:52:15 2003
@@ -27,7 +27,6 @@
 #include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/fcntl.h>
 
diff -Nru a/drivers/char/ftape/zftape/zftape_syms.c b/drivers/char/ftape/zftape/zftape_syms.c
--- a/drivers/char/ftape/zftape/zftape_syms.c	Wed Sep 11 01:38:06 2002
+++ b/drivers/char/ftape/zftape/zftape_syms.c	Thu Mar 13 16:52:15 2003
@@ -24,7 +24,6 @@
  *      the ftape floppy tape driver exports 
  */		 
 
-#define __NO_VERSION__
 #include <linux/module.h>
 
 #include <linux/zftape.h>
diff -Nru a/drivers/char/genrtc.c b/drivers/char/genrtc.c
--- a/drivers/char/genrtc.c	Wed Feb 19 12:19:16 2003
+++ b/drivers/char/genrtc.c	Sun Mar  2 08:34:59 2003
@@ -1,5 +1,8 @@
 /*
- *	Real Time Clock interface for q40 and other m68k machines
+ *	Real Time Clock interface for
+ *		- q40 and other m68k machines,
+ *		- HP PARISC machines
+ *		- PowerPC machines
  *      emulate some RTC irq capabilities in software
  *
  *      Copyright (C) 1999 Richard Zidlicky
@@ -13,7 +16,7 @@
  *	pseudo-file for status information.
  *
  *	The ioctls can be used to set the interrupt behaviour where
- *  supported.
+ *	supported.
  *
  *	The /dev/rtc interface will block on reads until an interrupt
  *	has been received. If a RTC interrupt has already happened,
@@ -34,9 +37,10 @@
  *      1.04 removed useless timer code       rz@linux-m68k.org
  *      1.05 portable RTC_UIE emulation       rz@linux-m68k.org
  *      1.06 set_rtc_time can return an error trini@kernel.crashing.org
+ *      1.07 ported to HP PARISC (hppa)	      Helge Deller <deller@gmx.de>
  */
 
-#define RTC_VERSION	"1.06"
+#define RTC_VERSION	"1.07"
 
 #include <linux/module.h>
 #include <linux/config.h>
@@ -63,20 +67,17 @@
 
 static DECLARE_WAIT_QUEUE_HEAD(gen_rtc_wait);
 
-static int gen_rtc_ioctl(struct inode *inode, struct file *file,
-		     unsigned int cmd, unsigned long arg);
-
 /*
  *	Bits in gen_rtc_status.
  */
 
 #define RTC_IS_OPEN		0x01	/* means /dev/rtc is in use	*/
 
-unsigned char gen_rtc_status;		/* bitmapped status byte.	*/
-unsigned long gen_rtc_irq_data;		/* our output to the world	*/
+static unsigned char gen_rtc_status;	/* bitmapped status byte.	*/
+static unsigned long gen_rtc_irq_data;	/* our output to the world	*/
 
 /* months start at 0 now */
-unsigned char days_in_mo[] =
+static unsigned char days_in_mo[] =
 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
 static int irq_active;
@@ -89,18 +90,20 @@
 static int lostint;
 static int tt_exp;
 
-void gen_rtc_timer(unsigned long data);
+static void gen_rtc_timer(unsigned long data);
 
 static volatile int stask_active;              /* schedule_work */
 static volatile int ttask_active;              /* timer_task */
 static int stop_rtc_timers;                    /* don't requeue tasks */
 static spinlock_t gen_rtc_lock = SPIN_LOCK_UNLOCKED;
 
+static void gen_rtc_interrupt(unsigned long arg);
+
 /*
  * Routine to poll RTC seconds field for change as often as possible,
  * after first RTC_UIE use timer to reduce polling
  */
-void genrtc_troutine(void *data)
+static void genrtc_troutine(void *data)
 {
 	unsigned int tmp = get_rtc_ss();
 	
@@ -124,7 +127,7 @@
 		stask_active = 0;
 }
 
-void gen_rtc_timer(unsigned long data)
+static void gen_rtc_timer(unsigned long data)
 {
 	lostint = get_rtc_ss() - oldsecs ;
 	if (lostint<0) 
@@ -145,7 +148,7 @@
  * from some routine that periodically (eg 100HZ) monitors
  * whether RTC_SECS changed
  */
-void gen_rtc_interrupt(unsigned long arg)
+static void gen_rtc_interrupt(unsigned long arg)
 {
 	/*  We store the status in the low byte and the number of
 	 *	interrupts received since the last read in the remainder
@@ -175,7 +178,7 @@
 	unsigned long data;
 	ssize_t retval;
 
-        if (count != sizeof (unsigned int) && count != sizeof (unsigned long))
+	if (count != sizeof (unsigned int) && count != sizeof (unsigned long))
 		return -EINVAL;
 
 	if (file->f_flags & O_NONBLOCK && !gen_rtc_irq_data)
@@ -385,24 +388,24 @@
  */
 
 static struct file_operations gen_rtc_fops = {
-	.owner =	THIS_MODULE,
+	.owner		= THIS_MODULE,
 #ifdef CONFIG_GEN_RTC_X
-	.read =		gen_rtc_read,
-	.poll =		gen_rtc_poll,
+	.read		= gen_rtc_read,
+	.poll		= gen_rtc_poll,
 #endif
-	.ioctl =	gen_rtc_ioctl,
-	.open =		gen_rtc_open,
-	.release =	gen_rtc_release
+	.ioctl		= gen_rtc_ioctl,
+	.open		= gen_rtc_open,
+	.release	= gen_rtc_release,
 };
 
 static struct miscdevice rtc_gen_dev =
 {
-	RTC_MINOR,
-	"rtc",
-	&gen_rtc_fops
+	.minor		= RTC_MINOR,
+	.name		= "rtc",
+	.fops		= &gen_rtc_fops,
 };
 
-int __init rtc_generic_init(void)
+static int __init rtc_generic_init(void)
 {
 	int retval;
 
@@ -436,16 +439,18 @@
  *	Info exported via "/proc/rtc".
  */
 
-int gen_rtc_proc_output(char *buf)
+#ifdef CONFIG_PROC_FS
+
+static int gen_rtc_proc_output(char *buf)
 {
 	char *p;
 	struct rtc_time tm;
-	unsigned tmp;
+	unsigned int flags;
 	struct rtc_pll_info pll;
 
 	p = buf;
 
-	get_rtc_time(&tm);
+	flags = get_rtc_time(&tm);
 
 	p += sprintf(p,
 		     "rtc_time\t: %02d:%02d:%02d\n"
@@ -454,7 +459,7 @@
 		     tm.tm_hour, tm.tm_min, tm.tm_sec,
 		     tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 1900);
 
-	tm.tm_hour=0;tm.tm_min=0;tm.tm_sec=0;
+	tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
 
 	p += sprintf(p, "alarm\t\t: ");
 	if (tm.tm_hour <= 24)
@@ -472,7 +477,6 @@
 	else
 		p += sprintf(p, "**\n");
 
-	tmp= RTC_24H ;
 	p += sprintf(p,
 		     "DST_enable\t: %s\n"
 		     "BCD\t\t: %s\n"
@@ -483,15 +487,15 @@
 		     "periodic_IRQ\t: %s\n"
 		     "periodic_freq\t: %ld\n"
 		     "batt_status\t: %s\n",
-		     (tmp & RTC_DST_EN) ? "yes" : "no",
-		     (tmp & RTC_DM_BINARY) ? "no" : "yes",
-		     (tmp & RTC_24H) ? "yes" : "no",
-		     (tmp & RTC_SQWE) ? "yes" : "no",
-		     (tmp & RTC_AIE) ? "yes" : "no",
+		     (flags & RTC_DST_EN) ? "yes" : "no",
+		     (flags & RTC_DM_BINARY) ? "no" : "yes",
+		     (flags & RTC_24H) ? "yes" : "no",
+		     (flags & RTC_SQWE) ? "yes" : "no",
+		     (flags & RTC_AIE) ? "yes" : "no",
 		     irq_active ? "yes" : "no",
-		     (tmp & RTC_PIE) ? "yes" : "no",
+		     (flags & RTC_PIE) ? "yes" : "no",
 		     0L /* freq */,
-		     "okay" );
+		     (flags & RTC_BATT_BAD) ? "bad" : "okay");
 	if (!get_rtc_pll(&pll))
 	    p += sprintf(p,
 			 "PLL adjustment\t: %d\n"
@@ -506,7 +510,7 @@
 			 pll.pll_posmult,
 			 pll.pll_negmult,
 			 pll.pll_clock);
-	return  p - buf;
+	return p - buf;
 }
 
 static int gen_rtc_read_proc(char *page, char **start, off_t off,
@@ -521,6 +525,9 @@
 	return len;
 }
 
+#endif /* CONFIG_PROC_FS */
+
 
 MODULE_AUTHOR("Richard Zidlicky");
 MODULE_LICENSE("GPL");
+
diff -Nru a/drivers/char/ip2/ip2.h b/drivers/char/ip2/ip2.h
--- a/drivers/char/ip2/ip2.h	Mon Feb  4 23:53:43 2002
+++ b/drivers/char/ip2/ip2.h	Sat Mar 22 22:14:19 2003
@@ -23,21 +23,10 @@
 /* Constants */
 /*************/
 
-/* Device major numbers
- * The first set are the major numbers allocated from the Linux Device Registry.
- * This was expanded from 64 to 128 with version 2.0.26. If this code is built
- * under earlier versions we use majors from the LOCAL/EXPERIMENTAL range.
- */
-#if MAX_CHRDEV > 64
-#	define IP2_TTY_MAJOR      71
-#	define IP2_CALLOUT_MAJOR  72
-#	define IP2_IPL_MAJOR      73
-#else
-#	define IP2_TTY_MAJOR      60
-#	define IP2_CALLOUT_MAJOR  61
-#	define IP2_IPL_MAJOR      62
-#endif
-
+/* Device major numbers - since version 2.0.26. */
+#define IP2_TTY_MAJOR      71
+#define IP2_CALLOUT_MAJOR  72
+#define IP2_IPL_MAJOR      73
 
 /* Board configuration array.
  * This array defines the hardware irq and address for up to IP2_MAX_BOARDS
diff -Nru a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
--- a/drivers/char/ipmi/ipmi_devintf.c	Tue Nov 26 14:06:25 2002
+++ b/drivers/char/ipmi/ipmi_devintf.c	Sat Mar 22 09:04:18 2003
@@ -105,7 +105,7 @@
 
 static struct ipmi_user_hndl ipmi_hndlrs =
 {
-	ipmi_recv_hndl : file_receive_handler
+	.ipmi_recv_hndl	= file_receive_handler,
 };
 
 static int ipmi_open(struct inode *inode, struct file *file)
@@ -424,12 +424,12 @@
 
 
 static struct file_operations ipmi_fops = {
-	owner:   THIS_MODULE,
-	ioctl:   ipmi_ioctl,
-	open:    ipmi_open,
-	release: ipmi_release,
-	fasync:  ipmi_fasync,
-	poll:    ipmi_poll
+	.owner		= THIS_MODULE,
+	.ioctl		= ipmi_ioctl,
+	.open		= ipmi_open,
+	.release	= ipmi_release,
+	.fasync		= ipmi_fasync,
+	.poll		= ipmi_poll,
 };
 
 #define DEVICE_NAME     "ipmidev"
@@ -444,15 +444,14 @@
 
 static void ipmi_new_smi(int if_num)
 {
-	char name[2];
+	char name[10];
 
 	if (if_num > MAX_DEVICES)
 		return;
 
-	name[0] = if_num + '0';
-	name[1] = '\0';
+	snprinf(name, sizeof(name), "ipmidev/%d", if_num);
 
-	handles[if_num] = devfs_register(devfs_handle, name, DEVFS_FL_NONE,
+	handles[if_num] = devfs_register(NULL, name, DEVFS_FL_NONE,
 					 ipmi_major, if_num,
 					 S_IFCHR | S_IRUSR | S_IWUSR,
 					 &ipmi_fops, NULL);
@@ -468,8 +467,8 @@
 
 static struct ipmi_smi_watcher smi_watcher =
 {
-	new_smi  : ipmi_new_smi,
-	smi_gone : ipmi_smi_gone
+	.new_smi	= ipmi_new_smi,
+	.smi_gone	= ipmi_smi_gone,
 };
 
 static __init int init_ipmi_devintf(void)
@@ -489,7 +488,7 @@
 		ipmi_major = rv;
 	}
 
-	devfs_handle = devfs_mk_dir(NULL, DEVICE_NAME, NULL);
+	devfs_handle = devfs_mk_dir(DEVICE_NAME);
 
 	rv = ipmi_smi_watcher_register(&smi_watcher);
 	if (rv) {
diff -Nru a/drivers/char/istallion.c b/drivers/char/istallion.c
--- a/drivers/char/istallion.c	Sat Dec  7 17:41:45 2002
+++ b/drivers/char/istallion.c	Sat Mar 22 07:38:05 2003
@@ -5334,7 +5334,7 @@
 		printk(KERN_ERR "STALLION: failed to register serial memory "
 				"device\n");
 
-	devfs_mk_dir (NULL, "staliomem", NULL);
+	devfs_mk_dir("staliomem");
 	for (i = 0; i < 4; i++) {
 		char name[16];
 		sprintf(name, "staliomem/%d", i);
diff -Nru a/drivers/char/ite_gpio.c b/drivers/char/ite_gpio.c
--- a/drivers/char/ite_gpio.c	Tue Nov  5 07:39:55 2002
+++ b/drivers/char/ite_gpio.c	Thu Mar  6 14:03:51 2003
@@ -140,7 +140,7 @@
 {
 	int ret=-1;
 
-	if (MAX_GPIO_LINE > *data >= 0) 
+	if ((MAX_GPIO_LINE > *data) && (*data >= 0)) 
 		ret=ite_gpio_irq_pending[*data];
  
 	DEB(printk("ite_gpio_in_status %d ret=%d\n",*data, ret));
diff -Nru a/drivers/char/lp.c b/drivers/char/lp.c
--- a/drivers/char/lp.c	Tue Dec  3 10:08:41 2002
+++ b/drivers/char/lp.c	Sat Mar 22 07:38:04 2003
@@ -906,7 +906,7 @@
 		return -EIO;
 	}
 
-	devfs_mk_dir (NULL, "printers", NULL);
+	devfs_mk_dir("printers");
 
 	if (parport_register_driver (&lp_driver)) {
 		printk (KERN_ERR "lp: unable to register with parport\n");
diff -Nru a/drivers/char/lp_old98.c b/drivers/char/lp_old98.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/lp_old98.c	Thu Mar 13 17:23:19 2003
@@ -0,0 +1,544 @@
+/*
+ *	linux/drivers/char/lp_old98.c
+ *
+ * printer port driver for ancient PC-9800s with no bidirectional port support
+ *
+ * Copyright (C)  1998,99  Kousuke Takai <tak@kmc.kyoto-u.ac.jp>,
+ *			   Kyoto University Microcomputer Club
+ *
+ * This driver is based on and has compatibility with `lp.c',
+ * generic PC printer port driver.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/delay.h>
+#include <linux/console.h>
+#include <linux/version.h>
+#include <linux/fs.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#include <linux/lp.h>
+
+/*
+ *  I/O port numbers
+ */
+#define	LP_PORT_DATA	0x40
+#define	LP_PORT_STATUS	(LP_PORT_DATA + 2)
+#define	LP_PORT_STROBE	(LP_PORT_DATA + 4)
+#define LP_PORT_CONTROL	(LP_PORT_DATA + 6)
+
+#define	LP_PORT_H98MODE	0x0448
+#define	LP_PORT_EXTMODE	0x0149
+
+/*
+ *  bit mask for I/O
+ */
+#define	LP_MASK_nBUSY	(1 << 2)
+#define	LP_MASK_nSTROBE	(1 << 7)
+
+#define LP_CONTROL_ASSERT_STROBE	(0x0e)
+#define LP_CONTROL_NEGATE_STROBE	(0x0f)
+
+/*
+ *  Acceptable maximum value for non-privileged user for LPCHARS ioctl.
+ */
+#define LP_CHARS_NOPRIV_MAX	65535
+
+#define	DC1	'\x11'
+#define	DC3	'\x13'
+
+/* PC-9800s have at least and at most one old-style printer port. */
+static struct lp_struct lp = {
+	.flags	= LP_EXIST | LP_ABORTOPEN,
+	.chars	= LP_INIT_CHAR,
+	.time	= LP_INIT_TIME,
+	.wait	= LP_INIT_WAIT,
+};
+
+static	int	dc1_check;
+static spinlock_t lp_old98_lock = SPIN_LOCK_UNLOCKED;
+
+
+#undef LP_OLD98_DEBUG
+
+#ifdef CONFIG_PC9800_OLDLP_CONSOLE
+static struct console lp_old98_console;		/* defined later */
+static short saved_console_flags;
+#endif
+
+static DECLARE_WAIT_QUEUE_HEAD (lp_old98_waitq);
+
+static void lp_old98_timer_function(unsigned long data)
+{
+	if (inb(LP_PORT_STATUS) & LP_MASK_nBUSY)
+		wake_up_interruptible(&lp_old98_waitq);
+	else {
+		struct timer_list *t = (struct timer_list *) data;
+
+		t->expires = jiffies + 1;
+		add_timer(t);
+	}
+}
+
+static inline int lp_old98_wait_ready(void)
+{
+	struct timer_list timer;
+
+	init_timer(&timer);
+	timer.function = lp_old98_timer_function;
+	timer.expires = jiffies + 1;
+	timer.data = (unsigned long)&timer;
+	add_timer(&timer);
+	interruptible_sleep_on(&lp_old98_waitq);
+	del_timer(&timer);
+	return signal_pending(current);
+}
+
+static inline int lp_old98_char(char lpchar)
+{
+	unsigned long count = 0;
+#ifdef LP_STATS
+	int tmp;
+#endif
+
+	while (!(inb(LP_PORT_STATUS) & LP_MASK_nBUSY)) {
+		count++;
+		if (count >= lp.chars)
+			return 0;
+	}
+
+	outb(lpchar, LP_PORT_DATA);
+
+#ifdef LP_STATS
+	/*
+	 *  Update lp statsistics here (and between next two outb()'s).
+	 *  Time to compute it is part of storobe delay.
+	 */
+	if (count > lp.stats.maxwait) {
+#ifdef LP_OLD98_DEBUG
+		printk(KERN_DEBUG "lp_old98: success after %d counts.\n",
+		       count);
+#endif
+		lp.stats.maxwait = count;
+	}
+	count *= 256;
+	tmp = count - lp.stats.meanwait;
+	if (tmp < 0)
+		tmp = -tmp;
+#endif
+	ndelay(lp.wait);
+    
+	/* negate PSTB# (activate strobe)	*/
+	outb(LP_CONTROL_ASSERT_STROBE, LP_PORT_CONTROL);
+
+#ifdef LP_STATS
+	lp.stats.meanwait = (255 * lp.stats.meanwait + count + 128) / 256;
+	lp.stats.mdev = (127 * lp.stats.mdev + tmp + 64) / 128;
+	lp.stats.chars ++;
+#endif
+
+	ndelay(lp.wait);
+
+	/* assert PSTB# (deactivate strobe)	*/
+	outb(LP_CONTROL_NEGATE_STROBE, LP_PORT_CONTROL);
+
+	return 1;
+}
+
+static ssize_t lp_old98_write(struct file * file,
+			      const char * buf, size_t count,
+			      loff_t *dummy)
+{
+	unsigned long total_bytes_written = 0;
+
+	if (!access_ok(VERIFY_READ, buf, count))
+		return -EFAULT;
+
+#ifdef LP_STATS
+	if (jiffies - lp.lastcall > lp.time)
+		lp.runchars = 0;
+	lp.lastcall = jiffies;
+#endif
+
+	do {
+		unsigned long bytes_written = 0;
+		unsigned long copy_size
+			= (count < LP_BUFFER_SIZE ? count : LP_BUFFER_SIZE);
+
+		if (__copy_from_user(lp.lp_buffer, buf, copy_size))
+			return -EFAULT;
+
+		while (bytes_written < copy_size) {
+			if (lp_old98_char(lp.lp_buffer[bytes_written]))
+				bytes_written ++;
+			else {
+#ifdef LP_STATS
+				int rc = lp.runchars + bytes_written;
+
+				if (rc > lp.stats.maxrun)
+					lp.stats.maxrun = rc;
+
+				lp.stats.sleeps ++;
+#endif
+#ifdef LP_OLD98_DEBUG
+				printk(KERN_DEBUG
+				       "lp_old98: sleeping at %d characters"
+				       " for %d jiffies\n",
+				       lp.runchars, lp.time);
+				lp.runchars = 0;
+#endif
+				if (lp_old98_wait_ready())
+					return ((total_bytes_written
+						 + bytes_written)
+						? : -EINTR);
+			}
+		}
+		total_bytes_written += bytes_written;
+		buf += bytes_written;
+#ifdef LP_STATS
+		lp.runchars += bytes_written;
+#endif
+		count -= bytes_written;
+	} while (count > 0);
+
+	return total_bytes_written;
+}
+
+static int lp_old98_open(struct inode * inode, struct file * file)
+{
+	if (minor(inode->i_rdev) != 0)
+		return -ENXIO;
+
+	if (lp.flags & LP_BUSY)
+		return -EBUSY;
+
+	if (dc1_check && (lp.flags & LP_ABORTOPEN)
+	    && !(file->f_flags & O_NONBLOCK)) {
+		/*
+		 *  Check whether printer is on-line.
+		 *  PC-9800's old style port have only BUSY# as status input,
+		 *  so that it is impossible to distinguish that the printer is
+		 *  ready and that the printer is off-line or not connected
+		 *  (in both case BUSY# is in the same state). So:
+		 *
+		 *    (1) output DC1 (0x11) to printer port and do strobe.
+		 *    (2) watch BUSY# line for a while. If BUSY# is pulled
+		 *	  down, the printer will be ready. Otherwise,
+		 *	  it will be off-line (or not connected, or power-off,
+		 *	   ...).
+		 *
+		 *  The source of this procedure:
+		 *	Terumasa KODAKA, Kazufumi SHIMIZU, Yu HAYAMI:
+		 *		`PC-9801 Super Technique', Ascii, 1992.
+		 */
+		int count;
+		unsigned long flags;
+
+		/* interrupts while check is fairly bad */
+		spin_lock_irqsave(&lp_old98_lock, flags);
+
+		if (!lp_old98_char(DC1)) {
+			spin_unlock_irqrestore(&lp_old98_lock, flags);
+			return -EBUSY;
+		}
+		count = (unsigned int)dc1_check > 10000 ? 10000 : dc1_check;
+		while (inb(LP_PORT_STATUS) & LP_MASK_nBUSY) {
+			if (--count == 0) {
+				spin_unlock_irqrestore(&lp_old98_lock, flags);
+				return -ENODEV;
+			}
+		}
+		spin_unlock_irqrestore(&lp_old98_lock, flags);
+	}
+
+	if ((lp.lp_buffer = kmalloc(LP_BUFFER_SIZE, GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+
+	lp.flags |= LP_BUSY;
+
+#ifdef CONFIG_PC9800_OLDLP_CONSOLE
+	saved_console_flags = lp_old98_console.flags;
+	lp_old98_console.flags &= ~CON_ENABLED;
+#endif
+	return 0;
+}
+
+static int lp_old98_release(struct inode * inode, struct file * file)
+{
+	kfree(lp.lp_buffer);
+	lp.lp_buffer = NULL;
+	lp.flags &= ~LP_BUSY;
+#ifdef CONFIG_PC9800_OLDLP_CONSOLE
+	lp_old98_console.flags = saved_console_flags;
+#endif
+	return 0;
+}
+
+static int lp_old98_init_device(void)
+{
+	unsigned char data;
+
+	if ((data = inb(LP_PORT_EXTMODE)) != 0xFF && (data & 0x10)) {
+		printk(KERN_INFO
+		       "lp_old98: shutting down extended parallel port mode...\n");
+		outb(data & ~0x10, LP_PORT_EXTMODE);
+	}
+#ifdef	PC98_HW_H98
+	if ((pc98_hw_flags & PC98_HW_H98)
+	    && ((data = inb(LP_PORT_H98MODE)) & 0x01)) {
+		printk(KERN_INFO
+		       "lp_old98: shutting down H98 full centronics mode...\n");
+		outb(data & ~0x01, LP_PORT_H98MODE);
+	}
+#endif
+	return 0;
+}
+
+static int lp_old98_ioctl(struct inode *inode, struct file *file,
+			  unsigned int command, unsigned long arg)
+{
+	int retval = 0;
+
+	switch (command) {
+	case LPTIME:
+		lp.time = arg * HZ/100;
+		break;
+	case LPCHAR:
+		lp.chars = arg;
+		break;
+	case LPABORT:
+		if (arg)
+			lp.flags |= LP_ABORT;
+		else
+			lp.flags &= ~LP_ABORT;
+		break;
+	case LPABORTOPEN:
+		if (arg)
+			lp.flags |= LP_ABORTOPEN;
+		else
+			lp.flags &= ~LP_ABORTOPEN;
+		break;
+	case LPCAREFUL:
+		/* do nothing */
+		break;
+	case LPWAIT:
+		lp.wait = arg;
+		break;
+	case LPGETIRQ:
+		retval = put_user(0, (int *)arg);
+		break;
+	case LPGETSTATUS:
+		/*
+		 * convert PC-9800's status to IBM PC's one, so that tunelp(8)
+		 * works in the same way on this driver.
+		 */
+		retval = put_user((inb(LP_PORT_STATUS) & LP_MASK_nBUSY)
+					? (LP_PBUSY | LP_PERRORP) : LP_PERRORP,
+					(int *)arg);
+		break;
+	case LPRESET:
+		retval = lp_old98_init_device();
+		break;
+#ifdef LP_STATS
+	case LPGETSTATS:
+		if (copy_to_user((struct lp_stats *)arg, &lp.stats,
+				 sizeof(struct lp_stats)))
+			retval = -EFAULT;
+		else if (suser())
+			memset(&lp.stats, 0, sizeof(struct lp_stats));
+		break;
+#endif
+	case LPGETFLAGS:
+		retval = put_user(lp.flags, (int *)arg);
+		break;
+	case LPSETIRQ: 
+	default:
+		retval = -EINVAL;
+	}
+	return retval;
+}
+
+static struct file_operations lp_old98_fops = {
+	.owner		= THIS_MODULE,
+	.write		= lp_old98_write,
+	.ioctl		= lp_old98_ioctl,
+	.open		= lp_old98_open,
+	.release	= lp_old98_release,
+};
+
+/*
+ *  Support for console on lp_old98
+ */
+#ifdef CONFIG_PC9800_OLDLP_CONSOLE
+
+static inline void io_delay(void)
+{
+	unsigned char dummy;	/* actually not output */
+
+	asm volatile ("out%B0 %0,%1" : "=a"(dummy) : "N"(0x5f));
+}
+
+static void lp_old98_console_write(struct console *console,
+				    const char *s, unsigned int count)
+{
+	int i;
+	static unsigned int timeout_run = 0;
+
+	while (count) {
+		/* wait approx 1.2 seconds */
+		for (i = 2000000; !(inb(LP_PORT_STATUS) & LP_MASK_nBUSY);
+								io_delay())
+			if (!--i) {
+				if (++timeout_run >= 10)
+					/* disable forever... */
+					console->flags &= ~CON_ENABLED;
+				return;
+			}
+
+		timeout_run = 0;
+
+		if (*s == '\n') {
+			outb('\r', LP_PORT_DATA);
+			io_delay();
+			io_delay();
+			outb(LP_CONTROL_ASSERT_STROBE, LP_PORT_CONTROL);
+			io_delay();
+			io_delay();
+			outb(LP_CONTROL_NEGATE_STROBE, LP_PORT_CONTROL);
+			io_delay();
+			io_delay();
+			for (i = 1000000;
+					!(inb(LP_PORT_STATUS) & LP_MASK_nBUSY);
+					io_delay())
+				if (!--i)
+					return;
+		}
+
+		outb(*s++, LP_PORT_DATA);
+		io_delay();
+		io_delay();
+		outb(LP_CONTROL_ASSERT_STROBE, LP_PORT_CONTROL);
+		io_delay();
+		io_delay();
+		outb(LP_CONTROL_NEGATE_STROBE, LP_PORT_CONTROL);
+		io_delay();
+		io_delay();
+
+		--count;
+	}
+}
+
+static kdev_t lp_old98_console_device(struct console *console)
+{
+	return mk_kdev(LP_MAJOR, 0);
+}
+
+static struct console lp_old98_console = {
+	.name	= "lp_old98",
+	.write	= lp_old98_console_write,
+	.device	= lp_old98_console_device,
+	.flags	= CON_PRINTBUFFER,
+	.index	= -1,
+};
+
+#endif	/* console on lp_old98 */
+
+static int __init lp_old98_init(void)
+{
+	char *errmsg = "I/O ports already occupied, giving up.";
+
+#ifdef	PC98_HW_H98
+	if (pc98_hw_flags & PC98_HW_H98)
+	    if (!request_region(LP_PORT_H98MODE, 1, "lp_old98")
+		goto err1;
+#endif
+	if (!request_region(LP_PORT_DATA,   1, "lp_old98"))
+		goto err2;
+	if (!request_region(LP_PORT_STATUS, 1, "lp_old98"))
+		goto err3;
+	if (!request_region(LP_PORT_STROBE, 1, "lp_old98"))
+		goto err4;
+	if (!request_region(LP_PORT_EXTMODE, 1, "lp_old98"))
+		goto err5;
+	if (!register_chrdev(LP_MAJOR, "lp", &lp_old98_fops)) {
+#ifdef CONFIG_PC9800_OLDLP_CONSOLE
+		register_console(&lp_old98_console);
+		printk(KERN_INFO "lp_old98: console ready\n");
+#endif
+		/*
+		 * rest are not needed by this driver,
+		 * but for locking out other printer drivers...
+		 */
+		lp_old98_init_device();
+		return 0;
+	} else
+		errmsg = "unable to register device";
+
+	release_region(LP_PORT_EXTMODE, 1);
+err5:
+	release_region(LP_PORT_STROBE, 1);
+err4:
+	release_region(LP_PORT_STATUS, 1);
+err3:
+	release_region(LP_PORT_DATA, 1);
+err2:
+#ifdef	PC98_HW_H98
+	if (pc98_hw_flags & PC98_HW_H98)
+	    release_region(LP_PORT_H98MODE, 1);
+
+err1:
+#endif
+	printk(KERN_ERR "lp_old98: %s\n", errmsg);
+	return -EBUSY;
+}
+
+static void __exit lp_old98_exit(void)
+{
+#ifdef CONFIG_PC9800_OLDLP_CONSOLE
+	unregister_console(&lp_old98_console);
+#endif
+	unregister_chrdev(LP_MAJOR, "lp");
+
+	release_region(LP_PORT_DATA,   1);
+	release_region(LP_PORT_STATUS, 1);
+	release_region(LP_PORT_STROBE, 1);
+#ifdef	PC98_HW_H98
+	if (pc98_hw_flags & PC98_HW_H98)
+		release_region(LP_PORT_H98MODE, 1);
+#endif
+	release_region(LP_PORT_EXTMODE, 1);
+}
+
+#ifndef MODULE
+static int __init lp_old98_setup(char *str)
+{
+        int ints[4];
+
+        str = get_options(str, ARRAY_SIZE(ints), ints);
+        if (ints[0] > 0)
+		dc1_check = ints[1];
+        return 1;
+}
+__setup("lp_old98_dc1_check=", lp_old98_setup);
+#endif
+
+MODULE_PARM(dc1_check, "i");
+MODULE_AUTHOR("Kousuke Takai <tak@kmc.kyoto-u.ac.jp>");
+MODULE_DESCRIPTION("PC-9800 old printer port driver");
+MODULE_LICENSE("GPL");
+
+module_init(lp_old98_init);
+module_exit(lp_old98_exit);
diff -Nru a/drivers/char/misc.c b/drivers/char/misc.c
--- a/drivers/char/misc.c	Wed Feb 12 01:28:11 2003
+++ b/drivers/char/misc.c	Sat Mar 22 07:38:05 2003
@@ -196,7 +196,7 @@
 	if (misc->minor < DYNAMIC_MINORS)
 		misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
 	if (!devfs_handle)
-		devfs_handle = devfs_mk_dir (NULL, "misc", NULL);
+		devfs_handle = devfs_mk_dir("misc");
 	dir = strchr (misc->name, '/') ? NULL : devfs_handle;
 	misc->devfs_handle =
 		devfs_register (dir, misc->name, DEVFS_FL_NONE,
diff -Nru a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
--- a/drivers/char/mwave/mwavedd.c	Tue Dec 10 11:51:11 2002
+++ b/drivers/char/mwave/mwavedd.c	Fri Mar 21 22:15:44 2003
@@ -53,46 +53,20 @@
 #include <linux/init.h>
 #include <linux/major.h>
 #include <linux/miscdevice.h>
-#include <linux/proc_fs.h>
+#include <linux/device.h>
 #include <linux/serial.h>
 #include <linux/sched.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #include <linux/spinlock.h>
-#else
-#include <asm/spinlock.h>
-#endif
 #include <linux/delay.h>
 #include "smapi.h"
 #include "mwavedd.h"
 #include "3780i.h"
 #include "tp3780i.h"
 
-#ifndef __exit
-#define __exit
-#endif
-
 MODULE_DESCRIPTION("3780i Advanced Communications Processor (Mwave) driver");
 MODULE_AUTHOR("Mike Sullivan and Paul Schroeder");
 MODULE_LICENSE("GPL");
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-static int mwave_get_info(char *buf, char **start, off_t offset, int len);
-#else
-static int mwave_read_proc(char *buf, char **start, off_t offset, int xlen, int unused);
-static struct proc_dir_entry mwave_proc = {
-	0,                      /* unsigned short low_ino */
-	5,                      /* unsigned short namelen */
-	"mwave",                /* const char *name */
-	S_IFREG | S_IRUGO,      /* mode_t mode */
-	1,                      /* nlink_t nlink */
-	0,                      /* uid_t uid */
-	0,                      /* gid_t gid */
-	0,                      /* unsigned long size */
-	NULL,                   /* struct inode_operations *ops */
-	&mwave_read_proc        /* int (*get_info) (...) */
-};
-#endif
-
 /*
 * These parameters support the setting of MWave resources. Note that no
 * checks are made against other devices (ie. superio) for conflicts.
@@ -157,19 +131,23 @@
 
 		case IOCTL_MW_RESET:
 			PRINTK_1(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl, IOCTL_MW_RESET calling tp3780I_ResetDSP\n");
+				"mwavedd::mwave_ioctl, IOCTL_MW_RESET"
+				" calling tp3780I_ResetDSP\n");
 			retval = tp3780I_ResetDSP(&pDrvData->rBDData);
 			PRINTK_2(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl, IOCTL_MW_RESET retval %x from tp3780I_ResetDSP\n",
+				"mwavedd::mwave_ioctl, IOCTL_MW_RESET"
+				" retval %x from tp3780I_ResetDSP\n",
 				retval);
 			break;
 	
 		case IOCTL_MW_RUN:
 			PRINTK_1(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl, IOCTL_MW_RUN calling tp3780I_StartDSP\n");
+				"mwavedd::mwave_ioctl, IOCTL_MW_RUN"
+				" calling tp3780I_StartDSP\n");
 			retval = tp3780I_StartDSP(&pDrvData->rBDData);
 			PRINTK_2(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl, IOCTL_MW_RUN retval %x from tp3780I_StartDSP\n",
+				"mwavedd::mwave_ioctl, IOCTL_MW_RUN"
+				" retval %x from tp3780I_StartDSP\n",
 				retval);
 			break;
 	
@@ -177,17 +155,24 @@
 			MW_ABILITIES rAbilities;
 	
 			PRINTK_1(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES calling tp3780I_QueryAbilities\n");
-			retval = tp3780I_QueryAbilities(&pDrvData->rBDData, &rAbilities);
+				"mwavedd::mwave_ioctl,"
+				" IOCTL_MW_DSP_ABILITIES calling"
+				" tp3780I_QueryAbilities\n");
+			retval = tp3780I_QueryAbilities(&pDrvData->rBDData,
+					&rAbilities);
 			PRINTK_2(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES retval %x from tp3780I_QueryAbilities\n",
+				"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES"
+				" retval %x from tp3780I_QueryAbilities\n",
 				retval);
 			if (retval == 0) {
-				if( copy_to_user((char *) ioarg, (char *) &rAbilities, sizeof(MW_ABILITIES)) )
+				if( copy_to_user((char *) ioarg,
+							(char *) &rAbilities,
+							sizeof(MW_ABILITIES)) )
 					return -EFAULT;
 			}
 			PRINTK_2(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES exit retval %x\n",
+				"mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES"
+				" exit retval %x\n",
 				retval);
 		}
 			break;
@@ -197,15 +182,21 @@
 			MW_READWRITE rReadData;
 			unsigned short *pusBuffer = 0;
 	
-			if( copy_from_user((char *) &rReadData, (char *) ioarg, sizeof(MW_READWRITE)) )
+			if( copy_from_user((char *) &rReadData,
+						(char *) ioarg,
+						sizeof(MW_READWRITE)) )
 				return -EFAULT;
 			pusBuffer = (unsigned short *) (rReadData.pBuf);
 	
 			PRINTK_4(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl IOCTL_MW_READ_DATA, size %lx, ioarg %lx pusBuffer %p\n",
+				"mwavedd::mwave_ioctl IOCTL_MW_READ_DATA,"
+				" size %lx, ioarg %lx pusBuffer %p\n",
 				rReadData.ulDataLength, ioarg, pusBuffer);
-			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, iocmd,
-				(void *) pusBuffer, rReadData.ulDataLength, rReadData.usDspAddress);
+			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
+					iocmd,
+					(void *) pusBuffer,
+					rReadData.ulDataLength,
+					rReadData.usDspAddress);
 		}
 			break;
 	
@@ -213,12 +204,14 @@
 			MW_READWRITE rReadData;
 			unsigned short *pusBuffer = 0;
 	
-			if( copy_from_user((char *) &rReadData, (char *) ioarg, sizeof(MW_READWRITE)) )
+			if( copy_from_user((char *) &rReadData, (char *) ioarg,
+						sizeof(MW_READWRITE)) )
 				return -EFAULT;
 			pusBuffer = (unsigned short *) (rReadData.pBuf);
 	
 			PRINTK_4(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl IOCTL_MW_READ_INST, size %lx, ioarg %lx pusBuffer %p\n",
+				"mwavedd::mwave_ioctl IOCTL_MW_READ_INST,"
+				" size %lx, ioarg %lx pusBuffer %p\n",
 				rReadData.ulDataLength / 2, ioarg,
 				pusBuffer);
 			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
@@ -232,16 +225,21 @@
 			MW_READWRITE rWriteData;
 			unsigned short *pusBuffer = 0;
 	
-			if( copy_from_user((char *) &rWriteData, (char *) ioarg, sizeof(MW_READWRITE)) )
+			if( copy_from_user((char *) &rWriteData,
+						(char *) ioarg,
+						sizeof(MW_READWRITE)) )
 				return -EFAULT;
 			pusBuffer = (unsigned short *) (rWriteData.pBuf);
 	
 			PRINTK_4(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl IOCTL_MW_WRITE_DATA, size %lx, ioarg %lx pusBuffer %p\n",
+				"mwavedd::mwave_ioctl IOCTL_MW_WRITE_DATA,"
+				" size %lx, ioarg %lx pusBuffer %p\n",
 				rWriteData.ulDataLength, ioarg,
 				pusBuffer);
-			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, iocmd,
-				pusBuffer, rWriteData.ulDataLength, rWriteData.usDspAddress);
+			retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
+					iocmd, pusBuffer,
+					rWriteData.ulDataLength,
+					rWriteData.usDspAddress);
 		}
 			break;
 	
@@ -249,16 +247,21 @@
 			MW_READWRITE rWriteData;
 			unsigned short *pusBuffer = 0;
 	
-			if( copy_from_user((char *) &rWriteData, (char *) ioarg, sizeof(MW_READWRITE)) )
+			if( copy_from_user((char *) &rWriteData,
+						(char *) ioarg,
+						sizeof(MW_READWRITE)) )
 				return -EFAULT;
 			pusBuffer = (unsigned short *) (rWriteData.pBuf);
 	
 			PRINTK_4(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl IOCTL_MW_WRITE_INST, size %lx, ioarg %lx pusBuffer %p\n",
+				"mwavedd::mwave_ioctl IOCTL_MW_WRITE_INST,"
+				" size %lx, ioarg %lx pusBuffer %p\n",
 				rWriteData.ulDataLength, ioarg,
 				pusBuffer);
-			retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData, iocmd,
-					pusBuffer, rWriteData.ulDataLength, rWriteData.usDspAddress);
+			retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData,
+					iocmd, pusBuffer,
+					rWriteData.ulDataLength,
+					rWriteData.usDspAddress);
 		}
 			break;
 	
@@ -266,23 +269,25 @@
 			unsigned int ipcnum = (unsigned int) ioarg;
 	
 			PRINTK_3(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC ipcnum %x entry usIntCount %x\n",
+				"mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC"
+				" ipcnum %x entry usIntCount %x\n",
 				ipcnum,
 				pDrvData->IPCs[ipcnum].usIntCount);
 	
-			if (ipcnum > 16) {
-				PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: IOCTL_MW_REGISTER_IPC: Error: Invalid ipcnum %x\n", ipcnum);
+			if (ipcnum > ARRAY_SIZE(pDrvData->IPCs)) {
+				PRINTK_ERROR(KERN_ERR_MWAVE
+						"mwavedd::mwave_ioctl:"
+						" IOCTL_MW_REGISTER_IPC:"
+						" Error: Invalid ipcnum %x\n",
+						ipcnum);
 				return -EINVAL;
 			}
 			pDrvData->IPCs[ipcnum].bIsHere = FALSE;
 			pDrvData->IPCs[ipcnum].bIsEnabled = TRUE;
-	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-	#else
-			current->priority = 0x28;	/* boost to provide priority timing */
-	#endif
 	
 			PRINTK_2(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC ipcnum %x exit\n",
+				"mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC"
+				" ipcnum %x exit\n",
 				ipcnum);
 		}
 			break;
@@ -293,17 +298,22 @@
 			unsigned long flags;
 	
 			PRINTK_3(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x, usIntCount %x\n",
+				"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC"
+				" ipcnum %x, usIntCount %x\n",
 				ipcnum,
 				pDrvData->IPCs[ipcnum].usIntCount);
-			if (ipcnum > 16) {
-				PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: IOCTL_MW_GET_IPC: Error: Invalid ipcnum %x\n", ipcnum);
+			if (ipcnum > ARRAY_SIZE(pDrvData->IPCs)) {
+				PRINTK_ERROR(KERN_ERR_MWAVE
+						"mwavedd::mwave_ioctl:"
+						" IOCTL_MW_GET_IPC: Error:"
+						" Invalid ipcnum %x\n", ipcnum);
 				return -EINVAL;
 			}
 	
 			if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) {
 				PRINTK_2(TRACE_MWAVE,
-					"mwavedd::mwave_ioctl, thread for ipc %x going to sleep\n",
+					"mwavedd::mwave_ioctl, thread for"
+					" ipc %x going to sleep\n",
 					ipcnum);
 	
 				spin_lock_irqsave(&ipc_lock, flags);
@@ -313,10 +323,13 @@
 					pDrvData->IPCs[ipcnum].usIntCount = 2;	/* first int has been handled */
 					spin_unlock_irqrestore(&ipc_lock, flags);
 					PRINTK_2(TRACE_MWAVE,
-						"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x handling first int\n",
+						"mwavedd::mwave_ioctl"
+						" IOCTL_MW_GET_IPC ipcnum %x"
+						" handling first int\n",
 						ipcnum);
 				} else {	/* either 1st int has not yet occurred, or we have already handled the first int */
 					pDrvData->IPCs[ipcnum].bIsHere = TRUE;
+#warning "Sleeping on spinlock"
 					interruptible_sleep_on(&pDrvData->IPCs[ipcnum].ipc_wait_queue);
 					pDrvData->IPCs[ipcnum].bIsHere = FALSE;
 					if (pDrvData->IPCs[ipcnum].usIntCount == 1) {
@@ -325,11 +338,16 @@
 					}
 					spin_unlock_irqrestore(&ipc_lock, flags);
 					PRINTK_2(TRACE_MWAVE,
-						"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC ipcnum %x woke up and returning to application\n",
+						"mwavedd::mwave_ioctl"
+						" IOCTL_MW_GET_IPC ipcnum %x"
+						" woke up and returning to"
+						" application\n",
 						ipcnum);
 				}
 				PRINTK_2(TRACE_MWAVE,
-					"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC, returning thread for ipc %x processing\n",
+					"mwavedd::mwave_ioctl IOCTL_MW_GET_IPC,"
+					" returning thread for ipc %x"
+					" processing\n",
 					ipcnum);
 			}
 		}
@@ -339,10 +357,15 @@
 			unsigned int ipcnum = (unsigned int) ioarg;
 	
 			PRINTK_2(TRACE_MWAVE,
-				"mwavedd::mwave_ioctl IOCTL_MW_UNREGISTER_IPC ipcnum %x\n",
+				"mwavedd::mwave_ioctl IOCTL_MW_UNREGISTER_IPC"
+				" ipcnum %x\n",
 				ipcnum);
-			if (ipcnum > 16) {
-				PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: IOCTL_MW_UNREGISTER_IPC: Error: Invalid ipcnum %x\n", ipcnum);
+			if (ipcnum > ARRAY_SIZE(pDrvData->IPCs)) {
+				PRINTK_ERROR(KERN_ERR_MWAVE
+						"mwavedd::mwave_ioctl:"
+						" IOCTL_MW_UNREGISTER_IPC:"
+						" Error: Invalid ipcnum %x\n",
+						ipcnum);
 				return -EINVAL;
 			}
 			if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) {
@@ -355,7 +378,9 @@
 			break;
 	
 		default:
-			PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl: Error: Unrecognized iocmd %x\n", iocmd);
+			PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_ioctl:"
+					" Error: Unrecognized iocmd %x\n",
+					iocmd);
 			return -ENOTTY;
 			break;
 	} /* switch */
@@ -381,7 +406,8 @@
                            size_t count, loff_t * ppos)
 {
 	PRINTK_5(TRACE_MWAVE,
-		"mwavedd::mwave_write entry file %p, buf %p, count %x ppos %p\n",
+		"mwavedd::mwave_write entry file %p, buf %p,"
+		" count %x ppos %p\n",
 		file, buf, count, ppos);
 
 	return -EINVAL;
@@ -400,7 +426,9 @@
 			/* OK */
 			break;
 		default:
-			PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::register_serial_portandirq: Error: Illegal port %x\n", port );
+			PRINTK_ERROR(KERN_ERR_MWAVE
+					"mwavedd::register_serial_portandirq:"
+					" Error: Illegal port %x\n", port );
 			return -1;
 	} /* switch */
 	/* port is okay */
@@ -413,7 +441,9 @@
 			/* OK */
 			break;
 		default:
-			PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::register_serial_portandirq: Error: Illegal irq %x\n", irq );
+			PRINTK_ERROR(KERN_ERR_MWAVE
+					"mwavedd::register_serial_portandirq:"
+					" Error: Illegal irq %x\n", irq );
 			return -1;
 	} /* switch */
 	/* irq is okay */
@@ -427,7 +457,6 @@
 }
 
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 static struct file_operations mwave_fops = {
 	.owner		= THIS_MODULE,
 	.read		= mwave_read,
@@ -436,24 +465,47 @@
 	.open		= mwave_open,
 	.release	= mwave_close
 };
-#else
-static struct file_operations mwave_fops = {
-	NULL,			/* lseek */
-	mwave_read,		/* read */
-	mwave_write,		/* write */
-	NULL,			/* readdir */
-	NULL,			/* poll */
-	mwave_ioctl,		/* ioctl */
-	NULL,			/* mmap */
-	mwave_open,		/* open */
-	NULL,			/* flush */
-	mwave_close		/* release */
-};
-#endif
+
 
 static struct miscdevice mwave_misc_dev = { MWAVE_MINOR, "mwave", &mwave_fops };
 
 /*
+ * sysfs support <paulsch@us.ibm.com>
+ */
+
+struct device mwave_device;
+
+/* Prevent code redundancy, create a macro for mwave_show_* functions. */
+#define mwave_show_function(attr_name, format_string, field)		\
+static ssize_t mwave_show_##attr_name(struct device *dev, char *buf)	\
+{									\
+	DSP_3780I_CONFIG_SETTINGS *pSettings =				\
+		&mwave_s_mdd.rBDData.rDspSettings;			\
+        return sprintf(buf, format_string, pSettings->field);		\
+}
+
+/* All of our attributes are read attributes. */
+#define mwave_dev_rd_attr(attr_name, format_string, field)		\
+	mwave_show_function(attr_name, format_string, field)		\
+static DEVICE_ATTR(attr_name, S_IRUGO, mwave_show_##attr_name, NULL)
+
+mwave_dev_rd_attr (3780i_dma, "%i\n", usDspDma);
+mwave_dev_rd_attr (3780i_irq, "%i\n", usDspIrq);
+mwave_dev_rd_attr (3780i_io, "%#.4x\n", usDspBaseIO);
+mwave_dev_rd_attr (uart_irq, "%i\n", usUartIrq);
+mwave_dev_rd_attr (uart_io, "%#.4x\n", usUartBaseIO);
+
+static struct device_attribute * const mwave_dev_attrs[] = {
+	&dev_attr_3780i_dma,
+	&dev_attr_3780i_irq,
+	&dev_attr_3780i_io,
+	&dev_attr_uart_irq,
+	&dev_attr_uart_io,
+};
+static int nr_registered_attrs;
+static int device_registered;
+
+/*
 * mwave_init is called on module load
 *
 * mwave_exit is called on module unload
@@ -461,17 +513,20 @@
 */
 static void mwave_exit(void)
 {
+	int i;
 	pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
 
 	PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_exit entry\n");
 
-	if (pDrvData->bProcEntryCreated) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-		remove_proc_entry("mwave", NULL);
-#else
-		proc_unregister(&proc_root, mwave_proc.low_ino);
-#endif
+	for (i = 0; i < nr_registered_attrs; i++)
+		device_remove_file(&mwave_device, mwave_dev_attrs[i]);
+	nr_registered_attrs = 0;
+
+	if (device_registered) {
+		device_unregister(&mwave_device);
+		device_registered = 0;
 	}
+
 	if ( pDrvData->sLine >= 0 ) {
 		unregister_serial(pDrvData->sLine);
 	}
@@ -497,72 +552,81 @@
 {
 	int i;
 	int retval = 0;
-	unsigned int resultMiscRegister;
 	pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
 
-	memset(&mwave_s_mdd, 0, sizeof(MWAVE_DEVICE_DATA));
-
 	PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_init entry\n");
 
+	memset(&mwave_s_mdd, 0, sizeof(MWAVE_DEVICE_DATA));
+
 	pDrvData->bBDInitialized = FALSE;
 	pDrvData->bResourcesClaimed = FALSE;
 	pDrvData->bDSPEnabled = FALSE;
 	pDrvData->bDSPReset = FALSE;
 	pDrvData->bMwaveDevRegistered = FALSE;
 	pDrvData->sLine = -1;
-	pDrvData->bProcEntryCreated = FALSE;
 
-	for (i = 0; i < 16; i++) {
+	for (i = 0; i < ARRAY_SIZE(pDrvData->IPCs); i++) {
 		pDrvData->IPCs[i].bIsEnabled = FALSE;
 		pDrvData->IPCs[i].bIsHere = FALSE;
 		pDrvData->IPCs[i].usIntCount = 0;	/* no ints received yet */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 		init_waitqueue_head(&pDrvData->IPCs[i].ipc_wait_queue);
-#endif
 	}
 
 	retval = tp3780I_InitializeBoardData(&pDrvData->rBDData);
 	PRINTK_2(TRACE_MWAVE,
-		"mwavedd::mwave_init, return from tp3780I_InitializeBoardData retval %x\n",
+		"mwavedd::mwave_init, return from tp3780I_InitializeBoardData"
+		" retval %x\n",
 		retval);
 	if (retval) {
-		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_init: Error: Failed to initialize board data\n");
+		PRINTK_ERROR(KERN_ERR_MWAVE
+				"mwavedd::mwave_init: Error:"
+				" Failed to initialize board data\n");
 		goto cleanup_error;
 	}
 	pDrvData->bBDInitialized = TRUE;
 
 	retval = tp3780I_CalcResources(&pDrvData->rBDData);
 	PRINTK_2(TRACE_MWAVE,
-		"mwavedd::mwave_init, return from tp3780I_CalcResources retval %x\n",
+		"mwavedd::mwave_init, return from tp3780I_CalcResources"
+		" retval %x\n",
 		retval);
 	if (retval) {
-		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to calculate resources\n");
+		PRINTK_ERROR(KERN_ERR_MWAVE
+				"mwavedd:mwave_init: Error:"
+				" Failed to calculate resources\n");
 		goto cleanup_error;
 	}
 
 	retval = tp3780I_ClaimResources(&pDrvData->rBDData);
 	PRINTK_2(TRACE_MWAVE,
-		"mwavedd::mwave_init, return from tp3780I_ClaimResources retval %x\n",
+		"mwavedd::mwave_init, return from tp3780I_ClaimResources"
+		" retval %x\n",
 		retval);
 	if (retval) {
-		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to claim resources\n");
+		PRINTK_ERROR(KERN_ERR_MWAVE
+				"mwavedd:mwave_init: Error:"
+				" Failed to claim resources\n");
 		goto cleanup_error;
 	}
 	pDrvData->bResourcesClaimed = TRUE;
 
 	retval = tp3780I_EnableDSP(&pDrvData->rBDData);
 	PRINTK_2(TRACE_MWAVE,
-		"mwavedd::mwave_init, return from tp3780I_EnableDSP retval %x\n",
+		"mwavedd::mwave_init, return from tp3780I_EnableDSP"
+		" retval %x\n",
 		retval);
 	if (retval) {
-		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to enable DSP\n");
+		PRINTK_ERROR(KERN_ERR_MWAVE
+				"mwavedd:mwave_init: Error:"
+				" Failed to enable DSP\n");
 		goto cleanup_error;
 	}
 	pDrvData->bDSPEnabled = TRUE;
 
-	resultMiscRegister = misc_register(&mwave_misc_dev);
-	if (resultMiscRegister < 0) {
-		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to register misc device\n");
+	if (misc_register(&mwave_misc_dev) < 0) {
+		PRINTK_ERROR(KERN_ERR_MWAVE
+				"mwavedd:mwave_init: Error:"
+				" Failed to register misc device\n");
 		goto cleanup_error;
 	}
 	pDrvData->bMwaveDevRegistered = TRUE;
@@ -572,28 +636,39 @@
 		pDrvData->rBDData.rDspSettings.usUartIrq
 	);
 	if (pDrvData->sLine < 0) {
-		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd:mwave_init: Error: Failed to register serial driver\n");
+		PRINTK_ERROR(KERN_ERR_MWAVE
+				"mwavedd:mwave_init: Error:"
+				" Failed to register serial driver\n");
 		goto cleanup_error;
 	}
 	/* uart is registered */
 
-	if (
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-		!create_proc_info_entry("mwave", 0, NULL, mwave_get_info)
-#else
-		proc_register(&proc_root, &mwave_proc)
-#endif
-	) {
-		PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_init: Error: Failed to register /proc/mwave\n");
+	/* sysfs */
+	memset(&mwave_device, 0, sizeof (struct device));
+	snprintf(mwave_device.name, DEVICE_NAME_SIZE, "mwave");
+	snprintf(mwave_device.bus_id, BUS_ID_SIZE, "mwave");
+
+	if (device_register(&mwave_device))
 		goto cleanup_error;
+	device_registered = 1;
+	for (i = 0; i < ARRAY_SIZE(mwave_dev_attrs); i++) {
+		if(device_create_file(&mwave_device, mwave_dev_attrs[i])) {
+			PRINTK_ERROR(KERN_ERR_MWAVE
+					"mwavedd:mwave_init: Error:"
+					" Failed to create sysfs file %s\n",
+					mwave_dev_attrs[i]->attr.name);
+			goto cleanup_error;
+		}
+		nr_registered_attrs++;
 	}
-	pDrvData->bProcEntryCreated = TRUE;
 
 	/* SUCCESS! */
 	return 0;
 
-	cleanup_error:
-	PRINTK_ERROR(KERN_ERR_MWAVE "mwavedd::mwave_init: Error: Failed to initialize\n");
+cleanup_error:
+	PRINTK_ERROR(KERN_ERR_MWAVE
+			"mwavedd::mwave_init: Error:"
+			" Failed to initialize\n");
 	mwave_exit(); /* clean up */
 
 	return -EIO;
@@ -601,39 +676,3 @@
 
 module_init(mwave_init);
 
-
-/*
-* proc entry stuff added by Ian Pilcher <pilcher@us.ibm.com>
-*/
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-static int mwave_get_info(char *buf, char **start, off_t offset, int len)
-{
-	DSP_3780I_CONFIG_SETTINGS *pSettings = &mwave_s_mdd.rBDData.rDspSettings;
-
-	char *out = buf;
-
-	out += sprintf(out, "3780i_IRQ %i\n", pSettings->usDspIrq);
-	out += sprintf(out, "3780i_DMA %i\n", pSettings->usDspDma);
-	out += sprintf(out, "3780i_IO  %#.4x\n", pSettings->usDspBaseIO);
-	out += sprintf(out, "UART_IRQ  %i\n", pSettings->usUartIrq);
-	out += sprintf(out, "UART_IO   %#.4x\n", pSettings->usUartBaseIO);
-
-	return out - buf;
-}
-#else /* kernel version < 2.4.0 */
-static int mwave_read_proc(char *buf, char **start, off_t offset,
-                           int xlen, int unused)
-{
-	DSP_3780I_CONFIG_SETTINGS *pSettings = &mwave_s_mdd.rBDData.rDspSettings;
-	int len;
-
-	len = sprintf(buf,        "3780i_IRQ %i\n", pSettings->usDspIrq);
-	len += sprintf(&buf[len], "3780i_DMA %i\n", pSettings->usDspDma);
-	len += sprintf(&buf[len], "3780i_IO  %#.4x\n", pSettings->usDspBaseIO);
-	len += sprintf(&buf[len], "UART_IRQ  %i\n", pSettings->usUartIrq);
-	len += sprintf(&buf[len], "UART_IO   %#.4x\n", pSettings->usUartBaseIO);
-
-	return len;
-}
-#endif
diff -Nru a/drivers/char/mwave/mwavedd.h b/drivers/char/mwave/mwavedd.h
--- a/drivers/char/mwave/mwavedd.h	Mon Feb  4 23:49:25 2002
+++ b/drivers/char/mwave/mwavedd.h	Thu Mar  6 15:15:49 2003
@@ -126,11 +126,7 @@
 	BOOLEAN bIsEnabled;
 	BOOLEAN bIsHere;
 	/* entry spin lock */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	wait_queue_head_t ipc_wait_queue;
-#else
-	struct wait_queue *ipc_wait_queue;
-#endif
 } MWAVE_IPC;
 
 typedef struct _MWAVE_DEVICE_DATA {
@@ -143,7 +139,6 @@
 	BOOLEAN bDSPReset;
 	MWAVE_IPC IPCs[16];
 	BOOLEAN bMwaveDevRegistered;
-	BOOLEAN bProcEntryCreated;
 	short sLine;
 
 } MWAVE_DEVICE_DATA, *pMWAVE_DEVICE_DATA;
diff -Nru a/drivers/char/mwave/mwavepub.h b/drivers/char/mwave/mwavepub.h
--- a/drivers/char/mwave/mwavepub.h	Mon Feb  4 23:49:25 2002
+++ b/drivers/char/mwave/mwavepub.h	Thu Mar  6 15:15:49 2003
@@ -50,13 +50,8 @@
 #ifndef _LINUX_MWAVEPUB_H
 #define _LINUX_MWAVEPUB_H
 
-#ifndef MWAVEM_APP_DIST
 #include <linux/miscdevice.h>
-#endif
 
-#ifdef MWAVEM_APP_DIST
-#define MWAVE_MINOR      219
-#endif
 
 typedef struct _MW_ABILITIES {
 	unsigned long instr_per_sec;
diff -Nru a/drivers/char/mwave/smapi.c b/drivers/char/mwave/smapi.c
--- a/drivers/char/mwave/smapi.c	Mon Feb  4 23:49:25 2002
+++ b/drivers/char/mwave/smapi.c	Thu Mar  6 15:15:49 2003
@@ -280,10 +280,11 @@
 				if ((usSI & 0xFF) == mwave_uart_irq) {
 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
 					PRINTK_ERROR(KERN_ERR_MWAVE
+						"smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
 #else
 					PRINTK_3(TRACE_SMAPI,
+						"smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
 #endif
-						"smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI, mwave_uart_irq);
 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
 					PRINTK_1(TRACE_SMAPI,
 						"smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
@@ -300,13 +301,14 @@
 					if ((usSI >> 8) == uartio_index) {
 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
 						PRINTK_ERROR(KERN_ERR_MWAVE
+							"smapi::smapi_set_DSP_cfg: Serial port A base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
 #else
 						PRINTK_3(TRACE_SMAPI,
+							"smapi::smapi_set_DSP_cfg: Serial port A base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
 #endif
-							"smapi::smapi_set_DSP_cfg: Serial port A base I/O address index %x conflicts with uartio_index %x\n", usSI >> 8, uartio_index);
 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
 						PRINTK_1(TRACE_SMAPI,
-							"smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
+							"smapi::smapi_set_DSP_cfg Disabling conflicting serial port A\n");
 						bRC = smapi_request (0x1403, 0x0100, 0, usSI,
 							&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
 						if (bRC) goto exit_smapi_request_error;
@@ -331,13 +333,14 @@
 				if ((usSI & 0xFF) == mwave_uart_irq) {
 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
 					PRINTK_ERROR(KERN_ERR_MWAVE
+						"smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
 #else
 					PRINTK_3(TRACE_SMAPI,
+						"smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
 #endif
-						"smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI, mwave_uart_irq);
 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
 					PRINTK_1(TRACE_SMAPI,
-						"smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
+						"smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n");
 					bRC = smapi_request(0x1405, 0x0100, 0, usSI,
 						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
 					if (bRC) goto exit_smapi_request_error;
@@ -351,13 +354,14 @@
 					if ((usSI >> 8) == uartio_index) {
 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
 						PRINTK_ERROR(KERN_ERR_MWAVE
+							"smapi::smapi_set_DSP_cfg: Serial port B base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
 #else
 						PRINTK_3(TRACE_SMAPI,
+							"smapi::smapi_set_DSP_cfg: Serial port B base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
 #endif
-							"smapi::smapi_set_DSP_cfg: Serial port B base I/O address index %x conflicts with uartio_index %x\n", usSI >> 8, uartio_index);
 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
 						PRINTK_1 (TRACE_SMAPI,
-						    "smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
+						    "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n");
 						bRC = smapi_request (0x1405, 0x0100, 0, usSI,
 							&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
 						if (bRC) goto exit_smapi_request_error;
@@ -380,39 +384,15 @@
 			&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
 		if (bRC) goto exit_smapi_request_error;
 		/* bRC == 0 */
-		if ((usCX & 0xff) == mwave_uart_irq) {	/* serial port is enabled */
-#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
-			PRINTK_ERROR(KERN_ERR_MWAVE
-#else
-			PRINTK_3(TRACE_SMAPI,
-#endif
-				"smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usSI, mwave_uart_irq);
-#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
-			PRINTK_1(TRACE_SMAPI,
-				"smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
-			bRC = smapi_request(0x1701, 0x0100, 0, 0,
-				&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
-			if (bRC) goto exit_smapi_request_error;
-			bRC = smapi_request(0x1700, 0, 0, 0,
-				&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
-			if (bRC) goto exit_smapi_request_error;
-			bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
-				&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
-			if (bRC) goto exit_smapi_request_error;
-			bRC = smapi_request(0x1704, 0x0000, 0, 0,
-				&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
-			if (bRC) goto exit_smapi_request_error;
-#else
-			goto exit_conflict;
-#endif
-		} else {
-			if ((usSI & 0xff) == uartio_index) {
+		if ((usCX & 0xff) != 0xff) { /* IR port not disabled */
+			if ((usCX & 0xff) == mwave_uart_irq) {
 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
 				PRINTK_ERROR(KERN_ERR_MWAVE
+					"smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq);
 #else
 				PRINTK_3(TRACE_SMAPI,
+					"smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq);
 #endif
-					"smapi::smapi_set_DSP_cfg: IR port base I/O address index %x conflicts with uartio_index %x\n", usSI & 0xff, uartio_index);
 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
 				PRINTK_1(TRACE_SMAPI,
 					"smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
@@ -431,6 +411,34 @@
 #else
 				goto exit_conflict;
 #endif
+			} else {
+				if ((usSI & 0xff) == uartio_index) {
+#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
+					PRINTK_ERROR(KERN_ERR_MWAVE
+						"smapi::smapi_set_DSP_cfg: IR port base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI & 0xff], ausUartBases[uartio_index]);
+#else
+					PRINTK_3(TRACE_SMAPI,
+						"smapi::smapi_set_DSP_cfg: IR port base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI & 0xff], ausUartBases[uartio_index]);
+#endif
+#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
+					PRINTK_1(TRACE_SMAPI,
+						"smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
+					bRC = smapi_request(0x1701, 0x0100, 0, 0,
+						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+					if (bRC) goto exit_smapi_request_error;
+					bRC = smapi_request(0x1700, 0, 0, 0,
+						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+					if (bRC) goto exit_smapi_request_error;
+					bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
+						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+					if (bRC) goto exit_smapi_request_error;
+					bRC = smapi_request(0x1704, 0x0000, 0, 0,
+						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+					if (bRC) goto exit_smapi_request_error;
+#else
+					goto exit_conflict;
+#endif
+				}
 			}
 		}
 	}
diff -Nru a/drivers/char/n_tty.c b/drivers/char/n_tty.c
--- a/drivers/char/n_tty.c	Thu Jan 16 17:57:52 2003
+++ b/drivers/char/n_tty.c	Sat Mar 22 12:27:06 2003
@@ -1029,7 +1029,11 @@
 				break;
 			cs = tty->link->ctrl_status;
 			tty->link->ctrl_status = 0;
-			put_user(cs, b++);
+			if (put_user(cs, b++)) {
+				retval = -EFAULT;
+				b--;
+				break;
+			}
 			nr--;
 			break;
 		}
@@ -1068,7 +1072,11 @@
 
 		/* Deal with packet mode. */
 		if (tty->packet && b == buf) {
-			put_user(TIOCPKT_DATA, b++);
+			if (put_user(TIOCPKT_DATA, b++)) {
+				retval = -EFAULT;
+				b--;
+				break;
+			}
 			nr--;
 		}
 
@@ -1095,12 +1103,18 @@
 				spin_unlock_irqrestore(&tty->read_lock, flags);
 
 				if (!eol || (c != __DISABLED_CHAR)) {
-					put_user(c, b++);
+					if (put_user(c, b++)) {
+						retval = -EFAULT;
+						b--;
+						break;
+					}
 					nr--;
 				}
 				if (eol)
 					break;
 			}
+			if (retval)
+				break;
 		} else {
 			int uncopied;
 			uncopied = copy_from_read_buf(tty, &b, &nr);
diff -Nru a/drivers/char/nwflash.c b/drivers/char/nwflash.c
--- a/drivers/char/nwflash.c	Tue Feb 25 09:56:31 2003
+++ b/drivers/char/nwflash.c	Wed Mar 19 03:39:14 2003
@@ -354,6 +354,7 @@
 {
 	volatile unsigned int c1;
 	volatile unsigned char *pWritePtr;
+	unsigned long timeout;
 	int temp, temp1;
 
 	/*
@@ -406,9 +407,9 @@
 	/*
 	 * wait while erasing in process (up to 10 sec)
 	 */
-	temp = jiffies + 10 * HZ;
+	timeout = jiffies + 10 * HZ;
 	c1 = 0;
-	while (!(c1 & 0x80) && time_before(jiffies, temp)) {
+	while (!(c1 & 0x80) && time_before(jiffies, timeout)) {
 		flash_wait(HZ / 100);
 		/*
 		 * read any address
@@ -466,8 +467,8 @@
 	unsigned char *pWritePtr;
 	unsigned int uAddress;
 	unsigned int offset;
-	unsigned int timeout;
-	unsigned int timeout1;
+	unsigned long timeout;
+	unsigned long timeout1;
 
 	/*
 	 * red LED == write
diff -Nru a/drivers/char/ppdev.c b/drivers/char/ppdev.c
--- a/drivers/char/ppdev.c	Tue Feb 18 10:25:13 2003
+++ b/drivers/char/ppdev.c	Sat Mar 22 07:38:05 2003
@@ -758,7 +758,7 @@
 			PP_MAJOR);
 		return -EIO;
 	}
-	devfs_mk_dir (NULL, "parports", NULL);
+	devfs_mk_dir("parports");
 	for (i = 0; i < PARPORT_MAX; i++) {
 		char name[16];
 		sprintf(name, "parports/%d", i);
diff -Nru a/drivers/char/pty.c b/drivers/char/pty.c
--- a/drivers/char/pty.c	Sun Dec 29 23:59:27 2002
+++ b/drivers/char/pty.c	Sat Mar 22 07:38:04 2003
@@ -432,7 +432,7 @@
 
 	/* Unix98 devices */
 #ifdef CONFIG_UNIX98_PTYS
-	devfs_mk_dir (NULL, "pts", NULL);
+	devfs_mk_dir("pts");
 	printk("pty: %d Unix98 ptys configured\n", UNIX98_NR_MAJORS*NR_PTYS);
 	for ( i = 0 ; i < UNIX98_NR_MAJORS ; i++ ) {
 		int j;
diff -Nru a/drivers/char/raw.c b/drivers/char/raw.c
--- a/drivers/char/raw.c	Sat Mar  8 14:50:48 2003
+++ b/drivers/char/raw.c	Thu Mar 20 03:11:46 2003
@@ -50,7 +50,7 @@
 		filp->f_op = &raw_ctl_fops;
 		return 0;
 	}
-	
+
 	down(&raw_mutex);
 
 	/*
@@ -70,10 +70,10 @@
 		} else {
 			err = set_blocksize(bdev, bdev_hardsect_size(bdev));
 			if (err == 0) {
-				raw_devices[minor].inuse++;
-				filp->f_dentry->d_inode->i_mapping =
-					bdev->bd_inode->i_mapping;
 				filp->f_flags |= O_DIRECT;
+				if (++raw_devices[minor].inuse == 1)
+					filp->f_dentry->d_inode->i_mapping =
+						bdev->bd_inode->i_mapping;
 			}
 		}
 	}
@@ -83,6 +83,10 @@
 	return err;
 }
 
+/*
+ * When the final fd which refers to this character-special node is closed, we
+ * make its ->mapping point back at its own i_data.
+ */
 static int raw_release(struct inode *inode, struct file *filp)
 {
 	const int minor= minor(inode->i_rdev);
@@ -90,13 +94,13 @@
 
 	down(&raw_mutex);
 	bdev = raw_devices[minor].binding;
-	raw_devices[minor].inuse--;
+	if (--raw_devices[minor].inuse == 0) {
+		/* Here  inode->i_mapping == bdev->bd_inode->i_mapping  */
+		inode->i_mapping = &inode->i_data;
+		inode->i_mapping->backing_dev_info = &default_backing_dev_info;
+	}
 	up(&raw_mutex);
 
-	/* Here  inode->i_mapping == bdev->bd_inode->i_mapping  */
-	inode->i_mapping = &inode->i_data;
-	inode->i_mapping->backing_dev_info = &default_backing_dev_info;
-	
 	bd_release(bdev);
 	blkdev_put(bdev, BDEV_RAW);
 	return 0;
@@ -118,27 +122,28 @@
  * Deal with ioctls against the raw-device control interface, to bind
  * and unbind other raw devices.
  */
-static int
-raw_ctl_ioctl(struct inode *inode, struct file *filp,
-		unsigned int command, unsigned long arg)
+static int raw_ctl_ioctl(struct inode *inode, struct file *filp,
+			unsigned int command, unsigned long arg)
 {
 	struct raw_config_request rq;
 	struct raw_device_data *rawdev;
-	int err;
-	
+	int err = 0;
+
 	switch (command) {
 	case RAW_SETBIND:
 	case RAW_GETBIND:
 
 		/* First, find out which raw minor we want */
 
-		err = -EFAULT;
-		if (copy_from_user(&rq, (void *) arg, sizeof(rq)))
+		if (copy_from_user(&rq, (void *) arg, sizeof(rq))) {
+			err = -EFAULT;
 			goto out;
-		
-		err = -EINVAL;
-		if (rq.raw_minor < 0 || rq.raw_minor >= MAX_RAW_MINORS)
+		}
+
+		if (rq.raw_minor < 0 || rq.raw_minor >= MAX_RAW_MINORS) {
+			err = -EINVAL;
 			goto out;
+		}
 		rawdev = &raw_devices[rq.raw_minor];
 
 		if (command == RAW_SETBIND) {
@@ -148,9 +153,10 @@
 			 * This is like making block devices, so demand the
 			 * same capability
 			 */
-			err = -EPERM;
-			if (!capable(CAP_SYS_ADMIN))
+			if (!capable(CAP_SYS_ADMIN)) {
+				err = -EPERM;
 				goto out;
+			}
 
 			/*
 			 * For now, we don't need to check that the underlying
@@ -159,17 +165,18 @@
 			 * major/minor numbers make sense.
 			 */
 
-			err = -EINVAL;
 			dev = MKDEV(rq.block_major, rq.block_minor);
 			if ((rq.block_major == 0 && rq.block_minor != 0) ||
-			    MAJOR(dev) != rq.block_major ||
-			    MINOR(dev) != rq.block_minor)
+					MAJOR(dev) != rq.block_major ||
+					MINOR(dev) != rq.block_minor) {
+				err = -EINVAL;
 				goto out;
-			
+			}
+
 			down(&raw_mutex);
-			err = -EBUSY;
 			if (rawdev->inuse) {
 				up(&raw_mutex);
+				err = -EBUSY;
 				goto out;
 			}
 			if (rawdev->binding) {
@@ -181,7 +188,10 @@
 				rawdev->binding = NULL;
 			} else {
 				rawdev->binding = bdget(dev);
-				MOD_INC_USE_COUNT;
+				if (rawdev->binding == NULL)
+					err = -ENOMEM;
+				else
+					try_module_get(THIS_MODULE);
 			}
 			up(&raw_mutex);
 		} else {
@@ -196,13 +206,12 @@
 				rq.block_major = rq.block_minor = 0;
 			}
 			up(&raw_mutex);
-			err = -EFAULT;
-			if (copy_to_user((void *)arg, &rq, sizeof(rq)))
+			if (copy_to_user((void *)arg, &rq, sizeof(rq))) {
+				err = -EFAULT;
 				goto out;
+			}
 		}
-		err = 0;
 		break;
-		
 	default:
 		err = -EINVAL;
 		break;
diff -Nru a/drivers/char/rio/rioboot.c b/drivers/char/rio/rioboot.c
--- a/drivers/char/rio/rioboot.c	Sun Feb 16 16:15:30 2003
+++ b/drivers/char/rio/rioboot.c	Tue Mar 18 08:58:11 2003
@@ -34,7 +34,6 @@
 static char *_rioboot_c_sccs_ = "@(#)rioboot.c	1.3";
 #endif
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
diff -Nru a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
--- a/drivers/char/rio/riocmd.c	Sun Feb 16 16:15:30 2003
+++ b/drivers/char/rio/riocmd.c	Tue Mar 18 08:58:11 2003
@@ -34,7 +34,6 @@
 static char *_riocmd_c_sccs_ = "@(#)riocmd.c	1.2";
 #endif
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
diff -Nru a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c
--- a/drivers/char/rio/rioctrl.c	Sun Feb 16 16:15:30 2003
+++ b/drivers/char/rio/rioctrl.c	Tue Mar 18 08:58:11 2003
@@ -34,7 +34,6 @@
 #endif
 
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
diff -Nru a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
--- a/drivers/char/rio/rioinit.c	Thu Mar  6 09:17:26 2003
+++ b/drivers/char/rio/rioinit.c	Tue Mar 18 08:58:11 2003
@@ -33,7 +33,6 @@
 static char *_rioinit_c_sccs_ = "@(#)rioinit.c	1.3";
 #endif
 
-#define __NO_VERSION__
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/slab.h>
diff -Nru a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c
--- a/drivers/char/rio/riointr.c	Sun Feb 16 16:15:30 2003
+++ b/drivers/char/rio/riointr.c	Tue Mar 18 08:58:11 2003
@@ -34,7 +34,6 @@
 #endif
 
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
diff -Nru a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c
--- a/drivers/char/rio/rioparam.c	Thu Mar  6 09:17:26 2003
+++ b/drivers/char/rio/rioparam.c	Tue Mar 18 08:58:24 2003
@@ -34,7 +34,6 @@
 static char *_rioparam_c_sccs_ = "@(#)rioparam.c	1.3";
 #endif
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
diff -Nru a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c
--- a/drivers/char/rio/rioroute.c	Thu Mar  6 09:17:26 2003
+++ b/drivers/char/rio/rioroute.c	Tue Mar 18 08:58:24 2003
@@ -33,7 +33,6 @@
 static char *_rioroute_c_sccs_ = "@(#)rioroute.c	1.3";
 #endif
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
diff -Nru a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c
--- a/drivers/char/rio/riotable.c	Thu Mar  6 09:17:26 2003
+++ b/drivers/char/rio/riotable.c	Tue Mar 18 08:58:24 2003
@@ -33,7 +33,6 @@
 static char *_riotable_c_sccs_ = "@(#)riotable.c	1.2";
 #endif
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
diff -Nru a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
--- a/drivers/char/rio/riotty.c	Thu Mar  6 09:17:26 2003
+++ b/drivers/char/rio/riotty.c	Tue Mar 18 08:58:24 2003
@@ -36,7 +36,6 @@
 
 #define __EXPLICIT_DEF_H__
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
diff -Nru a/drivers/char/rtc.c b/drivers/char/rtc.c
--- a/drivers/char/rtc.c	Thu Mar  6 08:17:53 2003
+++ b/drivers/char/rtc.c	Tue Mar 18 08:58:24 2003
@@ -47,7 +47,7 @@
 
 #define RTC_VERSION		"1.11"
 
-#define RTC_IO_EXTENT	0x10	/* Only really two ports, but...	*/
+#define RTC_IO_EXTENT	0x8
 
 /*
  *	Note that *all* calls to CMOS_READ and CMOS_WRITE are done with
diff -Nru a/drivers/char/serial167.c b/drivers/char/serial167.c
--- a/drivers/char/serial167.c	Fri Feb 14 15:16:47 2003
+++ b/drivers/char/serial167.c	Tue Mar 18 07:43:19 2003
@@ -2836,7 +2836,7 @@
 };
 
 
-static void __init serial167_console_init(void)
+static int __init serial167_console_init(void)
 {
 	if (vme_brdtype == VME_TYPE_MVME166 ||
 			vme_brdtype == VME_TYPE_MVME167 ||
@@ -2844,6 +2844,7 @@
 		mvme167_serial_console_setup(0);
 		register_console(&sercons);
 	}
+	return 0;
 }
 console_initcall(serial167_console_init);
 
diff -Nru a/drivers/char/serial_tx3912.c b/drivers/char/serial_tx3912.c
--- a/drivers/char/serial_tx3912.c	Fri Feb 14 15:16:47 2003
+++ b/drivers/char/serial_tx3912.c	Tue Mar 18 07:43:35 2003
@@ -1054,9 +1054,10 @@
 	.index    = -1
 };
 
-static void __init tx3912_console_init(void)
+static int __init tx3912_console_init(void)
 {
 	register_console(&sercons);
+	return 0;
 }
 console_initcall(tx3912_console_init);
 
diff -Nru a/drivers/char/sh-sci.c b/drivers/char/sh-sci.c
--- a/drivers/char/sh-sci.c	Fri Feb 14 15:16:47 2003
+++ b/drivers/char/sh-sci.c	Tue Mar 18 07:43:51 2003
@@ -1275,7 +1275,7 @@
 extern void sh_console_unregister (void);
 #endif
 
-static void __init sci_console_init(void)
+static int __init sci_console_init(void)
 {
 	register_console(&sercons);
 #ifdef CONFIG_SH_EARLY_PRINTK
@@ -1284,6 +1284,7 @@
 	 */
 	sh_console_unregister();
 #endif
+	return 0;
 }
 console_initcall(sci_console_init);
 
diff -Nru a/drivers/char/stallion.c b/drivers/char/stallion.c
--- a/drivers/char/stallion.c	Mon Dec 30 20:26:12 2002
+++ b/drivers/char/stallion.c	Sat Mar 22 07:38:05 2003
@@ -3213,7 +3213,7 @@
  */
 	if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem))
 		printk("STALLION: failed to register serial board device\n");
-	devfs_mk_dir (NULL, "staliomem", NULL);
+	devfs_mk_dir("staliomem");
 	for (i = 0; i < 4; i++) {
 		char name[16];
 		sprintf(name, "staliomem/%d", i);
diff -Nru a/drivers/char/tipar.c b/drivers/char/tipar.c
--- a/drivers/char/tipar.c	Wed Feb 19 12:18:01 2003
+++ b/drivers/char/tipar.c	Sat Mar 22 07:38:05 2003
@@ -490,7 +490,7 @@
 	}
 
 	/* Use devfs with tree: /dev/ticables/par/[0..2] */
-	devfs_mk_dir(NULL, "ticables/par", NULL);
+	devfs_mk_dir("ticables/par");
 
 	if (parport_register_driver(&tipar_driver)) {
 		printk("tipar: unable to register with parport\n");
diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c
--- a/drivers/char/tty_io.c	Sat Mar 15 02:33:56 2003
+++ b/drivers/char/tty_io.c	Sat Mar 22 22:14:19 2003
@@ -1034,7 +1034,9 @@
 		}
 		o_tty->magic = 0;
 		(*o_tty->driver.refcount)--;
+		file_list_lock();
 		list_del(&o_tty->tty_files);
+		file_list_unlock();
 		free_tty_struct(o_tty);
 	}
 
@@ -1046,7 +1048,9 @@
 	}
 	tty->magic = 0;
 	(*tty->driver.refcount)--;
+	file_list_lock();
 	list_del(&tty->tty_files);
+	file_list_unlock();
 	module_put(tty->driver.owner);
 	free_tty_struct(tty);
 }
@@ -2114,7 +2118,8 @@
 	if (driver->flags & TTY_DRIVER_INSTALLED)
 		return 0;
 
-	error = register_chrdev(driver->major, driver->name, &tty_fops);
+	error = register_chrdev_region(driver->major, driver->minor_start,
+				       driver->num, driver->name, &tty_fops);
 	if (error < 0)
 		return error;
 	else if(driver->major == 0)
diff -Nru a/drivers/char/upd4990a.c b/drivers/char/upd4990a.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/upd4990a.c	Thu Mar 13 17:23:19 2003
@@ -0,0 +1,423 @@
+/*
+ * NEC PC-9800 Real Time Clock interface for Linux	
+ *
+ * Copyright (C) 1997-2001  Linux/98 project,
+ *			    Kyoto University Microcomputer Club.
+ *
+ * Based on:
+ *	drivers/char/rtc.c by Paul Gortmaker
+ *
+ * Changes:
+ *  2001-02-09	Call check_region on rtc_init and do not request I/O 0033h.
+ *		Call del_timer and release_region on rtc_exit. -- tak
+ *  2001-07-14	Rewrite <linux/upd4990a.h> and split to <linux/upd4990a.h>
+ *		and <asm-i386/upd4990a.h>.
+ *		Introduce a lot of spin_lock/unlock (&rtc_lock).
+ */
+
+#define RTC98_VERSION	"1.2"
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/upd4990a.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+/*
+ *	We sponge a minor off of the misc major. No need slurping
+ *	up another valuable major dev number for this. If you add
+ *	an ioctl, make sure you don't conflict with SPARC's RTC
+ *	ioctls.
+ */
+
+static struct fasync_struct *rtc_async_queue;
+
+static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
+
+static struct timer_list rtc_uie_timer;
+static u8 old_refclk;
+
+static int rtc_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg);
+
+static int rtc_read_proc(char *page, char **start, off_t off,
+			  int count, int *eof, void *data);
+
+/*
+ *	Bits in rtc_status. (5 bits of room for future expansion)
+ */
+
+#define RTC_IS_OPEN		0x01	/* means /dev/rtc is in use	*/
+#define RTC_TIMER_ON            0x02    /* not used */
+#define RTC_UIE_TIMER_ON        0x04	/* UIE emulation timer is active */
+
+/*
+ * rtc_status is never changed by rtc_interrupt, and ioctl/open/close is
+ * protected by the big kernel lock. However, ioctl can still disable the timer
+ * in rtc_status and then with del_timer after the interrupt has read
+ * rtc_status but before mod_timer is called, which would then reenable the
+ * timer (but you would need to have an awful timing before you'd trip on it)
+ */
+static unsigned char rtc_status;	/* bitmapped status byte.	*/
+static unsigned long rtc_irq_data;	/* our output to the world	*/
+
+static const unsigned char days_in_mo[] = 
+{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+extern spinlock_t rtc_lock;	/* defined in arch/i386/kernel/time.c */
+
+static void rtc_uie_intr(unsigned long data)
+{
+	u8 refclk, tmp;
+
+	/* Kernel timer does del_timer internally before calling
+	   each timer entry, so this is unnecessary.
+	   del_timer(&rtc_uie_timer);  */
+	spin_lock(&rtc_lock);
+
+	/* Detect rising edge of 1Hz reference clock.  */
+	refclk = UPD4990A_READ_DATA();
+	tmp = old_refclk & refclk;
+	old_refclk = ~refclk;
+	if (!(tmp & 1))
+		rtc_irq_data += 0x100;
+
+	spin_unlock(&rtc_lock);
+
+	if (!(tmp & 1)) {
+		/* Now do the rest of the actions */
+		wake_up_interruptible(&rtc_wait);
+		kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
+	}
+
+	rtc_uie_timer.expires = jiffies + 1;
+	add_timer(&rtc_uie_timer);
+}
+
+/*
+ *	Now all the various file operations that we export.
+ */
+
+static ssize_t rtc_read(struct file *file, char *buf,
+			size_t count, loff_t *ppos)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	unsigned long data;
+	ssize_t retval = 0;
+	
+	if (count < sizeof(unsigned long))
+		return -EINVAL;
+
+	add_wait_queue(&rtc_wait, &wait);
+
+	set_current_state(TASK_INTERRUPTIBLE);
+
+	do {
+		/* First make it right. Then make it fast. Putting this whole
+		 * block within the parentheses of a while would be too
+		 * confusing. And no, xchg() is not the answer. */
+		spin_lock_irq(&rtc_lock);
+		data = rtc_irq_data;
+		rtc_irq_data = 0;
+		spin_unlock_irq(&rtc_lock);
+
+		if (data != 0)
+			break;
+		if (file->f_flags & O_NONBLOCK) {
+			retval = -EAGAIN;
+			goto out;
+		}
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			goto out;
+		}
+		schedule();
+	} while (1);
+
+	retval = put_user(data, (unsigned long *)buf);
+	if (!retval)
+		retval = sizeof(unsigned long); 
+ out:
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&rtc_wait, &wait);
+
+	return retval;
+}
+
+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		     unsigned long arg)
+{
+	struct rtc_time wtime; 
+	struct upd4990a_raw_data raw;
+
+	switch (cmd) {
+	case RTC_UIE_OFF:	/* Mask ints from RTC updates.	*/
+		spin_lock_irq(&rtc_lock);
+		if (rtc_status & RTC_UIE_TIMER_ON) {
+			rtc_status &= ~RTC_UIE_TIMER_ON;
+			del_timer(&rtc_uie_timer);
+		}
+		spin_unlock_irq(&rtc_lock);
+		return 0;
+
+	case RTC_UIE_ON:	/* Allow ints for RTC updates.	*/
+		spin_lock_irq(&rtc_lock);
+		rtc_irq_data = 0;
+		if (!(rtc_status & RTC_UIE_TIMER_ON)) {
+			rtc_status |= RTC_UIE_TIMER_ON;
+			rtc_uie_timer.expires = jiffies + 1;
+			add_timer(&rtc_uie_timer);
+		}
+		/* Just in case... */
+		upd4990a_serial_command(UPD4990A_REGISTER_HOLD);
+		old_refclk = ~UPD4990A_READ_DATA();
+		spin_unlock_irq(&rtc_lock);
+		return 0;
+
+	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
+		spin_lock_irq(&rtc_lock);
+		upd4990a_get_time(&raw, 0);
+		spin_unlock_irq(&rtc_lock);
+
+		wtime.tm_sec	= BCD2BIN(raw.sec);
+		wtime.tm_min	= BCD2BIN(raw.min);
+		wtime.tm_hour	= BCD2BIN(raw.hour);
+		wtime.tm_mday	= BCD2BIN(raw.mday);
+		wtime.tm_mon	= raw.mon - 1; /* convert to 0-base */
+		wtime.tm_wday	= raw.wday;
+
+		/*
+		 * Account for differences between how the RTC uses the values
+		 * and how they are defined in a struct rtc_time;
+		 */
+		if ((wtime.tm_year = BCD2BIN(raw.year)) < 95)
+			wtime.tm_year += 100;
+
+		wtime.tm_isdst = 0;
+		break;
+
+	case RTC_SET_TIME:	/* Set the RTC */
+	{
+		int leap_yr;
+
+		if (!capable(CAP_SYS_TIME))
+			return -EACCES;
+
+		if (copy_from_user(&wtime, (struct rtc_time *) arg,
+				    sizeof (struct rtc_time)))
+			return -EFAULT;
+
+		/* Valid year is 1995 - 2094, inclusive.  */
+		if (wtime.tm_year < 95 || wtime.tm_year > 194)
+			return -EINVAL;
+
+		if (wtime.tm_mon > 11 || wtime.tm_mday == 0)
+			return -EINVAL;
+
+		/* For acceptable year domain (1995 - 2094),
+		   this IS sufficient.  */
+		leap_yr = !(wtime.tm_year % 4);
+
+		if (wtime.tm_mday > (days_in_mo[wtime.tm_mon]
+				     + (wtime.tm_mon == 2 && leap_yr)))
+			return -EINVAL;
+			
+		if (wtime.tm_hour >= 24
+		    || wtime.tm_min >= 60 || wtime.tm_sec >= 60)
+			return -EINVAL;
+
+		if (wtime.tm_wday > 6)
+			return -EINVAL;
+
+		raw.sec  = BIN2BCD(wtime.tm_sec);
+		raw.min  = BIN2BCD(wtime.tm_min);
+		raw.hour = BIN2BCD(wtime.tm_hour);
+		raw.mday = BIN2BCD(wtime.tm_mday);
+		raw.mon  = wtime.tm_mon + 1;
+		raw.wday = wtime.tm_wday;
+		raw.year = BIN2BCD(wtime.tm_year % 100);
+
+		spin_lock_irq(&rtc_lock);
+		upd4990a_set_time(&raw, 0);
+		spin_unlock_irq(&rtc_lock);
+
+		return 0;
+	}
+	default:
+		return -EINVAL;
+	}
+	return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
+}
+
+/*
+ *	We enforce only one user at a time here with the open/close.
+ *	Also clear the previous interrupt data on an open, and clean
+ *	up things on a close.
+ */
+
+static int rtc_open(struct inode *inode, struct file *file)
+{
+	spin_lock_irq(&rtc_lock);
+
+	if(rtc_status & RTC_IS_OPEN)
+		goto out_busy;
+
+	rtc_status |= RTC_IS_OPEN;
+
+	rtc_irq_data = 0;
+	spin_unlock_irq(&rtc_lock);
+	return 0;
+
+ out_busy:
+	spin_unlock_irq(&rtc_lock);
+	return -EBUSY;
+}
+
+static int rtc_fasync(int fd, struct file *filp, int on)
+{
+	return fasync_helper(fd, filp, on, &rtc_async_queue);
+}
+
+static int rtc_release(struct inode *inode, struct file *file)
+{
+	del_timer(&rtc_uie_timer);
+
+	if (file->f_flags & FASYNC)
+		rtc_fasync(-1, file, 0);
+
+	rtc_irq_data = 0;
+
+	/* No need for locking -- nobody else can do anything until this rmw is
+	 * committed, and no timer is running. */
+	rtc_status &= ~(RTC_IS_OPEN | RTC_UIE_TIMER_ON);
+	return 0;
+}
+
+static unsigned int rtc_poll(struct file *file, poll_table *wait)
+{
+	unsigned long l;
+
+	poll_wait(file, &rtc_wait, wait);
+
+	spin_lock_irq(&rtc_lock);
+	l = rtc_irq_data;
+	spin_unlock_irq(&rtc_lock);
+
+	if (l != 0)
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+/*
+ *	The various file operations we support.
+ */
+
+static struct file_operations rtc_fops = {
+	.owner		= THIS_MODULE,
+	.read		= rtc_read,
+	.poll		= rtc_poll,
+	.ioctl		= rtc_ioctl,
+	.open		= rtc_open,
+	.release	= rtc_release,
+	.fasync		= rtc_fasync,
+};
+
+static struct miscdevice rtc_dev=
+{
+	.minor	= RTC_MINOR,
+	.name	= "rtc",
+	.fops	= &rtc_fops,
+};
+
+static int __init rtc_init(void)
+{
+	if (!request_region(UPD4990A_IO, 1, "rtc")) {
+		printk(KERN_ERR "upd4990a: could not acquire I/O port %#x\n",
+			UPD4990A_IO);
+		return -EBUSY;
+	}
+
+#if 0
+	printk(KERN_INFO "\xB6\xDA\xDD\xC0\xDE \xC4\xDE\xB9\xB2 Driver\n");  /* Calender Clock Driver */
+#else
+	printk(KERN_INFO
+	       "Real Time Clock driver for NEC PC-9800 v" RTC98_VERSION "\n");
+#endif
+	misc_register(&rtc_dev);
+	create_proc_read_entry("driver/rtc", 0, NULL, rtc_read_proc, NULL);
+
+	init_timer(&rtc_uie_timer);
+	rtc_uie_timer.function = rtc_uie_intr;
+
+	return 0;
+}
+
+module_init (rtc_init);
+
+static void __exit rtc_exit(void)
+{
+	del_timer(&rtc_uie_timer);
+	release_region(UPD4990A_IO, 1);
+	remove_proc_entry("driver/rtc", NULL);
+	misc_deregister(&rtc_dev);
+}
+
+module_exit (rtc_exit);
+
+/*
+ *	Info exported via "/proc/driver/rtc".
+ */
+
+static inline int rtc_get_status(char *buf)
+{
+	char *p;
+	unsigned int year;
+	struct upd4990a_raw_data data;
+
+	p = buf;
+
+	upd4990a_get_time(&data, 0);
+
+	/*
+	 * There is no way to tell if the luser has the RTC set for local
+	 * time or for Universal Standard Time (GMT). Probably local though.
+	 */
+	if ((year = BCD2BIN(data.year) + 1900) < 1995)
+		year += 100;
+	p += sprintf(p,
+		     "rtc_time\t: %02d:%02d:%02d\n"
+		     "rtc_date\t: %04d-%02d-%02d\n",
+		     BCD2BIN(data.hour), BCD2BIN(data.min),
+		     BCD2BIN(data.sec),
+		     year, data.mon, BCD2BIN(data.mday));
+
+	return  p - buf;
+}
+
+static int rtc_read_proc(char *page, char **start, off_t off,
+			 int count, int *eof, void *data)
+{
+	int len = rtc_get_status(page);
+
+	if (len <= off + count)
+		*eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len > count)
+		len = count;
+	if (len < 0)
+		len = 0;
+	return len;
+}
diff -Nru a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
--- a/drivers/char/vme_scc.c	Fri Feb 14 15:18:33 2003
+++ b/drivers/char/vme_scc.c	Tue Mar 18 07:44:08 2003
@@ -1091,7 +1091,7 @@
 };
 
 
-static void __init vme_scc_console_init(void)
+static int __init vme_scc_console_init(void)
 {
 	if (vme_brdtype == VME_TYPE_MVME147 ||
 			vme_brdtype == VME_TYPE_MVME162 ||
@@ -1099,5 +1099,6 @@
 			vme_brdtype == VME_TYPE_BVME4000 ||
 			vme_brdtype == VME_TYPE_BVME6000)
 		register_console(&sercons);
+	return 0;
 }
 console_initcall(vme_scc_console_init);
diff -Nru a/drivers/char/vt.c b/drivers/char/vt.c
--- a/drivers/char/vt.c	Fri Mar  7 11:25:45 2003
+++ b/drivers/char/vt.c	Thu Mar 20 06:36:40 2003
@@ -792,6 +792,7 @@
 		memset(&ws, 0, sizeof(ws));
 		ws.ws_row = video_num_lines;
 		ws.ws_col = video_num_columns;
+		ws.ws_ypixel = video_scan_lines;
 		if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) &&
 		    vc_cons[currcons].d->vc_tty->pgrp > 0)
 			kill_pg(vc_cons[currcons].d->vc_tty->pgrp, SIGWINCH, 1);
@@ -3040,8 +3041,6 @@
 EXPORT_SYMBOL(default_red);
 EXPORT_SYMBOL(default_grn);
 EXPORT_SYMBOL(default_blu);
-EXPORT_SYMBOL(video_font_height);
-EXPORT_SYMBOL(video_scan_lines);
 EXPORT_SYMBOL(vc_cons_allocated);
 EXPORT_SYMBOL(update_region);
 EXPORT_SYMBOL(redraw_screen);
diff -Nru a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
--- a/drivers/char/vt_ioctl.c	Thu Oct 31 12:05:41 2002
+++ b/drivers/char/vt_ioctl.c	Thu Mar 20 06:36:40 2003
@@ -63,10 +63,6 @@
 asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on);
 #endif
 
-unsigned int video_font_height;
-unsigned int default_font_height;
-unsigned int video_scan_lines;
-
 /*
  * these are the valid i/o ports we're allowed to change. they map all the
  * video ports
@@ -191,38 +187,56 @@
 static inline int
 do_kdgkb_ioctl(int cmd, struct kbsentry *user_kdgkb, int perm)
 {
-	struct kbsentry tmp;
+	struct kbsentry *kbs;
 	char *p;
 	u_char *q;
 	int sz;
 	int delta;
 	char *first_free, *fj, *fnw;
 	int i, j, k;
+	int ret;
+
+	kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
+	if (!kbs) {
+		ret = -ENOMEM;
+		goto reterr;
+	}
 
 	/* we mostly copy too much here (512bytes), but who cares ;) */
-	if (copy_from_user(&tmp, user_kdgkb, sizeof(struct kbsentry)))
-		return -EFAULT;
-	tmp.kb_string[sizeof(tmp.kb_string)-1] = '\0';
-	if (tmp.kb_func >= MAX_NR_FUNC)
-		return -EINVAL;
-	i = tmp.kb_func;
+	if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
+		ret = -EFAULT;
+		goto reterr;
+	}
+	kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
+	if (kbs->kb_func >= MAX_NR_FUNC) {
+		ret = -EINVAL;
+		goto reterr;
+	}
+	i = kbs->kb_func;
 
 	switch (cmd) {
 	case KDGKBSENT:
-		sz = sizeof(tmp.kb_string) - 1; /* sz should have been
+		sz = sizeof(kbs->kb_string) - 1; /* sz should have been
 						  a struct member */
 		q = user_kdgkb->kb_string;
 		p = func_table[i];
 		if(p)
 			for ( ; *p && sz; p++, sz--)
-				if (put_user(*p, q++))
-					return -EFAULT;
-		if (put_user('\0', q))
-			return -EFAULT;
+				if (put_user(*p, q++)) {
+					ret = -EFAULT;
+					goto reterr;
+				}
+		if (put_user('\0', q)) {
+			ret = -EFAULT;
+			goto reterr;
+		}
+		kfree(kbs);
 		return ((p && *p) ? -EOVERFLOW : 0);
 	case KDSKBSENT:
-		if (!perm)
-			return -EPERM;
+		if (!perm) {
+			ret = -EPERM;
+			goto reterr;
+		}
 
 		q = func_table[i];
 		first_free = funcbufptr + (funcbufsize - funcbufleft);
@@ -233,7 +247,7 @@
 		else
 			fj = first_free;
 
-		delta = (q ? -strlen(q) : 1) + strlen(tmp.kb_string);
+		delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
 		if (delta <= funcbufleft) { 	/* it fits in current buf */
 		    if (j < MAX_NR_FUNC) {
 			memmove(fj + delta, fj, first_free - fj);
@@ -249,8 +263,10 @@
 		    while (sz < funcbufsize - funcbufleft + delta)
 		      sz <<= 1;
 		    fnw = (char *) kmalloc(sz, GFP_KERNEL);
-		    if(!fnw)
-		      return -ENOMEM;
+		    if(!fnw) {
+		      ret = -ENOMEM;
+		      goto reterr;
+		    }
 
 		    if (!q)
 		      func_table[i] = fj;
@@ -272,17 +288,19 @@
 		    funcbufleft = funcbufleft - delta + sz - funcbufsize;
 		    funcbufsize = sz;
 		}
-		strcpy(func_table[i], tmp.kb_string);
+		strcpy(func_table[i], kbs->kb_string);
 		break;
 	}
-	return 0;
+	ret = 0;
+reterr:
+	kfree(kbs);
+	return ret;
 }
 
 static inline int 
-do_fontx_ioctl(int cmd, struct consolefontdesc *user_cfd, int perm)
+do_fontx_ioctl(int cmd, struct consolefontdesc *user_cfd, int perm, struct console_font_op *op)
 {
 	struct consolefontdesc cfdarg;
-	struct console_font_op op;
 	int i;
 
 	if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc))) 
@@ -292,25 +310,25 @@
 	case PIO_FONTX:
 		if (!perm)
 			return -EPERM;
-		op.op = KD_FONT_OP_SET;
-		op.flags = KD_FONT_FLAG_OLD;
-		op.width = 8;
-		op.height = cfdarg.charheight;
-		op.charcount = cfdarg.charcount;
-		op.data = cfdarg.chardata;
-		return con_font_op(fg_console, &op);
+		op->op = KD_FONT_OP_SET;
+		op->flags = KD_FONT_FLAG_OLD;
+		op->width = 8;
+		op->height = cfdarg.charheight;
+		op->charcount = cfdarg.charcount;
+		op->data = cfdarg.chardata;
+		return con_font_op(fg_console, op);
 	case GIO_FONTX: {
-		op.op = KD_FONT_OP_GET;
-		op.flags = KD_FONT_FLAG_OLD;
-		op.width = 8;
-		op.height = cfdarg.charheight;
-		op.charcount = cfdarg.charcount;
-		op.data = cfdarg.chardata;
-		i = con_font_op(fg_console, &op);
+		op->op = KD_FONT_OP_GET;
+		op->flags = KD_FONT_FLAG_OLD;
+		op->width = 8;
+		op->height = cfdarg.charheight;
+		op->charcount = cfdarg.charcount;
+		op->data = cfdarg.chardata;
+		i = con_font_op(fg_console, op);
 		if (i)
 			return i;
-		cfdarg.charheight = op.height;
-		cfdarg.charcount = op.charcount;
+		cfdarg.charheight = op->height;
+		cfdarg.charcount = op->charcount;
 		if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc)))
 			return -EFAULT;
 		return 0;
@@ -350,12 +368,14 @@
 int vt_ioctl(struct tty_struct *tty, struct file * file,
 	     unsigned int cmd, unsigned long arg)
 {
-	int i, perm;
+	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
+	struct vc_data *vc = vc_cons[vt->vc_num].d;
+	struct console_font_op op;	/* used in multiple places here */
+	struct kbd_struct * kbd;
 	unsigned int console;
 	unsigned char ucval;
-	struct kbd_struct * kbd;
-	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
-
+	int i, perm;
+	
 	console = vt->vc_num;
 
 	if (!vc_cons_allocated(console)) 	/* impossible? */
@@ -830,7 +850,7 @@
 		__get_user(clin, &vtconsize->v_clin);
 		__get_user(vcol, &vtconsize->v_vcol);
 		__get_user(ccol, &vtconsize->v_ccol);
-		vlin = vlin ? vlin : video_scan_lines;
+		vlin = vlin ? vlin : vc->vc_scan_lines;
 		if (clin) {
 			if (ll) {
 				if (ll != vlin/clin)
@@ -850,9 +870,9 @@
 			return -EINVAL;
 		    
 		if (vlin)
-			video_scan_lines = vlin;
+			vc->vc_scan_lines = vlin;
 		if (clin)
-			video_font_height = clin;
+			vc->vc_font.height = clin;
 	
 		for (i = 0; i < MAX_NR_CONSOLES; i++)
 			vc_resize(i, cc, ll);
@@ -860,7 +880,6 @@
 	}
 
 	case PIO_FONT: {
-		struct console_font_op op;
 		if (!perm)
 			return -EPERM;
 		op.op = KD_FONT_OP_SET;
@@ -873,7 +892,6 @@
 	}
 
 	case GIO_FONT: {
-		struct console_font_op op;
 		op.op = KD_FONT_OP_GET;
 		op.flags = KD_FONT_FLAG_OLD;
 		op.width = 8;
@@ -893,7 +911,7 @@
 
 	case PIO_FONTX:
 	case GIO_FONTX:
-		return do_fontx_ioctl(cmd, (struct consolefontdesc *)arg, perm);
+		return do_fontx_ioctl(cmd, (struct consolefontdesc *)arg, perm, &op);
 
 	case PIO_FONTRESET:
 	{
@@ -906,7 +924,6 @@
 		return -ENOSYS;
 #else
 		{
-		struct console_font_op op;
 		op.op = KD_FONT_OP_SET_DEFAULT;
 		op.data = NULL;
 		i = con_font_op(fg_console, &op);
@@ -918,7 +935,6 @@
 	}
 
 	case KDFONTOP: {
-		struct console_font_op op;
 		if (copy_from_user(&op, (void *) arg, sizeof(op)))
 			return -EFAULT;
 		if (!perm && op.op != KD_FONT_OP_GET)
diff -Nru a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c
--- a/drivers/char/watchdog/acquirewdt.c	Thu Feb 27 17:28:13 2003
+++ b/drivers/char/watchdog/acquirewdt.c	Fri Feb 14 10:07:43 2003
@@ -141,6 +141,8 @@
 			spin_unlock(&acq_lock);
 			return -EBUSY;
 		}
+		if (nowayout)
+			MOD_INC_USE_COUNT;
 
 		/* Activate */
 		acq_is_open=1;
diff -Nru a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c
--- a/drivers/char/watchdog/ib700wdt.c	Thu Feb 27 17:13:12 2003
+++ b/drivers/char/watchdog/ib700wdt.c	Thu Mar  6 09:19:52 2003
@@ -228,6 +228,8 @@
 			spin_unlock(&ibwdt_lock);
 			return -EBUSY;
 		}
+		if (nowayout)
+			MOD_INC_USE_COUNT;
 
 		/* Activate */
 		ibwdt_is_open = 1;
diff -Nru a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c
--- a/drivers/char/watchdog/indydog.c	Thu Feb 27 17:28:13 2003
+++ b/drivers/char/watchdog/indydog.c	Fri Feb 14 10:03:27 2003
@@ -53,6 +53,9 @@
 	if( test_and_set_bit(0,&indydog_alive) )
 		return -EBUSY;
 
+	if (nowayout)
+		MOD_INC_USE_COUNT;
+
 	/*
 	 *	Activate timer
 	 */
diff -Nru a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
--- a/drivers/char/watchdog/machzwd.c	Thu Feb 27 17:28:13 2003
+++ b/drivers/char/watchdog/machzwd.c	Fri Feb 14 10:07:43 2003
@@ -390,6 +390,9 @@
 				return -EBUSY;
 			}
 
+			if (nowayout)
+				MOD_INC_USE_COUNT;
+
 			zf_is_open = 1;
 
 			spin_unlock(&zf_lock);
diff -Nru a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
--- a/drivers/char/watchdog/mixcomwd.c	Thu Feb 27 17:28:13 2003
+++ b/drivers/char/watchdog/mixcomwd.c	Fri Feb 14 10:03:27 2003
@@ -93,7 +93,9 @@
 	}
 	mixcomwd_ping();
 	
-	if (!nowayout) {
+	if (nowayout) {
+		MOD_INC_USE_COUNT;
+	} else {
 		if(mixcomwd_timer_alive) {
 			del_timer(&mixcomwd_timer);
 			mixcomwd_timer_alive=0;
diff -Nru a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
--- a/drivers/char/watchdog/pcwd.c	Thu Feb 27 17:28:13 2003
+++ b/drivers/char/watchdog/pcwd.c	Fri Feb 14 10:07:43 2003
@@ -430,7 +430,7 @@
 			atomic_inc( &open_allowed );
 			return -EBUSY;
 		}
-
+		MOD_INC_USE_COUNT;
 		/*  Enable the port  */
 		if (revision == PCWD_REVISION_C) {
 			spin_lock(&io_lock);
diff -Nru a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c
--- a/drivers/char/watchdog/sbc60xxwdt.c	Thu Feb 27 17:28:13 2003
+++ b/drivers/char/watchdog/sbc60xxwdt.c	Thu Mar  6 09:20:38 2003
@@ -206,7 +206,9 @@
 			/* Just in case we're already talking to someone... */
 			if(wdt_is_open)
 				return -EBUSY;
-
+			if (nowayout) {
+				MOD_INC_USE_COUNT;
+			}
 			/* Good, fire up the show */
 			wdt_is_open = 1;
 			wdt_startup();
diff -Nru a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
--- a/drivers/char/watchdog/sc520_wdt.c	Thu Feb 27 17:28:13 2003
+++ b/drivers/char/watchdog/sc520_wdt.c	Thu Mar  6 09:21:14 2003
@@ -229,6 +229,8 @@
 				return -EBUSY;
 			/* Good, fire up the show */
 			wdt_startup();
+			if (nowayout)
+				MOD_INC_USE_COUNT;
 
 			return 0;
 		default:
diff -Nru a/drivers/char/watchdog/shwdt.c b/drivers/char/watchdog/shwdt.c
--- a/drivers/char/watchdog/shwdt.c	Thu Feb 27 17:28:13 2003
+++ b/drivers/char/watchdog/shwdt.c	Thu Mar  6 09:21:14 2003
@@ -189,6 +189,10 @@
 			if (test_and_set_bit(0, &sh_is_open))
 				return -EBUSY;
 
+			if (nowayout) {
+				MOD_INC_USE_COUNT;
+			}
+
 			sh_wdt_start();
 
 			break;
diff -Nru a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
--- a/drivers/char/watchdog/softdog.c	Thu Feb 27 17:28:13 2003
+++ b/drivers/char/watchdog/softdog.c	Fri Feb 14 10:03:27 2003
@@ -103,7 +103,9 @@
 {
 	if(test_and_set_bit(0, &timer_alive))
 		return -EBUSY;
-
+	if (nowayout) {
+		MOD_INC_USE_COUNT;
+	}
 	/*
 	 *	Activate timer
 	 */
diff -Nru a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c
--- a/drivers/char/watchdog/wdt977.c	Thu Feb 27 17:28:13 2003
+++ b/drivers/char/watchdog/wdt977.c	Wed Feb 19 07:26:28 2003
@@ -99,6 +99,8 @@
 
 	if (nowayout)
 	{
+		MOD_INC_USE_COUNT;
+
 		/* do not permit disabling the watchdog by writing 0 to reg. 0xF2 */
 		if (!timeoutM) timeoutM = DEFAULT_TIMEOUT;
 	}
diff -Nru a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
--- a/drivers/char/watchdog/wdt_pci.c	Thu Feb 27 17:28:13 2003
+++ b/drivers/char/watchdog/wdt_pci.c	Thu Mar  6 09:21:14 2003
@@ -365,6 +365,9 @@
 			if (down_trylock(&open_sem))
 				return -EBUSY;
 
+			if (nowayout) {
+				MOD_INC_USE_COUNT;
+			}
 			/*
 			 *	Activate 
 			 */
diff -Nru a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
--- a/drivers/eisa/eisa-bus.c	Wed Mar  5 07:11:17 2003
+++ b/drivers/eisa/eisa-bus.c	Sat Mar 22 09:33:05 2003
@@ -191,7 +191,7 @@
 			eisa_register_device (root, str, i);
                 }
         }
-        printk (KERN_INFO "EISA: Detected %d card%s.\n", c, c < 2 ? "" : "s");
+        printk (KERN_INFO "EISA: Detected %d card%s.\n", c, c == 1 ? "" : "s");
 
 	return 0;
 }
diff -Nru a/drivers/fc4/fc_syms.c b/drivers/fc4/fc_syms.c
--- a/drivers/fc4/fc_syms.c	Tue Oct 29 00:10:52 2002
+++ b/drivers/fc4/fc_syms.c	Thu Mar 13 16:52:15 2003
@@ -2,7 +2,6 @@
  * We should not even be trying to compile this if we are not doing
  * a module.
  */
-#define __NO_VERSION__
 #include <linux/config.h>
 #include <linux/module.h>
 
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Thu Mar 13 11:52:16 2003
+++ b/drivers/i2c/busses/Kconfig	Thu Mar 20 11:47:34 2003
@@ -76,6 +76,24 @@
 	  in the lm_sensors package, which you can download at 
 	  http://www.lm-sensors.nu
 
+config I2C_ISA
+	tristate "  ISA Bus support"
+	depends on I2C && I2C_PROC && ISA && EXPERIMENTAL
+	help
+	  If you say yes to this option, support will be included for i2c
+	  interfaces that are on the ISA bus.
+
+	  This can also be built as a module which can be inserted and removed 
+	  while the kernel is running.  If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  The module will be called i2c-isa.
+
+	  You will also need the latest user-space utilties: you can find them
+	  in the lm_sensors package, which you can download at 
+	  http://www.lm-sensors.nu
+
+
 config I2C_PIIX4
 	tristate "  Intel PIIX4"
 	depends on I2C && I2C_PROC && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Thu Mar 13 11:52:16 2003
+++ b/drivers/i2c/busses/Makefile	Thu Mar 20 11:47:34 2003
@@ -6,4 +6,5 @@
 obj-$(CONFIG_I2C_AMD756)	+= i2c-amd756.o
 obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
 obj-$(CONFIG_I2C_I801)		+= i2c-i801.o
+obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
diff -Nru a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
--- a/drivers/i2c/busses/i2c-ali15x3.c	Thu Mar 13 16:39:32 2003
+++ b/drivers/i2c/busses/i2c-ali15x3.c	Thu Mar 20 03:14:08 2003
@@ -60,6 +60,8 @@
 
 /* Note: we assume there can only be one ALI15X3, with one SMBus interface */
 
+/* #define DEBUG 1 */
+
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
@@ -71,46 +73,46 @@
 #include <asm/io.h>
 
 /* ALI15X3 SMBus address offsets */
-#define SMBHSTSTS (0 + ali15x3_smba)
-#define SMBHSTCNT (1 + ali15x3_smba)
-#define SMBHSTSTART (2 + ali15x3_smba)
-#define SMBHSTCMD (7 + ali15x3_smba)
-#define SMBHSTADD (3 + ali15x3_smba)
-#define SMBHSTDAT0 (4 + ali15x3_smba)
-#define SMBHSTDAT1 (5 + ali15x3_smba)
-#define SMBBLKDAT (6 + ali15x3_smba)
+#define SMBHSTSTS	(0 + ali15x3_smba)
+#define SMBHSTCNT	(1 + ali15x3_smba)
+#define SMBHSTSTART	(2 + ali15x3_smba)
+#define SMBHSTCMD	(7 + ali15x3_smba)
+#define SMBHSTADD	(3 + ali15x3_smba)
+#define SMBHSTDAT0	(4 + ali15x3_smba)
+#define SMBHSTDAT1	(5 + ali15x3_smba)
+#define SMBBLKDAT	(6 + ali15x3_smba)
 
 /* PCI Address Constants */
-#define SMBCOM    0x004
-#define SMBBA     0x014
-#define SMBATPC   0x05B		/* used to unlock xxxBA registers */
-#define SMBHSTCFG 0x0E0
-#define SMBSLVC   0x0E1
-#define SMBCLK    0x0E2
-#define SMBREV    0x008
+#define SMBCOM		0x004
+#define SMBBA		0x014
+#define SMBATPC		0x05B	/* used to unlock xxxBA registers */
+#define SMBHSTCFG	0x0E0
+#define SMBSLVC		0x0E1
+#define SMBCLK		0x0E2
+#define SMBREV		0x008
 
 /* Other settings */
-#define MAX_TIMEOUT 200		/* times 1/100 sec */
-#define ALI15X3_SMB_IOSIZE 32
+#define MAX_TIMEOUT		200	/* times 1/100 sec */
+#define ALI15X3_SMB_IOSIZE	32
 
 /* this is what the Award 1004 BIOS sets them to on a ASUS P5A MB.
    We don't use these here. If the bases aren't set to some value we
    tell user to upgrade BIOS and we fail.
 */
-#define ALI15X3_SMB_DEFAULTBASE 0xE800
+#define ALI15X3_SMB_DEFAULTBASE	0xE800
 
 /* ALI15X3 address lock bits */
-#define ALI15X3_LOCK	0x06
+#define ALI15X3_LOCK		0x06
 
 /* ALI15X3 command constants */
-#define ALI15X3_ABORT      0x02
-#define ALI15X3_T_OUT      0x04
-#define ALI15X3_QUICK      0x00
-#define ALI15X3_BYTE       0x10
-#define ALI15X3_BYTE_DATA  0x20
-#define ALI15X3_WORD_DATA  0x30
-#define ALI15X3_BLOCK_DATA 0x40
-#define ALI15X3_BLOCK_CLR  0x80
+#define ALI15X3_ABORT		0x02
+#define ALI15X3_T_OUT		0x04
+#define ALI15X3_QUICK		0x00
+#define ALI15X3_BYTE		0x10
+#define ALI15X3_BYTE_DATA	0x20
+#define ALI15X3_WORD_DATA	0x30
+#define ALI15X3_BLOCK_DATA	0x40
+#define ALI15X3_BLOCK_CLR	0x80
 
 /* ALI15X3 status register bits */
 #define ALI15X3_STS_IDLE	0x04
@@ -129,55 +131,52 @@
 MODULE_PARM_DESC(force_addr,
 		 "Initialize the base address of the i2c controller");
 
-
-static void ali15x3_do_pause(unsigned int amount);
-static int ali15x3_transaction(void);
-
 static unsigned short ali15x3_smba = 0;
 
-int ali15x3_setup(struct pci_dev *ALI15X3_dev)
+static int ali15x3_setup(struct pci_dev *ALI15X3_dev)
 {
 	u16 a;
 	unsigned char temp;
 
-/* Check the following things:
-	- SMB I/O address is initialized
-	- Device is enabled
-	- We can use the addresses
-*/
-
-/* Unlock the register.
-   The data sheet says that the address registers are read-only
-   if the lock bits are 1, but in fact the address registers
-   are zero unless you clear the lock bits.
-*/
+	/* Check the following things:
+		- SMB I/O address is initialized
+		- Device is enabled
+		- We can use the addresses
+	*/
+
+	/* Unlock the register.
+	   The data sheet says that the address registers are read-only
+	   if the lock bits are 1, but in fact the address registers
+	   are zero unless you clear the lock bits.
+	*/
 	pci_read_config_byte(ALI15X3_dev, SMBATPC, &temp);
 	if (temp & ALI15X3_LOCK) {
 		temp &= ~ALI15X3_LOCK;
 		pci_write_config_byte(ALI15X3_dev, SMBATPC, temp);
 	}
 
-/* Determine the address of the SMBus area */
+	/* Determine the address of the SMBus area */
 	pci_read_config_word(ALI15X3_dev, SMBBA, &ali15x3_smba);
 	ali15x3_smba &= (0xffff & ~(ALI15X3_SMB_IOSIZE - 1));
 	if (ali15x3_smba == 0 && force_addr == 0) {
-		printk
-		    ("i2c-ali15x3.o: ALI15X3_smb region uninitialized - upgrade BIOS or use force_addr=0xaddr\n");
+		dev_err(&ALI15X3_dev->dev, "ALI15X3_smb region uninitialized "
+			"- upgrade BIOS or use force_addr=0xaddr\n");
 		return -ENODEV;
 	}
 
 	if(force_addr)
 		ali15x3_smba = force_addr & ~(ALI15X3_SMB_IOSIZE - 1);
 
-	if (check_region(ali15x3_smba, ALI15X3_SMB_IOSIZE)) {
-		printk
-		    ("i2c-ali15x3.o: ALI15X3_smb region 0x%x already in use!\n",
-		     ali15x3_smba);
+	if (!request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE, "ali15x3-smb")) {
+		dev_err(&ALI15X3_dev->dev,
+			"ALI15X3_smb region 0x%x already in use!\n",
+			ali15x3_smba);
 		return -ENODEV;
 	}
 
 	if(force_addr) {
-		printk("i2c-ali15x3.o: forcing ISA address 0x%04X\n", ali15x3_smba);
+		dev_info(&ALI15X3_dev->dev, "forcing ISA address 0x%04X\n",
+			ali15x3_smba);
 		if (PCIBIOS_SUCCESSFUL !=
 		    pci_write_config_word(ALI15X3_dev, SMBBA, ali15x3_smba))
 			return -ENODEV;
@@ -186,68 +185,60 @@
 			return -ENODEV;
 		if ((a & ~(ALI15X3_SMB_IOSIZE - 1)) != ali15x3_smba) {
 			/* make sure it works */
-			printk("i2c-ali15x3.o: force address failed - not supported?\n");
+			dev_err(&ALI15X3_dev->dev,
+				"force address failed - not supported?\n");
 			return -ENODEV;
 		}
 	}
-/* check if whole device is enabled */
+	/* check if whole device is enabled */
 	pci_read_config_byte(ALI15X3_dev, SMBCOM, &temp);
 	if ((temp & 1) == 0) {
-		printk("i2c-ali15x3: enabling SMBus device\n");
+		dev_info(&ALI15X3_dev->dev, "enabling SMBus device\n");
 		pci_write_config_byte(ALI15X3_dev, SMBCOM, temp | 0x01);
 	}
 
-/* Is SMB Host controller enabled? */
+	/* Is SMB Host controller enabled? */
 	pci_read_config_byte(ALI15X3_dev, SMBHSTCFG, &temp);
 	if ((temp & 1) == 0) {
-		printk("i2c-ali15x3: enabling SMBus controller\n");
+		dev_info(&ALI15X3_dev->dev, "enabling SMBus controller\n");
 		pci_write_config_byte(ALI15X3_dev, SMBHSTCFG, temp | 0x01);
 	}
 
-/* set SMB clock to 74KHz as recommended in data sheet */
+	/* set SMB clock to 74KHz as recommended in data sheet */
 	pci_write_config_byte(ALI15X3_dev, SMBCLK, 0x20);
 
-	/* Everything is happy, let's grab the memory and set things up. */
-	request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE, "ali15x3-smb");
-
-#ifdef DEBUG
-/*
-  The interrupt routing for SMB is set up in register 0x77 in the
-  1533 ISA Bridge device, NOT in the 7101 device.
-  Don't bother with finding the 1533 device and reading the register.
-  if ((....... & 0x0F) == 1)
-     printk("i2c-ali15x3.o: ALI15X3 using Interrupt 9 for SMBus.\n");
-*/
+	/*
+	  The interrupt routing for SMB is set up in register 0x77 in the
+	  1533 ISA Bridge device, NOT in the 7101 device.
+	  Don't bother with finding the 1533 device and reading the register.
+	if ((....... & 0x0F) == 1)
+		dev_dbg(&ALI15X3_dev->dev, "ALI15X3 using Interrupt 9 for SMBus.\n");
+	*/
 	pci_read_config_byte(ALI15X3_dev, SMBREV, &temp);
-	printk("i2c-ali15x3.o: SMBREV = 0x%X\n", temp);
-	printk("i2c-ali15x3.o: ALI15X3_smba = 0x%X\n", ali15x3_smba);
-#endif				/* DEBUG */
+	dev_dbg(&ALI15X3_dev->dev, "SMBREV = 0x%X\n", temp);
+	dev_dbg(&ALI15X3_dev->dev, "iALI15X3_smba = 0x%X\n", ali15x3_smba);
 
 	return 0;
 }
 
-
 /* Internally used pause function */
-void ali15x3_do_pause(unsigned int amount)
+static void ali15x3_do_pause(unsigned int amount)
 {
 	current->state = TASK_INTERRUPTIBLE;
 	schedule_timeout(amount);
 }
 
 /* Another internally used function */
-int ali15x3_transaction(void)
+static int ali15x3_transaction(struct i2c_adapter *adap)
 {
 	int temp;
 	int result = 0;
 	int timeout = 0;
 
-#ifdef DEBUG
-	printk
-	    ("i2c-ali15x3.o: Transaction (pre): STS=%02x, CNT=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, "
-	     "DAT1=%02x\n", inb_p(SMBHSTSTS), inb_p(SMBHSTCNT),
-	     inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
-	     inb_p(SMBHSTDAT1));
-#endif
+	dev_dbg(&adap->dev, "Transaction (pre): STS=%02x, CNT=%02x, CMD=%02x, "
+		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTSTS),
+		inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
+		inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
 
 	/* get status */
 	temp = inb_p(SMBHSTSTS);
@@ -255,43 +246,32 @@
 	/* Make sure the SMBus host is ready to start transmitting */
 	/* Check the busy bit first */
 	if (temp & ALI15X3_STS_BUSY) {
-/*
-   If the host controller is still busy, it may have timed out in the previous transaction,
-   resulting in a "SMBus Timeout" printk.
-   I've tried the following to reset a stuck busy bit.
-	1. Reset the controller with an ABORT command.
-	   (this doesn't seem to clear the controller if an external device is hung)
-	2. Reset the controller and the other SMBus devices with a T_OUT command.
-	   (this clears the host busy bit if an external device is hung,
-	   but it comes back upon a new access to a device)
-	3. Disable and reenable the controller in SMBHSTCFG
-   Worst case, nothing seems to work except power reset.
-*/
-/* Abort - reset the host controller */
-/*
-#ifdef DEBUG
-    printk("i2c-ali15x3.o: Resetting host controller to clear busy condition\n",temp);
-#endif
-    outb_p(ALI15X3_ABORT, SMBHSTCNT);
-    temp = inb_p(SMBHSTSTS);
-    if (temp & ALI15X3_STS_BUSY) {
-*/
-
-/*
-   Try resetting entire SMB bus, including other devices -
-   This may not work either - it clears the BUSY bit but
-   then the BUSY bit may come back on when you try and use the chip again.
-   If that's the case you are stuck.
-*/
-		printk
-		    ("i2c-ali15x3.o: Resetting entire SMB Bus to clear busy condition (%02x)\n",
-		     temp);
+	/*
+	   If the host controller is still busy, it may have timed out in the
+	   previous transaction, resulting in a "SMBus Timeout" Dev.
+	   I've tried the following to reset a stuck busy bit.
+		1. Reset the controller with an ABORT command.
+		   (this doesn't seem to clear the controller if an external
+		   device is hung)
+		2. Reset the controller and the other SMBus devices with a
+		   T_OUT command.  (this clears the host busy bit if an
+		   external device is hung, but it comes back upon a new access
+		   to a device)
+		3. Disable and reenable the controller in SMBHSTCFG
+	   Worst case, nothing seems to work except power reset.
+	*/
+	/* Abort - reset the host controller */
+	/*
+	   Try resetting entire SMB bus, including other devices -
+	   This may not work either - it clears the BUSY bit but
+	   then the BUSY bit may come back on when you try and use the chip again.
+	   If that's the case you are stuck.
+	*/
+		dev_info(&adap->dev, "Resetting entire SMB Bus to "
+			"clear busy condition (%02x)\n", temp);
 		outb_p(ALI15X3_T_OUT, SMBHSTCNT);
 		temp = inb_p(SMBHSTSTS);
 	}
-/*
-  }
-*/
 
 	/* now check the error bits and the busy bit */
 	if (temp & (ALI15X3_STS_ERR | ALI15X3_STS_BUSY)) {
@@ -302,9 +282,9 @@
 			/* this is probably going to be correctable only by a power reset
 			   as one of the bits now appears to be stuck */
 			/* This may be a bus or device with electrical problems. */
-			printk
-			    ("i2c-ali15x3.o: SMBus reset failed! (0x%02x) - controller or device on bus is probably hung\n",
-			     temp);
+			dev_err(&adap->dev, "SMBus reset failed! (0x%02x) - "
+				"controller or device on bus is probably hung\n",
+				temp);
 			return -1;
 		}
 	} else {
@@ -328,48 +308,41 @@
 	/* If the SMBus is still busy, we give up */
 	if (timeout >= MAX_TIMEOUT) {
 		result = -1;
-		printk("i2c-ali15x3.o: SMBus Timeout!\n");
+		dev_err(&adap->dev, "SMBus Timeout!\n");
 	}
 
 	if (temp & ALI15X3_STS_TERM) {
 		result = -1;
-#ifdef DEBUG
-		printk("i2c-ali15x3.o: Error: Failed bus transaction\n");
-#endif
+		dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
 	}
 
-/*
-  Unfortunately the ALI SMB controller maps "no response" and "bus collision"
-  into a single bit. No reponse is the usual case so don't
-  do a printk.
-  This means that bus collisions go unreported.
-*/
+	/*
+	  Unfortunately the ALI SMB controller maps "no response" and "bus
+	  collision" into a single bit. No reponse is the usual case so don't
+	  do a printk.
+	  This means that bus collisions go unreported.
+	*/
 	if (temp & ALI15X3_STS_COLL) {
 		result = -1;
-#ifdef DEBUG
-		printk
-		    ("i2c-ali15x3.o: Error: no response or bus collision ADD=%02x\n",
-		     inb_p(SMBHSTADD));
-#endif
+		dev_dbg(&adap->dev,
+			"Error: no response or bus collision ADD=%02x\n",
+			inb_p(SMBHSTADD));
 	}
 
-/* haven't ever seen this */
+	/* haven't ever seen this */
 	if (temp & ALI15X3_STS_DEV) {
 		result = -1;
-		printk("i2c-ali15x3.o: Error: device error\n");
+		dev_err(&adap->dev, "Error: device error\n");
 	}
-#ifdef DEBUG
-	printk
-	    ("i2c-ali15x3.o: Transaction (post): STS=%02x, CNT=%02x, CMD=%02x, ADD=%02x, "
-	     "DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTSTS), inb_p(SMBHSTCNT),
-	     inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
-	     inb_p(SMBHSTDAT1));
-#endif
+	dev_dbg(&adap->dev, "Transaction (post): STS=%02x, CNT=%02x, CMD=%02x, "
+		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTSTS),
+		inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
+		inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
 	return result;
 }
 
 /* Return -1 on error. */
-s32 ali15x3_access(struct i2c_adapter * adap, u16 addr,
+static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr,
 		   unsigned short flags, char read_write, u8 command,
 		   int size, union i2c_smbus_data * data)
 {
@@ -377,9 +350,9 @@
 	int temp;
 	int timeout;
 
-/* clear all the bits (clear-on-write) */
+	/* clear all the bits (clear-on-write) */
 	outb_p(0xFF, SMBHSTSTS);
-/* make sure SMBus is idle */
+	/* make sure SMBus is idle */
 	temp = inb_p(SMBHSTSTS);
 	for (timeout = 0;
 	     (timeout < MAX_TIMEOUT) && !(temp & ALI15X3_STS_IDLE);
@@ -388,14 +361,12 @@
 		temp = inb_p(SMBHSTSTS);
 	}
 	if (timeout >= MAX_TIMEOUT) {
-		printk("i2c-ali15x3.o: Idle wait Timeout! STS=0x%02x\n",
-		       temp);
+		dev_err(&adap->dev, "Idle wait Timeout! STS=0x%02x\n", temp);
 	}
 
 	switch (size) {
 	case I2C_SMBUS_PROC_CALL:
-		printk
-		    ("i2c-ali15x3.o: I2C_SMBUS_PROC_CALL not supported!\n");
+		dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
 		return -1;
 	case I2C_SMBUS_QUICK:
 		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
@@ -442,7 +413,8 @@
 				data->block[0] = len;
 			}
 			outb_p(len, SMBHSTDAT0);
-			outb_p(inb_p(SMBHSTCNT) | ALI15X3_BLOCK_CLR, SMBHSTCNT);	/* Reset SMBBLKDAT */
+			/* Reset SMBBLKDAT */
+			outb_p(inb_p(SMBHSTCNT) | ALI15X3_BLOCK_CLR, SMBHSTCNT);
 			for (i = 1; i <= len; i++)
 				outb_p(data->block[i], SMBBLKDAT);
 		}
@@ -452,7 +424,7 @@
 
 	outb_p(size, SMBHSTCNT);	/* output command */
 
-	if (ali15x3_transaction())	/* Error in transaction */
+	if (ali15x3_transaction(adap))	/* Error in transaction */
 		return -1;
 
 	if ((read_write == I2C_SMBUS_WRITE) || (size == ALI15X3_QUICK))
@@ -474,22 +446,19 @@
 		if (len > 32)
 			len = 32;
 		data->block[0] = len;
-		outb_p(inb_p(SMBHSTCNT) | ALI15X3_BLOCK_CLR, SMBHSTCNT);	/* Reset SMBBLKDAT */
+		/* Reset SMBBLKDAT */
+		outb_p(inb_p(SMBHSTCNT) | ALI15X3_BLOCK_CLR, SMBHSTCNT);
 		for (i = 1; i <= data->block[0]; i++) {
 			data->block[i] = inb_p(SMBBLKDAT);
-#ifdef DEBUG
-			printk
-			    ("i2c-ali15x3.o: Blk: len=%d, i=%d, data=%02x\n",
-			     len, i, data->block[i]);
-#endif	/* DEBUG */
+			dev_dbg(&adap->dev, "Blk: len=%d, i=%d, data=%02x\n",
+				len, i, data->block[i]);
 		}
 		break;
 	}
 	return 0;
 }
 
-
-u32 ali15x3_func(struct i2c_adapter *adapter)
+static u32 ali15x3_func(struct i2c_adapter *adapter)
 {
 	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
 	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
@@ -510,8 +479,6 @@
 	.algo		= &smbus_algorithm,
 };
 
-
-
 static struct pci_device_id ali15x3_ids[] __devinitdata = {
 	{
 	.vendor =	PCI_VENDOR_ID_AL,
@@ -525,9 +492,8 @@
 static int __devinit ali15x3_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	if (ali15x3_setup(dev)) {
-		printk
-		    ("i2c-ali15x3.o: ALI15X3 not detected, module not inserted.\n");
-
+		dev_err(&dev->dev,
+			"ALI15X3 not detected, module not inserted.\n");
 		return -ENODEV;
 	}
 
@@ -557,17 +523,15 @@
 	return pci_module_init(&ali15x3_driver);
 }
 
-
 static void __exit i2c_ali15x3_exit(void)
 {
 	pci_unregister_driver(&ali15x3_driver);
 	release_region(ali15x3_smba, ALI15X3_SMB_IOSIZE);
 }
 
-
-
-MODULE_AUTHOR
-    ("Frodo Looijaard <frodol@dds.nl>, Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker <mdsxyz123@yahoo.com>");
+MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl>, "
+		"Philip Edelbrock <phil@netroedge.com>, "
+		"and Mark D. Studebaker <mdsxyz123@yahoo.com>");
 MODULE_DESCRIPTION("ALI15X3 SMBus driver");
 MODULE_LICENSE("GPL");
 
diff -Nru a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
--- a/drivers/i2c/busses/i2c-amd756.c	Thu Mar 13 16:39:32 2003
+++ b/drivers/i2c/busses/i2c-amd756.c	Thu Mar 20 03:14:12 2003
@@ -35,6 +35,8 @@
    Note: we assume there can only be one device, with one SMBus interface.
 */
 
+/* #define DEBUG 1 */
+
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -46,44 +48,42 @@
 #include <linux/init.h>
 #include <asm/io.h>
 
-#define DRV_NAME	"i2c-amd756"
-
 /* AMD756 SMBus address offsets */
-#define SMB_ADDR_OFFSET        0xE0
-#define SMB_IOSIZE             16
-#define SMB_GLOBAL_STATUS      (0x0 + amd756_ioport)
-#define SMB_GLOBAL_ENABLE      (0x2 + amd756_ioport)
-#define SMB_HOST_ADDRESS       (0x4 + amd756_ioport)
-#define SMB_HOST_DATA          (0x6 + amd756_ioport)
-#define SMB_HOST_COMMAND       (0x8 + amd756_ioport)
-#define SMB_HOST_BLOCK_DATA    (0x9 + amd756_ioport)
-#define SMB_HAS_DATA           (0xA + amd756_ioport)
-#define SMB_HAS_DEVICE_ADDRESS (0xC + amd756_ioport)
-#define SMB_HAS_HOST_ADDRESS   (0xE + amd756_ioport)
-#define SMB_SNOOP_ADDRESS      (0xF + amd756_ioport)
+#define SMB_ADDR_OFFSET		0xE0
+#define SMB_IOSIZE		16
+#define SMB_GLOBAL_STATUS	(0x0 + amd756_ioport)
+#define SMB_GLOBAL_ENABLE	(0x2 + amd756_ioport)
+#define SMB_HOST_ADDRESS	(0x4 + amd756_ioport)
+#define SMB_HOST_DATA		(0x6 + amd756_ioport)
+#define SMB_HOST_COMMAND	(0x8 + amd756_ioport)
+#define SMB_HOST_BLOCK_DATA	(0x9 + amd756_ioport)
+#define SMB_HAS_DATA		(0xA + amd756_ioport)
+#define SMB_HAS_DEVICE_ADDRESS	(0xC + amd756_ioport)
+#define SMB_HAS_HOST_ADDRESS	(0xE + amd756_ioport)
+#define SMB_SNOOP_ADDRESS	(0xF + amd756_ioport)
 
 /* PCI Address Constants */
 
 /* address of I/O space */
-#define SMBBA     0x058		/* mh */
-#define SMBBANFORCE     0x014
+#define SMBBA		0x058		/* mh */
+#define SMBBANFORCE	0x014
 
 /* general configuration */
-#define SMBGCFG   0x041		/* mh */
+#define SMBGCFG		0x041		/* mh */
 
 /* silicon revision code */
-#define SMBREV    0x008
+#define SMBREV		0x008
 
 /* Other settings */
-#define MAX_TIMEOUT 500
+#define MAX_TIMEOUT	500
 
 /* AMD756 constants */
-#define AMD756_QUICK        0x00
-#define AMD756_BYTE         0x01
-#define AMD756_BYTE_DATA    0x02
-#define AMD756_WORD_DATA    0x03
-#define AMD756_PROCESS_CALL 0x04
-#define AMD756_BLOCK_DATA   0x05
+#define AMD756_QUICK		0x00
+#define AMD756_BYTE		0x01
+#define AMD756_BYTE_DATA	0x02
+#define AMD756_WORD_DATA	0x03
+#define AMD756_PROCESS_CALL	0x04
+#define AMD756_BLOCK_DATA	0x05
 
 
 static unsigned short amd756_ioport = 0;
@@ -101,36 +101,36 @@
 	schedule_timeout(amount);
 }
 
-#define GS_ABRT_STS (1 << 0)
-#define GS_COL_STS (1 << 1)
-#define GS_PRERR_STS (1 << 2)
-#define GS_HST_STS (1 << 3)
-#define GS_HCYC_STS (1 << 4)
-#define GS_TO_STS (1 << 5)
-#define GS_SMB_STS (1 << 11)
-
-#define GS_CLEAR_STS (GS_ABRT_STS | GS_COL_STS | GS_PRERR_STS | \
-  GS_HCYC_STS | GS_TO_STS )
-
-#define GE_CYC_TYPE_MASK (7)
-#define GE_HOST_STC (1 << 3)
-#define GE_ABORT (1 << 5)
+#define GS_ABRT_STS	(1 << 0)
+#define GS_COL_STS	(1 << 1)
+#define GS_PRERR_STS	(1 << 2)
+#define GS_HST_STS	(1 << 3)
+#define GS_HCYC_STS	(1 << 4)
+#define GS_TO_STS	(1 << 5)
+#define GS_SMB_STS	(1 << 11)
+
+#define GS_CLEAR_STS	(GS_ABRT_STS | GS_COL_STS | GS_PRERR_STS | \
+			 GS_HCYC_STS | GS_TO_STS )
+
+#define GE_CYC_TYPE_MASK	(7)
+#define GE_HOST_STC		(1 << 3)
+#define GE_ABORT		(1 << 5)
 
 
-static int amd756_transaction(void)
+static int amd756_transaction(struct i2c_adapter *adap)
 {
 	int temp;
 	int result = 0;
 	int timeout = 0;
 
-	pr_debug(DRV_NAME
-	       ": Transaction (pre): GS=%04x, GE=%04x, ADD=%04x, DAT=%04x\n",
-	       inw_p(SMB_GLOBAL_STATUS), inw_p(SMB_GLOBAL_ENABLE),
-	       inw_p(SMB_HOST_ADDRESS), inb_p(SMB_HOST_DATA));
+	dev_dbg(&adap->dev, ": Transaction (pre): GS=%04x, GE=%04x, ADD=%04x, "
+		"DAT=%04x\n", inw_p(SMB_GLOBAL_STATUS),
+		inw_p(SMB_GLOBAL_ENABLE), inw_p(SMB_HOST_ADDRESS),
+		inb_p(SMB_HOST_DATA));
 
 	/* Make sure the SMBus host is ready to start transmitting */
 	if ((temp = inw_p(SMB_GLOBAL_STATUS)) & (GS_HST_STS | GS_SMB_STS)) {
-		pr_debug(DRV_NAME ": SMBus busy (%04x). Waiting... \n", temp);
+		dev_dbg(&adap->dev, ": SMBus busy (%04x). Waiting... \n", temp);
 		do {
 			amd756_do_pause(1);
 			temp = inw_p(SMB_GLOBAL_STATUS);
@@ -138,7 +138,7 @@
 		         (timeout++ < MAX_TIMEOUT));
 		/* If the SMBus is still busy, we give up */
 		if (timeout >= MAX_TIMEOUT) {
-			pr_debug(DRV_NAME ": Busy wait timeout (%04x)\n", temp);
+			dev_dbg(&adap->dev, ": Busy wait timeout (%04x)\n", temp);
 			goto abort;
 		}
 		timeout = 0;
@@ -155,46 +155,46 @@
 
 	/* If the SMBus is still busy, we give up */
 	if (timeout >= MAX_TIMEOUT) {
-		pr_debug(DRV_NAME ": Completion timeout!\n");
+		dev_dbg(&adap->dev, ": Completion timeout!\n");
 		goto abort;
 	}
 
 	if (temp & GS_PRERR_STS) {
 		result = -1;
-		pr_debug(DRV_NAME ": SMBus Protocol error (no response)!\n");
+		dev_dbg(&adap->dev, ": SMBus Protocol error (no response)!\n");
 	}
 
 	if (temp & GS_COL_STS) {
 		result = -1;
-		printk(KERN_WARNING DRV_NAME " SMBus collision!\n");
+		dev_warn(&adap->dev, " SMBus collision!\n");
 	}
 
 	if (temp & GS_TO_STS) {
 		result = -1;
-		pr_debug(DRV_NAME ": SMBus protocol timeout!\n");
+		dev_dbg(&adap->dev, ": SMBus protocol timeout!\n");
 	}
 
 	if (temp & GS_HCYC_STS)
-		pr_debug(DRV_NAME " SMBus protocol success!\n");
+		dev_dbg(&adap->dev, " SMBus protocol success!\n");
 
 	outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS);
 
 #ifdef DEBUG
 	if (((temp = inw_p(SMB_GLOBAL_STATUS)) & GS_CLEAR_STS) != 0x00) {
-		pr_debug(DRV_NAME
-		         ": Failed reset at end of transaction (%04x)\n", temp);
+		dev_dbg(&adap->dev,
+			": Failed reset at end of transaction (%04x)\n", temp);
 	}
-
-	pr_debug(DRV_NAME
-		 ": Transaction (post): GS=%04x, GE=%04x, ADD=%04x, DAT=%04x\n",
-		 inw_p(SMB_GLOBAL_STATUS), inw_p(SMB_GLOBAL_ENABLE),
-		 inw_p(SMB_HOST_ADDRESS), inb_p(SMB_HOST_DATA));
 #endif
 
+	dev_dbg(&adap->dev,
+		": Transaction (post): GS=%04x, GE=%04x, ADD=%04x, DAT=%04x\n",
+		inw_p(SMB_GLOBAL_STATUS), inw_p(SMB_GLOBAL_ENABLE),
+		inw_p(SMB_HOST_ADDRESS), inb_p(SMB_HOST_DATA));
+
 	return result;
 
  abort:
-	printk(KERN_WARNING DRV_NAME ": Sending abort.\n");
+	dev_warn(&adap->dev, ": Sending abort.\n");
 	outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE);
 	amd756_do_pause(100);
 	outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS);
@@ -211,7 +211,7 @@
 	/** TODO: Should I supporte the 10-bit transfers? */
 	switch (size) {
 	case I2C_SMBUS_PROC_CALL:
-		pr_debug(DRV_NAME ": I2C_SMBUS_PROC_CALL not supported!\n");
+		dev_dbg(&adap->dev, ": I2C_SMBUS_PROC_CALL not supported!\n");
 		/* TODO: Well... It is supported, I'm just not sure what to do here... */
 		return -1;
 	case I2C_SMBUS_QUICK:
@@ -266,7 +266,7 @@
 	/* How about enabling interrupts... */
 	outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE);
 
-	if (amd756_transaction())	/* Error in transaction */
+	if (amd756_transaction(adap))	/* Error in transaction */
 		return -1;
 
 	if ((read_write == I2C_SMBUS_WRITE) || (size == AMD756_QUICK))
@@ -334,7 +334,7 @@
 	u8 temp;
 	
 	if (amd756_ioport) {
-		printk(KERN_ERR DRV_NAME ": Only one device supported. "
+		dev_err(&pdev->dev, ": Only one device supported. "
 		       "(you have a strange motherboard, btw..)\n");
 		return -ENODEV;
 	}
@@ -351,8 +351,8 @@
 
 		pci_read_config_byte(pdev, SMBGCFG, &temp);
 		if ((temp & 128) == 0) {
-			printk(KERN_ERR DRV_NAME
-			       ": Error: SMBus controller I/O not enabled!\n");
+			dev_err(&pdev->dev,
+				": Error: SMBus controller I/O not enabled!\n");
 			return -ENODEV;
 		}
 
@@ -364,16 +364,14 @@
 	}
 
 	if (!request_region(amd756_ioport, SMB_IOSIZE, "amd756-smbus")) {
-		printk(KERN_ERR DRV_NAME
-		       ": SMB region 0x%x already in use!\n", amd756_ioport);
+		dev_err(&pdev->dev, ": SMB region 0x%x already in use!\n",
+			amd756_ioport);
 		return -ENODEV;
 	}
 
-#ifdef DEBUG
 	pci_read_config_byte(pdev, SMBREV, &temp);
-	printk(KERN_DEBUG DRV_NAME ": SMBREV = 0x%X\n", temp);
-	printk(KERN_DEBUG DRV_NAME ": AMD756_smba = 0x%X\n", amd756_ioport);
-#endif
+	dev_dbg(&pdev->dev, ": SMBREV = 0x%X\n", temp);
+	dev_dbg(&pdev->dev, ": AMD756_smba = 0x%X\n", amd756_ioport);
 
 	/* set up the driverfs linkage to our parent device */
 	amd756_adapter.dev.parent = &pdev->dev;
@@ -383,8 +381,8 @@
 
 	error = i2c_add_adapter(&amd756_adapter);
 	if (error) {
-		printk(KERN_ERR DRV_NAME
-		       ": Adapter registration failed, module not inserted.\n");
+		dev_err(&pdev->dev,
+			": Adapter registration failed, module not inserted.\n");
 		goto out_err;
 	}
 
diff -Nru a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
--- a/drivers/i2c/busses/i2c-amd8111.c	Thu Mar 13 16:39:32 2003
+++ b/drivers/i2c/busses/i2c-amd8111.c	Thu Mar 20 11:28:04 2003
@@ -74,7 +74,7 @@
 		udelay(1);
 
 	if (!timeout) {
-		printk(KERN_WARNING "i2c-amd8111.c: Timeout while waiting for IBF to clear\n");
+		dev_warn(&smbus->dev->dev, "Timeout while waiting for IBF to clear\n");
 		return -1;
 	}
 
@@ -89,7 +89,7 @@
 		udelay(1);
 
 	if (!timeout) {
-		printk(KERN_WARNING "i2c-amd8111.c: Timeout while waiting for OBF to set\n");
+		dev_warn(&smbus->dev->dev, "Timeout while waiting for OBF to set\n");
 		return -1;
 	}
 
@@ -256,11 +256,11 @@
 		case I2C_SMBUS_BLOCK_DATA_PEC:
 		case I2C_SMBUS_PROC_CALL_PEC:
 		case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
-			printk(KERN_WARNING "i2c-amd8111.c: Unexpected software PEC transaction %d\n.", size);
+			dev_warn(&adap->dev, "Unexpected software PEC transaction %d\n.", size);
 			return -1;
 
 		default:
-			printk(KERN_WARNING "i2c-amd8111.c: Unsupported transaction %d\n", size);
+			dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
 			return -1;
 	}
 
@@ -392,7 +392,7 @@
 }
 
 static struct pci_driver amd8111_driver = {
-	.name		= "amd8111 smbus",
+	.name		= "amd8111 smbus 2",
 	.id_table	= amd8111_ids,
 	.probe		= amd8111_probe,
 	.remove		= __devexit_p(amd8111_remove),
diff -Nru a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
--- a/drivers/i2c/busses/i2c-i801.c	Thu Mar 13 16:39:32 2003
+++ b/drivers/i2c/busses/i2c-i801.c	Tue Mar 18 06:36:23 2003
@@ -49,65 +49,48 @@
 #include <linux/i2c.h>
 #include <asm/io.h>
 
-MODULE_LICENSE("GPL");
-
 #ifdef I2C_FUNC_SMBUS_BLOCK_DATA_PEC
 #define HAVE_PEC
 #endif
 
-#ifndef PCI_DEVICE_ID_INTEL_82801CA_SMBUS
-#define PCI_DEVICE_ID_INTEL_82801CA_SMBUS	0x2483
-#endif
-
-#ifndef PCI_DEVICE_ID_INTEL_82801DB_SMBUS
-#define PCI_DEVICE_ID_INTEL_82801DB_SMBUS	0x24C3
-#endif
-
-static int supported[] = {PCI_DEVICE_ID_INTEL_82801AA_3,
-                          PCI_DEVICE_ID_INTEL_82801AB_3,
-                          PCI_DEVICE_ID_INTEL_82801BA_2,
-			  PCI_DEVICE_ID_INTEL_82801CA_SMBUS,
-			  PCI_DEVICE_ID_INTEL_82801DB_SMBUS,
-                          0 };
-
 /* I801 SMBus address offsets */
-#define SMBHSTSTS (0 + i801_smba)
-#define SMBHSTCNT (2 + i801_smba)
-#define SMBHSTCMD (3 + i801_smba)
-#define SMBHSTADD (4 + i801_smba)
-#define SMBHSTDAT0 (5 + i801_smba)
-#define SMBHSTDAT1 (6 + i801_smba)
-#define SMBBLKDAT (7 + i801_smba)
-#define SMBPEC    (8 + i801_smba)	/* ICH4 only */
-#define SMBAUXSTS (12 + i801_smba)	/* ICH4 only */
-#define SMBAUXCTL (13 + i801_smba)	/* ICH4 only */
+#define SMBHSTSTS	(0 + i801_smba)
+#define SMBHSTCNT	(2 + i801_smba)
+#define SMBHSTCMD	(3 + i801_smba)
+#define SMBHSTADD	(4 + i801_smba)
+#define SMBHSTDAT0	(5 + i801_smba)
+#define SMBHSTDAT1	(6 + i801_smba)
+#define SMBBLKDAT	(7 + i801_smba)
+#define SMBPEC		(8 + i801_smba)	/* ICH4 only */
+#define SMBAUXSTS	(12 + i801_smba)	/* ICH4 only */
+#define SMBAUXCTL	(13 + i801_smba)	/* ICH4 only */
 
 /* PCI Address Constants */
-#define SMBBA     0x020
-#define SMBHSTCFG 0x040
-#define SMBREV    0x008
+#define SMBBA		0x020
+#define SMBHSTCFG	0x040
+#define SMBREV		0x008
 
 /* Host configuration bits for SMBHSTCFG */
-#define SMBHSTCFG_HST_EN      1
-#define SMBHSTCFG_SMB_SMI_EN  2
-#define SMBHSTCFG_I2C_EN      4
+#define SMBHSTCFG_HST_EN	1
+#define SMBHSTCFG_SMB_SMI_EN	2
+#define SMBHSTCFG_I2C_EN	4
 
 /* Other settings */
-#define MAX_TIMEOUT 100
-#define ENABLE_INT9 0	/* set to 0x01 to enable - untested */
+#define MAX_TIMEOUT		100
+#define ENABLE_INT9		0	/* set to 0x01 to enable - untested */
 
 /* I801 command constants */
-#define I801_QUICK          0x00
-#define I801_BYTE           0x04
-#define I801_BYTE_DATA      0x08
-#define I801_WORD_DATA      0x0C
-#define I801_PROC_CALL      0x10	/* later chips only, unimplemented */
-#define I801_BLOCK_DATA     0x14
-#define I801_I2C_BLOCK_DATA 0x18	/* unimplemented */
-#define I801_BLOCK_LAST     0x34
-#define I801_I2C_BLOCK_LAST 0x38	/* unimplemented */
-#define I801_START          0x40
-#define I801_PEC_EN         0x80	/* ICH4 only */
+#define I801_QUICK		0x00
+#define I801_BYTE		0x04
+#define I801_BYTE_DATA		0x08
+#define I801_WORD_DATA		0x0C
+#define I801_PROC_CALL		0x10	/* later chips only, unimplemented */
+#define I801_BLOCK_DATA		0x14
+#define I801_I2C_BLOCK_DATA	0x18	/* unimplemented */
+#define I801_BLOCK_LAST		0x34
+#define I801_I2C_BLOCK_LAST	0x38	/* unimplemented */
+#define I801_START		0x40
+#define I801_PEC_EN		0x80	/* ICH4 only */
 
 /* insmod parameters */
 
@@ -119,10 +102,6 @@
 		 "Forcibly enable the I801 at the given address. "
 		 "EXTREMELY DANGEROUS!");
 
-
-
-
-
 static void i801_do_pause(unsigned int amount);
 static int i801_transaction(void);
 static int i801_block_transaction(union i2c_smbus_data *data,
@@ -135,7 +114,6 @@
 static int i801_setup(struct pci_dev *dev)
 {
 	int error_return = 0;
-	int *num = supported;
 	unsigned char temp;
 
 	/* Note: we keep on searching until we have found 'function 3' */
@@ -143,101 +121,90 @@
 		return -ENODEV;
 
 	I801_dev = dev;
-	isich4 = *num == PCI_DEVICE_ID_INTEL_82801DB_SMBUS;
+	if (dev->device == PCI_DEVICE_ID_INTEL_82801DB_3)
+		isich4 = 1;
+	else
+		isich4 = 0;
 
-/* Determine the address of the SMBus areas */
+	/* Determine the address of the SMBus areas */
 	if (force_addr) {
 		i801_smba = force_addr & 0xfff0;
 	} else {
 		pci_read_config_word(I801_dev, SMBBA, &i801_smba);
 		i801_smba &= 0xfff0;
 		if(i801_smba == 0) {
-			printk(KERN_ERR "i2c-i801.o: SMB base address uninitialized - upgrade BIOS or use force_addr=0xaddr\n");
+			dev_err(&dev->dev, "SMB base address uninitialized"
+				"- upgrade BIOS or use force_addr=0xaddr\n");
 			return -ENODEV;
 		}
 	}
 
-	if (check_region(i801_smba, (isich4 ? 16 : 8))) {
-		printk
-		    (KERN_ERR "i2c-i801.o: I801_smb region 0x%x already in use!\n",
-		     i801_smba);
-		error_return = -ENODEV;
+	if (!request_region(i801_smba, (isich4 ? 16 : 8), "i801-smbus")) {
+		dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n",
+			i801_smba);
+		error_return = -EBUSY;
 		goto END;
 	}
 
 	pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
 	temp &= ~SMBHSTCFG_I2C_EN;	/* SMBus timing */
 	pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
-/* If force_addr is set, we program the new address here. Just to make
-   sure, we disable the device first. */
+
+	/* If force_addr is set, we program the new address here. Just to make
+	   sure, we disable the device first. */
 	if (force_addr) {
 		pci_write_config_byte(I801_dev, SMBHSTCFG, temp & 0xfe);
 		pci_write_config_word(I801_dev, SMBBA, i801_smba);
 		pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 0x01);
-		printk
-		    (KERN_WARNING "i2c-i801.o: WARNING: I801 SMBus interface set to new "
-		     "address %04x!\n", i801_smba);
+		dev_warn(&dev->dev, "WARNING: I801 SMBus interface set to "
+			"new address %04x!\n", i801_smba);
 	} else if ((temp & 1) == 0) {
 		pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 1);
-		printk(KERN_WARNING "i2c-i801.o: enabling SMBus device\n");
+		dev_warn(&dev->dev, "enabling SMBus device\n");
 	}
 
-	request_region(i801_smba, (isich4 ? 16 : 8), "i801-smbus");
-
-#ifdef DEBUG
 	if (temp & 0x02)
-		printk
-		    (KERN_DEBUG "i2c-i801.o: I801 using Interrupt SMI# for SMBus.\n");
+		dev_dbg(&dev->dev, "I801 using Interrupt SMI# for SMBus.\n");
 	else
-		printk
-		    (KERN_DEBUG "i2c-i801.o: I801 using PCI Interrupt for SMBus.\n");
+		dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n");
 
 	pci_read_config_byte(I801_dev, SMBREV, &temp);
-	printk(KERN_DEBUG "i2c-i801.o: SMBREV = 0x%X\n", temp);
-	printk(KERN_DEBUG "i2c-i801.o: I801_smba = 0x%X\n", i801_smba);
-#endif				/* DEBUG */
+	dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
+	dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba);
 
-      END:
+END:
 	return error_return;
 }
 
 
-void i801_do_pause(unsigned int amount)
+static void i801_do_pause(unsigned int amount)
 {
 	current->state = TASK_INTERRUPTIBLE;
 	schedule_timeout(amount);
 }
 
-int i801_transaction(void)
+static int i801_transaction(void)
 {
 	int temp;
 	int result = 0;
 	int timeout = 0;
 
-#ifdef DEBUG
-	printk
-	    (KERN_DEBUG "i2c-i801.o: Transaction (pre): CNT=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, "
-	     "DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD),
-	     inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
-#endif
+	dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x,"
+		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
+		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
+		inb_p(SMBHSTDAT1));
 
 	/* Make sure the SMBus host is ready to start transmitting */
 	/* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
 	if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
-#ifdef DEBUG
-		printk(KERN_DEBUG "i2c-i801.o: SMBus busy (%02x). Resetting... \n",
-		       temp);
-#endif
+		dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting... \n",
+			temp);
 		outb_p(temp, SMBHSTSTS);
 		if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
-#ifdef DEBUG
-			printk(KERN_DEBUG "i2c-i801.o: Failed! (%02x)\n", temp);
-#endif
+			dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp);
 			return -1;
 		} else {
-#ifdef DEBUG
-			printk(KERN_DEBUG "i2c-i801.o: Successfull!\n");
-#endif
+			dev_dbg(&I801_dev->dev, "Successfull!\n");
 		}
 	}
 
@@ -251,76 +218,64 @@
 
 	/* If the SMBus is still busy, we give up */
 	if (timeout >= MAX_TIMEOUT) {
-#ifdef DEBUG
-		printk(KERN_DEBUG "i2c-i801.o: SMBus Timeout!\n");
+		dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
 		result = -1;
-#endif
 	}
 
 	if (temp & 0x10) {
 		result = -1;
-#ifdef DEBUG
-		printk(KERN_DEBUG "i2c-i801.o: Error: Failed bus transaction\n");
-#endif
+		dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n");
 	}
 
 	if (temp & 0x08) {
 		result = -1;
-		printk
-		    (KERN_ERR "i2c-i801.o: Bus collision! SMBus may be locked until next hard\n"
-		     "reset. (sorry!)\n");
+		dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked "
+			"until next hard reset. (sorry!)\n");
 		/* Clock stops and slave is stuck in mid-transmission */
 	}
 
 	if (temp & 0x04) {
 		result = -1;
-#ifdef DEBUG
-		printk(KERN_DEBUG "i2c-i801.o: Error: no response!\n");
-#endif
+		dev_dbg(&I801_dev->dev, "Error: no response!\n");
 	}
 
 	if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00)
 		outb_p(inb(SMBHSTSTS), SMBHSTSTS);
 
 	if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
-#ifdef DEBUG
-		printk
-		    (KERN_DEBUG "i2c-i801.o: Failed reset at end of transaction (%02x)\n",
-		     temp);
-#endif
+		dev_dbg(&I801_dev->dev, "Failed reset at end of transaction"
+			"(%02x)\n", temp);
 	}
-#ifdef DEBUG
-	printk
-	    (KERN_DEBUG "i2c-i801.o: Transaction (post): CNT=%02x, CMD=%02x, ADD=%02x, "
-	     "DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD),
-	     inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
-#endif
+	dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, "
+		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
+		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
+		inb_p(SMBHSTDAT1));
 	return result;
 }
 
 /* All-inclusive block transaction function */
-int i801_block_transaction(union i2c_smbus_data *data, char read_write, 
-                           int command)
+static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
+				  int command)
 {
 	int i, len;
 	int smbcmd;
 	int temp;
 	int result = 0;
 	int timeout;
-        unsigned char hostc, errmask;
+	unsigned char hostc, errmask;
 
-        if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
-                if (read_write == I2C_SMBUS_WRITE) {
-                        /* set I2C_EN bit in configuration register */
-                        pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
-                        pci_write_config_byte(I801_dev, SMBHSTCFG, 
-                                              hostc | SMBHSTCFG_I2C_EN);
-                } else {
-                        printk("i2c-i801.o: "
-                               "I2C_SMBUS_I2C_BLOCK_READ not supported!\n");
-                        return -1;
-                }
-        }
+	if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
+		if (read_write == I2C_SMBUS_WRITE) {
+			/* set I2C_EN bit in configuration register */
+			pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
+			pci_write_config_byte(I801_dev, SMBHSTCFG,
+					      hostc | SMBHSTCFG_I2C_EN);
+		} else {
+			dev_err(&I801_dev->dev,
+				"I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
+			return -1;
+		}
+	}
 
 	if (read_write == I2C_SMBUS_WRITE) {
 		len = data->block[0];
@@ -343,60 +298,43 @@
 			smbcmd = I801_BLOCK_LAST;
 		else
 			smbcmd = I801_BLOCK_DATA;
-#if 0 /* now using HW PEC */
-		if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC)
-			smbcmd |= I801_PEC_EN;
-#endif
 		outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT);
 
-#ifdef DEBUG
-		printk
-		    (KERN_DEBUG "i2c-i801.o: Block (pre %d): CNT=%02x, CMD=%02x, ADD=%02x, "
-		     "DAT0=%02x, BLKDAT=%02x\n", i, inb_p(SMBHSTCNT),
-		     inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
-		     inb_p(SMBBLKDAT));
-#endif
+		dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, "
+			"ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
+			inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
+			inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
 
 		/* Make sure the SMBus host is ready to start transmitting */
 		temp = inb_p(SMBHSTSTS);
-                if (i == 1) {
-                    /* Erronenous conditions before transaction: 
-                     * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
-                    errmask=0x9f; 
-                } else {
-                    /* Erronenous conditions during transaction: 
-                     * Failed, Bus_Err, Dev_Err, Intr */
-                    errmask=0x1e; 
-                }
+		if (i == 1) {
+			/* Erronenous conditions before transaction: 
+			 * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
+			errmask=0x9f; 
+		} else {
+			/* Erronenous conditions during transaction: 
+			 * Failed, Bus_Err, Dev_Err, Intr */
+			errmask=0x1e; 
+		}
 		if (temp & errmask) {
-#ifdef DEBUG
-			printk
-			    (KERN_DEBUG "i2c-i801.o: SMBus busy (%02x). Resetting... \n",
-			     temp);
-#endif
+			dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
+				"Resetting... \n", temp);
 			outb_p(temp, SMBHSTSTS);
 			if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
-				printk
-				    (KERN_ERR "i2c-i801.o: Reset failed! (%02x)\n",
-				     temp);
+				dev_err(&I801_dev->dev,
+					"Reset failed! (%02x)\n", temp);
 				result = -1;
                                 goto END;
 			}
 			if (i != 1) {
-                                result = -1;  /* if die in middle of block transaction, fail */
-                                goto END;
-                        }
+				/* if die in middle of block transaction, fail */
+				result = -1;
+				goto END;
+			}
 		}
 
-		if (i == 1) {
-#if 0 /* #ifdef HAVE_PEC (now using HW PEC) */
-			if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) {
-				if(read_write == I2C_SMBUS_WRITE)
-					outb_p(data->block[len + 1], SMBPEC);
-			}
-#endif
+		if (i == 1)
 			outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);
-		}
 
 		/* We will always wait for a fraction of a second! */
 		timeout = 0;
@@ -410,25 +348,19 @@
 		/* If the SMBus is still busy, we give up */
 		if (timeout >= MAX_TIMEOUT) {
 			result = -1;
-#ifdef DEBUG
-			printk(KERN_DEBUG "i2c-i801.o: SMBus Timeout!\n");
-#endif
+			dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
 		}
 
 		if (temp & 0x10) {
 			result = -1;
-#ifdef DEBUG
-			printk
-			    (KERN_DEBUG "i2c-i801.o: Error: Failed bus transaction\n");
-#endif
+			dev_dbg(&I801_dev->dev,
+				"Error: Failed bus transaction\n");
 		} else if (temp & 0x08) {
 			result = -1;
-			printk(KERN_ERR "i2c-i801.o: Bus collision!\n");
+			dev_err(&I801_dev->dev, "Bus collision!\n");
 		} else if (temp & 0x04) {
 			result = -1;
-#ifdef DEBUG
-			printk(KERN_DEBUG "i2c-i801.o: Error: no response!\n");
-#endif
+			dev_dbg(&I801_dev->dev, "Error: no response!\n");
 		}
 
 		if (i == 1 && read_write == I2C_SMBUS_READ) {
@@ -440,7 +372,7 @@
 			data->block[0] = len;
 		}
 
-                /* Retrieve/store value in SMBBLKDAT */
+		/* Retrieve/store value in SMBBLKDAT */
 		if (read_write == I2C_SMBUS_READ)
 			data->block[i] = inb_p(SMBBLKDAT);
 		if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
@@ -448,18 +380,15 @@
 		if ((temp & 0x9e) != 0x00)
 			outb_p(temp, SMBHSTSTS);  /* signals SMBBLKDAT ready */
 
-#ifdef DEBUG
 		if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) {
-			printk
-			    (KERN_DEBUG "i2c-i801.o: Bad status (%02x) at end of transaction\n",
-			     temp);
-		}
-		printk
-		    (KERN_DEBUG "i2c-i801.o: Block (post %d): CNT=%02x, CMD=%02x, ADD=%02x, "
-		     "DAT0=%02x, BLKDAT=%02x\n", i, inb_p(SMBHSTCNT),
-		     inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
-		     inb_p(SMBBLKDAT));
-#endif
+			dev_dbg(&I801_dev->dev,
+				"Bad status (%02x) at end of transaction\n",
+				temp);
+		}
+		dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, "
+			"ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
+			inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
+			inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
 
 		if (result < 0)
 			goto END;
@@ -476,29 +405,24 @@
 			   && (timeout++ < MAX_TIMEOUT));
 
 		if (timeout >= MAX_TIMEOUT) {
-			printk(KERN_DEBUG "i2c-i801.o: PEC Timeout!\n");
+			dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
 		}
-#if 0 /* now using HW PEC */
-		if(read_write == I2C_SMBUS_READ) {
-			data->block[len + 1] = inb_p(SMBPEC);
-		}
-#endif
 		outb_p(temp, SMBHSTSTS); 
 	}
 #endif
-        result = 0;
+	result = 0;
 END:
-        if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
-                /* restore saved configuration register value */
+	if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
+		/* restore saved configuration register value */
 		pci_write_config_byte(I801_dev, SMBHSTCFG, hostc);
-        }
+	}
 	return result;
 }
 
 /* Return -1 on error. */
-s32 i801_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
-		char read_write, u8 command, int size,
-		union i2c_smbus_data * data)
+static s32 i801_access(struct i2c_adapter * adap, u16 addr,
+		       unsigned short flags, char read_write, u8 command,
+		       int size, union i2c_smbus_data * data)
 {
 	int hwpec = 0;
 	int block = 0;
@@ -554,7 +478,7 @@
 		break;
 	case I2C_SMBUS_PROC_CALL:
 	default:
-		printk(KERN_ERR "i2c-i801.o: Unsupported transaction %d\n", size);
+		dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size);
 		return -1;
 	}
 
@@ -600,7 +524,7 @@
 }
 
 
-u32 i801_func(struct i2c_adapter *adapter)
+static u32 i801_func(struct i2c_adapter *adapter)
 {
 	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
 	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
@@ -627,8 +551,6 @@
 	.algo		= &smbus_algorithm,
 };
 
-
-
 static struct pci_device_id i801_ids[] __devinitdata = {
 	{
 		.vendor =	PCI_VENDOR_ID_INTEL,
@@ -650,13 +572,13 @@
 	},
 	{
 		.vendor =	PCI_VENDOR_ID_INTEL,
-		.device =	PCI_DEVICE_ID_INTEL_82801CA_SMBUS,
+		.device =	PCI_DEVICE_ID_INTEL_82801CA_3,
 		.subvendor =	PCI_ANY_ID,
 		.subdevice =	PCI_ANY_ID,
 	},
 	{
 		.vendor =	PCI_VENDOR_ID_INTEL,
-		.device =	PCI_DEVICE_ID_INTEL_82801DB_SMBUS,
+		.device =	PCI_DEVICE_ID_INTEL_82801DB_3,
 		.subvendor =	PCI_ANY_ID,
 		.subdevice =	PCI_ANY_ID,
 	},
@@ -667,8 +589,8 @@
 {
 
 	if (i801_setup(dev)) {
-		printk
-		    (KERN_WARNING "i2c-i801.o: I801 not detected, module not inserted.\n");
+		dev_warn(&dev->dev,
+			"I801 not detected, module not inserted.\n");
 		return -ENODEV;
 	}
 
@@ -694,22 +616,21 @@
 
 static int __init i2c_i801_init(void)
 {
-	printk(KERN_INFO "i2c-i801.o version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c-i801 version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&i801_driver);
 }
 
-
 static void __exit i2c_i801_exit(void)
 {
 	pci_unregister_driver(&i801_driver);
 	release_region(i801_smba, (isich4 ? 16 : 8));
 }
 
-
-
-MODULE_AUTHOR
-    ("Frodo Looijaard <frodol@dds.nl>, Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker <mdsxyz123@yahoo.com>");
+MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl>, "
+		"Philip Edelbrock <phil@netroedge.com>, "
+		"and Mark D. Studebaker <mdsxyz123@yahoo.com>");
 MODULE_DESCRIPTION("I801 SMBus driver");
+MODULE_LICENSE("GPL");
 
 module_init(i2c_i801_init);
 module_exit(i2c_i801_exit);
diff -Nru a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-isa.c	Thu Mar 20 11:47:34 2003
@@ -0,0 +1,62 @@
+/*
+    i2c-isa.c - Part of lm_sensors, Linux kernel modules for hardware
+            monitoring
+    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> 
+
+    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 implements an i2c algorithm/adapter for ISA bus. Not that this is
+   on first sight very useful; almost no functionality is preserved.
+   Except that it makes writing drivers for chips which can be on both
+   the SMBus and the ISA bus very much easier. See lm78.c for an example
+   of this. */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+
+/* This is the actual algorithm we define */
+static struct i2c_algorithm isa_algorithm = {
+	.name		= "ISA bus algorithm",
+	.id		= I2C_ALGO_ISA,
+};
+
+/* There can only be one... */
+static struct i2c_adapter isa_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= "ISA main adapter",
+	.id		= I2C_ALGO_ISA | I2C_HW_ISA,
+	.algo		= &isa_algorithm,
+};
+
+static int __init i2c_isa_init(void)
+{
+	return i2c_add_adapter(&isa_adapter);
+}
+
+static void __exit i2c_isa_exit(void)
+{
+	i2c_del_adapter(&isa_adapter);
+}
+
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
+MODULE_DESCRIPTION("ISA bus access through i2c");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_isa_init);
+module_exit(i2c_isa_exit);
diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	Thu Mar 13 16:39:32 2003
+++ b/drivers/i2c/busses/i2c-piix4.c	Tue Mar 18 09:10:21 2003
@@ -28,6 +28,8 @@
    Note: we assume there can only be one device, with one SMBus interface.
 */
 
+/* #define DEBUG 1 */
+
 #include <linux/module.h>
 #include <linux/config.h>
 #include <linux/pci.h>
@@ -49,37 +51,37 @@
 };
 
 /* PIIX4 SMBus address offsets */
-#define SMBHSTSTS (0 + piix4_smba)
-#define SMBHSLVSTS (1 + piix4_smba)
-#define SMBHSTCNT (2 + piix4_smba)
-#define SMBHSTCMD (3 + piix4_smba)
-#define SMBHSTADD (4 + piix4_smba)
-#define SMBHSTDAT0 (5 + piix4_smba)
-#define SMBHSTDAT1 (6 + piix4_smba)
-#define SMBBLKDAT (7 + piix4_smba)
-#define SMBSLVCNT (8 + piix4_smba)
-#define SMBSHDWCMD (9 + piix4_smba)
-#define SMBSLVEVT (0xA + piix4_smba)
-#define SMBSLVDAT (0xC + piix4_smba)
+#define SMBHSTSTS	(0 + piix4_smba)
+#define SMBHSLVSTS	(1 + piix4_smba)
+#define SMBHSTCNT	(2 + piix4_smba)
+#define SMBHSTCMD	(3 + piix4_smba)
+#define SMBHSTADD	(4 + piix4_smba)
+#define SMBHSTDAT0	(5 + piix4_smba)
+#define SMBHSTDAT1	(6 + piix4_smba)
+#define SMBBLKDAT	(7 + piix4_smba)
+#define SMBSLVCNT	(8 + piix4_smba)
+#define SMBSHDWCMD	(9 + piix4_smba)
+#define SMBSLVEVT	(0xA + piix4_smba)
+#define SMBSLVDAT	(0xC + piix4_smba)
 
 /* PCI Address Constants */
-#define SMBBA     0x090
-#define SMBHSTCFG 0x0D2
-#define SMBSLVC   0x0D3
-#define SMBSHDW1  0x0D4
-#define SMBSHDW2  0x0D5
-#define SMBREV    0x0D6
+#define SMBBA		0x090
+#define SMBHSTCFG	0x0D2
+#define SMBSLVC		0x0D3
+#define SMBSHDW1	0x0D4
+#define SMBSHDW2	0x0D5
+#define SMBREV		0x0D6
 
 /* Other settings */
-#define MAX_TIMEOUT 500
-#define  ENABLE_INT9 0
+#define MAX_TIMEOUT	500
+#define  ENABLE_INT9	0
 
 /* PIIX4 constants */
-#define PIIX4_QUICK      0x00
-#define PIIX4_BYTE       0x04
-#define PIIX4_BYTE_DATA  0x08
-#define PIIX4_WORD_DATA  0x0C
-#define PIIX4_BLOCK_DATA 0x14
+#define PIIX4_QUICK		0x00
+#define PIIX4_BYTE		0x04
+#define PIIX4_BYTE_DATA		0x08
+#define PIIX4_WORD_DATA		0x0C
+#define PIIX4_BLOCK_DATA	0x14
 
 /* insmod parameters */
 
@@ -102,6 +104,7 @@
 
 
 static unsigned short piix4_smba = 0;
+static struct i2c_adapter piix4_adapter;
 
 /*
  * Get DMI information.
@@ -125,18 +128,17 @@
 	if (PCI_FUNC(PIIX4_dev->devfn) != id->driver_data)
 		return -ENODEV;
 
-	printk(KERN_INFO "i2c-piix4.o: Found %s device\n", PIIX4_dev->dev.name);
+	dev_info(&PIIX4_dev->dev, "Found %s device\n", PIIX4_dev->dev.name);
 
 	if(ibm_dmi_probe()) {
-		printk
-		  (KERN_ERR "i2c-piix4.o: IBM Laptop detected; this module may corrupt\n");
-		printk
-		  (KERN_ERR "             your serial eeprom! Refusing to load module!\n");
-		 error_return = -EPERM;
-		 goto END;
+		dev_err(&PIIX4_dev->dev, "IBM Laptop detected; this module "
+			"may corrupt your serial eeprom! Refusing to load "
+			"module!\n");
+		error_return = -EPERM;
+		goto END;
 	}
 
-/* Determine the address of the SMBus areas */
+	/* Determine the address of the SMBus areas */
 	if (force_addr) {
 		piix4_smba = force_addr & 0xfff0;
 		force = 0;
@@ -144,75 +146,68 @@
 		pci_read_config_word(PIIX4_dev, SMBBA, &piix4_smba);
 		piix4_smba &= 0xfff0;
 		if(piix4_smba == 0) {
-			printk(KERN_ERR "i2c-piix4.o: SMB base address uninitialized - upgrade BIOS or use force_addr=0xaddr\n");
+			dev_err(&PIIX4_dev->dev, "SMB base address "
+				"uninitialized - upgrade BIOS or use "
+				"force_addr=0xaddr\n");
 			return -ENODEV;
 		}
 	}
 
-	if (check_region(piix4_smba, 8)) {
-		printk
-		    (KERN_ERR "i2c-piix4.o: SMB region 0x%x already in use!\n",
-		     piix4_smba);
+	if (!request_region(piix4_smba, 8, "piix4-smbus")) {
+		dev_err(&PIIX4_dev->dev, "SMB region 0x%x already in use!\n",
+			piix4_smba);
 		error_return = -ENODEV;
 		goto END;
 	}
 
 	pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp);
-/* If force_addr is set, we program the new address here. Just to make
-   sure, we disable the PIIX4 first. */
+	/* If force_addr is set, we program the new address here. Just to make
+	   sure, we disable the PIIX4 first. */
 	if (force_addr) {
 		pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp & 0xfe);
 		pci_write_config_word(PIIX4_dev, SMBBA, piix4_smba);
 		pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp | 0x01);
-		printk
-		    (KERN_INFO "i2c-piix4.o: WARNING: SMBus interface set to new "
-		     "address %04x!\n", piix4_smba);
+		dev_info(&PIIX4_dev->dev, "WARNING: SMBus interface set to "
+			"new address %04x!\n", piix4_smba);
 	} else if ((temp & 1) == 0) {
 		if (force) {
-/* This should never need to be done, but has been noted that
-   many Dell machines have the SMBus interface on the PIIX4
-   disabled!? NOTE: This assumes I/O space and other allocations WERE
-   done by the Bios!  Don't complain if your hardware does weird 
-   things after enabling this. :') Check for Bios updates before
-   resorting to this.  */
+			/* This should never need to be done, but has been
+			 * noted that many Dell machines have the SMBus
+			 * interface on the PIIX4 disabled!? NOTE: This assumes
+			 * I/O space and other allocations WERE done by the
+			 * Bios!  Don't complain if your hardware does weird
+			 * things after enabling this. :') Check for Bios
+			 * updates before resorting to this.
+			 */
 			pci_write_config_byte(PIIX4_dev, SMBHSTCFG,
 					      temp | 1);
-			printk
-			    (KERN_NOTICE "i2c-piix4.o: WARNING: SMBus interface has been FORCEFULLY "
-			     "ENABLED!\n");
+			dev_printk(KERN_NOTICE, &PIIX4_dev->dev,
+				"WARNING: SMBus interface has been "
+				"FORCEFULLY ENABLED!\n");
 		} else {
-			printk
-			    (KERN_ERR "i2c-piix4.o: Host SMBus controller not enabled!\n");
+			dev_err(&PIIX4_dev->dev,
+				"Host SMBus controller not enabled!\n");
 			error_return = -ENODEV;
 			goto END;
 		}
 	}
 
-	/* Everything is happy, let's grab the memory and set things up. */
-	request_region(piix4_smba, 8, "piix4-smbus");
-
-#ifdef DEBUG
 	if ((temp & 0x0E) == 8)
-		printk
-		    (KERN_DEBUG "i2c-piix4.o: Using Interrupt 9 for SMBus.\n");
+		dev_dbg(&PIIX4_dev->dev, "Using Interrupt 9 for SMBus.\n");
 	else if ((temp & 0x0E) == 0)
-		printk
-		    (KERN_DEBUG "i2c-piix4.o: Using Interrupt SMI# for SMBus.\n");
+		dev_dbg(&PIIX4_dev->dev, "Using Interrupt SMI# for SMBus.\n");
 	else
-		printk
-		    (KERN_ERR "i2c-piix4.o: Illegal Interrupt configuration (or code out "
-		     "of date)!\n");
+		dev_err(&PIIX4_dev->dev, "Illegal Interrupt configuration "
+			"(or code out of date)!\n");
 
 	pci_read_config_byte(PIIX4_dev, SMBREV, &temp);
-	printk(KERN_DEBUG "i2c-piix4.o: SMBREV = 0x%X\n", temp);
-	printk(KERN_DEBUG "i2c-piix4.o: SMBA = 0x%X\n", piix4_smba);
-#endif				/* DEBUG */
+	dev_dbg(&PIIX4_dev->dev, "SMBREV = 0x%X\n", temp);
+	dev_dbg(&PIIX4_dev->dev, "SMBA = 0x%X\n", piix4_smba);
 
-      END:
+END:
 	return error_return;
 }
 
-
 /* Internally used pause function */
 static void piix4_do_pause(unsigned int amount)
 {
@@ -227,29 +222,21 @@
 	int result = 0;
 	int timeout = 0;
 
-#ifdef DEBUG
-	printk
-	    (KERN_DEBUG "i2c-piix4.o: Transaction (pre): CNT=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, "
-	     "DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD),
-	     inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
-#endif
+	dev_dbg(&piix4_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
+		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
+		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
+		inb_p(SMBHSTDAT1));
 
 	/* Make sure the SMBus host is ready to start transmitting */
 	if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
-#ifdef DEBUG
-		printk(KERN_DEBUG "i2c-piix4.o: SMBus busy (%02x). Resetting... \n",
-		       temp);
-#endif
+		dev_dbg(&piix4_adapter.dev, "SMBus busy (%02x). "
+			"Resetting... \n", temp);
 		outb_p(temp, SMBHSTSTS);
 		if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
-#ifdef DEBUG
-			printk(KERN_ERR "i2c-piix4.o: Failed! (%02x)\n", temp);
-#endif
+			dev_err(&piix4_adapter.dev, "Failed! (%02x)\n", temp);
 			return -1;
 		} else {
-#ifdef DEBUG
-			printk(KERN_DEBUG "i2c-piix4.o: Successfull!\n");
-#endif
+			dev_dbg(&piix4_adapter.dev, "Successfull!\n");
 		}
 	}
 
@@ -262,50 +249,40 @@
 		temp = inb_p(SMBHSTSTS);
 	} while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
 
-#ifdef DEBUG
 	/* If the SMBus is still busy, we give up */
 	if (timeout >= MAX_TIMEOUT) {
-		printk(KERN_ERR "i2c-piix4.o: SMBus Timeout!\n");
+		dev_err(&piix4_adapter.dev, "SMBus Timeout!\n");
 		result = -1;
 	}
-#endif
 
 	if (temp & 0x10) {
 		result = -1;
-#ifdef DEBUG
-		printk(KERN_ERR "i2c-piix4.o: Error: Failed bus transaction\n");
-#endif
+		dev_err(&piix4_adapter.dev, "Error: Failed bus transaction\n");
 	}
 
 	if (temp & 0x08) {
 		result = -1;
-		printk
-		    (KERN_ERR "i2c-piix4.o: Bus collision! SMBus may be locked until next hard\n"
-		     "reset. (sorry!)\n");
+		dev_dbg(&piix4_adapter.dev, "Bus collision! SMBus may be "
+			"locked until next hard reset. (sorry!)\n");
 		/* Clock stops and slave is stuck in mid-transmission */
 	}
 
 	if (temp & 0x04) {
 		result = -1;
-#ifdef DEBUG
-		printk(KERN_ERR "i2c-piix4.o: Error: no response!\n");
-#endif
+		dev_err(&piix4_adapter.dev, "Error: no response!\n");
 	}
 
 	if (inb_p(SMBHSTSTS) != 0x00)
 		outb_p(inb(SMBHSTSTS), SMBHSTSTS);
 
-#ifdef DEBUG
 	if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
-		printk
-		    (KERN_ERR "i2c-piix4.o: Failed reset at end of transaction (%02x)\n",
-		     temp);
-	}
-	printk
-	    (KERN_DEBUG "i2c-piix4.o: Transaction (post): CNT=%02x, CMD=%02x, ADD=%02x, "
-	     "DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), inb_p(SMBHSTCMD),
-	     inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
-#endif
+		dev_err(&piix4_adapter.dev, "Failed reset at end of "
+			"transaction (%02x)\n", temp);
+	}
+	dev_dbg(&piix4_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, "
+		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
+		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
+		inb_p(SMBHSTDAT1));
 	return result;
 }
 
@@ -318,8 +295,7 @@
 
 	switch (size) {
 	case I2C_SMBUS_PROC_CALL:
-		printk
-		    (KERN_ERR "i2c-piix4.o: I2C_SMBUS_PROC_CALL not supported!\n");
+		dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
 		return -1;
 	case I2C_SMBUS_QUICK:
 		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
@@ -402,7 +378,6 @@
 	return 0;
 }
 
-
 static u32 piix4_func(struct i2c_adapter *adapter)
 {
 	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
@@ -424,8 +399,6 @@
 	.algo		= &smbus_algorithm,
 };
 
-
-
 static struct pci_device_id piix4_ids[] __devinitdata = {
 	{
 		.vendor =	PCI_VENDOR_ID_INTEL,
@@ -468,7 +441,7 @@
 static int __devinit piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	int retval;
-	
+
 	retval = piix4_setup(dev, id);
 	if (retval)
 		return retval;
@@ -499,7 +472,7 @@
 
 static int __init i2c_piix4_init(void)
 {
-	printk("i2c-piix4.o version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c-piix4 version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&piix4_driver);
 }
 
@@ -509,8 +482,6 @@
 	pci_unregister_driver(&piix4_driver);
 	release_region(piix4_smba, 8);
 }
-
-
 
 MODULE_AUTHOR
     ("Frodo Looijaard <frodol@dds.nl> and Philip Edelbrock <phil@netroedge.com>");
diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
--- a/drivers/i2c/chips/adm1021.c	Thu Feb 20 12:01:09 2003
+++ b/drivers/i2c/chips/adm1021.c	Thu Mar 13 13:49:39 2003
@@ -93,9 +93,9 @@
 
 /* Initial values */
 
-/* Note: Eventhough I left the low and high limits named os and hyst, 
+/* Note: Even though I left the low and high limits named os and hyst, 
 they don't quite work like a thermostat the way the LM75 does.  I.e., 
-a lower temp than THYST actuall triggers an alarm instead of 
+a lower temp than THYST actually triggers an alarm instead of 
 clearing it.  Weird, ey?   --Phil  */
 #define adm1021_INIT_TOS 60
 #define adm1021_INIT_THYST 20
diff -Nru a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c
--- a/drivers/i2c/chips/lm75.c	Thu Feb 20 12:01:03 2003
+++ b/drivers/i2c/chips/lm75.c	Thu Mar 13 13:38:56 2003
@@ -25,7 +25,7 @@
 #include <linux/i2c-proc.h>
 
 
-#define LM75_SYSCTL_TEMP 1200	/* Degrees Celcius * 10 */
+#define LM75_SYSCTL_TEMP 1200	/* Degrees Celsius * 10 */
 
 /* Addresses to scan */
 static unsigned short normal_i2c[] = { SENSORS_I2C_END };
diff -Nru a/drivers/i2c/i2c-algo-pcf.c b/drivers/i2c/i2c-algo-pcf.c
--- a/drivers/i2c/i2c-algo-pcf.c	Tue Mar 11 12:21:11 2003
+++ b/drivers/i2c/i2c-algo-pcf.c	Thu Mar 13 13:49:39 2003
@@ -152,7 +152,7 @@
 
 	/* load own address in S0, effective address is (own << 1)	*/
 	i2c_outb(adap, get_own(adap));
-	/* check it's realy writen */
+	/* check it's really written */
 	if ((temp = i2c_inb(adap)) != get_own(adap)) {
 		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp));
 		return -ENXIO;
@@ -168,7 +168,7 @@
 
 	/* load clock register S2					*/
 	i2c_outb(adap, get_clock(adap));
-	/* check it's realy writen, the only 5 lowest bits does matter */
+	/* check it's really written, the only 5 lowest bits does matter */
 	if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
 		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp));
 		return -ENXIO;
@@ -177,7 +177,7 @@
 	/* Enable serial interface, idle, S0 selected			*/
 	set_pcf(adap, 1, I2C_PCF_IDLE);
 
-	/* check to see PCF is realy idled and we can access status register */
+	/* check to see PCF is really idled and we can access status register */
 	if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) {
 		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
 		return -ENXIO;
diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
--- a/drivers/i2c/i2c-core.c	Fri Mar 14 19:51:45 2003
+++ b/drivers/i2c/i2c-core.c	Thu Mar 20 12:07:43 2003
@@ -53,6 +53,16 @@
 #endif /* CONFIG_PROC_FS */
 
 
+int i2c_device_probe(struct device *dev)
+{
+	return -ENODEV;
+}
+
+int i2c_device_remove(struct device *dev)
+{
+	return 0;
+}
+
 /* ---------------------------------------------------
  * registering functions 
  * --------------------------------------------------- 
@@ -204,6 +214,16 @@
 	drivers[i] = driver;
 	
 	DEB(printk(KERN_DEBUG "i2c-core.o: driver %s registered.\n",driver->name));
+
+	/* add the driver to the list of i2c drivers in the driver core */
+	driver->driver.name = driver->name;
+	driver->driver.bus = &i2c_bus_type;
+	driver->driver.probe = i2c_device_probe;
+	driver->driver.remove = i2c_device_remove;
+
+	res = driver_register(&driver->driver);
+	if (res)
+		goto out_unlock;
 	
 	/* now look for instances of driver on our adapters
 	 */
@@ -235,6 +255,8 @@
 		res = -ENODEV;
 		goto out_unlock;
 	}
+
+	driver_unregister(&driver->driver);
 
 	/* Have a look at each adapter, if clients of this driver are still
 	 * attached. If so, detach them to be able to kill the driver 
diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
--- a/drivers/i2c/i2c-dev.c	Thu Feb 20 11:54:16 2003
+++ b/drivers/i2c/i2c-dev.c	Sat Mar 22 07:38:05 2003
@@ -436,7 +436,7 @@
 		       I2C_MAJOR);
 		return -EIO;
 	}
-	devfs_mk_dir(NULL, "i2c", NULL);
+	devfs_mk_dir("i2c");
 	if ((res = i2c_add_driver(&i2cdev_driver))) {
 		printk(KERN_ERR "i2c-dev.o: Driver registration failed, module not inserted.\n");
 		devfs_remove("i2c");
diff -Nru a/drivers/i2c/i2c-proc.c b/drivers/i2c/i2c-proc.c
--- a/drivers/i2c/i2c-proc.c	Wed Mar 12 07:37:16 2003
+++ b/drivers/i2c/i2c-proc.c	Thu Mar 13 13:38:57 2003
@@ -270,7 +270,7 @@
 }
 
 
-/* This funcion reads or writes a 'real' value (encoded by the combination
+/* This function reads or writes a 'real' value (encoded by the combination
    of an integer and a magnitude, the last is the power of ten the value
    should be divided with) to a /proc/sys directory. To use this function,
    you must (before registering the ctl_table) set the extra2 field to the
diff -Nru a/drivers/ide/Kconfig b/drivers/ide/Kconfig
--- a/drivers/ide/Kconfig	Wed Feb 19 09:48:49 2003
+++ b/drivers/ide/Kconfig	Sun Mar 23 08:45:07 2003
@@ -44,7 +44,25 @@
 
 config BLK_DEV_HD_IDE
 	bool "Use old disk-only driver on primary interface"
-	depends on BLK_DEV_IDE && X86
+	depends on BLK_DEV_IDE && X86 && X86_PC9800!=y
+	---help---
+	  There are two drivers for MFM/RLL/IDE disks.  Most people use just
+	  the new enhanced driver by itself.  This option however installs the
+	  old hard disk driver to control the primary IDE/disk interface in
+	  the system, leaving the new enhanced IDE driver to take care of only
+	  the 2nd/3rd/4th IDE interfaces.  Doing this will prevent you from
+	  having an IDE/ATAPI CD-ROM or tape drive connected to the primary
+	  IDE interface.  Choosing this option may be useful for older systems
+	  which have MFM/RLL/ESDI controller+drives at the primary port
+	  address (0x1f0), along with IDE drives at the secondary/3rd/4th port
+	  addresses.
+
+	  Normally, just say N here; you will then use the new driver for all
+	  4 interfaces.
+
+config BLK_DEV_HD_IDE98
+	bool "Use old disk-only driver on primary interface"
+	depends on BLK_DEV_IDE && X86 && X86_PC9800
 	---help---
 	  There are two drivers for MFM/RLL/IDE disks.  Most people use just
 	  the new enhanced driver by itself.  This option however installs the
diff -Nru a/drivers/ide/Makefile b/drivers/ide/Makefile
--- a/drivers/ide/Makefile	Mon Mar  3 12:06:45 2003
+++ b/drivers/ide/Makefile	Tue Mar 18 09:14:47 2003
@@ -12,7 +12,7 @@
 
 # Core IDE code - must come before legacy
 
-obj-$(CONFIG_BLK_DEV_IDE)		+= ide-io.o ide-probe.o ide-geometry.o ide-iops.o ide-taskfile.o ide.o ide-lib.o
+obj-$(CONFIG_BLK_DEV_IDE)		+= ide-io.o ide-probe.o ide-geometry.o ide-iops.o ide-taskfile.o ide.o ide-lib.o ide-default.o
 obj-$(CONFIG_BLK_DEV_IDEDISK)		+= ide-disk.o
 obj-$(CONFIG_BLK_DEV_IDECD)		+= ide-cd.o
 obj-$(CONFIG_BLK_DEV_IDETAPE)		+= ide-tape.o
diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c	Tue Feb 25 09:44:36 2003
+++ b/drivers/ide/ide-cd.c	Thu Mar 13 16:49:24 2003
@@ -294,7 +294,7 @@
  *
  *************************************************************************/
  
-#define IDECD_VERSION "4.59"
+#define IDECD_VERSION "4.59-ac1"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -635,6 +635,23 @@
 	return ide_stopped;
 }
 
+ide_startstop_t ide_cdrom_abort (ide_drive_t *drive, const char *msg)
+{
+	struct request *rq;
+
+	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
+		return ide_stopped;
+	/* retry only "normal" I/O: */
+	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
+		rq->errors = 1;
+		ide_end_drive_cmd(drive, BUSY_STAT, 0);
+		return ide_stopped;
+	}
+	rq->errors |= ERROR_RESET;
+	DRIVER(drive)->end_request(drive, 0, 0);
+	return ide_stopped;
+}
+
 static void cdrom_end_request (ide_drive_t *drive, int uptodate)
 {
 	struct request *rq = HWGROUP(drive)->rq;
@@ -899,9 +916,6 @@
 			return startstop;
 	}
 
-	if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
-		BUG();
-
 	/* Arm the interrupt handler. */
 	ide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry);
 
@@ -1133,9 +1147,6 @@
 		}
 	}
 
-	if (HWGROUP(drive)->handler != NULL)    /* paranoia check */
-		BUG();
-
 	/* Done moving data!  Wait for another interrupt. */
 	ide_set_handler(drive, &cdrom_read_intr, WAIT_CMD, NULL);
 	return ide_started;
@@ -1470,9 +1481,6 @@
 		rq->flags |= REQ_FAILED;
 	}
 
-	if (HWGROUP(drive)->handler != NULL)
-		BUG();
-
 	/* Now we wait for another interrupt. */
 	ide_set_handler(drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
 	return ide_started;
@@ -1863,9 +1871,6 @@
 			cdrom_end_request(drive, 1);
 	}
 
-	if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
-		BUG();
-
 	/* re-arm handler */
 	ide_set_handler(drive, &cdrom_write_intr, 5 * WAIT_CMD, NULL);
 	return ide_started;
@@ -2837,11 +2842,9 @@
 	 * ACER50 (and others?) require the full spec length mode sense
 	 * page capabilities size, but older drives break.
 	 */
-	if (drive->id) {
-		if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
-		    !strcmp(drive->id->model, "WPI CDS-32X")))
-			size -= sizeof(cap->pad);
-	}
+	if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
+	    !strcmp(drive->id->model, "WPI CDS-32X")))
+		size -= sizeof(cap->pad);
 
 	/* we have to cheat a little here. the packet will eventually
 	 * be queued with ide_cdrom_packet(), which extracts the
@@ -2924,7 +2927,7 @@
 	}
 
 	/* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
-	if (drive->id && !drive->id->model[0] &&
+	if (!drive->id->model[0] &&
 	    !strncmp(drive->id->fw_rev, "241N", 4)) {
 		CDROM_STATE_FLAGS(drive)->current_speed  = 
 			(((unsigned int)cap.curspeed) + (176/2)) / 176;
@@ -3089,12 +3092,7 @@
 	CDROM_CONFIG_FLAGS(drive)->no_doorlock = 0;
 #endif
 
-	if (drive->id != NULL)
-		CDROM_CONFIG_FLAGS(drive)->drq_interrupt =
-			((drive->id->config & 0x0060) == 0x20);
-	else
-		CDROM_CONFIG_FLAGS(drive)->drq_interrupt = 0;
-
+	CDROM_CONFIG_FLAGS(drive)->drq_interrupt = ((drive->id->config & 0x0060) == 0x20);
 	CDROM_CONFIG_FLAGS(drive)->is_changer = 0;
 	CDROM_CONFIG_FLAGS(drive)->cd_r = 0;
 	CDROM_CONFIG_FLAGS(drive)->cd_rw = 0;
@@ -3109,16 +3107,14 @@
 	
 	/* limit transfer size per interrupt. */
 	CDROM_CONFIG_FLAGS(drive)->limit_nframes = 0;
-	if (drive->id != NULL) {
-		/* a testament to the nice quality of Samsung drives... */
-		if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2430"))
-			CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1;
-		else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432"))
-			CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1;
-		/* the 3231 model does not support the SET_CD_SPEED command */
-		else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231"))
-			cdi->mask |= CDC_SELECT_SPEED;
-	}
+	/* a testament to the nice quality of Samsung drives... */
+	if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2430"))
+		CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1;
+	else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432"))
+		CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1;
+	/* the 3231 model does not support the SET_CD_SPEED command */
+	else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231"))
+		cdi->mask |= CDC_SELECT_SPEED;
 
 #if ! STANDARD_ATAPI
 	/* by default Sanyo 3 CD changer support is turned off and
@@ -3131,55 +3127,47 @@
 	CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 0;
 	CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 0;
 
-	if (drive->id != NULL) {
-		if (strcmp (drive->id->model, "V003S0DS") == 0 &&
-		    drive->id->fw_rev[4] == '1' &&
-		    drive->id->fw_rev[6] <= '2') {
-			/* Vertos 300.
-			   Some versions of this drive like to talk BCD. */
-			CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd = 1;
-			CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd = 1;
-			CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1;
-			CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1;
-		}
-
-		else if (strcmp (drive->id->model, "V006E0DS") == 0 &&
-		    drive->id->fw_rev[4] == '1' &&
-		    drive->id->fw_rev[6] <= '2') {
-			/* Vertos 600 ESD. */
-			CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd = 1;
-		}
-
-		else if (strcmp(drive->id->model,
-				 "NEC CD-ROM DRIVE:260") == 0 &&
-			 strncmp(drive->id->fw_rev, "1.01", 4) == 0) { /* FIXME */
-			/* Old NEC260 (not R).
-			   This drive was released before the 1.2 version
-			   of the spec. */
-			CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd = 1;
-			CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1;
-			CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1;
-			CDROM_CONFIG_FLAGS(drive)->nec260         = 1;
-		}
-
-		else if (strcmp(drive->id->model, "WEARNES CDD-120") == 0 &&
-			 strncmp(drive->id->fw_rev, "A1.1", 4) == 0) { /* FIXME */
-			/* Wearnes */
-			CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1;
-			CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1;
-		}
-
-                /* Sanyo 3 CD changer uses a non-standard command
-                    for CD changing */
-                 else if ((strcmp(drive->id->model, "CD-ROM CDR-C3 G") == 0) ||
-                         (strcmp(drive->id->model, "CD-ROM CDR-C3G") == 0) ||
-                         (strcmp(drive->id->model, "CD-ROM CDR_C36") == 0)) {
-                        /* uses CD in slot 0 when value is set to 3 */
-                        cdi->sanyo_slot = 3;
-                }
-
-
-	}
+	if (strcmp (drive->id->model, "V003S0DS") == 0 &&
+	    drive->id->fw_rev[4] == '1' &&
+	    drive->id->fw_rev[6] <= '2') {
+		/* Vertos 300.
+		   Some versions of this drive like to talk BCD. */
+		CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd = 1;
+		CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd = 1;
+		CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1;
+		CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1;
+	}
+
+	else if (strcmp (drive->id->model, "V006E0DS") == 0 &&
+	    drive->id->fw_rev[4] == '1' &&
+	    drive->id->fw_rev[6] <= '2') {
+		/* Vertos 600 ESD. */
+		CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd = 1;
+	}
+	else if (strcmp(drive->id->model, "NEC CD-ROM DRIVE:260") == 0 &&
+		 strncmp(drive->id->fw_rev, "1.01", 4) == 0) { /* FIXME */
+		/* Old NEC260 (not R).
+		   This drive was released before the 1.2 version
+		   of the spec. */
+		CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd = 1;
+		CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1;
+		CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1;
+		CDROM_CONFIG_FLAGS(drive)->nec260         = 1;
+	}
+	else if (strcmp(drive->id->model, "WEARNES CDD-120") == 0 &&
+		 strncmp(drive->id->fw_rev, "A1.1", 4) == 0) { /* FIXME */
+		/* Wearnes */
+		CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1;
+		CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1;
+	}
+        /* Sanyo 3 CD changer uses a non-standard command
+           for CD changing */
+        else if ((strcmp(drive->id->model, "CD-ROM CDR-C3 G") == 0) ||
+                 (strcmp(drive->id->model, "CD-ROM CDR-C3G") == 0) ||
+                 (strcmp(drive->id->model, "CD-ROM CDR_C36") == 0)) {
+                 /* uses CD in slot 0 when value is set to 3 */
+                 cdi->sanyo_slot = 3;
+        }
 #endif /* not STANDARD_ATAPI */
 
 	info->toc		= NULL;
@@ -3246,6 +3234,7 @@
 		printk("%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name);
 	kfree(info);
 	drive->driver_data = NULL;
+	blk_queue_prep_rq(&drive->queue, NULL);
 	del_gendisk(g);
 	g->fops = ide_fops;
 	return 0;
@@ -3265,6 +3254,7 @@
 	.do_request		= ide_do_rw_cdrom,
 	.sense			= ide_cdrom_dump_status,
 	.error			= ide_cdrom_error,
+	.abort			= ide_cdrom_abort,
 	.capacity		= ide_cdrom_capacity,
 	.attach			= ide_cdrom_attach,
 	.drives			= LIST_HEAD_INIT(ide_cdrom_driver.drives),
diff -Nru a/drivers/ide/ide-default.c b/drivers/ide/ide-default.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/ide/ide-default.c	Fri Mar  7 15:01:51 2003
@@ -0,0 +1,71 @@
+/*
+ *	ide-default		-	Driver for unbound ide devices
+ *
+ *	This provides a clean way to bind a device to default operations
+ *	by having an actual driver class that rather than special casing
+ *	"no driver" all over the IDE code
+ *
+ *	Copyright (C) 2003, Red Hat <alan@redhat.com>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/genhd.h>
+#include <linux/slab.h>
+#include <linux/cdrom.h>
+#include <linux/ide.h>
+
+#include <asm/byteorder.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/unaligned.h>
+#include <asm/bitops.h>
+
+#define IDEDEFAULT_VERSION	"0.9.newide"
+/*
+ *	Driver initialization.
+ */
+
+static int idedefault_attach(ide_drive_t *drive);
+
+/*
+ *	IDE subdriver functions, registered with ide.c
+ *
+ *	idedefault *must* support DMA because it will be
+ *	attached before the other drivers are loaded and
+ *	we don't want to lose the DMA status at probe
+ *	time.
+ */
+
+ide_driver_t idedefault_driver = {
+	.name		=	"ide-default",
+	.version	=	IDEDEFAULT_VERSION,
+	.attach		=	idedefault_attach,
+	.supports_dma	=	1,
+	.drives		=	LIST_HEAD_INIT(idedefault_driver.drives)
+};
+
+static int idedefault_attach (ide_drive_t *drive)
+{
+	if (ide_register_subdriver(drive,
+			&idedefault_driver, IDE_SUBDRIVER_VERSION)) {
+		printk(KERN_ERR "ide-default: %s: Failed to register the "
+			"driver with ide.c\n", drive->name);
+		return 1;
+	}
+	return 0;
+}
+
+MODULE_DESCRIPTION("IDE Default Driver");
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
--- a/drivers/ide/ide-disk.c	Tue Feb 18 10:06:17 2003
+++ b/drivers/ide/ide-disk.c	Sat Mar 22 12:32:12 2003
@@ -1,11 +1,10 @@
 /*
- *  linux/drivers/ide/ide-disk.c	Version 1.16	April 7, 2002
- *
- *  Copyright (C) 1998-2002  Linux ATA Developemt
- *				Andre Hedrick <andre@linux-ide.org>
- *
+ *  linux/drivers/ide/ide-disk.c	Version 1.18	Mar 05, 2003
  *
  *  Copyright (C) 1994-1998  Linus Torvalds & authors (see below)
+ *  Copyright (C) 1998-2002  Linux ATA Development
+ *				Andre Hedrick <andre@linux-ide.org>
+ *  Copyright (C) 2003	     Red Hat <alan@redhat.com>
  */
 
 /*
@@ -42,7 +41,7 @@
  *			fix wcache setup.
  */
 
-#define IDEDISK_VERSION	"1.17"
+#define IDEDISK_VERSION	"1.18"
 
 #undef REALLY_SLOW_IO		/* most systems can safely undef this */
 
@@ -70,7 +69,7 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-/* FIXME: some day we shouldnt need to look in here! */
+/* FIXME: some day we shouldn't need to look in here! */
 
 #include "legacy/pdc4030.h"
 
@@ -154,8 +153,6 @@
 			return DRIVER(drive)->error(drive, "read_intr", stat);
 		}
 		/* no data yet, so wait for another interrupt */
-		if (HWGROUP(drive)->handler != NULL)
-			BUG();
 		ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
 		return ide_started;
 	}
@@ -182,15 +179,13 @@
 	if (((long)(rq->current_nr_sectors -= nsect)) <= 0)
 		ide_end_request(drive, 1, rq->hard_cur_sectors);
 	/*
-	 * Another BH Page walker and DATA INTERGRITY Questioned on ERROR.
+	 * Another BH Page walker and DATA INTEGRITY Questioned on ERROR.
 	 * If passed back up on multimode read, BAD DATA could be ACKED
 	 * to FILE SYSTEMS above ...
 	 */
 	if (i > 0) {
 		if (msect)
 			goto read_next;
-		if (HWGROUP(drive)->handler != NULL)
-			BUG();
 		ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
                 return ide_started;
 	}
@@ -230,8 +225,6 @@
 				char *to = ide_map_buffer(rq, &flags);
 				taskfile_output_data(drive, to, SECTOR_WORDS);
 				ide_unmap_buffer(rq, to, &flags);
-				if (HWGROUP(drive)->handler != NULL)
-					BUG();
 				ide_set_handler(drive, &write_intr, WAIT_CMD, NULL);
                                 return ide_started;
 			}
@@ -332,8 +325,6 @@
 			if (rq->nr_sectors) {
 				if (ide_multwrite(drive, drive->mult_count))
 					return ide_stopped;
-				if (HWGROUP(drive)->handler != NULL)
-					BUG();
 				ide_set_handler(drive, &multwrite_intr, WAIT_CMD, NULL);
 				return ide_started;
 			}
@@ -550,8 +541,6 @@
 	 * MAJOR DATA INTEGRITY BUG !!! only if we error 
 	 */
 			hwgroup->wrq = *rq; /* scratchpad */
-			if (HWGROUP(drive)->handler != NULL)
-				BUG();
 			ide_set_handler(drive, &multwrite_intr, WAIT_CMD, NULL);
 			if (ide_multwrite(drive, drive->mult_count)) {
 				unsigned long flags;
@@ -564,8 +553,6 @@
 		} else {
 			unsigned long flags;
 			char *to = ide_map_buffer(rq, &flags);
-			if (HWGROUP(drive)->handler != NULL)
-				BUG();
 			ide_set_handler(drive, &write_intr, WAIT_CMD, NULL);
 			taskfile_output_data(drive, to, SECTOR_WORDS);
 			ide_unmap_buffer(rq, to, &flags);
@@ -941,6 +928,26 @@
 	return ide_stopped;
 }
 
+ide_startstop_t idedisk_abort(ide_drive_t *drive, const char *msg)
+{
+	ide_hwif_t *hwif;
+	struct request *rq;
+
+	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
+		return ide_stopped;
+
+	hwif = HWIF(drive);
+
+	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
+		rq->errors = 1;
+		ide_end_drive_cmd(drive, BUSY_STAT, 0);
+		return ide_stopped;
+	}
+
+	DRIVER(drive)->end_request(drive, 0, 0);
+	return ide_stopped;
+}
+
 /*
  * Queries for true maximum capacity of the drive.
  * Returns maximum LBA address (> 0) of the drive, 0 if failed.
@@ -1073,7 +1080,7 @@
 {
 	int flag = (drive->id->cfs_enable_1 & 0x0400) ? 1 : 0;
 	if (flag)
-		printk("%s: host protected area => %d\n", drive->name, flag);
+		printk(KERN_INFO "%s: host protected area => %d\n", drive->name, flag);
 	return flag;
 }
 
@@ -1201,7 +1208,7 @@
 		}
 	} else if (s->b.set_multmode) {
 		s->b.set_multmode = 0;
-		if (drive->id && drive->mult_req > drive->id->max_multsect)
+		if (drive->mult_req > drive->id->max_multsect)
 			drive->mult_req = drive->id->max_multsect;
 		if (!IS_PDC4030_DRIVE) {
 			ide_task_t args;
@@ -1286,7 +1293,7 @@
 	char		*out = page;
 	int		len;
 
-	if (drive->id)
+	if (drive->id_read)
 		len = sprintf(out,"%i\n", drive->id->buf_size / 2);
 	else
 		len = sprintf(out,"(none)\n");
@@ -1549,7 +1556,7 @@
 	
 	idedisk_add_settings(drive);
 
-	if (id == NULL)
+	if (drive->id_read == 0)
 		return;
 
 	/*
@@ -1666,6 +1673,7 @@
 	.do_request		= do_rw_disk,
 	.sense			= idedisk_dump_status,
 	.error			= idedisk_error,
+	.abort			= idedisk_abort,
 	.pre_reset		= idedisk_pre_reset,
 	.capacity		= idedisk_capacity,
 	.special		= idedisk_special,
diff -Nru a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
--- a/drivers/ide/ide-dma.c	Thu Mar  6 09:21:37 2003
+++ b/drivers/ide/ide-dma.c	Fri Mar  7 09:14:31 2003
@@ -75,7 +75,6 @@
  */
 
 #include <linux/config.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -419,7 +418,7 @@
 	struct hd_driveid *id = drive->id;
 	ide_hwif_t *hwif = HWIF(drive);
 
-	if (id && (id->capability & 1) && hwif->autodma) {
+	if ((id->capability & 1) && hwif->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (hwif->ide_dma_bad_drive(drive))
 			return hwif->ide_dma_off(drive);
@@ -977,14 +976,12 @@
 {
 	printk(KERN_INFO "    %s: MMIO-DMA at 0x%08lx-0x%08lx",
 		hwif->name, base, base + ports - 1);
-	if (check_mem_region(base, ports)) {
-		printk(" -- Error, MMIO ports already in use.\n");
-		return 1;
-	}
-	request_mem_region(base, ports, hwif->name);
+	if (!request_mem_region(base, ports, hwif->name))
+		goto fail;
 	hwif->dma_base = base;
 	if ((hwif->cds->extra) && (hwif->channel == 0)) {
-		request_region(base+16, hwif->cds->extra, hwif->cds->name);
+		if (!request_region(base+16, hwif->cds->extra, hwif->cds->name))
+			goto release_mem;
 		hwif->dma_extra = hwif->cds->extra;
 	}
 	
@@ -993,10 +990,18 @@
 	else
 		hwif->dma_master = base;
 	if (hwif->dma_base2) {
-		if (!check_mem_region(hwif->dma_base2, ports))
-			request_mem_region(hwif->dma_base2, ports, hwif->name);
+		if (!request_mem_region(hwif->dma_base2, ports, hwif->name))
+			goto release_io;
 	}
 	return 0;
+
+release_mem:
+	release_mem_region(base, ports);
+release_io:
+	release_region(base+16, hwif->cds->extra);
+fail:
+	printk(" -- Error, MMIO ports already in use.\n");
+	return 1;
 }
 
 int ide_iomio_dma (ide_hwif_t *hwif, unsigned long base, unsigned int ports)
diff -Nru a/drivers/ide/ide-geometry.c b/drivers/ide/ide-geometry.c
--- a/drivers/ide/ide-geometry.c	Mon Dec  2 10:17:04 2002
+++ b/drivers/ide/ide-geometry.c	Fri Mar  7 09:15:21 2003
@@ -129,7 +129,7 @@
 	set_capacity(drive->disk, current_capacity(drive));
 
 	if (ret)
-		printk(KERN_INFO "%s%s [%d/%d/%d]", msg, msg1,
+		printk("%s%s [%d/%d/%d]", msg, msg1,
 		       drive->bios_cyl, drive->bios_head, drive->bios_sect);
 	return ret;
 }
diff -Nru a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
--- a/drivers/ide/ide-io.c	Thu Mar  6 09:21:48 2003
+++ b/drivers/ide/ide-io.c	Thu Mar 20 10:19:39 2003
@@ -330,10 +330,7 @@
 		hwif->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
 	}
 	if (rq->errors >= ERROR_MAX) {
-		if (drive->driver != NULL)
-			DRIVER(drive)->end_request(drive, 0, 0);
-		else
-	 		ide_end_request(drive, 0, 0);
+		DRIVER(drive)->end_request(drive, 0, 0);
 	} else {
 		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
 			++rq->errors;
@@ -349,6 +346,49 @@
 EXPORT_SYMBOL(ide_error);
 
 /**
+ *	ide_abort	-	abort pending IDE operatins
+ *	@drive: drive the error occurred on
+ *	@msg: message to report
+ *
+ *	ide_abort kills and cleans up when we are about to do a 
+ *	host initiated reset on active commands. Longer term we
+ *	want handlers to have sensible abort handling themselves
+ *
+ *	This differs fundamentally from ide_error because in 
+ *	this case the command is doing just fine when we
+ *	blow it away.
+ */
+ 
+ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg)
+{
+	ide_hwif_t *hwif;
+	struct request *rq;
+
+	if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
+		return ide_stopped;
+
+	hwif = HWIF(drive);
+	/* retry only "normal" I/O: */
+	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
+		rq->errors = 1;
+		ide_end_drive_cmd(drive, BUSY_STAT, 0);
+		return ide_stopped;
+	}
+	if (rq->flags & REQ_DRIVE_TASKFILE) {
+		rq->errors = 1;
+		ide_end_drive_cmd(drive, BUSY_STAT, 0);
+//		ide_end_taskfile(drive, BUSY_STAT, 0);
+		return ide_stopped;
+	}
+
+	rq->errors |= ERROR_RESET;
+	DRIVER(drive)->end_request(drive, 0, 0);
+	return ide_stopped;
+}
+
+EXPORT_SYMBOL(ide_abort);
+
+/**
  *	ide_cmd		-	issue a simple drive command
  *	@drive: drive the command is for
  *	@cmd: command byte
@@ -399,7 +439,7 @@
 			udelay(100);
 	}
 
-	if (!OK_STAT(stat, READY_STAT, BAD_STAT))
+	if (!OK_STAT(stat, READY_STAT, BAD_STAT) && DRIVER(drive) != NULL)
 		return DRIVER(drive)->error(drive, "drive_cmd", stat);
 		/* calls ide_end_drive_cmd */
 	ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
@@ -428,13 +468,10 @@
 		s->b.set_tune = 0;
 		if (HWIF(drive)->tuneproc != NULL)
 			HWIF(drive)->tuneproc(drive, drive->tune_req);
-	} else if (drive->driver != NULL) {
-		return DRIVER(drive)->special(drive);
-	} else if (s->all) {
-		printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, s->all);
-		s->all = 0;
+		return ide_stopped;
 	}
-	return ide_stopped;
+	else
+		return DRIVER(drive)->special(drive);
 }
 
 EXPORT_SYMBOL(do_special);
@@ -589,42 +626,17 @@
 			return execute_drive_cmd(drive, rq);
 		else if (rq->flags & REQ_DRIVE_TASKFILE)
 			return execute_drive_cmd(drive, rq);
-
-		if (drive->driver != NULL) {
-			return (DRIVER(drive)->do_request(drive, rq, block));
-		}
-		printk(KERN_ERR "%s: media type %d not supported\n", drive->name, drive->media);
-		goto kill_rq;
+		return (DRIVER(drive)->do_request(drive, rq, block));
 	}
 	return do_special(drive);
 kill_rq:
-	if (drive->driver != NULL)
-		DRIVER(drive)->end_request(drive, 0, 0);
-	else
-		ide_end_request(drive, 0, 0);
+	DRIVER(drive)->end_request(drive, 0, 0);
 	return ide_stopped;
 }
 
 EXPORT_SYMBOL(start_request);
 
 /**
- *	restart_request		-	reissue an IDE request
- *	@drive: drive for request
- *	@rq: request to reissue
- *
- *	Reissue a request. See start_request for details and for
- *	FIXME
- */
- 
-int restart_request (ide_drive_t *drive, struct request *rq)
-{
-	(void) start_request(drive, rq);
-	return 0;
-}
-
-EXPORT_SYMBOL(restart_request);
-
-/**
  *	ide_stall_queue		-	pause an IDE device
  *	@drive: drive to stall
  *	@timeout: time to stall for (jiffies)
@@ -742,8 +754,8 @@
 	/* for atari only: POSSIBLY BROKEN HERE(?) */
 	ide_get_lock(ide_intr, hwgroup);
 
-	/* necessary paranoia: ensure IRQs are masked on local CPU */
-	local_irq_disable();
+	/* caller must own ide_lock */
+	BUG_ON(!irqs_disabled());
 
 	while (!hwgroup->busy) {
 		hwgroup->busy = 1;
diff -Nru a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
--- a/drivers/ide/ide-iops.c	Thu Feb 20 08:50:44 2003
+++ b/drivers/ide/ide-iops.c	Sat Mar 22 19:26:14 2003
@@ -1,13 +1,12 @@
 /*
- * linux/drivers/ide/ide-iops.c	Version 0.33	April 11, 2002
+ * linux/drivers/ide/ide-iops.c	Version 0.37	Mar 05, 2003
  *
  *  Copyright (C) 2000-2002	Andre Hedrick <andre@linux-ide.org>
- *
+ *  Copyright (C) 2003		Red Hat <alan@redhat.com>
  *
  */
 
 #include <linux/config.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/string.h>
@@ -63,6 +62,10 @@
 {
 }
 
+static void ide_unplugged_outbsync (ide_drive_t *drive, u8 addr, unsigned long port)
+{
+}
+
 static void ide_unplugged_outw (u16 val, unsigned long port)
 {
 }
@@ -82,7 +85,7 @@
 void unplugged_hwif_iops (ide_hwif_t *hwif)
 {
 	hwif->OUTB	= ide_unplugged_outb;
-	hwif->OUTBSYNC	= ide_unplugged_outb;
+	hwif->OUTBSYNC	= ide_unplugged_outbsync;
 	hwif->OUTW	= ide_unplugged_outw;
 	hwif->OUTL	= ide_unplugged_outl;
 	hwif->OUTSW	= ide_unplugged_outsw;
@@ -130,6 +133,11 @@
 	outb(val, port);
 }
 
+static void ide_outbsync (ide_drive_t *drive, u8 addr, unsigned long port)
+{
+	outb(addr, port);
+}
+
 static void ide_outw (u16 val, unsigned long port)
 {
 	outw(val, port);
@@ -153,7 +161,7 @@
 void default_hwif_iops (ide_hwif_t *hwif)
 {
 	hwif->OUTB	= ide_outb;
-	hwif->OUTBSYNC	= ide_outb;
+	hwif->OUTBSYNC	= ide_outbsync;
 	hwif->OUTW	= ide_outw;
 	hwif->OUTL	= ide_outl;
 	hwif->OUTSW	= ide_outsw;
@@ -201,6 +209,11 @@
 	writeb(value, port);
 }
 
+static void ide_mm_outbsync (ide_drive_t *drive, u8 value, unsigned long port)
+{
+	writeb(value, port);	
+}
+
 static void ide_mm_outw (u16 value, unsigned long port)
 {
 	writew(value, port);
@@ -226,7 +239,7 @@
 	hwif->OUTB	= ide_mm_outb;
 	/* Most systems will need to override OUTBSYNC, alas however
 	   this one is controller specific! */
-	hwif->OUTBSYNC	= ide_mm_outb;
+	hwif->OUTBSYNC	= ide_mm_outbsync;
 	hwif->OUTW	= ide_mm_outw;
 	hwif->OUTL	= ide_mm_outl;
 	hwif->OUTSW	= ide_mm_outsw;
@@ -673,7 +686,7 @@
 		int hssbd = 0;
 		int i;
 		/*
-		 * Determime highest Supported SPEC
+		 * Determine highest Supported SPEC
 		 */
 		for (i=1; i<=15; i++)
 			if (drive->id->major_rev_num & (1<<i))
@@ -889,7 +902,7 @@
         /*
          * Select the drive, and issue the SETFEATURES command
          */
-	disable_irq(hwif->irq);	/* disable_irq_nosync ?? */
+	disable_irq_nosync(hwif->irq);
 	udelay(1);
 	SELECT_DRIVE(drive);
 	SELECT_MASK(drive, 0);
@@ -986,13 +999,11 @@
  *
  * See also ide_execute_command
  */
-void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
+void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
 		      unsigned int timeout, ide_expiry_t *expiry)
 {
-	unsigned long flags;
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
 
-	spin_lock_irqsave(&ide_lock, flags);
 	if (hwgroup->handler != NULL) {
 		printk(KERN_CRIT "%s: ide_set_handler: handler not null; "
 			"old=%p, new=%p\n",
@@ -1002,11 +1013,21 @@
 	hwgroup->expiry		= expiry;
 	hwgroup->timer.expires	= jiffies + timeout;
 	add_timer(&hwgroup->timer);
+}
+
+EXPORT_SYMBOL(__ide_set_handler);
+
+void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
+		      unsigned int timeout, ide_expiry_t *expiry)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&ide_lock, flags);
+	__ide_set_handler(drive, handler, timeout, expiry);
 	spin_unlock_irqrestore(&ide_lock, flags);
 }
 
 EXPORT_SYMBOL(ide_set_handler);
-
+ 
 /**
  *	ide_execute_command	-	execute an IDE command
  *	@drive: IDE drive to issue the command against
@@ -1035,7 +1056,7 @@
 	hwgroup->expiry		= expiry;
 	hwgroup->timer.expires	= jiffies + timeout;
 	add_timer(&hwgroup->timer);
-	hwif->OUTBSYNC(cmd, IDE_COMMAND_REG);
+	hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG);
 	/* Drive takes 400nS to respond, we must avoid the IRQ being
 	   serviced before that. 
 	   
@@ -1050,7 +1071,7 @@
 
 
 /* needed below */
-ide_startstop_t do_reset1 (ide_drive_t *, int);
+static ide_startstop_t do_reset1 (ide_drive_t *, int);
 
 /*
  * atapi_reset_pollfunc() gets invoked to poll the interface for completion every 50ms
@@ -1167,8 +1188,7 @@
 
 void pre_reset (ide_drive_t *drive)
 {
-	if (drive->driver != NULL)
-		DRIVER(drive)->pre_reset(drive);
+	DRIVER(drive)->pre_reset(drive);
 
 	if (!drive->keep_settings) {
 		if (drive->using_dma) {
@@ -1202,14 +1222,20 @@
  * (up to 30 seconds worstcase).  So, instead of busy-waiting here for it,
  * we set a timer to poll at 50ms intervals.
  */
-ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
+static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
 {
 	unsigned int unit;
 	unsigned long flags;
-	ide_hwif_t *hwif = HWIF(drive);
-	ide_hwgroup_t *hwgroup = HWGROUP(drive);
+	ide_hwif_t *hwif;
+	ide_hwgroup_t *hwgroup;
+	
+	spin_lock_irqsave(&ide_lock, flags);
+	hwif = HWIF(drive);
+	hwgroup = HWGROUP(drive);
 
-	local_irq_save(flags);
+	/* We must not reset with running handlers */
+	if(hwgroup->handler != NULL)
+		BUG();
 
 	/* For an ATAPI device, first try an ATAPI SRST. */
 	if (drive->media != ide_disk && !do_not_try_atapi) {
@@ -1218,10 +1244,8 @@
 		udelay (20);
 		hwif->OUTB(WIN_SRST, IDE_COMMAND_REG);
 		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
-		if (HWGROUP(drive)->handler != NULL)
-			BUG();
-		ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
-		local_irq_restore(flags);
+		__ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
+		spin_unlock_irqrestore(&ide_lock, flags);
 		return ide_started;
 	}
 
@@ -1234,20 +1258,10 @@
 
 #if OK_TO_RESET_CONTROLLER
 	if (!IDE_CONTROL_REG) {
-		local_irq_restore(flags);
+		spin_unlock_irqrestore(&ide_lock, flags);
 		return ide_stopped;
 	}
 
-# if 0
-        {
-		u8 control = hwif->INB(IDE_CONTROL_REG);
-		control |= 0x04;
-		hwif->OUTB(control,IDE_CONTROL_REG);
-		udelay(30);
-		control &= 0xFB;
-		hwif->OUTB(control, IDE_CONTROL_REG);
-	}
-# else
 	/*
 	 * Note that we also set nIEN while resetting the device,
 	 * to mask unwanted interrupts from the interface during the reset.
@@ -1257,23 +1271,21 @@
 	 * recover from reset very quickly, saving us the first 50ms wait time.
 	 */
 	/* set SRST and nIEN */
-	hwif->OUTB(drive->ctl|6,IDE_CONTROL_REG);
+	hwif->OUTBSYNC(drive, drive->ctl|6,IDE_CONTROL_REG);
 	/* more than enough time */
 	udelay(10);
 	if (drive->quirk_list == 2) {
 		/* clear SRST and nIEN */
-		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
+		hwif->OUTBSYNC(drive, drive->ctl, IDE_CONTROL_REG);
 	} else {
 		/* clear SRST, leave nIEN */
-		hwif->OUTB(drive->ctl|2, IDE_CONTROL_REG);
+		hwif->OUTBSYNC(drive, drive->ctl|2, IDE_CONTROL_REG);
 	}
 	/* more than enough time */
 	udelay(10);
 	hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
-	if (HWGROUP(drive)->handler != NULL)
-		BUG();
-	ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
-# endif
+	__ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
+
 	/*
 	 * Some weird controller like resetting themselves to a strange
 	 * state when the disks are reset this way. At least, the Winbond
@@ -1281,71 +1293,22 @@
 	 */
 	if (hwif->resetproc != NULL) {
 		hwif->resetproc(drive);
-
-# if 0
-		if (drive->failures) {
-			local_irq_restore(flags);
-			return ide_stopped;
-		}
-# endif
 	}
-
+	
 #endif	/* OK_TO_RESET_CONTROLLER */
 
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&ide_lock, flags);
 	return ide_started;
 }
 
-#if 0
 /*
  * ide_do_reset() is the entry point to the drive/interface reset code.
  */
+
 ide_startstop_t ide_do_reset (ide_drive_t *drive)
 {
 	return do_reset1(drive, 0);
 }
-#else
-/*
- * ide_do_reset() is the entry point to the drive/interface reset code.
- */
-ide_startstop_t ide_do_reset (ide_drive_t *drive)
-{
-	ide_startstop_t start_stop = ide_started;
-# if 0
-        u8 tmp_dma	= drive->using_dma;
-        u8 cspeed	= drive->current_speed;
-	u8 unmask	= drive->unmask;
-# endif
-
-	if (HWGROUP(drive)->handler != NULL) {
-		unsigned long flags;
-		spin_lock_irqsave(&ide_lock, flags);
-		HWGROUP(drive)->handler = NULL;
-		del_timer(&HWGROUP(drive)->timer);
-		spin_unlock_irqrestore(&ide_lock, flags);
-	}
-
-	start_stop = do_reset1(drive, 0);
-# if 0
-	/*
-	 * check for suspend-spindown flag,
-	 * to attempt a restart or spinup of device.
-	 */
-	if (drive->suspend_reset) {
-		/*
-		 * APM WAKE UP todo !!
-		 * int nogoodpower = 1;
-		 * while(nogoodpower) {
-		 * 	check_power1() or check_power2()
-		 * 	nogoodpower = 0;
-		 * }
-		 * HWIF(drive)->multiproc(drive);
-		 */
-# endif
-
-	return start_stop;
-}
-#endif
 
 EXPORT_SYMBOL(ide_do_reset);
 
diff -Nru a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
--- a/drivers/ide/ide-lib.c	Tue Feb 18 10:06:17 2003
+++ b/drivers/ide/ide-lib.c	Thu Mar  6 15:27:52 2003
@@ -1,5 +1,4 @@
 #include <linux/config.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/string.h>
diff -Nru a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
--- a/drivers/ide/ide-probe.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/ide/ide-probe.c	Sat Mar 22 07:38:05 2003
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/ide-probe.c	Version 1.10	Feb 11, 2003
+ *  linux/drivers/ide/ide-probe.c	Version 1.11	Mar 05, 2003
  *
  *  Copyright (C) 1994-1998  Linus Torvalds & authors (see below)
  */
@@ -65,23 +65,14 @@
  *	and make drive properties unconditional outside of this file
  */
  
-static int generic_id(ide_drive_t *drive)
+static void generic_id(ide_drive_t *drive)
 {
-	drive->id = kmalloc(SECTOR_WORDS *4, GFP_KERNEL);
-	if(drive->id == NULL)
-	{
-		printk(KERN_ERR "ide: out of memory for id data.\n");
-		return -ENOMEM;
-	}
-	memset(drive->id, 0, SECTOR_WORDS * 4);
 	drive->id->cyls = drive->cyl;
 	drive->id->heads = drive->head;
 	drive->id->sectors = drive->sect;
 	drive->id->cur_cyls = drive->cyl;
 	drive->id->cur_heads = drive->head;
 	drive->id->cur_sectors = drive->sect;
-	strcpy(drive->id->model, "UNKNOWN");
-	return 0;
 }
 		
 /**
@@ -107,7 +98,7 @@
 {
 	struct hd_driveid *id = drive->id;
 
-	if (drive->removable && id != NULL) {
+	if (drive->removable) {
 		if (id->config == 0x848a) return 1;	/* CompactFlash */
 		if (!strncmp(id->model, "KODAK ATA_FLASH", 15)	/* Kodak */
 		 || !strncmp(id->model, "Hitachi CV", 10)	/* Hitachi */
@@ -138,16 +129,11 @@
 	int bswap = 1;
 	struct hd_driveid *id;
 
-	/* called with interrupts disabled! */
-	id = drive->id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC);
-	if (!id) {
-		printk(KERN_WARNING "(ide-probe::do_identify) "
-			"Out of memory.\n");
-		goto err_kmalloc;
-	}
+	id = drive->id;
 	/* read 512 bytes of id info */
 	hwif->ata_input_data(drive, id, SECTOR_WORDS);
 
+	drive->id_read = 1;
 	local_irq_enable();
 	ide_fix_driveid(id);
 
@@ -290,7 +276,6 @@
 
 err_misc:
 	kfree(id);
-err_kmalloc:
 	drive->present = 0;
 	return;
 }
@@ -298,7 +283,7 @@
 /**
  *	actual_try_to_identify	-	send ata/atapi identify
  *	@drive: drive to identify
- *	@cmd: comamnd to use
+ *	@cmd: command to use
  *
  *	try_to_identify() sends an ATA(PI) IDENTIFY request to a drive
  *	and waits for a response.  It also monitors irqs while this is
@@ -386,7 +371,7 @@
 /**
  *	try_to_identify	-	try to identify a drive
  *	@drive: drive to probe
- *	@cmd: comamnd to use
+ *	@cmd: command to use
  *
  *	Issue the identify command and then do IRQ probing to
  *	complete the identification when needed by finding the
@@ -592,6 +577,25 @@
  
 static inline u8 probe_for_drive (ide_drive_t *drive)
 {
+	/*
+	 *	In order to keep things simple we have an id
+	 *	block for all drives at all times. If the device
+	 *	is pre ATA or refuses ATA/ATAPI identify we
+	 *	will add faked data to this.
+	 *
+	 *	Also note that 0 everywhere means "can't do X"
+	 */
+ 
+	drive->id = kmalloc(SECTOR_WORDS *4, GFP_KERNEL);
+	drive->id_read = 0;
+	if(drive->id == NULL)
+	{
+		printk(KERN_ERR "ide: out of memory for id data.\n");
+		return 0;
+	}
+	memset(drive->id, 0, SECTOR_WORDS * 4);
+	strcpy(drive->id->model, "UNKNOWN");
+	
 	/* skip probing? */
 	if (!drive->noprobe)
 	{
@@ -600,14 +604,14 @@
 			/* look for ATAPI device */
 			(void) do_probe(drive, WIN_PIDENTIFY);
 		}
-		if (drive->id && strstr(drive->id->model, "E X A B Y T E N E S T"))
+		if (strstr(drive->id->model, "E X A B Y T E N E S T"))
 			enable_nest(drive);
 		if (!drive->present)
 			/* drive not found */
 			return 0;
 	
 		/* identification failed? */
-		if (drive->id == NULL) {
+		if (!drive->id_read) {
 			if (drive->media == ide_disk) {
 				printk(KERN_INFO "%s: non-IDE drive, CHS=%d/%d/%d\n",
 					drive->name, drive->cyl,
@@ -616,6 +620,7 @@
 				printk(KERN_INFO "%s: ATAPI cdrom (?)\n", drive->name);
 			} else {
 				/* nuke it */
+				printk(KERN_WARNING "%s: Unknown device on bus refused identification. Ignoring.\n", drive->name);
 				drive->present = 0;
 			}
 		}
@@ -623,9 +628,9 @@
 	}
 	if(!drive->present)
 		return 0;
-	if(drive->id == NULL)
-		if(generic_id(drive) < 0)
-			drive->present = 0;
+	/* The drive wasn't being helpful. Add generic info only */
+	if(!drive->id_read)
+		generic_id(drive);
 	return drive->present;
 }
 
@@ -945,6 +950,9 @@
 		u16 unit = 0;
 		for (unit = 0; unit < MAX_DRIVES; ++unit) {
 			ide_drive_t *drive = &hwif->drives[unit];
+			/* For now don't attach absent drives, we may
+			   want them on default or a new "empty" class
+			   for hotplug reprobing ? */
 			if (drive->present) {
 				ata_attach(drive);
 			}
@@ -990,18 +998,23 @@
 static void ide_init_queue(ide_drive_t *drive)
 {
 	request_queue_t *q = &drive->queue;
-	int max_sectors;
+	int max_sectors = 256;
 
+	/*
+	 *	Our default set up assumes the normal IDE case,
+	 *	that is 64K segmenting, standard PRD setup
+	 *	and LBA28. Some drivers then impose their own
+	 *	limits and LBA48 we could raise it but as yet
+	 *	do not.
+	 */
+	 
 	q->queuedata = HWGROUP(drive);
 	blk_init_queue(q, do_ide_request, &ide_lock);
 	drive->queue_setup = 1;
 	blk_queue_segment_boundary(q, 0xffff);
 
-#ifdef CONFIG_BLK_DEV_PDC4030
-	max_sectors = 127;
-#else
-	max_sectors = 255;
-#endif
+	if (HWIF(drive)->rqsize)
+		max_sectors = HWIF(drive)->rqsize;
 	blk_queue_max_sectors(q, max_sectors);
 
 	/* IDE DMA can do PRD_ENTRIES number of segments. */
@@ -1009,7 +1022,13 @@
 
 	/* This is a driver limit and could be eliminated. */
 	blk_queue_max_phys_segments(q, PRD_ENTRIES);
+}
 
+/*
+ * Setup the drive for request handling.
+ */
+static void ide_init_drive(ide_drive_t *drive)
+{
 	ide_toggle_bounce(drive, 1);
 
 #ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
@@ -1032,16 +1051,14 @@
  */
 static int init_irq (ide_hwif_t *hwif)
 {
-	unsigned long flags;
 	unsigned int index;
-	ide_hwgroup_t *hwgroup, *new_hwgroup;
+	ide_hwgroup_t *hwgroup;
 	ide_hwif_t *match = NULL;
 
-	/* Allocate the buffer and potentially sleep first */
-	new_hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL);
-	
-	spin_lock_irqsave(&ide_lock, flags);
 
+	BUG_ON(in_interrupt());
+	BUG_ON(irqs_disabled());	
+	down(&ide_cfg_sem);
 	hwif->hwgroup = NULL;
 #if MAX_HWIFS > 1
 	/*
@@ -1073,14 +1090,28 @@
 	 */
 	if (match) {
 		hwgroup = match->hwgroup;
-		if(new_hwgroup)
-			kfree(new_hwgroup);
+		hwif->hwgroup = hwgroup;
+		/*
+		 * Link us into the hwgroup.
+		 * This must be done early, do ensure that unexpected_intr
+		 * can find the hwif and prevent irq storms.
+		 * No drives are attached to the new hwif, choose_drive
+		 * can't do anything stupid (yet).
+		 * Add ourself as the 2nd entry to the hwgroup->hwif
+		 * linked list, the first entry is the hwif that owns
+		 * hwgroup->handler - do not change that.
+		 */
+		spin_lock_irq(&ide_lock);
+		hwif->next = hwgroup->hwif->next;
+		hwgroup->hwif->next = hwif;
+		spin_unlock_irq(&ide_lock);
 	} else {
-		hwgroup = new_hwgroup;
-		if (!hwgroup) {
-			spin_unlock_irqrestore(&ide_lock, flags);
-			return 1;
-		}
+		hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL);
+		if (!hwgroup)
+	       		goto out_up;
+
+		hwif->hwgroup = hwgroup;
+
 		memset(hwgroup, 0, sizeof(ide_hwgroup_t));
 		hwgroup->hwif     = hwif->next = hwif;
 		hwgroup->rq       = NULL;
@@ -1112,44 +1143,35 @@
 			/* clear nIEN */
 			hwif->OUTB(0x08, hwif->io_ports[IDE_CONTROL_OFFSET]);
 
-		if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup)) {
-			if (!match)
-				kfree(hwgroup);
-			spin_unlock_irqrestore(&ide_lock, flags);
-			return 1;
-		}
+		if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup))
+	       		goto out_unlink;
 	}
 
 	/*
-	 * Everything is okay, so link us into the hwgroup
+	 * Link any new drives into the hwgroup, allocate
+	 * the block device queue and initialize the drive.
+	 * Note that ide_init_drive sends commands to the new
+	 * drive.
 	 */
-	hwif->hwgroup = hwgroup;
-	hwif->next = hwgroup->hwif->next;
-	hwgroup->hwif->next = hwif;
-
 	for (index = 0; index < MAX_DRIVES; ++index) {
 		ide_drive_t *drive = &hwif->drives[index];
 		if (!drive->present)
 			continue;
-		if (!hwgroup->drive)
-			hwgroup->drive = drive;
-		drive->next = hwgroup->drive->next;
-		hwgroup->drive->next = drive;
-		spin_unlock_irqrestore(&ide_lock, flags);
 		ide_init_queue(drive);
-		spin_lock_irqsave(&ide_lock, flags);
-	}
-
-	if (!hwgroup->hwif) {
-		hwgroup->hwif = HWIF(hwgroup->drive);
-#ifdef DEBUG
-		printk("%s : Adding missed hwif to hwgroup!!\n", hwif->name);
-#endif
+		spin_lock_irq(&ide_lock);
+		if (!hwgroup->drive) {
+			/* first drive for hwgroup. */
+			drive->next = drive;
+			hwgroup->drive = drive;
+			hwgroup->hwif = HWIF(hwgroup->drive);
+		} else {
+			drive->next = hwgroup->drive->next;
+			hwgroup->drive->next = drive;
+		}
+		spin_unlock_irq(&ide_lock);
+		ide_init_drive(drive);
 	}
 
-	/* all CPUs; safe now that hwif->hwgroup is set up */
-	spin_unlock_irqrestore(&ide_lock, flags);
-
 #if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__)
 	printk("%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
 		hwif->io_ports[IDE_DATA_OFFSET],
@@ -1168,6 +1190,30 @@
 		printk(" (%sed with %s)",
 			hwif->sharing_irq ? "shar" : "serializ", match->name);
 	printk("\n");
+	up(&ide_cfg_sem);
+	return 0;
+out_unlink:
+	spin_lock_irq(&ide_lock);
+	if (hwif->next == hwif) {
+		BUG_ON(match);
+		BUG_ON(hwgroup->hwif != hwif);
+		kfree(hwgroup);
+	} else {
+		ide_hwif_t *g;
+		g = hwgroup->hwif;
+		while (g->next != hwif)
+			g = g->next;
+		g->next = hwif->next;
+		if (hwgroup->hwif == hwif) {
+			/* Impossible. */
+			printk(KERN_ERR "Duh. Uninitialized hwif listed as active hwif.\n");
+			hwgroup->hwif = g;
+		}
+		BUG_ON(hwgroup->hwif == hwif);
+	}
+	spin_unlock_irq(&ide_lock);
+out_up:
+	up(&ide_cfg_sem);
 	return 0;
 }
 
@@ -1258,7 +1304,7 @@
 			hwif->channel, unit, drive->lun);
 		if (drive->present) {
 			device_register(&drive->gendev);
-			drive->de = devfs_mk_dir(NULL, name, NULL);
+			drive->de = devfs_mk_dir(name);
 		}
 	}
 	blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
@@ -1340,6 +1386,7 @@
 void export_ide_init_queue (ide_drive_t *drive)
 {
 	ide_init_queue(drive);
+	ide_init_drive(drive);
 }
 
 EXPORT_SYMBOL(export_ide_init_queue);
@@ -1384,7 +1431,8 @@
 			if (!hwif->present)
 				continue;
 			for (unit = 0; unit < MAX_DRIVES; ++unit)
-				ata_attach(&hwif->drives[unit]);
+				if (hwif->drives[unit].present)
+					ata_attach(&hwif->drives[unit]);
 		}
 	}
 	if (!ide_probe)
diff -Nru a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
--- a/drivers/ide/ide-proc.c	Tue Feb 18 10:06:17 2003
+++ b/drivers/ide/ide-proc.c	Thu Mar 13 17:20:37 2003
@@ -1,7 +1,8 @@
 /*
- *  linux/drivers/ide/ide-proc.c	Version 1.03	January  2, 1998
+ *  linux/drivers/ide/ide-proc.c	Version 1.05	Mar 05, 2003
  *
  *  Copyright (C) 1997-1998	Mark Lord
+ *  Copyright (C) 2003		Red Hat <alan@redhat.com>
  */
 
 /*
@@ -57,7 +58,6 @@
  */
 
 #include <linux/config.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 
 #include <asm/uaccess.h>
@@ -365,6 +365,7 @@
 		case ide_cy82c693:	name = "cy82c693";	break;
 		case ide_4drives:	name = "4drives";	break;
 		case ide_pmac:		name = "mac-io";	break;
+		case ide_pc9800:	name = "pc9800";	break;
 		default:		name = "(unknown)";	break;
 	}
 	len = sprintf(page, "%s\n", name);
@@ -568,14 +569,10 @@
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
 	ide_drive_t	*drive = (ide_drive_t *) data;
-	ide_driver_t    *driver = (ide_driver_t *) drive->driver;
 	int		len;
 
-	if (!driver)
-		len = sprintf(page, "(none)\n");
-        else
-		len = sprintf(page,"%llu\n",
-			      (long long) ((ide_driver_t *)drive->driver)->capacity(drive));
+	len = sprintf(page,"%llu\n",
+		      (long long) (DRIVER(drive)->capacity(drive)));
 	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
@@ -620,10 +617,7 @@
 	ide_driver_t	*driver = drive->driver;
 	int		len;
 
-	if (!driver)
-		len = sprintf(page, "(none)\n");
-	else
-		len = sprintf(page, "%s version %s\n",
+	len = sprintf(page, "%s version %s\n",
 			driver->name, driver->version);
 	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
@@ -775,8 +769,7 @@
 	ide_driver_t *driver = drive->driver;
 
 	if (drive->proc) {
-		if (driver)
-			ide_remove_proc_entries(drive->proc, driver->proc);
+		ide_remove_proc_entries(drive->proc, driver->proc);
 		ide_remove_proc_entries(drive->proc, generic_drive_entries);
 		remove_proc_entry(drive->name, proc_ide_root);
 		remove_proc_entry(drive->name, hwif->proc);
diff -Nru a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
--- a/drivers/ide/ide-tape.c	Tue Feb 18 10:06:17 2003
+++ b/drivers/ide/ide-tape.c	Sat Mar 22 12:32:12 2003
@@ -280,7 +280,7 @@
  *			- Add idetape_onstream_mode_sense_tape_parameter_page
  *			  function to get tape capacity in frames: tape->capacity.
  *			- Add support for DI-50 drives( or any DI- drive).
- *			- 'workaround' for read error/blank block arround block 3000.
+ *			- 'workaround' for read error/blank block around block 3000.
  *			- Implement Early warning for end of media for Onstream.
  *			- Cosmetic code changes for readability.
  *			- Idetape_position_tape should not use SKIP bit during
@@ -422,7 +422,7 @@
  *		sharing a (fast) ATA-2 disk with any (slow) new ATAPI device.
  */
 
-#define IDETAPE_VERSION "1.17b"
+#define IDETAPE_VERSION "1.17b-ac1"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -514,7 +514,7 @@
  * AUX
  */
 typedef struct os_aux_s {
-	__u32		format_id;		/* hardware compability AUX is based on */
+	__u32		format_id;		/* hardware compatibility AUX is based on */
 	char		application_sig[4];	/* driver used to write this media */
 	__u32		hdwr;			/* reserved */
 	__u32		update_frame_cntr;	/* for configuration frame */
@@ -1005,7 +1005,7 @@
 	struct completion *waiting;
 	int onstream_write_error;		/* write error recovery active */
 	int header_ok;				/* header frame verified ok */
-	int linux_media;			/* reading linux-specifc media */
+	int linux_media;			/* reading linux-specific media */
 	int linux_media_version;
 	char application_sig[5];		/* application signature */
 	int filemark_cnt;
@@ -2128,8 +2128,6 @@
 			if (temp > pc->buffer_size) {
 				printk(KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n");
 				idetape_discard_data(drive, bcount.all);
-				if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
-					BUG();
 				ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
 				return ide_started;
 			}
@@ -2156,8 +2154,6 @@
 	if (tape->debug_level >= 2)
 		printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all);
 #endif
-	if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
-		BUG();
 	ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);	/* And set the interrupt handler again */
 	return ide_started;
 }
@@ -2235,8 +2231,6 @@
 		return ide_do_reset(drive);
 	}
 	tape->cmd_start_time = jiffies;
-	if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
-		BUG();
 	/* Set the interrupt routine */
 	ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
 #ifdef CONFIG_BLK_DEV_IDEDMA
@@ -2325,8 +2319,6 @@
 	if (dma_ok)			/* Will begin DMA later */
 		set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
 	if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
-		if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
-			BUG();
 		ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
 		OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
 		return ide_started;
@@ -5605,15 +5597,16 @@
  *
  *	0 	If this tape driver is not currently supported by us.
  */
-static int idetape_identify_device (ide_drive_t *drive,struct hd_driveid *id)
+static int idetape_identify_device (ide_drive_t *drive)
 {
 	struct idetape_id_gcw gcw;
+	struct hd_driveid *id = drive->id;
 #if IDETAPE_DEBUG_INFO
 	unsigned short mask,i;
 #endif /* IDETAPE_DEBUG_INFO */
 
-	if (!id)
-		return 0;
+	if (drive->id_read == 0)
+		return 1;
 
 	*((unsigned short *) &gcw) = id->config;
 
@@ -6287,7 +6280,7 @@
 		goto failed;
 	if (drive->media != ide_tape)
 		goto failed;
-	if (!idetape_identify_device (drive, drive->id)) {
+	if (!idetape_identify_device (drive)) {
 		printk(KERN_ERR "ide-tape: %s: not supported by this version of ide-tape\n", drive->name);
 		goto failed;
 	}
diff -Nru a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
--- a/drivers/ide/ide-taskfile.c	Tue Feb 18 10:06:17 2003
+++ b/drivers/ide/ide-taskfile.c	Thu Mar 20 10:23:19 2003
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/ide-taskfile.c	Version 0.33	April 11, 2002
+ * linux/drivers/ide/ide-taskfile.c	Version 0.38	March 05, 2003
  *
  *  Copyright (C) 2000-2002	Michael Cornwell <cornwell@acm.org>
  *  Copyright (C) 2000-2002	Andre Hedrick <andre@linux-ide.org>
@@ -27,7 +27,6 @@
  */
 
 #include <linux/config.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/string.h>
@@ -642,7 +641,7 @@
 				 * NOTE: could rewind beyond beginning :-/
 				 */
 			} else {
-				printk("%s: MULTI-READ assume all data " \
+				printk(KERN_ERR "%s: MULTI-READ assume all data " \
 					"transfered is bad status=0x%02x\n",
 					drive->name, stat);
 			}
@@ -810,11 +809,6 @@
 	rq->errors = 0;
 	return ide_started;
 #else /* ! ALTERNATE_STATE_DIAGRAM_MULTI_OUT */
-
-#if 0
-	if (wait_for_ready(drive, 100))
-		IDE_DEBUG(__LINE__);		//BUG();
-#else
 	if (!(drive_is_ready(drive))) {
 		int i;
 		for (i=0; i<100; i++) {
@@ -822,7 +816,7 @@
 				break;
 		}
 	}
-#endif
+
 	/*
 	 * WARNING :: if the drive as not acked good status we may not
 	 * move the DATA-TRANSFER T-Bar as BSY != 0. <andre@linux-ide.org>
@@ -864,7 +858,7 @@
 				 * NOTE: could rewind beyond beginning :-/
 				 */
 			} else {
-				printk("%s: MULTI-WRITE assume all data " \
+				printk(KERN_ERR "%s: MULTI-WRITE assume all data " \
 					"transfered is bad status=0x%02x\n",
 					drive->name, stat);
 			}
@@ -1497,7 +1491,7 @@
 		case TASKFILE_MULTI_OUT:
 			if (!drive->mult_count) {
 				/* (hs): give up if multcount is not set */
-				printk("%s: %s Multimode Write " \
+				printk(KERN_ERR "%s: %s Multimode Write " \
 					"multcount is not set\n",
 					drive->name, __FUNCTION__);
 				err = -EPERM;
@@ -1525,7 +1519,7 @@
 		case TASKFILE_MULTI_IN:
 			if (!drive->mult_count) {
 				/* (hs): give up if multcount is not set */
-				printk("%s: %s Multimode Read failure " \
+				printk(KERN_ERR "%s: %s Multimode Read failure " \
 					"multcount is not set\n",
 					drive->name, __FUNCTION__);
 				err = -EPERM;
diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
--- a/drivers/ide/ide.c	Wed Feb 19 09:48:49 2003
+++ b/drivers/ide/ide.c	Sat Mar 22 07:38:04 2003
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/ide.c		Version 7.00alpha1	August 19 2002
+ *  linux/drivers/ide/ide.c		Version 7.00beta2	Mar 05 2003
  *
  *  Copyright (C) 1994-1998  Linus Torvalds & authors (see below)
  */
@@ -177,6 +177,7 @@
 static int system_bus_speed;	/* holds what we think is VESA/PCI bus speed */
 static int initializing;	/* set while initializing built-in drivers */
 
+DECLARE_MUTEX(ide_cfg_sem);
 spinlock_t ide_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
 
 static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
@@ -214,6 +215,8 @@
 EXPORT_SYMBOL(idetape);
 EXPORT_SYMBOL(idescsi);
 
+extern ide_driver_t idedefault_driver;
+static void setup_driver_defaults (ide_drive_t *drive);
 
 /*
  * Do not even *think* about calling this!
@@ -271,6 +274,8 @@
 		drive->max_failures		= IDE_DEFAULT_MAX_FAILURES;
 		drive->using_dma		= 0;
 		drive->is_flash			= 0;
+		drive->driver			= &idedefault_driver;
+		setup_driver_defaults(drive);
 		drive->vdma			= 0;
 		INIT_LIST_HEAD(&drive->list);
 	}
@@ -349,9 +354,7 @@
 {
 	if (!drive->present)
 		return 0;
-	if (drive->driver != NULL)
-		return DRIVER(drive)->capacity(drive);
-	return 0;
+	return DRIVER(drive)->capacity(drive);
 }
 
 EXPORT_SYMBOL(current_capacity);
@@ -580,17 +583,19 @@
  
 void ide_unregister (unsigned int index)
 {
-	ide_drive_t *drive, *d;
+	ide_drive_t *drive;
 	ide_hwif_t *hwif, *g;
 	ide_hwgroup_t *hwgroup;
 	int irq_count = 0, unit, i;
-	unsigned long flags;
 	ide_hwif_t old_hwif;
 
 	if (index >= MAX_HWIFS)
 		BUG();
 		
-	spin_lock_irqsave(&ide_lock, flags);
+	BUG_ON(in_interrupt());
+	BUG_ON(irqs_disabled());
+	down(&ide_cfg_sem);
+	spin_lock_irq(&ide_lock);
 	hwif = &ide_hwifs[index];
 	if (!hwif->present)
 		goto abort;
@@ -600,25 +605,23 @@
 			continue;
 		if (drive->usage)
 			goto abort;
-		if (drive->driver != NULL && DRIVER(drive)->shutdown(drive))
+		if (DRIVER(drive)->shutdown(drive))
 			goto abort;
 	}
 	hwif->present = 0;
 	
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irq(&ide_lock);
 
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 		drive = &hwif->drives[unit];
 		if (!drive->present)
 			continue;
-		if (drive->driver != NULL)
-			DRIVER(drive)->cleanup(drive);
+		DRIVER(drive)->cleanup(drive);
 	}
 	
 #ifdef CONFIG_PROC_FS
 	destroy_proc_ide_drives(hwif);
 #endif
-	spin_lock_irqsave(&ide_lock, flags);
 	hwgroup = hwif->hwgroup;
 
 	/*
@@ -633,6 +636,7 @@
 	if (irq_count == 1)
 		free_irq(hwif->irq, hwgroup);
 
+	spin_lock_irq(&ide_lock);
 	/*
 	 * Note that we only release the standard ports,
 	 * and do not even try to handle any extra ports
@@ -644,7 +648,6 @@
 	 * Remove us from the hwgroup, and free
 	 * the hwgroup if we were the only member
 	 */
-	d = hwgroup->drive;
 	for (i = 0; i < MAX_DRIVES; ++i) {
 		drive = &hwif->drives[i];
 		if (drive->de) {
@@ -653,11 +656,23 @@
 		}
 		if (!drive->present)
 			continue;
-		while (hwgroup->drive->next != drive)
-			hwgroup->drive = hwgroup->drive->next;
-		hwgroup->drive->next = drive->next;
-		if (hwgroup->drive == drive)
+		if (drive == drive->next) {
+			/* special case: last drive from hwgroup. */
+			BUG_ON(hwgroup->drive != drive);
 			hwgroup->drive = NULL;
+		} else {
+			ide_drive_t *walk;
+
+			walk = hwgroup->drive;
+			while (walk->next != drive)
+				walk = walk->next;
+			walk->next = drive->next;
+			if (hwgroup->drive == drive) {
+				hwgroup->drive = drive->next;
+				hwgroup->hwif = HWIF(hwgroup->drive);
+			}
+		}
+		BUG_ON(hwgroup->drive == drive);
 		if (drive->id != NULL) {
 			kfree(drive->id);
 			drive->id = NULL;
@@ -665,15 +680,28 @@
 		drive->present = 0;
 		blk_cleanup_queue(&drive->queue);
 	}
-	if (d->present)
-		hwgroup->drive = d;
-	while (hwgroup->hwif->next != hwif)
-		hwgroup->hwif = hwgroup->hwif->next;
-	hwgroup->hwif->next = hwif->next;
-	if (hwgroup->hwif == hwif)
+	if (hwif->next == hwif) {
 		kfree(hwgroup);
-	else
-		hwgroup->hwif = HWIF(hwgroup->drive);
+		BUG_ON(hwgroup->hwif != hwif);
+	} else {
+		/* There is another interface in hwgroup.
+		 * Unlink us, and set hwgroup->drive and ->hwif to
+		 * something sane.
+		 */
+		g = hwgroup->hwif;
+		while (g->next != hwif)
+			g = g->next;
+		g->next = hwif->next;
+		if (hwgroup->hwif == hwif) {
+			/* Chose a random hwif for hwgroup->hwif.
+			 * It's guaranteed that there are no drives
+			 * left in the hwgroup.
+			 */
+			BUG_ON(hwgroup->drive != NULL);
+			hwgroup->hwif = g;
+		}
+		BUG_ON(hwgroup->hwif == hwif);
+	}
 
 #if !defined(CONFIG_DMA_NONPCI)
 	if (hwif->dma_base) {
@@ -813,7 +841,8 @@
 
 	hwif->hwif_data			= old_hwif.hwif_data;
 abort:
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irq(&ide_lock);
+	up(&ide_cfg_sem);
 }
 
 EXPORT_SYMBOL(ide_unregister);
@@ -875,7 +904,7 @@
 EXPORT_SYMBOL(ide_setup_ports);
 
 /*
- * Register an IDE interface, specifing exactly the registers etc
+ * Register an IDE interface, specifying exactly the registers etc
  * Set init=1 iff calling before probes have taken place.
  */
 int ide_register_hw (hw_regs_t *hw, ide_hwif_t **hwifp)
@@ -926,7 +955,7 @@
 EXPORT_SYMBOL(ide_register_hw);
 
 /*
- * Compatability function with existing drivers.  If you want
+ * Compatibility function with existing drivers.  If you want
  * something different, use the function above.
  */
 int ide_register (int arg1, int arg2, int irq)
@@ -998,7 +1027,7 @@
 	setting->set = set;
 	
 	setting->next = *p;
-	if (drive->driver)
+	if (drive->driver != &idedefault_driver)
 		setting->auto_remove = 1;
 	*p = setting;
 	up(&ide_setting_sem);
@@ -1255,13 +1284,14 @@
 
 static int set_using_dma (ide_drive_t *drive, int arg)
 {
-	if (!drive->driver || !DRIVER(drive)->supports_dma)
+	if (!DRIVER(drive)->supports_dma)
 		return -EPERM;
 	if (!drive->id || !(drive->id->capability & 1))
 		return -EPERM;
 	if (HWIF(drive)->ide_dma_check == NULL)
 		return -EPERM;
 	if (arg) {
+		if (HWIF(drive)->ide_dma_check(drive)) return -EIO;
 		if (HWIF(drive)->ide_dma_on(drive)) return -EIO;
 	} else {
 		if (HWIF(drive)->ide_dma_off(drive)) return -EIO;
@@ -1304,15 +1334,9 @@
 		return 0;
 	}
 
-	if (drive->driver != NULL) {
-#if 0
-		ide_unregister_subdriver(drive);
-#else
-		if (DRIVER(drive)->cleanup(drive)) {
-			drive->scsi = 0;
-			return 0;
-		}
-#endif
+	if (DRIVER(drive)->cleanup(drive)) {
+		drive->scsi = 0;
+		return 0;
 	}
 
 	drive->scsi = (u8) arg;
@@ -1353,7 +1377,7 @@
 	mdelay(50);
 #else
 	__set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ/20);
+	schedule_timeout(1+HZ/20);
 #endif /* CONFIG_BLK_DEV_IDECS */
 }
 
@@ -1375,7 +1399,7 @@
 {
 	if (!drive->present || drive->usage || drive->dead)
 		goto abort;
-	if (drive->driver != NULL && DRIVER(drive)->cleanup(drive))
+	if (DRIVER(drive)->cleanup(drive))
 		goto abort;
 	strncpy(drive->driver_req, driver, 9);
 	if (ata_attach(drive)) {
@@ -1387,7 +1411,7 @@
 	} else {
 		drive->driver_req[0] = 0;
 	}
-	if (DRIVER(drive) && !strcmp(DRIVER(drive)->name, driver))
+	if (DRIVER(drive)!= &idedefault_driver && !strcmp(DRIVER(drive)->name, driver))
 		return 0;
 abort:
 	return 1;
@@ -1412,10 +1436,12 @@
 		spin_lock(&drivers_lock);
 		module_put(driver->owner);
 	}
+	drive->gendev.driver = &idedefault_driver.gen_driver;
 	spin_unlock(&drivers_lock);
+	if(idedefault_driver.attach(drive) != 0)
+		panic("ide: default attach failed");
 	spin_lock(&drives_lock);
 	list_add_tail(&drive->list, &ata_unused);
-	drive->gendev.driver = NULL;
 	spin_unlock(&drives_lock);
 	return 1;
 }
@@ -1476,7 +1502,7 @@
 		case HDIO_GET_IDENTITY:
 			if (bdev != bdev->bd_contains)
 				return -EINVAL;
-			if (drive->id == NULL)
+			if (drive->id_read == 0)
 				return -ENOMSG;
 			if (copy_to_user((char *)arg, (char *)drive->id, (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142))
 				return -EFAULT;
@@ -1521,7 +1547,7 @@
 		case HDIO_SCAN_HWIF:
 		{
 			int args[3];
-			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+			if (!capable(CAP_SYS_RAWIO)) return -EACCES;
 			if (copy_from_user(args, (void *)arg, 3 * sizeof(int)))
 				return -EFAULT;
 			if (ide_register(args[0], args[1], args[2]) == -1)
@@ -1529,14 +1555,12 @@
 			return 0;
 		}
 	        case HDIO_UNREGISTER_HWIF:
-			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+			if (!capable(CAP_SYS_RAWIO)) return -EACCES;
 			/* (arg > MAX_HWIFS) checked in function */
 			ide_unregister(arg);
 			return 0;
 		case HDIO_SET_NICE:
 			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-			if (drive->driver == NULL)
-				return -EPERM;
 			if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1))))
 				return -EPERM;
 			drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1;
@@ -1550,18 +1574,26 @@
 		{
 			unsigned long flags;
 			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-#if 1
+			
+			/*
+			 *	Abort the current command on the
+			 *	group if there is one, taking
+			 *	care not to allow anything else
+			 *	to be queued and to die on the
+			 *	spot if we miss one somehow
+			 */
+
 			spin_lock_irqsave(&ide_lock, flags);
-			if ( HWGROUP(drive)->handler != NULL) {
-				printk(KERN_ERR "%s: ide_set_handler: handler not null; %p\n", drive->name, HWGROUP(drive)->handler);
-				(void) HWGROUP(drive)->handler(drive);
-//				HWGROUP(drive)->handler = NULL;
-				HWGROUP(drive)->expiry	= NULL;
-				del_timer(&HWGROUP(drive)->timer);
-			}
+			
+			DRIVER(drive)->abort(drive, "drive reset");
+			if(HWGROUP(drive)->handler)
+				BUG();
+				
+			/* Ensure nothing gets queued after we
+			   drop the lock. Reset will clear the busy */
+		   
+			HWGROUP(drive)->busy = 1;
 			spin_unlock_irqrestore(&ide_lock, flags);
-
-#endif
 			(void) ide_do_reset(drive);
 			if (drive->suspend_reset) {
 /*
@@ -1593,9 +1625,8 @@
 			if (!capable(CAP_SYS_ADMIN))
 				return -EACCES;
 			if (HWIF(drive)->busproc)
-				HWIF(drive)->busproc(drive, (int)arg);
-			return 0;
-
+				return HWIF(drive)->busproc(drive, (int)arg);
+			return -EOPNOTSUPP;
 		default:
 			return -EINVAL;
 	}
@@ -2193,7 +2224,7 @@
  
 static int default_shutdown(ide_drive_t *drive)
 {
-	if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) {
+	if (drive->usage || DRIVER(drive)->busy) {
 		return 1;
 	}
 	drive->dead = 1;
@@ -2261,6 +2292,11 @@
 	return 0;
 }
 
+static ide_startstop_t default_abort (ide_drive_t *drive, const char *msg)
+{
+	return ide_abort(drive, msg);
+}
+
 static void setup_driver_defaults (ide_drive_t *drive)
 {
 	ide_driver_t *d = drive->driver;
@@ -2272,6 +2308,7 @@
 	if (d->end_request == NULL)	d->end_request = default_end_request;
 	if (d->sense == NULL)		d->sense = default_sense;
 	if (d->error == NULL)		d->error = default_error;
+	if (d->abort == NULL)		d->abort = default_abort;
 	if (d->pre_reset == NULL)	d->pre_reset = default_pre_reset;
 	if (d->capacity == NULL)	d->capacity = default_capacity;
 	if (d->special == NULL)		d->special = default_special;
@@ -2282,9 +2319,11 @@
 {
 	unsigned long flags;
 	
+	BUG_ON(drive->driver == NULL);
+	
 	spin_lock_irqsave(&ide_lock, flags);
 	if (version != IDE_SUBDRIVER_VERSION || !drive->present ||
-	    drive->driver != NULL || drive->usage || drive->dead) {
+	    drive->driver != &idedefault_driver || drive->usage || drive->dead) {
 		spin_unlock_irqrestore(&ide_lock, flags);
 		return 1;
 	}
@@ -2294,6 +2333,7 @@
 	spin_lock(&drives_lock);
 	list_add(&drive->list, &driver->drives);
 	spin_unlock(&drives_lock);
+//	printk(KERN_INFO "%s: attached %s driver.\n", drive->name, driver->name);
 	if ((drive->autotune == IDE_TUNE_DEFAULT) ||
 		(drive->autotune == IDE_TUNE_AUTO)) {
 		/* DMA timings and setup moved to ide-probe.c */
@@ -2318,7 +2358,7 @@
 	unsigned long flags;
 	
 	spin_lock_irqsave(&ide_lock, flags);
-	if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) {
+	if (drive->usage || drive->driver == &idedefault_driver || DRIVER(drive)->busy) {
 		spin_unlock_irqrestore(&ide_lock, flags);
 		return 1;
 	}
@@ -2330,10 +2370,12 @@
 	ide_remove_proc_entries(drive->proc, generic_subdriver_entries);
 #endif
 	auto_remove_settings(drive);
-	drive->driver = NULL;
+	drive->driver = &idedefault_driver;
+	setup_driver_defaults(drive);
 	spin_unlock_irqrestore(&ide_lock, flags);
 	spin_lock(&drives_lock);
 	list_del_init(&drive->list);
+	list_add(&drive->list, &drive->driver->drives);
 	spin_unlock(&drives_lock);
 	return 0;
 }
@@ -2343,16 +2385,15 @@
 static int ide_drive_remove(struct device * dev)
 {
 	ide_drive_t * drive = container_of(dev,ide_drive_t,gendev);
-	ide_driver_t * driver = drive->driver;
-
-	if (driver && driver->cleanup)
-		driver->cleanup(drive);
+	DRIVER(drive)->cleanup(drive);
 	return 0;
 }
 
 int ide_register_driver(ide_driver_t *driver)
 {
 	struct list_head list;
+	struct list_head *list_loop;
+	struct list_head *tmp_storage;
 
 	spin_lock(&drivers_lock);
 	list_add(&driver->drivers, &drivers);
@@ -2363,10 +2404,11 @@
 	list_splice_init(&ata_unused, &list);
 	spin_unlock(&drives_lock);
 
-	while (!list_empty(&list)) {
-		ide_drive_t *drive = list_entry(list.next, ide_drive_t, list);
+	list_for_each_safe(list_loop, tmp_storage, &list) {
+		ide_drive_t *drive = container_of(list_loop, ide_drive_t, list);
 		list_del_init(&drive->list);
-		ata_attach(drive);
+		if (drive->present)
+			ata_attach(drive);
 	}
 	driver->gen_driver.name = (char *) driver->name;
 	driver->gen_driver.bus = &ide_bus_type;
@@ -2430,7 +2472,7 @@
 	static char banner_printed;
 	if (!banner_printed) {
 		printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
-		devfs_mk_dir(NULL, "ide", NULL);
+		devfs_mk_dir("ide");
 		system_bus_speed = ide_system_bus_speed();
 		banner_printed = 1;
 	}
diff -Nru a/drivers/ide/legacy/Makefile b/drivers/ide/legacy/Makefile
--- a/drivers/ide/legacy/Makefile	Sat Dec 14 04:38:56 2002
+++ b/drivers/ide/legacy/Makefile	Sun Mar 23 08:43:38 2003
@@ -2,6 +2,7 @@
 obj-$(CONFIG_BLK_DEV_ALI14XX)		+= ali14xx.o
 obj-$(CONFIG_BLK_DEV_DTC2278)		+= dtc2278.o
 obj-$(CONFIG_BLK_DEV_HT6560B)		+= ht6560b.o
+obj-$(CONFIG_BLK_DEV_IDE_PC9800)	+= pc9800.o
 obj-$(CONFIG_BLK_DEV_PDC4030)		+= pdc4030.o
 obj-$(CONFIG_BLK_DEV_QD65XX)		+= qd65xx.o
 obj-$(CONFIG_BLK_DEV_UMC8672)		+= umc8672.o
@@ -16,5 +17,6 @@
 
 # Last of all
 obj-$(CONFIG_BLK_DEV_HD)		+= hd.o
+obj-$(CONFIG_BLK_DEV_HD98)		+= hd98.o
 
 EXTRA_CFLAGS	:= -Idrivers/ide
diff -Nru a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c
--- a/drivers/ide/legacy/ali14xx.c	Tue Feb 18 10:06:19 2003
+++ b/drivers/ide/legacy/ali14xx.c	Thu Mar 20 10:23:19 2003
@@ -229,10 +229,8 @@
 		return 1;
 	}
 
-#ifndef HWIF_PROBE_CLASSIC_METHOD
 	probe_hwif_init(&ide_hwifs[0]);
 	probe_hwif_init(&ide_hwifs[1]);
-#endif /* HWIF_PROBE_CLASSIC_METHOD */
 
 	return 0;
 }
diff -Nru a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c
--- a/drivers/ide/legacy/dtc2278.c	Tue Feb 18 10:06:19 2003
+++ b/drivers/ide/legacy/dtc2278.c	Thu Mar 20 10:23:19 2003
@@ -138,11 +138,8 @@
 	ide_hwifs[1].mate = &ide_hwifs[0];
 	ide_hwifs[1].channel = 1;
 
-#ifndef HWIF_PROBE_CLASSIC_METHOD
 	probe_hwif_init(&ide_hwifs[0]);
 	probe_hwif_init(&ide_hwifs[1]);
-#endif /* HWIF_PROBE_CLASSIC_METHOD */
-
 }
 
 void __init dtc2278_release (void)
diff -Nru a/drivers/ide/legacy/hd98.c b/drivers/ide/legacy/hd98.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/ide/legacy/hd98.c	Thu Mar 13 17:19:57 2003
@@ -0,0 +1,904 @@
+/*
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This is the low-level hd interrupt support. It traverses the
+ * request-list, using interrupts to jump between functions. As
+ * all the functions are called within interrupts, we may not
+ * sleep. Special care is recommended.
+ *
+ *  modified by Drew Eckhardt to check nr of hd's from the CMOS.
+ *
+ *  Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
+ *  in the early extended-partition checks and added DM partitions
+ *
+ *  IRQ-unmask, drive-id, multiple-mode, support for ">16 heads",
+ *  and general streamlining by Mark Lord.
+ *
+ *  Removed 99% of above. Use Mark's ide driver for those options.
+ *  This is now a lightweight ST-506 driver. (Paul Gortmaker)
+ *
+ *  Modified 1995 Russell King for ARM processor.
+ *
+ *  Bugfix: max_sectors must be <= 255 or the wheels tend to come
+ *  off in a hurry once you queue things up - Paul G. 02/2001
+ */
+
+/* Uncomment the following if you want verbose error reports. */
+/* #define VERBOSE_ERRORS */
+
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/genhd.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/mc146818rtc.h> /* CMOS defines */
+#include <linux/init.h>
+#include <linux/blkpg.h>
+#include <linux/hdreg.h>
+
+#define REALLY_SLOW_IO
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#define MAJOR_NR HD_MAJOR
+#define DEVICE_NR(device) (minor(device)>>6)
+#include <linux/blk.h>
+
+#include "io_ports.h"
+
+#ifdef __arm__
+#undef  HD_IRQ
+#endif
+#include <asm/irq.h>
+#ifdef __arm__
+#define HD_IRQ IRQ_HARDDISK
+#endif
+
+/* Hd controller regster ports */
+
+#define HD_DATA		0x640	/* _CTL when writing */
+#define HD_ERROR	0x642	/* see err-bits */
+#define HD_NSECTOR	0x644	/* nr of sectors to read/write */
+#define HD_SECTOR	0x646	/* starting sector */
+#define HD_LCYL		0x648	/* starting cylinder */
+#define HD_HCYL		0x64a	/* high byte of starting cyl */
+#define HD_CURRENT	0x64c	/* 101dhhhh , d=drive, hhhh=head */
+#define HD_STATUS	0x64e	/* see status-bits */
+#define HD_FEATURE	HD_ERROR	/* same io address, read=error, write=feature */
+#define HD_PRECOMP	HD_FEATURE	/* obsolete use of this port - predates IDE */
+#define HD_COMMAND	HD_STATUS	/* same io address, read=status, write=cmd */
+
+#define HD_CMD		0x74c	/* used for resets */
+#define HD_ALTSTATUS	0x74c	/* same as HD_STATUS but doesn't clear irq */
+
+/* Bits of HD_STATUS */
+#define ERR_STAT		0x01
+#define INDEX_STAT		0x02
+#define ECC_STAT		0x04	/* Corrected error */
+#define DRQ_STAT		0x08
+#define SEEK_STAT		0x10
+#define SERVICE_STAT		SEEK_STAT
+#define WRERR_STAT		0x20
+#define READY_STAT		0x40
+#define BUSY_STAT		0x80
+
+/* Bits for HD_ERROR */
+#define MARK_ERR		0x01	/* Bad address mark */
+#define TRK0_ERR		0x02	/* couldn't find track 0 */
+#define ABRT_ERR		0x04	/* Command aborted */
+#define MCR_ERR			0x08	/* media change request */
+#define ID_ERR			0x10	/* ID field not found */
+#define MC_ERR			0x20	/* media changed */
+#define ECC_ERR			0x40	/* Uncorrectable ECC error */
+#define BBD_ERR			0x80	/* pre-EIDE meaning:  block marked bad */
+#define ICRC_ERR		0x80	/* new meaning:  CRC error during transfer */
+
+static spinlock_t hd_lock = SPIN_LOCK_UNLOCKED;
+
+#define TIMEOUT_VALUE	(6*HZ)
+#define	HD_DELAY	0
+
+#define MAX_ERRORS     16	/* Max read/write errors/sector */
+#define RESET_FREQ      8	/* Reset controller every 8th retry */
+#define RECAL_FREQ      4	/* Recalibrate every 4th retry */
+#define MAX_HD		2
+
+#define STAT_OK		(READY_STAT|SEEK_STAT)
+#define OK_STATUS(s)	(((s)&(STAT_OK|(BUSY_STAT|WRERR_STAT|ERR_STAT)))==STAT_OK)
+
+static void recal_intr(void);
+static void bad_rw_intr(void);
+
+static char recalibrate[MAX_HD];
+static char special_op[MAX_HD];
+
+static int reset;
+static int hd_error;
+
+#define SUBSECTOR(block) (CURRENT->current_nr_sectors > 0)
+
+/*
+ *  This struct defines the HD's and their types.
+ */
+struct hd_i_struct {
+	unsigned int head,sect,cyl,wpcom,lzone,ctl;
+};
+	
+#ifdef HD_TYPE
+struct hd_i_struct hd_info[] = { HD_TYPE };
+static int NR_HD = ((sizeof (hd_info))/(sizeof (struct hd_i_struct)));
+#else
+struct hd_i_struct hd_info[MAX_HD];
+static int NR_HD;
+#endif
+
+static struct gendisk *hd_gendisk[MAX_HD];
+
+static struct timer_list device_timer;
+
+#define TIMEOUT_VALUE (6*HZ)
+
+#define SET_TIMER							\
+	do {								\
+		mod_timer(&device_timer, jiffies + TIMEOUT_VALUE);	\
+	} while (0)
+
+static void (*do_hd)(void) = NULL;
+#define SET_HANDLER(x) \
+if ((do_hd = (x)) != NULL) \
+	SET_TIMER; \
+else \
+	del_timer(&device_timer);
+
+
+#if (HD_DELAY > 0)
+unsigned long last_req;
+
+unsigned long read_timer(void)
+{
+        extern spinlock_t i8253_lock;
+	unsigned long t, flags;
+	int i;
+
+	spin_lock_irqsave(&i8253_lock, flags);
+	t = jiffies * 11932;
+    	outb_p(0, PIT_MODE);
+	i = inb_p(PIT_CH0);
+	i |= inb(PIT_CH0) << 8;
+	spin_unlock_irqrestore(&i8253_lock, flags);
+	return(t - i);
+}
+#endif
+
+void __init hd_setup(char *str, int *ints)
+{
+	int hdind = 0;
+
+	if (ints[0] != 3)
+		return;
+	if (hd_info[0].head != 0)
+		hdind=1;
+	hd_info[hdind].head = ints[2];
+	hd_info[hdind].sect = ints[3];
+	hd_info[hdind].cyl = ints[1];
+	hd_info[hdind].wpcom = 0;
+	hd_info[hdind].lzone = ints[1];
+	hd_info[hdind].ctl = (ints[2] > 8 ? 8 : 0);
+	NR_HD = hdind+1;
+}
+
+static void dump_status (const char *msg, unsigned int stat)
+{
+	char devc;
+
+	devc = !blk_queue_empty(QUEUE) ? 'a' + DEVICE_NR(CURRENT->rq_dev) : '?';
+#ifdef VERBOSE_ERRORS
+	printk("hd%c: %s: status=0x%02x { ", devc, msg, stat & 0xff);
+	if (stat & BUSY_STAT)	printk("Busy ");
+	if (stat & READY_STAT)	printk("DriveReady ");
+	if (stat & WRERR_STAT)	printk("WriteFault ");
+	if (stat & SEEK_STAT)	printk("SeekComplete ");
+	if (stat & DRQ_STAT)	printk("DataRequest ");
+	if (stat & ECC_STAT)	printk("CorrectedError ");
+	if (stat & INDEX_STAT)	printk("Index ");
+	if (stat & ERR_STAT)	printk("Error ");
+	printk("}\n");
+	if ((stat & ERR_STAT) == 0) {
+		hd_error = 0;
+	} else {
+		hd_error = inb(HD_ERROR);
+		printk("hd%c: %s: error=0x%02x { ", devc, msg, hd_error & 0xff);
+		if (hd_error & BBD_ERR)		printk("BadSector ");
+		if (hd_error & ECC_ERR)		printk("UncorrectableError ");
+		if (hd_error & ID_ERR)		printk("SectorIdNotFound ");
+		if (hd_error & ABRT_ERR)	printk("DriveStatusError ");
+		if (hd_error & TRK0_ERR)	printk("TrackZeroNotFound ");
+		if (hd_error & MARK_ERR)	printk("AddrMarkNotFound ");
+		printk("}");
+		if (hd_error & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) {
+			printk(", CHS=%d/%d/%d", (inb(HD_HCYL)<<8) + inb(HD_LCYL),
+				inb(HD_CURRENT) & 0xf, inb(HD_SECTOR));
+			if (!blk_queue_empty(QUEUE))
+				printk(", sector=%ld", CURRENT->sector);
+		}
+		printk("\n");
+	}
+#else
+	printk("hd%c: %s: status=0x%02x.\n", devc, msg, stat & 0xff);
+	if ((stat & ERR_STAT) == 0) {
+		hd_error = 0;
+	} else {
+		hd_error = inb(HD_ERROR);
+		printk("hd%c: %s: error=0x%02x.\n", devc, msg, hd_error & 0xff);
+	}
+#endif
+}
+
+void check_status(void)
+{
+	int i = inb(HD_STATUS);
+
+	if (!OK_STATUS(i)) {
+		dump_status("check_status", i);
+		bad_rw_intr();
+	}
+}
+
+static int controller_busy(void)
+{
+	int retries = 100000;
+	unsigned char status;
+
+	do {
+		status = inb(HD_STATUS);
+	} while ((status & BUSY_STAT) && --retries);
+	return status;
+}
+
+static int status_ok(void)
+{
+	unsigned char status = inb(HD_STATUS);
+
+	if (status & BUSY_STAT)
+		return 1;	/* Ancient, but does it make sense??? */
+	if (status & WRERR_STAT)
+		return 0;
+	if (!(status & READY_STAT))
+		return 0;
+	if (!(status & SEEK_STAT))
+		return 0;
+	return 1;
+}
+
+static int controller_ready(unsigned int drive, unsigned int head)
+{
+	int retry = 100;
+
+	do {
+		if (controller_busy() & BUSY_STAT)
+			return 0;
+		outb(0xA0 | (drive<<4) | head, HD_CURRENT);
+		if (status_ok())
+			return 1;
+	} while (--retry);
+	return 0;
+}
+
+static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect,
+		unsigned int head,unsigned int cyl,unsigned int cmd,
+		void (*intr_addr)(void))
+{
+	unsigned short port;
+
+#if (HD_DELAY > 0)
+	while (read_timer() - last_req < HD_DELAY)
+		/* nothing */;
+#endif
+	if (reset)
+		return;
+	if (!controller_ready(drive, head)) {
+		reset = 1;
+		return;
+	}
+	SET_HANDLER(intr_addr);
+	outb(hd_info[drive].ctl,HD_CMD);
+	port=HD_DATA + 2;
+	outb(hd_info[drive].wpcom>>2, port); port += 2;
+	outb(nsect, port); port += 2;
+	outb(sect, port); port += 2;
+	outb(cyl, port); port += 2;
+	outb(cyl>>8, port); port += 2;
+	outb(0xA0|(drive<<4)|head, port); port += 2;
+	outb(cmd, port);
+}
+
+static void hd_request (void);
+
+static int drive_busy(void)
+{
+	unsigned int i;
+	unsigned char c;
+
+	for (i = 0; i < 500000 ; i++) {
+		c = inb(HD_STATUS);
+		if ((c & (BUSY_STAT | READY_STAT | SEEK_STAT)) == STAT_OK)
+			return 0;
+	}
+	dump_status("reset timed out", c);
+	return 1;
+}
+
+static void reset_controller(void)
+{
+	int	i;
+
+	outb(4,HD_CMD);
+	for(i = 0; i < 1000; i++) barrier();
+	outb(hd_info[0].ctl & 0x0f,HD_CMD);
+	for(i = 0; i < 1000; i++) barrier();
+	if (drive_busy())
+		printk("hd: controller still busy\n");
+	else if ((hd_error = inb(HD_ERROR)) != 1)
+		printk("hd: controller reset failed: %02x\n",hd_error);
+}
+
+static void reset_hd(void)
+{
+	static int i;
+
+repeat:
+	if (reset) {
+		reset = 0;
+		i = -1;
+		reset_controller();
+	} else {
+		check_status();
+		if (reset)
+			goto repeat;
+	}
+	if (++i < NR_HD) {
+		special_op[i] = recalibrate[i] = 1;
+		hd_out(i,hd_info[i].sect,hd_info[i].sect,hd_info[i].head-1,
+			hd_info[i].cyl,WIN_SPECIFY,&reset_hd);
+		if (reset)
+			goto repeat;
+	} else
+		hd_request();
+}
+
+/*
+ * Ok, don't know what to do with the unexpected interrupts: on some machines
+ * doing a reset and a retry seems to result in an eternal loop. Right now I
+ * ignore it, and just set the timeout.
+ *
+ * On laptops (and "green" PCs), an unexpected interrupt occurs whenever the
+ * drive enters "idle", "standby", or "sleep" mode, so if the status looks
+ * "good", we just ignore the interrupt completely.
+ */
+void unexpected_hd_interrupt(void)
+{
+	unsigned int stat = inb(HD_STATUS);
+
+	if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) {
+		dump_status ("unexpected interrupt", stat);
+		SET_TIMER;
+	}
+}
+
+/*
+ * bad_rw_intr() now tries to be a bit smarter and does things
+ * according to the error returned by the controller.
+ * -Mika Liljeberg (liljeber@cs.Helsinki.FI)
+ */
+static void bad_rw_intr(void)
+{
+	int dev;
+
+	if (blk_queue_empty(QUEUE))
+		return;
+	dev = DEVICE_NR(CURRENT->rq_dev);
+	if (++CURRENT->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) {
+		end_request(CURRENT, 0);
+		special_op[dev] = recalibrate[dev] = 1;
+	} else if (CURRENT->errors % RESET_FREQ == 0)
+		reset = 1;
+	else if ((hd_error & TRK0_ERR) || CURRENT->errors % RECAL_FREQ == 0)
+		special_op[dev] = recalibrate[dev] = 1;
+	/* Otherwise just retry */
+}
+
+static inline int wait_DRQ(void)
+{
+	int retries = 100000, stat;
+
+	while (--retries > 0)
+		if ((stat = inb(HD_STATUS)) & DRQ_STAT)
+			return 0;
+	dump_status("wait_DRQ", stat);
+	return -1;
+}
+
+static void read_intr(void)
+{
+	int i, retries = 100000;
+
+	do {
+		i = (unsigned) inb(HD_STATUS);
+		if (i & BUSY_STAT)
+			continue;
+		if (!OK_STATUS(i))
+			break;
+		if (i & DRQ_STAT)
+			goto ok_to_read;
+	} while (--retries > 0);
+	dump_status("read_intr", i);
+	bad_rw_intr();
+	hd_request();
+	return;
+ok_to_read:
+	insw(HD_DATA,CURRENT->buffer,256);
+	CURRENT->sector++;
+	CURRENT->buffer += 512;
+	CURRENT->errors = 0;
+	i = --CURRENT->nr_sectors;
+	--CURRENT->current_nr_sectors;
+#ifdef DEBUG
+	printk("hd%c: read: sector %ld, remaining = %ld, buffer=0x%08lx\n",
+		dev+'a', CURRENT->sector, CURRENT->nr_sectors,
+		(unsigned long) CURRENT->buffer+512);
+#endif
+	if (CURRENT->current_nr_sectors <= 0)
+		end_request(CURRENT, 1);
+	if (i > 0) {
+		SET_HANDLER(&read_intr);
+		return;
+	}
+	(void) inb(HD_STATUS);
+#if (HD_DELAY > 0)
+	last_req = read_timer();
+#endif
+	if (!blk_queue_empty(QUEUE))
+		hd_request();
+	return;
+}
+
+static void write_intr(void)
+{
+	int i;
+	int retries = 100000;
+
+	do {
+		i = (unsigned) inb(HD_STATUS);
+		if (i & BUSY_STAT)
+			continue;
+		if (!OK_STATUS(i))
+			break;
+		if ((CURRENT->nr_sectors <= 1) || (i & DRQ_STAT))
+			goto ok_to_write;
+	} while (--retries > 0);
+	dump_status("write_intr", i);
+	bad_rw_intr();
+	hd_request();
+	return;
+ok_to_write:
+	CURRENT->sector++;
+	i = --CURRENT->nr_sectors;
+	--CURRENT->current_nr_sectors;
+	CURRENT->buffer += 512;
+	if (!i || (CURRENT->bio && !SUBSECTOR(i)))
+		end_request(CURRENT, 1);
+	if (i > 0) {
+		SET_HANDLER(&write_intr);
+		outsw(HD_DATA,CURRENT->buffer,256);
+		local_irq_enable();
+	} else {
+#if (HD_DELAY > 0)
+		last_req = read_timer();
+#endif
+		hd_request();
+	}
+	return;
+}
+
+static void recal_intr(void)
+{
+	check_status();
+#if (HD_DELAY > 0)
+	last_req = read_timer();
+#endif
+	hd_request();
+}
+
+/*
+ * This is another of the error-routines I don't know what to do with. The
+ * best idea seems to just set reset, and start all over again.
+ */
+static void hd_times_out(unsigned long dummy)
+{
+	unsigned int dev;
+
+	do_hd = NULL;
+
+	if (blk_queue_empty(QUEUE))
+		return;
+
+	disable_irq(HD_IRQ);
+	local_irq_enable();
+	reset = 1;
+	dev = DEVICE_NR(CURRENT->rq_dev);
+	printk("hd%c: timeout\n", dev+'a');
+	if (++CURRENT->errors >= MAX_ERRORS) {
+#ifdef DEBUG
+		printk("hd%c: too many errors\n", dev+'a');
+#endif
+		end_request(CURRENT, 0);
+	}
+	local_irq_disable();
+	hd_request();
+	enable_irq(HD_IRQ);
+}
+
+int do_special_op (unsigned int dev)
+{
+	if (recalibrate[dev]) {
+		recalibrate[dev] = 0;
+		hd_out(dev,hd_info[dev].sect,0,0,0,WIN_RESTORE,&recal_intr);
+		return reset;
+	}
+	if (hd_info[dev].head > 16) {
+		printk ("hd%c: cannot handle device with more than 16 heads - giving up\n", dev+'a');
+		end_request(CURRENT, 0);
+	}
+	special_op[dev] = 0;
+	return 1;
+}
+
+/*
+ * The driver enables interrupts as much as possible.  In order to do this,
+ * (a) the device-interrupt is disabled before entering hd_request(),
+ * and (b) the timeout-interrupt is disabled before the sti().
+ *
+ * Interrupts are still masked (by default) whenever we are exchanging
+ * data/cmds with a drive, because some drives seem to have very poor
+ * tolerance for latency during I/O. The IDE driver has support to unmask
+ * interrupts for non-broken hardware, so use that driver if required.
+ */
+static void hd_request(void)
+{
+	unsigned int dev, block, nsect, sec, track, head, cyl;
+
+	if (do_hd)
+		return;
+repeat:
+	del_timer(&device_timer);
+	local_irq_enable();
+
+	if (blk_queue_empty(QUEUE)) {
+		do_hd = NULL;
+		return;
+	}
+
+	if (reset) {
+		local_irq_disable();
+		reset_hd();
+		return;
+	}
+	dev = DEVICE_NR(CURRENT->rq_dev);
+	block = CURRENT->sector;
+	nsect = CURRENT->nr_sectors;
+	if (dev >= NR_HD) {
+		printk("hd: bad disk number: %d\n", dev);
+		end_request(CURRENT, 0);
+		goto repeat;
+	}
+	if (block >= get_capacity(hd_gendisk[dev]) ||
+	    ((block+nsect) > get_capacity(hd_gendisk[dev]))) {
+		printk("%s: bad access: block=%d, count=%d\n",
+			hd_gendisk[dev]->disk_name, block, nsect);
+		end_request(CURRENT, 0);
+		goto repeat;
+	}
+
+	if (special_op[dev]) {
+		if (do_special_op(dev))
+			goto repeat;
+		return;
+	}
+	sec   = block % hd_info[dev].sect + 1;
+	track = block / hd_info[dev].sect;
+	head  = track % hd_info[dev].head;
+	cyl   = track / hd_info[dev].head;
+#ifdef DEBUG
+	printk("hd%c: %sing: CHS=%d/%d/%d, sectors=%d, buffer=0x%08lx\n",
+		dev+'a', (CURRENT->cmd == READ)?"read":"writ",
+		cyl, head, sec, nsect, (unsigned long) CURRENT->buffer);
+#endif
+	if(CURRENT->flags & REQ_CMD) {
+		switch (rq_data_dir(CURRENT)) {
+		case READ:
+			hd_out(dev,nsect,sec,head,cyl,WIN_READ,&read_intr);
+			if (reset)
+				goto repeat;
+			break;
+		case WRITE:
+			hd_out(dev,nsect,sec,head,cyl,WIN_WRITE,&write_intr);
+			if (reset)
+				goto repeat;
+			if (wait_DRQ()) {
+				bad_rw_intr();
+				goto repeat;
+			}
+			outsw(HD_DATA,CURRENT->buffer,256);
+			break;
+		default:
+			printk("unknown hd-command\n");
+			end_request(CURRENT, 0);
+			break;
+		}
+	}
+}
+
+static void do_hd_request (request_queue_t * q)
+{
+	disable_irq(HD_IRQ);
+	hd_request();
+	enable_irq(HD_IRQ);
+}
+
+static int hd_ioctl(struct inode * inode, struct file * file,
+	unsigned int cmd, unsigned long arg)
+{
+	struct hd_geometry *loc = (struct hd_geometry *) arg;
+	int dev;
+
+	if ((!inode) || kdev_none(inode->i_rdev))
+		return -EINVAL;
+	dev = DEVICE_NR(inode->i_rdev);
+	if (dev >= NR_HD)
+		return -EINVAL;
+	switch (cmd) {
+		case HDIO_GETGEO:
+		{
+			struct hd_geometry g; 
+			if (!loc)  return -EINVAL;
+			g.heads = hd_info[dev].head;
+			g.sectors = hd_info[dev].sect;
+			g.cylinders = hd_info[dev].cyl;
+			g.start = get_start_sect(inode->i_bdev);
+			return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
+		}
+
+		default:
+			return -EINVAL;
+	}
+}
+
+static int hd_open(struct inode * inode, struct file * filp)
+{
+	int target =  DEVICE_NR(inode->i_rdev);
+	if (target >= NR_HD)
+		return -ENODEV;
+	return 0;
+}
+
+/*
+ * Releasing a block device means we sync() it, so that it can safely
+ * be forgotten about...
+ */
+
+extern struct block_device_operations hd_fops;
+
+static void hd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	void (*handler)(void) = do_hd;
+
+	do_hd = NULL;
+	del_timer(&device_timer);
+	if (!handler)
+		handler = unexpected_hd_interrupt;
+	handler();
+	local_irq_enable();
+}
+
+static struct block_device_operations hd_fops = {
+	.open =		hd_open,
+	.ioctl =	hd_ioctl,
+};
+
+/*
+ * This is the hard disk IRQ description. The SA_INTERRUPT in sa_flags
+ * means we run the IRQ-handler with interrupts disabled:  this is bad for
+ * interrupt latency, but anything else has led to problems on some
+ * machines.
+ *
+ * We enable interrupts in some of the routines after making sure it's
+ * safe.
+ */
+
+static int __init hd_init(void)
+{
+	int drive;
+	if (register_blkdev(MAJOR_NR,"hd",&hd_fops)) {
+		printk("hd: unable to get major %d for hard disk\n",MAJOR_NR);
+		return -1;
+	}
+	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_hd_request, &hd_lock);
+	blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), 255);
+	init_timer(&device_timer);
+	device_timer.function = hd_times_out;
+	blk_queue_hardsect_size(QUEUE, 512);
+
+#ifdef __i386__
+	if (!NR_HD) {
+		extern struct drive_info drive_info;
+		unsigned char *BIOS = (unsigned char *) &drive_info;
+		unsigned long flags;
+#ifndef CONFIG_X86_PC9800
+		int cmos_disks;
+#endif
+
+		for (drive=0 ; drive<2 ; drive++) {
+			hd_info[drive].cyl = *(unsigned short *) BIOS;
+			hd_info[drive].head = *(3+BIOS);
+			hd_info[drive].sect = *(2+BIOS);
+			hd_info[drive].wpcom = 0;
+			hd_info[drive].ctl = *(3+BIOS) > 8 ? 8 : 0;
+			hd_info[drive].lzone = *(unsigned short *) BIOS;
+			if (hd_info[drive].cyl && NR_HD == drive)
+				NR_HD++;
+			BIOS += 6;
+		}
+
+	}
+#endif /* __i386__ */
+#ifdef __arm__
+	if (!NR_HD) {
+		/* We don't know anything about the drive.  This means
+		 * that you *MUST* specify the drive parameters to the
+		 * kernel yourself.
+		 */
+		printk("hd: no drives specified - use hd=cyl,head,sectors"
+			" on kernel command line\n");
+	}
+#endif
+	if (!NR_HD)
+		goto out;
+
+	for (drive=0 ; drive < NR_HD ; drive++) {
+		struct gendisk *disk = alloc_disk();
+		if (!disk)
+			goto Enomem;
+		disk->major = MAJOR_NR;
+		disk->first_minor = drive << 6;
+		disk->minor_shift = 6;
+		disk->fops = &hd_fops;
+		sprintf(disk->disk_name, "hd%c", 'a'+drive);
+		hd_gendisk[drive] = disk;
+	}
+	for (drive=0 ; drive < NR_HD ; drive++) {
+		sector_t size = hd_info[drive].head *
+			hd_info[drive].sect * hd_info[drive].cyl;
+		set_capacity(hd_gendisk[drive], size);
+		printk ("%s: %ldMB, CHS=%d/%d/%d\n",
+			hd_gendisk[drive]->disk_name,
+			size / 2048, hd_info[drive].cyl,
+			hd_info[drive].head, hd_info[drive].sect);
+	}
+
+	if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd", NULL)) {
+		printk("hd: unable to get IRQ%d for the hard disk driver\n",
+			HD_IRQ);
+		goto out1;
+	}
+
+	if (!request_region(HD_DATA, 2, "hd(data)")) {
+		printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
+		NR_HD = 0;
+		free_irq(HD_IRQ, NULL);
+		return;
+	}
+
+	if (!request_region(HD_DATA + 2, 1, "hd"))
+	{
+		printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
+		goto out2;
+	}
+
+	if (!request_region(HD_DATA + 4, 1, "hd"))
+	{
+		printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
+		goto out3;
+	}
+
+	if (!request_region(HD_DATA + 6, 1, "hd"))
+	{
+		printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
+		goto out4;
+	}
+
+	if (!request_region(HD_DATA + 8, 1, "hd"))
+	{
+		printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
+		goto out5;
+	}
+
+	if (!request_region(HD_DATA + 10, 1, "hd"))
+	{
+		printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
+		goto out6;
+	}
+
+	if (!request_region(HD_DATA + 12, 1, "hd"))
+	{
+		printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
+		goto out7;
+	}
+
+	if (!request_region(HD_CMD, 1, "hd(cmd)"))
+	{
+		printk(KERN_WARNING "hd: port 0x%x busy\n", HD_CMD);
+		goto out8;
+	}
+
+	if (!request_region(HD_CMD + 2, 1, "hd(cmd)"))
+	{
+		printk(KERN_WARNING "hd: port 0x%x busy\n", HD_CMD);
+		goto out9;
+	}
+
+	for(drive=0; drive < NR_HD; drive++) {
+		struct hd_i_struct *p = hd_info + drive;
+		set_capacity(hd_gendisk[drive], p->head * p->sect * p->cyl);
+		add_disk(hd_gendisk[drive]);
+	}
+	return 0;
+
+out9:
+	release_region(HD_CMD, 1);
+out8:
+	release_region(HD_DATA + 12, 1);
+out7:
+	release_region(HD_DATA + 10, 1);
+out6:
+	release_region(HD_DATA + 8, 1);
+out5:
+	release_region(HD_DATA + 6, 1);
+out4:
+	release_region(HD_DATA + 4, 1);
+out3:
+	release_region(HD_DATA + 2, 1);
+out2:
+	release_region(HD_DATA, 2);
+	free_irq(HD_IRQ, NULL);
+out1:
+	for (drive = 0; drive < NR_HD; drive++)
+		put_disk(hd_gendisk[drive]);
+	NR_HD = 0;
+out:
+	del_timer(&device_timer);
+	unregister_blkdev(MAJOR_NR,"hd");
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+	return -1;
+Enomem:
+	while (drive--)
+		put_disk(hd_gendisk[drive]);
+	goto out;
+}
+
+static int parse_hd_setup (char *line) {
+	int ints[6];
+
+	(void) get_options(line, ARRAY_SIZE(ints), ints);
+	hd_setup(NULL, ints);
+
+	return 1;
+}
+__setup("hd=", parse_hd_setup);
+
+module_init(hd_init);
diff -Nru a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
--- a/drivers/ide/legacy/ht6560b.c	Tue Feb 18 10:06:19 2003
+++ b/drivers/ide/legacy/ht6560b.c	Thu Mar 20 10:23:19 2003
@@ -312,42 +312,7 @@
 #endif
 }
 
-void __init probe_ht6560b (void)
-{
-	int t;
-	
-	request_region(HT_CONFIG_PORT, 1, ide_hwifs[0].name);
-	ide_hwifs[0].chipset = ide_ht6560b;
-	ide_hwifs[1].chipset = ide_ht6560b;
-	ide_hwifs[0].selectproc = &ht6560b_selectproc;
-	ide_hwifs[1].selectproc = &ht6560b_selectproc;
-	ide_hwifs[0].tuneproc = &tune_ht6560b;
-	ide_hwifs[1].tuneproc = &tune_ht6560b;
-	ide_hwifs[0].serialized = 1;  /* is this needed? */
-	ide_hwifs[1].serialized = 1;  /* is this needed? */
-	ide_hwifs[0].mate = &ide_hwifs[1];
-	ide_hwifs[1].mate = &ide_hwifs[0];
-	ide_hwifs[1].channel = 1;
-			
-	/*
-	 * Setting default configurations for drives
-	 */
-	t = (HT_CONFIG_DEFAULT << 8);
-	t |= HT_TIMING_DEFAULT;
-	ide_hwifs[0].drives[0].drive_data = t;
-	ide_hwifs[0].drives[1].drive_data = t;
-	t |= (HT_SECONDARY_IF << 8);
-	ide_hwifs[1].drives[0].drive_data = t;
-	ide_hwifs[1].drives[1].drive_data = t;
-
-#ifndef HWIF_PROBE_CLASSIC_METHOD
-	probe_hwif_init(&ide_hwifs[0]);
-	probe_hwif_init(&ide_hwifs[1]);
-#endif /* HWIF_PROBE_CLASSIC_METHOD */
-
-}
-
-void __init ht6560b_release (void)
+void ht6560b_release (void)
 {
 	if (ide_hwifs[0].chipset != ide_ht6560b &&
 	    ide_hwifs[1].chipset != ide_ht6560b)
@@ -371,60 +336,80 @@
 	release_region(HT_CONFIG_PORT, 1);
 }
 
-#ifndef MODULE
-/*
- * init_ht6560b:
- *
- * called by ide.c when parsing command line
- */
-
-void __init init_ht6560b (void)
+int __init ht6560b_mod_init(void)
 {
-	if (check_region(HT_CONFIG_PORT,1)) {
+	int t;
+
+	if (!request_region(HT_CONFIG_PORT, 1, ide_hwifs[0].name)) {
 		printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n",
 			__FUNCTION__);
-		return;
+		return -ENODEV;
 	}
+
 	if (!try_to_init_ht6560b()) {
-                printk(KERN_NOTICE "%s: HBA not found\n", __FUNCTION__);
-		return;
+		printk(KERN_NOTICE "%s: HBA not found\n", __FUNCTION__);
+		goto release_region;
 	}
-	probe_ht6560b();
-}
 
-#else
+	ide_hwifs[0].chipset = ide_ht6560b;
+	ide_hwifs[1].chipset = ide_ht6560b;
+	ide_hwifs[0].selectproc = &ht6560b_selectproc;
+	ide_hwifs[1].selectproc = &ht6560b_selectproc;
+	ide_hwifs[0].tuneproc = &tune_ht6560b;
+	ide_hwifs[1].tuneproc = &tune_ht6560b;
+	ide_hwifs[0].serialized = 1;  /* is this needed? */
+	ide_hwifs[1].serialized = 1;  /* is this needed? */
+	ide_hwifs[0].mate = &ide_hwifs[1];
+	ide_hwifs[1].mate = &ide_hwifs[0];
+	ide_hwifs[1].channel = 1;
 
-MODULE_AUTHOR("See Local File");
-MODULE_DESCRIPTION("HT-6560B EIDE-controller support");
-MODULE_LICENSE("GPL");
+	/*
+	 * Setting default configurations for drives
+	 */
+	t = (HT_CONFIG_DEFAULT << 8);
+	t |= HT_TIMING_DEFAULT;
+	ide_hwifs[0].drives[0].drive_data = t;
+	ide_hwifs[0].drives[1].drive_data = t;
+	t |= (HT_SECONDARY_IF << 8);
+	ide_hwifs[1].drives[0].drive_data = t;
+	ide_hwifs[1].drives[1].drive_data = t;
 
-int __init ht6560b_mod_init(void)
-{
-	if (check_region(HT_CONFIG_PORT,1)) {
-		printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n",
-			__FUNCTION__);
-		return -ENODEV;
-	}
+	probe_hwif_init(&ide_hwifs[0]);
+	probe_hwif_init(&ide_hwifs[1]);
 
-	if (!try_to_init_ht6560b()) {
-		printk(KERN_NOTICE "%s: HBA not found\n", __FUNCTION__);
+#ifdef MODULE
+	if (ide_hwifs[0].chipset != ide_ht6560b &&
+	    ide_hwifs[1].chipset != ide_ht6560b) {
+		ht6560b_release();
 		return -ENODEV;
 	}
+#endif
 
-	probe_ht6560b();
-        if (ide_hwifs[0].chipset != ide_ht6560b &&
-            ide_hwifs[1].chipset != ide_ht6560b) {
-                ht6560b_release();
-                return -ENODEV;
-        }
-        return 0;
+	return 0;
+
+release_region:
+	release_region(HT_CONFIG_PORT, 1);
+	return -ENODEV;
 }
-module_init(ht6560b_mod_init);
 
+MODULE_AUTHOR("See Local File");
+MODULE_DESCRIPTION("HT-6560B EIDE-controller support");
+MODULE_LICENSE("GPL");
+
+#ifdef MODULE
 void __init ht6560b_mod_exit(void)
 {
         ht6560b_release();
 }
+
+module_init(ht6560b_mod_init);
 module_exit(ht6560b_mod_exit);
+#else
+/*
+ * called by ide.c when parsing command line
+ */
+void __init init_ht6560b (void)
+{
+	ht6560b_mod_init();	/* ignore return value */
+}
 #endif
-
diff -Nru a/drivers/ide/legacy/pc9800.c b/drivers/ide/legacy/pc9800.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/ide/legacy/pc9800.c	Sat Mar 22 12:36:26 2003
@@ -0,0 +1,84 @@
+/*
+ *  ide_pc9800.c
+ *
+ *  Copyright (C) 1997-2000  Linux/98 project,
+ *			     Kyoto University Microcomputer Club.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/pc9800.h>
+
+#define PC9800_IDE_BANKSELECT	0x432
+
+#undef PC9800_IDE_DEBUG
+
+static void pc9800_select(ide_drive_t *drive)
+{
+#ifdef PC9800_IDE_DEBUG
+	byte old;
+
+	/* Too noisy: */
+	/* printk(KERN_DEBUG "pc9800_select(%s)\n", drive->name); */
+
+	outb(0x80, PC9800_IDE_BANKSELECT);
+	old = inb(PC9800_IDE_BANKSELECT);
+	if (old != HWIF(drive)->index)
+		printk(KERN_DEBUG "ide-pc9800: switching bank #%d -> #%d\n",
+			old, HWIF(drive)->index);
+#endif
+	outb(HWIF(drive)->index, PC9800_IDE_BANKSELECT);
+}
+
+void __init ide_probe_for_pc9800(void)
+{
+	u8 saved_bank;
+
+	if (!PC9800_9821_P() /* || !PC9821_IDEIF_DOUBLE_P() */)
+		return;
+
+	if (!request_region(PC9800_IDE_BANKSELECT, 1, "ide0/1 bank")) {
+		printk(KERN_ERR
+			"ide: bank select port (%#x) is already occupied!\n",
+			PC9800_IDE_BANKSELECT);
+		return;
+	}
+
+	/* Do actual probing. */
+	if ((saved_bank = inb(PC9800_IDE_BANKSELECT)) == (u8) ~0
+	    || (outb(saved_bank ^ 1, PC9800_IDE_BANKSELECT),
+		/* Next outb is dummy for reading status. */
+		outb(0x80, PC9800_IDE_BANKSELECT),
+		inb(PC9800_IDE_BANKSELECT) != (saved_bank ^ 1))) {
+		printk(KERN_INFO
+			"ide: pc9800 type bank selecting port not found\n");
+		release_region(PC9800_IDE_BANKSELECT, 1);
+		return;
+	}
+
+	/* Restore original value, just in case. */
+	outb(saved_bank, PC9800_IDE_BANKSELECT);
+
+	/* These ports are reseved by IDE I/F.  */
+	if (!request_region(0x430, 1, "ide") ||
+	    !request_region(0x435, 1, "ide")) {
+		printk(KERN_WARNING
+			"ide: IO port 0x430 and 0x435 are reserved for IDE"
+			" the card using these ports may not work\n");
+	}
+
+	if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET] == HD_DATA &&
+	    ide_hwifs[1].io_ports[IDE_DATA_OFFSET] == HD_DATA) {
+		ide_hwifs[0].chipset = ide_pc9800;
+		ide_hwifs[0].mate = &ide_hwifs[1];
+		ide_hwifs[0].selectproc = pc9800_select;
+		ide_hwifs[1].chipset = ide_pc9800;
+		ide_hwifs[1].mate = &ide_hwifs[0];
+		ide_hwifs[1].selectproc = pc9800_select;
+	}
+}
diff -Nru a/drivers/ide/legacy/pdc4030.c b/drivers/ide/legacy/pdc4030.c
--- a/drivers/ide/legacy/pdc4030.c	Tue Feb 18 10:06:19 2003
+++ b/drivers/ide/legacy/pdc4030.c	Thu Mar 20 10:23:19 2003
@@ -256,12 +256,11 @@
 		if (!ident.current_tm[i+2].cyl)
 			hwif2->drives[i].noprobe = 1;
 	}
-#ifndef HWIF_PROBE_CLASSIC_METHOD
+
 	probe_hwif_init(&ide_hwifs[hwif->index]);
 	probe_hwif_init(&ide_hwifs[hwif2->index]);
-#endif /* HWIF_PROBE_CLASSIC_METHOD */
 
-        return 1;
+	return 1;
 }
 
 /*
diff -Nru a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c
--- a/drivers/ide/legacy/qd65xx.c	Tue Feb 18 10:06:19 2003
+++ b/drivers/ide/legacy/qd65xx.c	Thu Mar 20 10:23:19 2003
@@ -359,9 +359,7 @@
 	hwif->drives[0].io_32bit =
 	hwif->drives[1].io_32bit = 1;
 	hwif->tuneproc = tuneproc;
-#ifndef HWIF_PROBE_CLASSIC_METHOD
 	probe_hwif_init(hwif);
-#endif /* HWIF_PROBE_CLASSIC_METHOD */
 }
 
 /*
diff -Nru a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c
--- a/drivers/ide/legacy/umc8672.c	Tue Feb 18 10:06:19 2003
+++ b/drivers/ide/legacy/umc8672.c	Thu Mar 20 10:23:19 2003
@@ -162,10 +162,8 @@
 	ide_hwifs[1].mate = &ide_hwifs[0];
 	ide_hwifs[1].channel = 1;
 
-#ifndef HWIF_PROBE_CLASSIC_METHOD
 	probe_hwif_init(&ide_hwifs[0]);
 	probe_hwif_init(&ide_hwifs[1]);
-#endif /* HWIF_PROBE_CLASSIC_METHOD */
 
 	return 0;
 }
diff -Nru a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
--- a/drivers/ide/pci/aec62xx.c	Wed Feb 19 12:14:18 2003
+++ b/drivers/ide/pci/aec62xx.c	Fri Mar  7 09:35:41 2003
@@ -38,6 +38,7 @@
 	char *chipset_nums[] = {"error", "error", "error", "error",
 				"error", "error", "850UF",   "860",
 				 "860R",   "865",  "865R", "error"  };
+	int len;
 	int i;
 
 	for (i = 0; i < n_aec_devs; i++) {
@@ -170,7 +171,11 @@
 #endif /* DEBUG_AEC_REGS */
 		}
 	}
-	return p-buffer;/* => must be less than 4k! */
+	/* p - buffer must be less than 4k! */
+	len = (p - buffer) - offset;
+	*addr = buffer + offset;
+	
+	return len > count ? count : len;
 }
 #endif	/* defined(DISPLAY_AEC62xx_TIMINGS) && defined(CONFIG_PROC_FS) */
 
@@ -324,7 +329,7 @@
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct hd_driveid *id	= drive->id;
 
-	if (id && (id->capability & 1) && drive->autodma) {
+	if ((id->capability & 1) && drive->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (hwif->ide_dma_bad_drive(drive))
 			goto fast_ata_pio;
diff -Nru a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
--- a/drivers/ide/pci/alim15x3.c	Wed Feb 19 12:12:48 2003
+++ b/drivers/ide/pci/alim15x3.c	Thu Mar  6 15:11:45 2003
@@ -518,7 +518,7 @@
 	if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (hwif->ide_dma_bad_drive(drive))
-			goto fast_ata_pio;
+			goto ata_pio;
 		if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) {
 			if (id->dma_ultra & hwif->ultra_mask) {
 				/* Force if Capable UltraDMA */
@@ -540,12 +540,12 @@
 			if (!config_chipset_for_dma(drive))
 				goto no_dma_set;
 		} else {
-			goto fast_ata_pio;
+			goto ata_pio;
 		}
-	} else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
+	} else {
+ata_pio:
+		hwif->tuneproc(drive, 255);
 no_dma_set:
-		hwif->tuneproc(drive, 5);
 		return hwif->ide_dma_off_quietly(drive);
 	}
 	return hwif->ide_dma_on(drive);
@@ -752,6 +752,8 @@
 		hwif->drives[1].autotune = 1;
 		return;
 	}
+
+	hwif->atapi_dma = 1;
 
 	if (m5229_revision > 0x20)
 		hwif->ultra_mask = 0x3f;
diff -Nru a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
--- a/drivers/ide/pci/amd74xx.c	Mon Mar  3 12:09:31 2003
+++ b/drivers/ide/pci/amd74xx.c	Thu Mar  6 15:38:01 2003
@@ -98,6 +98,7 @@
 	unsigned int v, u, i;
 	unsigned short c, w;
 	unsigned char t;
+	int len;
 	char *p = buffer;
 
 	amd_print("----------AMD BusMastering IDE Configuration----------------");
@@ -167,7 +168,11 @@
 	amd_print_drive("Cycle Time:    ", "%8dns", cycle[i]);
 	amd_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10);
 
-	return p - buffer;	/* hoping it is less than 4K... */
+	/* hoping p - buffer is less than 4K... */
+	len = (p - buffer) - offset;
+	*addr = buffer + offset;
+	
+	return len > count ? count : len;
 }
 
 #endif
diff -Nru a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
--- a/drivers/ide/pci/cmd640.c	Tue Feb 18 10:06:19 2003
+++ b/drivers/ide/pci/cmd640.c	Thu Mar 13 16:49:44 2003
@@ -197,8 +197,8 @@
  * Interface to access cmd640x registers
  */
 static unsigned int cmd640_key;
-static void (*put_cmd640_reg)(u16 reg, u8 val);
-static u8 (*get_cmd640_reg)(u16 reg);
+static void (*__put_cmd640_reg)(u16 reg, u8 val);
+static u8 (*__get_cmd640_reg)(u16 reg);
 
 /*
  * This is read from the CFR reg, and is used in several places.
@@ -215,49 +215,32 @@
 
 static void put_cmd640_reg_pci1 (u16 reg, u8 val)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&ide_lock, flags);
 	outb_p((reg & 0xfc) | cmd640_key, 0xcf8);
 	outb_p(val, (reg & 3) | 0xcfc);
-	spin_unlock_irqrestore(&ide_lock, flags);
 }
 
 static u8 get_cmd640_reg_pci1 (u16 reg)
 {
-	u8 b;
-	unsigned long flags;
-
-	spin_lock_irqsave(&ide_lock, flags);
 	outb_p((reg & 0xfc) | cmd640_key, 0xcf8);
-	b = inb_p((reg & 3) | 0xcfc);
-	spin_unlock_irqrestore(&ide_lock, flags);
-	return b;
+	return inb_p((reg & 3) | 0xcfc);
 }
 
 /* PCI method 2 access (from CMD datasheet) */
 
 static void put_cmd640_reg_pci2 (u16 reg, u8 val)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&ide_lock, flags);
 	outb_p(0x10, 0xcf8);
 	outb_p(val, cmd640_key + reg);
 	outb_p(0, 0xcf8);
-	spin_unlock_irqrestore(&ide_lock, flags);
 }
 
 static u8 get_cmd640_reg_pci2 (u16 reg)
 {
 	u8 b;
-	unsigned long flags;
 
-	spin_lock_irqsave(&ide_lock, flags);
 	outb_p(0x10, 0xcf8);
 	b = inb_p(cmd640_key + reg);
 	outb_p(0, 0xcf8);
-	spin_unlock_irqrestore(&ide_lock, flags);
 	return b;
 }
 
@@ -265,26 +248,36 @@
 
 static void put_cmd640_reg_vlb (u16 reg, u8 val)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&ide_lock, flags);
 	outb_p(reg, cmd640_key);
 	outb_p(val, cmd640_key + 4);
-	spin_unlock_irqrestore(&ide_lock, flags);
 }
 
 static u8 get_cmd640_reg_vlb (u16 reg)
 {
+	outb_p(reg, cmd640_key);
+	return inb_p(cmd640_key + 4);
+}
+
+static u8 get_cmd640_reg(u16 reg)
+{
 	u8 b;
 	unsigned long flags;
 
 	spin_lock_irqsave(&ide_lock, flags);
-	outb_p(reg, cmd640_key);
-	b = inb_p(cmd640_key + 4);
+	b = __get_cmd640_reg(reg);
 	spin_unlock_irqrestore(&ide_lock, flags);
 	return b;
 }
 
+static void put_cmd640_reg(u16 reg, u8 val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ide_lock, flags);
+	__put_cmd640_reg(reg,val);
+	spin_unlock_irqrestore(&ide_lock, flags);
+}
+
 static int __init match_pci_cmd640_device (void)
 {
 	const u8 ven_dev[4] = {0x95, 0x10, 0x40, 0x06};
@@ -307,8 +300,8 @@
  */
 static int __init probe_for_cmd640_pci1 (void)
 {
-	get_cmd640_reg = get_cmd640_reg_pci1;
-	put_cmd640_reg = put_cmd640_reg_pci1;
+	__get_cmd640_reg = get_cmd640_reg_pci1;
+	__put_cmd640_reg = put_cmd640_reg_pci1;
 	for (cmd640_key = 0x80000000;
 	     cmd640_key <= 0x8000f800;
 	     cmd640_key += 0x800) {
@@ -323,8 +316,8 @@
  */
 static int __init probe_for_cmd640_pci2 (void)
 {
-	get_cmd640_reg = get_cmd640_reg_pci2;
-	put_cmd640_reg = put_cmd640_reg_pci2;
+	__get_cmd640_reg = get_cmd640_reg_pci2;
+	__put_cmd640_reg = put_cmd640_reg_pci2;
 	for (cmd640_key = 0xc000; cmd640_key <= 0xcf00; cmd640_key += 0x100) {
 		if (match_pci_cmd640_device())
 			return 1; /* success */
@@ -339,8 +332,8 @@
 {
 	u8 b;
 
-	get_cmd640_reg = get_cmd640_reg_vlb;
-	put_cmd640_reg = put_cmd640_reg_vlb;
+	__get_cmd640_reg = get_cmd640_reg_vlb;
+	__put_cmd640_reg = put_cmd640_reg_vlb;
 	cmd640_key = 0x178;
 	b = get_cmd640_reg(CFR);
 	if (b == 0xff || b == 0x00 || (b & CFR_AT_VESA_078h)) {
@@ -454,7 +447,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&ide_lock, flags);
-	b = get_cmd640_reg(reg);
+	b = __get_cmd640_reg(reg);
 	if (mode) {	/* want prefetch on? */
 #if CMD640_PREFETCH_MASKS
 		drive->no_unmask = 1;
@@ -468,7 +461,7 @@
 		drive->io_32bit = 0;
 		b |= prefetch_masks[index];	/* disable prefetch */
 	}
-	put_cmd640_reg(reg, b);
+	__put_cmd640_reg(reg, b);
 	spin_unlock_irqrestore(&ide_lock, flags);
 }
 
@@ -576,9 +569,9 @@
 	 * and then the active/recovery counts into the DRWTIM reg
 	 * (this converts counts of 16 into counts of zero -- okay).
 	 */
-	setup_count |= get_cmd640_reg(arttim_regs[index]) & 0x3f;
-	put_cmd640_reg(arttim_regs[index], setup_count);
-	put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count));
+	setup_count |= __get_cmd640_reg(arttim_regs[index]) & 0x3f;
+	__put_cmd640_reg(arttim_regs[index], setup_count);
+	__put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count));
 	spin_unlock_irqrestore(&ide_lock, flags);
 }
 
diff -Nru a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
--- a/drivers/ide/pci/cs5520.c	Wed Feb 19 12:14:15 2003
+++ b/drivers/ide/pci/cs5520.c	Thu Mar 20 10:18:57 2003
@@ -65,6 +65,7 @@
 {
 	char *p = buffer;
 	unsigned long bmiba = pci_resource_start(bmide_dev, 2);
+	int len;
 	u8 c0 = 0, c1 = 0;
 	u16 reg16;
 	u32 reg32;
@@ -94,7 +95,10 @@
 	pci_read_config_dword(bmide_dev, 0x68, &reg32);
 	p += sprintf(p, "16bit Secondary: %08x\n", reg32);
 	
-	return p-buffer;
+	len = (p - buffer) - offset;
+	*addr = buffer + offset;
+	
+	return len > count ? count : len;
 }
 
 #endif
@@ -259,9 +263,9 @@
 {
 	ata_index_t index;
 	ide_pci_device_t *d = &cyrix_chipsets[id->driver_data];
-	
-	ide_setup_pci_noise(dev, d);	
-	
+
+	ide_setup_pci_noise(dev, d);
+
 	/* We must not grab the entire device, it has 'ISA' space in its
 	   BARS too and we will freak out other bits of the kernel */
 	if(pci_enable_device_bars(dev, 1<<2))
@@ -271,15 +275,15 @@
 	}
 	pci_set_master(dev);
 	pci_set_dma_mask(dev, 0xFFFFFFFF);
-	init_chipset_cs5520(dev, d->name);	
-	
+	init_chipset_cs5520(dev, d->name);
+
 	index.all = 0xf0f0;
 
 	/*
 	 *	Now the chipset is configured we can let the core
 	 *	do all the device setup for us
 	 */
-	 	
+
 	ide_pci_setup_ports(dev, d, 1, 14, &index);
 
 	printk("Index.b %d %d\n", index.b.low, index.b.high);
@@ -288,7 +292,7 @@
 		probe_hwif_init(&ide_hwifs[index.b.low]);
 	if((index.b.high & 0xf0) != 0xf0)
 		probe_hwif_init(&ide_hwifs[index.b.high]);
-		
+	MOD_INC_USE_COUNT;
 	return 0;
 }
 
diff -Nru a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
--- a/drivers/ide/pci/cy82c693.c	Wed Feb 19 12:13:15 2003
+++ b/drivers/ide/pci/cy82c693.c	Sat Mar 22 12:32:12 2003
@@ -2,12 +2,12 @@
  * linux/drivers/ide/pci/cy82c693.c		Version 0.40	Sep. 10, 2002
  *
  *  Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
- *  Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrater
+ *  Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
  *
  * CYPRESS CY82C693 chipset IDE controller
  *
  * The CY82C693 chipset is used on Digital's PC-Alpha 164SX boards.
- * Writting the driver was quite simple, since most of the job is
+ * Writing the driver was quite simple, since most of the job is
  * done by the generic pci-ide support. 
  * The hard part was finding the CY82C693's datasheet on Cypress's
  * web page :-(. But Altavista solved this problem :-).
diff -Nru a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
--- a/drivers/ide/pci/hpt34x.c	Wed Feb 19 12:15:49 2003
+++ b/drivers/ide/pci/hpt34x.c	Sat Mar 22 12:32:12 2003
@@ -58,7 +58,7 @@
 static int hpt34x_get_info (char *buffer, char **addr, off_t offset, int count)
 {
 	char *p = buffer;
-	int i;
+	int i, len;
 
 	p += sprintf(p, "\n                             "
 			"HPT34X Chipset.\n");
@@ -96,7 +96,11 @@
 	}
 	p += sprintf(p, "\n");
 
-	return p-buffer;	/* => must be less than 4k! */
+	/* p - buffer must be less than 4k! */
+	len = (p - buffer) - offset;
+	*addr = buffer + offset;
+	
+	return len > count ? count : len;
 }
 #endif  /* defined(DISPLAY_HPT34X_TIMINGS) && defined(CONFIG_PROC_FS) */
 
@@ -162,7 +166,7 @@
 /*
  * 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.  Initally for designed for
+ * after the drive is reported by the OS.  Initially for designed for
  * HPT343 UDMA chipset by HighPoint|Triones Technologies, Inc.
  */
 
diff -Nru a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
--- a/drivers/ide/pci/hpt366.c	Wed Feb 19 12:15:55 2003
+++ b/drivers/ide/pci/hpt366.c	Sat Mar 22 12:32:12 2003
@@ -85,7 +85,7 @@
 	char *chipset_nums[] = {"366", "366",  "368",
 				"370", "370A", "372",
 				"302", "371",  "374" };
-	int i;
+	int i, len;
 
 	p += sprintf(p, "\n                             "
 		"HighPoint HPT366/368/370/372/374\n");
@@ -153,8 +153,12 @@
 		}
 	}
 	p += sprintf(p, "\n");
+
+	/* p - buffer must be less than 4k! */
+	len = (p - buffer) - offset;
+	*addr = buffer + offset;
 	
-	return p-buffer;/* => must be less than 4k! */
+	return len > count ? count : len;
 }
 #endif  /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */
 
@@ -443,7 +447,7 @@
 /*
  * 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.  Initally for designed for
+ * after the drive is reported by the OS.  Initially for designed for
  * HPT366 UDMA chipset by HighPoint|Triones Technologies, Inc.
  *
  * check_in_drive_lists(drive, bad_ata66_4)
diff -Nru a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
--- a/drivers/ide/pci/opti621.c	Wed Feb 19 12:16:22 2003
+++ b/drivers/ide/pci/opti621.c	Sat Mar 22 12:32:12 2003
@@ -118,7 +118,7 @@
  */
 
 /* #define READ_PREFETCH 0 */
-/* Uncommnent for disable read prefetch.
+/* Uncomment for disable read prefetch.
  * There is some readprefetch capatibility in hdparm,
  * but when I type hdparm -P 1 /dev/hda, I got errors
  * and till reset drive is inaccessible.
diff -Nru a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
--- a/drivers/ide/pci/pdc202xx_new.c	Tue Feb 25 11:05:27 2003
+++ b/drivers/ide/pci/pdc202xx_new.c	Thu Mar  6 15:37:05 2003
@@ -77,13 +77,17 @@
 static int pdcnew_get_info (char *buffer, char **addr, off_t offset, int count)
 {
 	char *p = buffer;
-	int i;
+	int i, len;
 
 	for (i = 0; i < n_pdc202_devs; i++) {
 		struct pci_dev *dev	= pdc202_devs[i];
 		p = pdcnew_info(buffer, dev);
 	}
-	return p-buffer;	/* => must be less than 4k! */
+	/* p - buffer must be less than 4k! */
+	len = (p - buffer) - offset;
+	*addr = buffer + offset;
+	
+	return len > count ? count : len;
 }
 #endif  /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */
 
diff -Nru a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
--- a/drivers/ide/pci/pdc202xx_old.c	Wed Feb 19 12:12:58 2003
+++ b/drivers/ide/pci/pdc202xx_old.c	Thu Mar  6 15:36:50 2003
@@ -177,13 +177,17 @@
 static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count)
 {
 	char *p = buffer;
-	int i;
+	int i, len;
 
 	for (i = 0; i < n_pdc202_devs; i++) {
 		struct pci_dev *dev	= pdc202_devs[i];
 		p = pdc202xx_info(buffer, dev);
 	}
-	return p-buffer;	/* => must be less than 4k! */
+	/* p - buffer must be less than 4k! */
+	len = (p - buffer) - offset;
+	*addr = buffer + offset;
+	
+	return len > count ? count : len;
 }
 #endif  /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */
 
diff -Nru a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
--- a/drivers/ide/pci/piix.c	Wed Feb 19 12:14:06 2003
+++ b/drivers/ide/pci/piix.c	Fri Mar 21 06:38:22 2003
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/pci/piix.c	Version 0.42	January 11, 2003
+ *  linux/drivers/ide/pci/piix.c	Version 0.44	March 20, 2003
  *
  *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
  *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
@@ -106,6 +106,7 @@
 #include "ide_modes.h"
 #include "piix.h"
 
+static int no_piix_dma;
 #if defined(DISPLAY_PIIX_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
@@ -114,7 +115,6 @@
 #define PIIX_MAX_DEVS		5
 static struct pci_dev *piix_devs[PIIX_MAX_DEVS];
 static int n_piix_devs;
-static int no_piix_dma = 0;
 
 /**
  *	piix_get_info		-	fill in /proc for PIIX ide
@@ -146,7 +146,9 @@
 			case PCI_DEVICE_ID_INTEL_82801BA_9:
 			case PCI_DEVICE_ID_INTEL_82801CA_10:
 			case PCI_DEVICE_ID_INTEL_82801CA_11:
+			case PCI_DEVICE_ID_INTEL_82801DB_10:
 			case PCI_DEVICE_ID_INTEL_82801DB_11:
+			case PCI_DEVICE_ID_INTEL_82801EB_11:
 			case PCI_DEVICE_ID_INTEL_82801E_11:
 				p += sprintf(p, "PIIX4 Ultra 100 ");
 				break;
@@ -279,7 +281,9 @@
 		case PCI_DEVICE_ID_INTEL_82801CA_10:
 		case PCI_DEVICE_ID_INTEL_82801CA_11:
 		case PCI_DEVICE_ID_INTEL_82801E_11:
+		case PCI_DEVICE_ID_INTEL_82801DB_10:
 		case PCI_DEVICE_ID_INTEL_82801DB_11:
+		case PCI_DEVICE_ID_INTEL_82801EB_11:
 			mode = 3;
 			break;
 		/* UDMA 66 capable */
@@ -551,7 +555,7 @@
 
 	drive->init_speed = 0;
 
-	if (id && (id->capability & 1) && drive->autodma) {
+	if ((id->capability & 1) && drive->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (hwif->ide_dma_bad_drive(drive))
 			goto fast_ata_pio;
@@ -605,7 +609,9 @@
 		case PCI_DEVICE_ID_INTEL_82801BA_9:
 		case PCI_DEVICE_ID_INTEL_82801CA_10:
 		case PCI_DEVICE_ID_INTEL_82801CA_11:
+		case PCI_DEVICE_ID_INTEL_82801DB_10:
 		case PCI_DEVICE_ID_INTEL_82801DB_11:
+		case PCI_DEVICE_ID_INTEL_82801EB_11:
 		case PCI_DEVICE_ID_INTEL_82801E_11:
 		{
 			unsigned int extra = 0;
@@ -794,7 +800,9 @@
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12},
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13},
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14},
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15},
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15},
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16},
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_10,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17},
 	{ 0, },
 };
 
diff -Nru a/drivers/ide/pci/piix.h b/drivers/ide/pci/piix.h
--- a/drivers/ide/pci/piix.h	Mon Nov 11 05:22:07 2002
+++ b/drivers/ide/pci/piix.h	Thu Mar 20 10:41:31 2003
@@ -251,8 +251,50 @@
 		.extra		= 0,
 	},{	/* 15 */
 		.vendor		= PCI_VENDOR_ID_INTEL,
+		.device		= PCI_DEVICE_ID_INTEL_82801EB_11,
+		.name		= "ICH5",
+		.init_setup	= init_setup_piix,
+		.init_chipset	= init_chipset_piix,
+		.init_iops	= NULL,
+		.init_hwif	= init_hwif_piix,
+		.init_dma	= init_dma_piix,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+		.bootable	= ON_BOARD,
+		.extra		= 0,
+	},{	/* 16 */
+		.vendor		= PCI_VENDOR_ID_INTEL,
 		.device		= PCI_DEVICE_ID_INTEL_82801E_11,
 		.name		= "C-ICH",
+		.init_setup	= init_setup_piix,
+		.init_chipset	= init_chipset_piix,
+		.init_iops	= NULL,
+		.init_hwif	= init_hwif_piix,
+		.init_dma	= init_dma_piix,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+		.bootable	= ON_BOARD,
+		.extra		= 0,
+	},{	/* 17 */
+		.vendor		= PCI_VENDOR_ID_INTEL,
+		.device		= PCI_DEVICE_ID_INTEL_82801DB_10,
+		.name		= "ICH4",
+		.init_setup	= init_setup_piix,
+		.init_chipset	= init_chipset_piix,
+		.init_iops	= NULL,
+		.init_hwif	= init_hwif_piix,
+		.init_dma	= init_dma_piix,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+		.bootable	= ON_BOARD,
+		.extra		= 0,
+	},{	/* 17 */
+		.vendor		= PCI_VENDOR_ID_INTEL,
+		.device		= PCI_DEVICE_ID_INTEL_82801DB_10,
+		.name		= "ICH4",
 		.init_setup	= init_setup_piix,
 		.init_chipset	= init_chipset_piix,
 		.init_iops	= NULL,
diff -Nru a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
--- a/drivers/ide/pci/sc1200.c	Wed Feb 19 12:15:43 2003
+++ b/drivers/ide/pci/sc1200.c	Thu Mar  6 15:36:26 2003
@@ -87,6 +87,7 @@
 {
 	char *p = buffer;
 	unsigned long bibma = pci_resource_start(bmide_dev, 4);
+	int len;
 	u8  c0 = 0, c1 = 0;
 
 	/*
@@ -111,7 +112,10 @@
 	p += sprintf(p, "DMA\n");
 	p += sprintf(p, "PIO\n");
 
-	return p-buffer;
+	len = (p - buffer) - offset;
+	*addr = buffer + offset;
+	
+	return len > count ? count : len;
 }
 #endif /* DISPLAY_SC1200_TIMINGS && CONFIG_PROC_FS */
 
diff -Nru a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
--- a/drivers/ide/pci/serverworks.c	Wed Feb 19 12:16:00 2003
+++ b/drivers/ide/pci/serverworks.c	Sat Mar 22 12:32:12 2003
@@ -57,7 +57,7 @@
 static int svwks_get_info (char *buffer, char **addr, off_t offset, int count)
 {
 	char *p = buffer;
-	int i;
+	int i, len;
 
 	p += sprintf(p, "\n                             "
 			"ServerWorks OSB4/CSB5/CSB6\n");
@@ -195,7 +195,11 @@
 	}
 	p += sprintf(p, "\n");
 
-	return p-buffer;	 /* => must be less than 4k! */
+	/* p - buffer must be less than 4k! */
+	len = (p - buffer) - offset;
+	*addr = buffer + offset;
+	
+	return len > count ? count : len;
 }
 #endif  /* defined(DISPLAY_SVWKS_TIMINGS) && defined(CONFIG_PROC_FS) */
 
@@ -578,7 +582,7 @@
 			 * This is a device pin issue on CSB6.
 			 * Since there will be a future raid mode,
 			 * early versions of the chipset require the
-			 * interrupt pin to be set, and it is a compatiblity
+			 * interrupt pin to be set, and it is a compatibility
 			 * mode issue.
 			 */
 			dev->irq = 0;
diff -Nru a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
--- a/drivers/ide/pci/siimage.c	Wed Feb 19 12:16:20 2003
+++ b/drivers/ide/pci/siimage.c	Thu Mar  6 15:35:51 2003
@@ -55,6 +55,7 @@
 static int siimage_get_info (char *buffer, char **addr, off_t offset, int count)
 {
 	char *p = buffer;
+	int len;
 	u16 i;
 
 	p += sprintf(p, "\n");
@@ -62,7 +63,11 @@
 		struct pci_dev *dev	= siimage_devs[i];
 		p = print_siimage_get_info(p, dev, i);
 	}
-	return p-buffer;	/* => must be less than 4k! */
+	/* p - buffer must be less than 4k! */
+	len = (p - buffer) - offset;
+	*addr = buffer + offset;
+	
+	return len > count ? count : len;
 }
 
 #endif	/* defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) */
diff -Nru a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
--- a/drivers/ide/pci/sis5513.c	Wed Feb 19 12:13:08 2003
+++ b/drivers/ide/pci/sis5513.c	Sat Mar 22 12:32:12 2003
@@ -70,7 +70,7 @@
    at boot time to its value */
 // #define BROKEN_LEVEL XFER_SW_DMA_0
 
-/* Miscellaneaous flags */
+/* Miscellaneous flags */
 #define SIS5513_LATENCY		0x01
 
 /* registers layout and init values are chipset family dependant */
@@ -185,7 +185,7 @@
 	{ "SiS5511",	PCI_DEVICE_ID_SI_5511,	ATA_16,		0},
 };
 
-/* Cycle time bits and values vary accross chip dma capabilities
+/* Cycle time bits and values vary across chip dma capabilities
    These three arrays hold the register layout and the values to set.
    Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */
 
@@ -202,7 +202,7 @@
 	{15,10,7,5,3,2,1}, /* ATA_133a (earliest 691 southbridges) */
 	{15,10,7,5,3,2,1}, /* ATA_133 */
 };
-/* CRC Valid Setup Time vary accross IDE clock setting 33/66/100/133
+/* CRC Valid Setup Time vary across IDE clock setting 33/66/100/133
    See SiS962 data sheet for more detail */
 static u8 cvs_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = {
 	{0,0,0,0,0,0,0}, /* no udma */
@@ -214,7 +214,7 @@
 	{9,6,4,2,2,2,2},
 	{9,6,4,2,2,2,2},
 };
-/* Initialize time, Active time, Recovery time vary accross
+/* Initialize time, Active time, Recovery time vary across
    IDE clock settings. These 3 arrays hold the register value
    for PIO0/1/2/3/4 and DMA0/1/2 mode in order */
 static u8 ini_time_value[][8] = {
@@ -424,6 +424,7 @@
 static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
 {
 	char *p = buffer;
+	int len;
 	u8 reg;
 	u16 reg2, reg3;
 
@@ -494,7 +495,10 @@
 	p = get_masters_info(p);
 	p = get_slaves_info(p);
 
-	return p-buffer;
+	len = (p - buffer) - offset;
+	*addr = buffer + offset;
+	
+	return len > count ? count : len;
 }
 #endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */
 
@@ -923,7 +927,7 @@
 	}
 
 	/* Make general config ops here
-	   1/ tell IDE channels to operate in Compabitility mode only
+	   1/ tell IDE channels to operate in Compatibility mode only
 	   2/ tell old chips to allow per drive IDE timings */
 	if (host_dev) {
 		u8 reg;
diff -Nru a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
--- a/drivers/ide/pci/slc90e66.c	Wed Feb 19 12:14:12 2003
+++ b/drivers/ide/pci/slc90e66.c	Thu Mar  6 15:34:56 2003
@@ -34,8 +34,9 @@
 static int slc90e66_get_info (char *buffer, char **addr, off_t offset, int count)
 {
 	char *p = buffer;
+	int len;
 	unsigned long bibma = pci_resource_start(bmide_dev, 4);
-        u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0;
+	u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0;
 	u8  c0 = 0, c1 = 0;
 	u8  reg44 = 0, reg47 = 0, reg48 = 0, reg4a = 0, reg4b = 0;
 
@@ -110,7 +111,11 @@
  *	FIXME.... Add configuration junk data....blah blah......
  */
 
-	return p-buffer;	 /* => must be less than 4k! */
+	/* p - buffer must be less than 4k! */
+	len = (p - buffer) - offset;
+	*addr = buffer + offset;
+	
+	return len > count ? count : len;
 }
 #endif  /* defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS) */
 
diff -Nru a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
--- a/drivers/ide/pci/via82cxxx.c	Mon Mar  3 12:11:59 2003
+++ b/drivers/ide/pci/via82cxxx.c	Thu Mar  6 14:19:29 2003
@@ -140,6 +140,7 @@
 		 uen[4], udma[4], umul[4], active8b[4], recover8b[4];
 	struct pci_dev *dev = bmide_dev;
 	unsigned int v, u, i;
+	int len;
 	u16 c, w;
 	u8 t, x;
 	char *p = buffer;
@@ -269,7 +270,10 @@
 		speed[i] / 1000, speed[i] / 100 % 10);
 
 	/* hoping it is less than 4K... */
-	return p - buffer;
+	len = (p - buffer) - offset;
+	*addr = buffer + offset;
+
+	return len > count ? count : len;
 }
 
 #endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */
diff -Nru a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
--- a/drivers/ide/ppc/pmac.c	Mon Feb 24 10:14:36 2003
+++ b/drivers/ide/ppc/pmac.c	Sat Mar 22 12:32:12 2003
@@ -61,7 +61,7 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
 	/* Those fields are duplicating what is in hwif. We currently
 	 * can't use the hwif ones because of some assumptions that are
-	 * beeing done by the generic code about the kind of dma controller
+	 * being done by the generic code about the kind of dma controller
 	 * and format of the dma table. This will have to be fixed though.
 	 */
 	volatile struct dbdma_regs*	dma_regs;
@@ -1392,7 +1392,7 @@
 	/* We have to things to deal with here:
 	 * 
 	 * - The dbdma won't stop if the command was started
-	 * but completed with an error without transfering all
+	 * but completed with an error without transferring all
 	 * datas. This happens when bad blocks are met during
 	 * a multi-block transfer.
 	 * 
diff -Nru a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
--- a/drivers/ieee1394/dv1394.c	Fri Feb 28 10:15:53 2003
+++ b/drivers/ieee1394/dv1394.c	Sat Mar 22 07:38:05 2003
@@ -177,15 +177,6 @@
 
 static struct hpsb_highlevel *hl_handle; /* = NULL; */
 
-static LIST_HEAD(dv1394_devfs);
-struct dv1394_devfs_entry {
-	struct list_head list;
-    devfs_handle_t devfs;
-	char name[32];
-	struct dv1394_devfs_entry *parent;
-};
-static spinlock_t dv1394_devfs_lock = SPIN_LOCK_UNLOCKED;
-
 /* translate from a struct file* to the corresponding struct video_card* */
 
 static inline struct video_card* file_to_video_card(struct file *file)
@@ -2456,137 +2447,25 @@
 };
 
 
-/*** DEVFS HELPERS *********************************************************/
-
-struct dv1394_devfs_entry *
-dv1394_devfs_find( char *name)
-{
-	struct list_head *lh;
-	struct dv1394_devfs_entry *p;
-
-	spin_lock( &dv1394_devfs_lock);
-	if(!list_empty(&dv1394_devfs)) {
-		list_for_each(lh, &dv1394_devfs) {
-			p = list_entry(lh, struct dv1394_devfs_entry, list);
-			if(!strncmp(p->name, name, sizeof(p->name))) {
-				goto found;
-			}
-		}
-	}
-	p = NULL;
-	
-found:
-	spin_unlock( &dv1394_devfs_lock);
-	return p;
-}
-
 #ifdef CONFIG_DEVFS_FS
 static int dv1394_devfs_add_entry(struct video_card *video)
 {
-	char buf[32];
-	struct dv1394_devfs_entry *p;
-	struct dv1394_devfs_entry *parent;
+	char buf[64];
 
-	p = kmalloc(sizeof(struct dv1394_devfs_entry), GFP_KERNEL);
-	if(!p) {
-		printk(KERN_ERR "dv1394: cannot allocate dv1394_devfs_entry\n");
-		goto err;
-	}
-	memset(p, 0, sizeof(struct dv1394_devfs_entry));
-	
-	snprintf(buf, sizeof(buf), "dv/host%d/%s", (video->id>>2),
-						(video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"));
-		
-	parent = dv1394_devfs_find(buf);
-	if (parent == NULL) {
-		printk(KERN_ERR "dv1394: unable to locate parent devfs of %s\n", buf);
-		goto err_free;
-	}
-	
-	video->devfs_handle = devfs_register(
-						 parent->devfs,
-					     (video->mode == MODE_RECEIVE ? "in" : "out"),
-						 DEVFS_FL_NONE,
-					     IEEE1394_MAJOR,
+	snprintf(buf, sizeof(buf), "ieee1394/dv/host%d/%s/%s",
+		(video->id>>2),
+		(video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"),
+		(video->mode == MODE_RECEIVE ? "in" : "out"));
+
+	video->devfs_handle = devfs_register(NULL, buf, 0, IEEE1394_MAJOR,
 					     IEEE1394_MINOR_BLOCK_DV1394*16 + video->id,
 					     S_IFCHR | S_IRUGO | S_IWUGO,
-					     &dv1394_fops,
-					     (void*) video);
-	p->devfs = video->devfs_handle;
-
-	if (p->devfs == NULL) {
-		printk(KERN_ERR "dv1394: unable to create /dev/ieee1394/%s/%s\n",
-			parent->name,
-			(video->mode == MODE_RECEIVE ? "in" : "out"));
-		goto err_free;
-	}
-	
-	spin_lock( &dv1394_devfs_lock);
-	INIT_LIST_HEAD(&p->list);
-	list_add_tail(&p->list, &dv1394_devfs);
-	spin_unlock( &dv1394_devfs_lock);
-	
-	return 0;
-	
- err_free:
-	kfree(p);
- err:
-	return -ENOMEM;
-}
-
-static int
-dv1394_devfs_add_dir( char *name,
-					struct dv1394_devfs_entry *parent, 
-					struct dv1394_devfs_entry **out)
-{
-	struct dv1394_devfs_entry *p;
-
-	p = kmalloc(sizeof(struct dv1394_devfs_entry), GFP_KERNEL);
-	if(!p) {
-		printk(KERN_ERR "dv1394: cannot allocate dv1394_devfs_entry\n");
-		goto err;
-	}
-	memset(p, 0, sizeof(struct dv1394_devfs_entry));
-	
-	if (parent == NULL) {
-		snprintf(p->name, sizeof(p->name), "%s", name);
-		p->devfs = devfs_mk_dir(ieee1394_devfs_handle, name, NULL);
-	} else {
-		snprintf(p->name, sizeof(p->name), "%s/%s", parent->name, name);
-		p->devfs = devfs_mk_dir(parent->devfs, name, NULL);
-	}
-	if (p->devfs == NULL) {
-		printk(KERN_ERR "dv1394: unable to create /dev/ieee1394/%s\n", p->name);
-		goto err_free;
+					     &dv1394_fops, video);
+	if (video->devfs_handle == NULL) {
+		printk(KERN_ERR "dv1394: unable to create /dev/%s\n", buf);
+		return -ENOMEM;
 	}
-
-	p->parent = parent;
-	if (out != NULL) *out = p;
-
-	spin_lock( &dv1394_devfs_lock);
-	INIT_LIST_HEAD(&p->list);
-	list_add_tail(&p->list, &dv1394_devfs);
-	spin_unlock( &dv1394_devfs_lock);
-
 	return 0;
-	
- err_free:
-	kfree(p);
- err:
-	return -ENOMEM;
-}
-
-void dv1394_devfs_del( char *name)
-{
-	struct dv1394_devfs_entry *p = dv1394_devfs_find(name);
-	if (p != NULL) {
-		devfs_unregister(p->devfs);
-		
-		spin_lock( &dv1394_devfs_lock);
-		list_del(&p->list);
-		spin_unlock( &dv1394_devfs_lock);
-		kfree(p);
-	}
 }
 #endif /* CONFIG_DEVFS_FS */
 
@@ -2664,7 +2543,7 @@
 	
 #ifdef CONFIG_DEVFS_FS
 	if (dv1394_devfs_add_entry(video) < 0)
-			goto err_free;
+		goto err_free;
 #endif
 
 	debug_printk("dv1394: dv1394_init() OK on ID %d\n", video->id);
@@ -2687,8 +2566,9 @@
 		(video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"),
 		(video->mode == MODE_RECEIVE ? "in" : "out")
 		);
+
 #ifdef CONFIG_DEVFS_FS
-	dv1394_devfs_del(buf);
+	devfs_remove("ieee1394/%s", buf);
 #endif
 #ifdef CONFIG_PROC_FS
 	dv1394_procfs_del(buf);
@@ -2726,13 +2606,11 @@
 	spin_unlock_irqrestore(&dv1394_cards_lock, flags);
 
 	n = (video->id >> 2);
+
 #ifdef CONFIG_DEVFS_FS
-	snprintf(buf, sizeof(buf), "dv/host%d/NTSC", n);
-	dv1394_devfs_del(buf);
-	snprintf(buf, sizeof(buf), "dv/host%d/PAL", n);
-	dv1394_devfs_del(buf);
-	snprintf(buf, sizeof(buf), "dv/host%d", n);
-	dv1394_devfs_del(buf);
+	devfs_remove("ieee1394/dv/host%d/NTSC", n);
+	devfs_remove("ieee1394/dv/host%d/PAL", n);
+	devfs_remove("ieee1394/dv/host%d", n);
 #endif
 
 #ifdef CONFIG_PROC_FS
@@ -2770,15 +2648,9 @@
 #endif
 
 #ifdef CONFIG_DEVFS_FS
-{
-	struct dv1394_devfs_entry *devfs_entry = dv1394_devfs_find("dv");
-	if (devfs_entry != NULL) {
-		snprintf(buf, sizeof(buf), "host%d", ohci->id);
-		dv1394_devfs_add_dir(buf, devfs_entry, &devfs_entry);
-		dv1394_devfs_add_dir("NTSC", devfs_entry, NULL);
-		dv1394_devfs_add_dir("PAL", devfs_entry, NULL);
-	}
-}
+	devfs_mk_dir("ieee1394/dv/host%d", ohci->id);
+	devfs_mk_dir("ieee1394/dv/host%d/NTSC", ohci->id);
+	devfs_mk_dir("ieee1394/dv/host%d/PAL", ohci->id);
 #endif
 	
 	dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
@@ -3028,7 +2900,7 @@
 	hpsb_unregister_highlevel (hl_handle);
 	ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
 #ifdef CONFIG_DEVFS_FS
-	dv1394_devfs_del("dv");
+	devfs_remove("ieee1394/dv");
 #endif
 #ifdef CONFIG_PROC_FS
 	dv1394_procfs_del("dv");
@@ -3047,8 +2919,7 @@
 	}
 
 #ifdef CONFIG_DEVFS_FS
-	ret = dv1394_devfs_add_dir("dv", NULL, NULL);
-	if (ret < 0) {
+	if (!devfs_mk_dir("ieee1394/dv")) {
 		printk(KERN_ERR "dv1394: unable to create /dev/ieee1394/dv\n");
 		ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
 		return -ENOMEM;
@@ -3061,7 +2932,7 @@
 		printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/dv\n");
 		ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
 #ifdef CONFIG_DEVFS_FS
-		dv1394_devfs_del("dv");
+		devfs_remove("ieee1394/dv");
 #endif
 		return -ENOMEM;
 	}
@@ -3072,7 +2943,7 @@
 		printk(KERN_ERR "dv1394: hpsb_register_highlevel failed\n");
 		ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
 #ifdef CONFIG_DEVFS_FS
-		dv1394_devfs_del("dv");
+		devfs_remove("ieee1394/dv");
 #endif
 #ifdef CONFIG_PROC_FS
 		dv1394_procfs_del("dv");
diff -Nru a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
--- a/drivers/ieee1394/ieee1394_core.c	Wed Feb 26 12:04:10 2003
+++ b/drivers/ieee1394/ieee1394_core.c	Sat Mar 22 07:38:04 2003
@@ -1155,7 +1155,7 @@
 	hpsb_packet_cache = kmem_cache_create("hpsb_packet", sizeof(struct hpsb_packet),
 					      0, 0, NULL, NULL);
 
-	ieee1394_devfs_handle = devfs_mk_dir(NULL, "ieee1394", NULL);
+	ieee1394_devfs_handle = devfs_mk_dir("ieee1394");
 
 	if (register_chrdev(IEEE1394_MAJOR, "ieee1394", &ieee1394_chardev_ops)) {
 		HPSB_ERR("unable to register character device major %d!\n", IEEE1394_MAJOR);
diff -Nru a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
--- a/drivers/ieee1394/video1394.c	Fri Feb 14 09:17:07 2003
+++ b/drivers/ieee1394/video1394.c	Sat Mar 22 09:04:07 2003
@@ -1251,7 +1251,7 @@
 {
 	struct video_card *video;
 	unsigned long flags;
-	char name[16];
+	char name[24];
 	int minor;
 
 	video = kmalloc(sizeof(struct video_card), GFP_KERNEL);
@@ -1270,9 +1270,9 @@
 	video->id = ohci->id;
 	video->ohci = ohci;
 
-	sprintf(name, "%d", video->id);
+	sprintf(name, "%s/%d", VIDEO1394_DRIVER_NAME, video->id);
 	minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + video->id;
-	video->devfs = devfs_register(devfs_handle, name, DEVFS_FL_DEFAULT,
+	video->devfs = devfs_register(NULL, name, DEVFS_FL_DEFAULT,
 				      IEEE1394_MAJOR, minor,
 				      S_IFCHR | S_IRUSR | S_IWUSR,
 				      &video1394_fops, NULL);
@@ -1486,7 +1486,7 @@
 		return -EIO;
         }
 
-	devfs_handle = devfs_mk_dir(NULL, VIDEO1394_DRIVER_NAME, NULL);
+	devfs_handle = devfs_mk_dir(VIDEO1394_DRIVER_NAME);
 
 	hl_handle = hpsb_register_highlevel (VIDEO1394_DRIVER_NAME, &hl_ops);
 	if (hl_handle == NULL) {
diff -Nru a/drivers/input/evdev.c b/drivers/input/evdev.c
--- a/drivers/input/evdev.c	Sun Nov 17 23:09:44 2002
+++ b/drivers/input/evdev.c	Sat Mar 22 09:03:17 2003
@@ -397,7 +397,7 @@
 	sprintf(evdev->name, "event%d", minor);
 
 	evdev_table[minor] = evdev;
-	evdev->devfs = input_register_minor("event%d", minor, EVDEV_MINOR_BASE);
+	evdev->devfs = input_register_minor("input/event%d", minor, EVDEV_MINOR_BASE);
 
 	return &evdev->handle;
 }
diff -Nru a/drivers/input/input.c b/drivers/input/input.c
--- a/drivers/input/input.c	Wed Feb 12 19:35:39 2003
+++ b/drivers/input/input.c	Sat Mar 22 07:38:05 2003
@@ -546,8 +546,11 @@
 {
 	char devfs_name[16];
 	sprintf(devfs_name, name, minor);
-	return devfs_register(input_devfs_handle, devfs_name, DEVFS_FL_DEFAULT, INPUT_MAJOR, minor + minor_base,
-		S_IFCHR | S_IRUGO | S_IWUSR, &input_fops, NULL);
+
+	return devfs_register(NULL, devfs_name, 0,
+			INPUT_MAJOR, minor + minor_base,
+			S_IFCHR|S_IRUGO|S_IWUSR,
+			&input_fops, NULL);
 }
 
 void input_unregister_minor(devfs_handle_t handle)
@@ -696,7 +699,7 @@
 		return -EBUSY;
 	}
 
-	input_devfs_handle = devfs_mk_dir(NULL, "input", NULL);
+	input_devfs_handle = devfs_mk_dir("input");
 
 	return 0;
 }
diff -Nru a/drivers/input/keyboard/98kbd.c b/drivers/input/keyboard/98kbd.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/input/keyboard/98kbd.c	Thu Mar 20 10:43:51 2003
@@ -0,0 +1,380 @@
+/*
+ *  drivers/input/keyboard/98kbd.c
+ *
+ *  PC-9801 keyboard driver for Linux
+ *
+ *    Based on atkbd.c and xtkbd.c written by Vojtech Pavlik
+ *
+ *  Copyright (c) 2002 Osamu Tomita
+ *  Copyright (c) 1999-2001 Vojtech Pavlik
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or 
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * 
+ */
+
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/init.h>
+#include <linux/serio.h>
+
+#include <asm/io.h>
+#include <asm/pc9800.h>
+
+MODULE_AUTHOR("Osamu Tomita <tomita@cinet.co.jp>");
+MODULE_DESCRIPTION("PC-9801 keyboard driver");
+MODULE_LICENSE("GPL");
+
+#define KBD98_KEY	0x7f
+#define KBD98_RELEASE	0x80
+
+static unsigned char kbd98_keycode[256] = {	 
+	  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 43, 14, 15,
+	 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 41, 26, 28, 30, 31, 32,
+	 33, 34, 35, 36, 37, 38, 39, 40, 27, 44, 45, 46, 47, 48, 49, 50,
+	 51, 52, 53, 12, 57,184,109,104,110,111,103,105,106,108,102,107,
+	 74, 98, 71, 72, 73, 55, 75, 76, 77, 78, 79, 80, 81,117, 82,124,
+	 83,185, 87, 88, 85, 89, 90,  0,  0,  0,  0,  0,  0,  0,102,  0,
+	 99,133, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,  0,  0,  0,  0,
+	 54, 58, 42, 56, 29
+};
+
+struct jis_kbd_conv {
+	unsigned char scancode;
+	struct {
+		unsigned char shift;
+		unsigned char keycode;
+	} emul[2];
+};
+
+static struct jis_kbd_conv kbd98_jis[] = {
+	{0x02, {{0,   3}, {1,  40}}},
+	{0x06, {{0,   7}, {1,   8}}},
+	{0x07, {{0,   8}, {0,  40}}},
+	{0x08, {{0,   9}, {1,  10}}},
+	{0x09, {{0,  10}, {1,  11}}},
+	{0x0a, {{0,  11}, {1, 255}}},
+	{0x0b, {{0,  12}, {0,  13}}},
+	{0x0c, {{1,   7}, {0,  41}}},
+	{0x1a, {{1,   3}, {1,  41}}},
+	{0x26, {{0,  39}, {1,  13}}},
+	{0x27, {{1,  39}, {1,   9}}},
+	{0x33, {{0, 255}, {1,  12}}},
+	{0xff, {{0, 255}, {1, 255}}}	/* terminater */
+};
+
+#define KBD98_CMD_SETEXKEY	0x1095	/* Enable/Disable Windows, Appli key */
+#define KBD98_CMD_SETRATE	0x109c	/* Set typematic rate */
+#define KBD98_CMD_SETLEDS	0x109d	/* Set keyboard leds */
+#define KBD98_CMD_GETLEDS	0x119d	/* Get keyboard leds */
+#define KBD98_CMD_GETID		0x019f
+
+#define KBD98_RET_ACK		0xfa
+#define KBD98_RET_NAK		0xfc	/* Command NACK, send the cmd again */
+
+#define KBD98_KEY_JIS_EMUL	253
+#define KBD98_KEY_UNKNOWN	254
+#define KBD98_KEY_NULL		255
+
+static char *kbd98_name = "PC-9801 Keyboard";
+
+struct kbd98 {
+	unsigned char keycode[256];
+	struct input_dev dev;
+	struct serio *serio;
+	char phys[32];
+	unsigned char cmdbuf[4];
+	unsigned char cmdcnt;
+	signed char ack;
+	unsigned char shift;
+	struct {
+		unsigned char scancode;
+		unsigned char keycode;
+	} emul;
+	struct jis_kbd_conv jis[16];
+};
+
+void kbd98_interrupt(struct serio *serio, unsigned char data,
+			unsigned int flags, struct pt_regs *regs)
+{
+	struct kbd98 *kbd98 = serio->private;
+	unsigned char scancode, keycode;
+	int press, i;
+
+	switch (data) {
+		case KBD98_RET_ACK:
+			kbd98->ack = 1;
+			return;
+		case KBD98_RET_NAK:
+			kbd98->ack = -1;
+			return;
+	}
+
+	if (kbd98->cmdcnt) {
+		kbd98->cmdbuf[--kbd98->cmdcnt] = data;
+		return;
+	}
+
+	scancode = data & KBD98_KEY;
+	keycode = kbd98->keycode[scancode];
+	press = !(data & KBD98_RELEASE);
+	if (kbd98->emul.scancode != KBD98_KEY_UNKNOWN
+	    && scancode != kbd98->emul.scancode) {
+		input_report_key(&kbd98->dev, kbd98->emul.keycode, 0);
+		kbd98->emul.scancode = KBD98_KEY_UNKNOWN;
+	}
+
+	if (keycode == KEY_RIGHTSHIFT)
+		kbd98->shift = press;
+
+	switch (keycode) {
+		case KEY_2:
+		case KEY_6:
+		case KEY_7:
+		case KEY_8:
+		case KEY_9:
+		case KEY_0:
+		case KEY_MINUS:
+		case KEY_EQUAL:
+		case KEY_GRAVE:
+		case KEY_SEMICOLON:
+		case KEY_APOSTROPHE:
+			/* emulation: JIS keyboard to US101 keyboard */
+			i = 0;
+			while (kbd98->jis[i].scancode != 0xff) {
+				if (scancode == kbd98->jis[i].scancode)
+					break;
+				i ++;
+			}
+
+			keycode = kbd98->jis[i].emul[kbd98->shift].keycode;
+			if (keycode == KBD98_KEY_NULL)
+				return;
+
+			if (press) {
+				kbd98->emul.scancode = scancode;
+				kbd98->emul.keycode = keycode;
+				if (kbd98->jis[i].emul[kbd98->shift].shift
+								!= kbd98->shift)
+					input_report_key(&kbd98->dev,
+							KEY_RIGHTSHIFT,
+							!(kbd98->shift));
+			}
+
+			input_report_key(&kbd98->dev, keycode, press);
+			if (!press) {
+				if (kbd98->jis[i].emul[kbd98->shift].shift
+								!= kbd98->shift)
+					input_report_key(&kbd98->dev,
+							KEY_RIGHTSHIFT,
+							kbd98->shift);
+				kbd98->emul.scancode = KBD98_KEY_UNKNOWN;
+			}
+
+			input_sync(&kbd98->dev);
+			return;
+
+		case KBD98_KEY_NULL:
+			return;
+
+		case 0:
+			printk(KERN_WARNING "kbd98.c: Unknown key (scancode %#x) %s.\n",
+				data & KBD98_KEY, data & KBD98_RELEASE ? "released" : "pressed");
+			return;
+
+		default:
+			input_report_key(&kbd98->dev, keycode, press);
+			input_sync(&kbd98->dev);
+		}
+}
+
+/*
+ * kbd98_sendbyte() sends a byte to the keyboard, and waits for
+ * acknowledge. It doesn't handle resends according to the keyboard
+ * protocol specs, because if these are needed, the keyboard needs
+ * replacement anyway, and they only make a mess in the protocol.
+ */
+
+static int kbd98_sendbyte(struct kbd98 *kbd98, unsigned char byte)
+{
+	int timeout = 10000; /* 100 msec */
+	kbd98->ack = 0;
+
+	if (serio_write(kbd98->serio, byte))
+		return -1;
+
+	while (!kbd98->ack && timeout--) udelay(10);
+
+	return -(kbd98->ack <= 0);
+}
+
+/*
+ * kbd98_command() sends a command, and its parameters to the keyboard,
+ * then waits for the response and puts it in the param array.
+ */
+
+static int kbd98_command(struct kbd98 *kbd98, unsigned char *param, int command)
+{
+	int timeout = 50000; /* 500 msec */
+	int send = (command >> 12) & 0xf;
+	int receive = (command >> 8) & 0xf;
+	int i;
+
+	kbd98->cmdcnt = receive;
+	
+	if (command & 0xff)
+		if (kbd98_sendbyte(kbd98, command & 0xff))
+			return (kbd98->cmdcnt = 0) - 1;
+
+	for (i = 0; i < send; i++)
+		if (kbd98_sendbyte(kbd98, param[i]))
+			return (kbd98->cmdcnt = 0) - 1;
+
+	while (kbd98->cmdcnt && timeout--) udelay(10);
+
+	if (param)
+		for (i = 0; i < receive; i++)
+			param[i] = kbd98->cmdbuf[(receive - 1) - i];
+
+	if (kbd98->cmdcnt) 
+		return (kbd98->cmdcnt = 0) - 1;
+
+	return 0;
+}
+
+/*
+ * Event callback from the input module. Events that change the state of
+ * the hardware are processed here.
+ */
+
+static int kbd98_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+{
+	struct kbd98 *kbd98 = dev->private;
+	char param[2];
+
+	switch (type) {
+
+		case EV_LED:
+
+			if (__PC9800SCA_TEST_BIT(0x481, 3)) {
+				/* 98note with Num Lock key */
+				/* keep Num Lock status     */
+				*param = 0x60;
+				if (kbd98_command(kbd98, param,
+							KBD98_CMD_GETLEDS))
+					printk(KERN_DEBUG
+						"kbd98: Get keyboard LED"
+						" status Error\n");
+
+				*param &= 1;
+			} else {
+				/* desktop PC-9801 */
+				*param = 1;	/* Always set Num Lock */
+			}
+
+			*param |= 0x70
+			       | (test_bit(LED_CAPSL,   dev->led) ? 4 : 0)
+			       | (test_bit(LED_KANA,    dev->led) ? 8 : 0);
+		        kbd98_command(kbd98, param, KBD98_CMD_SETLEDS);
+
+			return 0;
+	}
+
+	return -1;
+}
+
+void kbd98_connect(struct serio *serio, struct serio_dev *dev)
+{
+	struct kbd98 *kbd98;
+	int i;
+
+	if ((serio->type & SERIO_TYPE) != SERIO_PC9800)
+		return;
+
+	if (!(kbd98 = kmalloc(sizeof(struct kbd98), GFP_KERNEL)))
+		return;
+
+	memset(kbd98, 0, sizeof(struct kbd98));
+	kbd98->emul.scancode = KBD98_KEY_UNKNOWN;
+	
+	kbd98->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
+	kbd98->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_KANA);
+
+	kbd98->serio = serio;
+
+	init_input_dev(&kbd98->dev);
+	kbd98->dev.keycode = kbd98->keycode;
+	kbd98->dev.keycodesize = sizeof(unsigned char);
+	kbd98->dev.keycodemax = ARRAY_SIZE(kbd98_keycode);
+	kbd98->dev.event = kbd98_event;
+	kbd98->dev.private = kbd98;
+
+	serio->private = kbd98;
+
+	if (serio_open(serio, dev)) {
+		kfree(kbd98);
+		return;
+	}
+
+	memcpy(kbd98->jis, kbd98_jis, sizeof(kbd98_jis));
+	memcpy(kbd98->keycode, kbd98_keycode, sizeof(kbd98->keycode));
+	for (i = 0; i < 255; i++)
+		set_bit(kbd98->keycode[i], kbd98->dev.keybit);
+	clear_bit(0, kbd98->dev.keybit);
+
+	sprintf(kbd98->phys, "%s/input0", serio->phys);
+
+	kbd98->dev.name = kbd98_name;
+	kbd98->dev.phys = kbd98->phys;
+	kbd98->dev.id.bustype = BUS_XTKBD;
+	kbd98->dev.id.vendor = 0x0002;
+	kbd98->dev.id.product = 0x0001;
+	kbd98->dev.id.version = 0x0100;
+
+	input_register_device(&kbd98->dev);
+
+	printk(KERN_INFO "input: %s on %s\n", kbd98_name, serio->phys);
+}
+
+void kbd98_disconnect(struct serio *serio)
+{
+	struct kbd98 *kbd98 = serio->private;
+	input_unregister_device(&kbd98->dev);
+	serio_close(serio);
+	kfree(kbd98);
+}
+
+struct serio_dev kbd98_dev = {
+	.interrupt =	kbd98_interrupt,
+	.connect =	kbd98_connect,
+	.disconnect =	kbd98_disconnect
+};
+
+int __init kbd98_init(void)
+{
+	serio_register_device(&kbd98_dev);
+	return 0;
+}
+
+void __exit kbd98_exit(void)
+{
+	serio_unregister_device(&kbd98_dev);
+}
+
+module_init(kbd98_init);
+module_exit(kbd98_exit);
diff -Nru a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
--- a/drivers/input/keyboard/Kconfig	Sun Feb  9 17:29:49 2003
+++ b/drivers/input/keyboard/Kconfig	Thu Feb 20 08:30:36 2003
@@ -90,3 +90,15 @@
 	  The module will be called amikbd. If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
+config KEYBOARD_98KBD
+	tristate "NEC PC-9800 Keyboard support"
+	depends on X86_PC9800 && INPUT && INPUT_KEYBOARD && SERIO
+	help
+	  Say Y here if you want to use the NEC PC-9801/PC-9821 keyboard (or
+	  compatible) on your system. 
+
+	  This driver is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called xtkbd.o. If you want to compile it as a
+	  module, say M here and read <file:Documentation/modules.txt>.
+
diff -Nru a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
--- a/drivers/input/keyboard/Makefile	Sat Dec 14 04:38:56 2002
+++ b/drivers/input/keyboard/Makefile	Fri Feb 14 15:19:26 2003
@@ -10,3 +10,4 @@
 obj-$(CONFIG_KEYBOARD_XTKBD)		+= xtkbd.o
 obj-$(CONFIG_KEYBOARD_AMIGA)		+= amikbd.o
 obj-$(CONFIG_KEYBOARD_NEWTON)		+= newtonkbd.o
+obj-$(CONFIG_KEYBOARD_98KBD)		+= 98kbd.o
diff -Nru a/drivers/input/mouse/98busmouse.c b/drivers/input/mouse/98busmouse.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/input/mouse/98busmouse.c	Thu Feb 20 08:30:36 2003
@@ -0,0 +1,202 @@
+/*
+ *
+ *  Copyright (c) 2002 Osamu Tomita
+ *
+ *  Based on the work of:
+ *	James Banks		Matthew Dillon
+ *	David Giller		Nathan Laredo
+ *	Linus Torvalds		Johan Myreen
+ *	Cliff Matthews		Philip Blundell
+ *	Russell King		Vojtech Pavlik
+ */
+
+/*
+ * NEC PC-9801 Bus Mouse Driver for Linux
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or 
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * 
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+MODULE_AUTHOR("Osamu Tomita <tomita@cinet.co.jp>");
+MODULE_DESCRIPTION("PC-9801 busmouse driver");
+MODULE_LICENSE("GPL");
+
+#define	PC98BM_BASE		0x7fd9
+#define	PC98BM_DATA_PORT	PC98BM_BASE + 0
+/*	PC98BM_SIGNATURE_PORT	does not exist */
+#define	PC98BM_CONTROL_PORT	PC98BM_BASE + 4
+/*	PC98BM_INTERRUPT_PORT	does not exist */
+#define	PC98BM_CONFIG_PORT	PC98BM_BASE + 6
+
+#define	PC98BM_ENABLE_IRQ	0x00
+#define	PC98BM_DISABLE_IRQ	0x10
+#define	PC98BM_READ_X_LOW	0x80
+#define	PC98BM_READ_X_HIGH	0xa0
+#define	PC98BM_READ_Y_LOW	0xc0
+#define	PC98BM_READ_Y_HIGH	0xe0
+
+#define PC98BM_DEFAULT_MODE	0x93
+/*	PC98BM_CONFIG_BYTE	is not used */
+/*	PC98BM_SIGNATURE_BYTE	is not used */
+
+#define PC98BM_TIMER_PORT	0xbfdb
+#define PC98BM_DEFAULT_TIMER_VAL	0x00
+
+#define PC98BM_IRQ		13
+
+MODULE_PARM(pc98bm_irq, "i");
+
+static int pc98bm_irq = PC98BM_IRQ;
+static int pc98bm_used = 0;
+
+static void pc98bm_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+static int pc98bm_open(struct input_dev *dev)
+{
+	if (pc98bm_used++)
+		return 0;
+	if (request_irq(pc98bm_irq, pc98bm_interrupt, 0, "98busmouse", NULL)) {
+		pc98bm_used--;
+		printk(KERN_ERR "98busmouse.c: Can't allocate irq %d\n", pc98bm_irq);
+		return -EBUSY;
+	}
+	outb(PC98BM_ENABLE_IRQ, PC98BM_CONTROL_PORT);
+	return 0;
+}
+
+static void pc98bm_close(struct input_dev *dev)
+{
+	if (--pc98bm_used)
+		return;
+	outb(PC98BM_DISABLE_IRQ, PC98BM_CONTROL_PORT);
+	free_irq(pc98bm_irq, NULL);
+}
+
+static struct input_dev pc98bm_dev = {
+	.evbit	= { BIT(EV_KEY) | BIT(EV_REL) },
+	.keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) },
+	.relbit	= { BIT(REL_X) | BIT(REL_Y) },
+	.open	= pc98bm_open,
+	.close	= pc98bm_close,
+	.name	= "PC-9801 bus mouse",
+	.phys	= "isa7fd9/input0",
+	.id	= {
+		.bustype = BUS_ISA,
+		.vendor  = 0x0004,
+		.product = 0x0001,
+		.version = 0x0100,
+	},
+};
+
+static void pc98bm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	char dx, dy;
+	unsigned char buttons;
+
+	outb(PC98BM_READ_X_LOW, PC98BM_CONTROL_PORT);
+	dx = (inb(PC98BM_DATA_PORT) & 0xf);
+	outb(PC98BM_READ_X_HIGH, PC98BM_CONTROL_PORT);
+	dx |= (inb(PC98BM_DATA_PORT) & 0xf) << 4;
+	outb(PC98BM_READ_Y_LOW, PC98BM_CONTROL_PORT);
+	dy = (inb(PC98BM_DATA_PORT) & 0xf);
+	outb(PC98BM_READ_Y_HIGH, PC98BM_CONTROL_PORT);
+	buttons = inb(PC98BM_DATA_PORT);
+	dy |= (buttons & 0xf) << 4;
+	buttons = ~buttons >> 5;
+
+	input_report_rel(&pc98bm_dev, REL_X, dx);
+	input_report_rel(&pc98bm_dev, REL_Y, dy);
+	input_report_key(&pc98bm_dev, BTN_RIGHT,  buttons & 1);
+	input_report_key(&pc98bm_dev, BTN_MIDDLE, buttons & 2);
+	input_report_key(&pc98bm_dev, BTN_LEFT,   buttons & 4);
+	input_sync(&pc98bm_dev);
+
+	outb(PC98BM_ENABLE_IRQ, PC98BM_CONTROL_PORT);
+}
+
+#ifndef MODULE
+static int __init pc98bm_setup(char *str)
+{
+        int ints[4];
+        str = get_options(str, ARRAY_SIZE(ints), ints);
+        if (ints[0] > 0) pc98bm_irq = ints[1];
+        return 1;
+}
+__setup("pc98bm_irq=", pc98bm_setup);
+#endif
+
+static int __init pc98bm_init(void)
+{
+	int i;
+
+	for (i = 0; i <= 6; i += 2) {
+		if (!request_region(PC98BM_BASE + i, 1, "98busmouse")) {
+			printk(KERN_ERR "98busmouse.c: Can't allocate ports at %#x\n", PC98BM_BASE + i);
+			while (i > 0) {
+				i -= 2;
+				release_region(PC98BM_BASE + i, 1);
+			}
+
+			return -EBUSY;
+		}
+
+	}
+
+	if (!request_region(PC98BM_TIMER_PORT, 1, "98busmouse")) {
+		printk(KERN_ERR "98busmouse.c: Can't allocate ports at %#x\n", PC98BM_TIMER_PORT);
+		for (i = 0; i <= 6; i += 2)
+			release_region(PC98BM_BASE + i, 1);
+
+		return -EBUSY;
+	}
+
+	outb(PC98BM_DEFAULT_MODE, PC98BM_CONFIG_PORT);
+	outb(PC98BM_DISABLE_IRQ, PC98BM_CONTROL_PORT);
+
+	outb(PC98BM_DEFAULT_TIMER_VAL, PC98BM_TIMER_PORT);
+
+	input_register_device(&pc98bm_dev);
+	
+	printk(KERN_INFO "input: PC-9801 bus mouse at %#x irq %d\n", PC98BM_BASE, pc98bm_irq);
+
+	return 0;
+}
+
+static void __exit pc98bm_exit(void)
+{
+	int i;
+
+	input_unregister_device(&pc98bm_dev);
+	for (i = 0; i <= 6; i += 2)
+		release_region(PC98BM_BASE + i, 1);
+
+	release_region(PC98BM_TIMER_PORT, 1);
+}
+
+module_init(pc98bm_init);
+module_exit(pc98bm_exit);
diff -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
--- a/drivers/input/mouse/Kconfig	Sun Feb  9 17:29:49 2003
+++ b/drivers/input/mouse/Kconfig	Thu Feb 20 08:30:36 2003
@@ -121,3 +121,15 @@
 	  The module will be called rpcmouse. If you want to compile it as a
 	  module, say M here and read <file.:Documentation/modules.txt>.
 
+config MOUSE_PC9800
+	tristate "NEC PC-9800 busmouse"
+	depends on X86_PC9800 && INPUT && INPUT_MOUSE && ISA
+	help
+	  Say Y here if you have NEC PC-9801/PC-9821 computer and want its
+	  native mouse supported.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called logibm.o. If you want to compile it as a
+	  module, say M here and read <file.:Documentation/modules.txt>.
+
diff -Nru a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
--- a/drivers/input/mouse/Makefile	Sat Dec 14 04:38:56 2002
+++ b/drivers/input/mouse/Makefile	Fri Feb 14 15:19:40 2003
@@ -10,5 +10,6 @@
 obj-$(CONFIG_MOUSE_LOGIBM)	+= logibm.o
 obj-$(CONFIG_MOUSE_MAPLE)	+= maplemouse.o
 obj-$(CONFIG_MOUSE_PC110PAD)	+= pc110pad.o
+obj-$(CONFIG_MOUSE_PC9800)	+= 98busmouse.o
 obj-$(CONFIG_MOUSE_PS2)		+= psmouse.o
 obj-$(CONFIG_MOUSE_SERIAL)	+= sermouse.o
diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c
--- a/drivers/input/mousedev.c	Wed Feb 12 02:02:06 2003
+++ b/drivers/input/mousedev.c	Sat Mar 22 09:03:17 2003
@@ -425,7 +425,7 @@
 		input_open_device(&mousedev->handle);
 
 	mousedev_table[minor] = mousedev;
-	mousedev->devfs = input_register_minor("mouse%d", minor, MOUSEDEV_MINOR_BASE);
+	mousedev->devfs = input_register_minor("input/mouse%d", minor, MOUSEDEV_MINOR_BASE);
 
 	return &mousedev->handle;
 }
@@ -507,7 +507,7 @@
 	mousedev_table[MOUSEDEV_MIX] = &mousedev_mix;
 	mousedev_mix.exist = 1;
 	mousedev_mix.minor = MOUSEDEV_MIX;
-	mousedev_mix.devfs = input_register_minor("mice", MOUSEDEV_MIX, MOUSEDEV_MINOR_BASE);
+	mousedev_mix.devfs = input_register_minor("input/mice", MOUSEDEV_MIX, MOUSEDEV_MINOR_BASE);
 
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
 	if (!(mousedev_mix.misc = !misc_register(&psaux_mouse)))
diff -Nru a/drivers/input/serio/98kbd-io.c b/drivers/input/serio/98kbd-io.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/input/serio/98kbd-io.c	Thu Feb 20 08:30:36 2003
@@ -0,0 +1,178 @@
+/*
+ *  NEC PC-9801 keyboard controller driver for Linux
+ *
+ *  Copyright (c) 1999-2002 Osamu Tomita <tomita@cinet.co.jp>
+ *    Based on i8042.c written by Vojtech Pavlik
+ */
+
+/*
+ * 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/delay.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/serio.h>
+#include <linux/sched.h>
+
+#include <asm/io.h>
+
+MODULE_AUTHOR("Osamu Tomita <tomita@cinet.co.jp>");
+MODULE_DESCRIPTION("NEC PC-9801 keyboard controller driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * Names.
+ */
+
+#define KBD98_PHYS_DESC "isa0041/serio0"
+
+/*
+ * IRQs.
+ */
+
+#define KBD98_IRQ	1
+
+/*
+ * Register numbers.
+ */
+
+#define KBD98_COMMAND_REG	0x43	
+#define KBD98_STATUS_REG	0x43	
+#define KBD98_DATA_REG		0x41
+
+spinlock_t kbd98io_lock = SPIN_LOCK_UNLOCKED;
+
+static struct serio kbd98_port;
+extern struct pt_regs *kbd_pt_regs;
+
+static void kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/*
+ * kbd98_flush() flushes all data that may be in the keyboard buffers
+ */
+
+static int kbd98_flush(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&kbd98io_lock, flags);
+
+	while (inb(KBD98_STATUS_REG) & 0x02) /* RxRDY */
+		inb(KBD98_DATA_REG);
+
+	if (inb(KBD98_STATUS_REG) & 0x38)
+		printk("98kbd-io: Keyboard error!\n");
+
+	spin_unlock_irqrestore(&kbd98io_lock, flags);
+
+	return 0;
+}
+
+/*
+ * kbd98_write() sends a byte out through the keyboard interface.
+ */
+
+static int kbd98_write(struct serio *port, unsigned char c)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&kbd98io_lock, flags);
+
+	outb(0, 0x5f);			/* wait */
+	outb(0x17, KBD98_COMMAND_REG);	/* enable send command */
+	outb(0, 0x5f);			/* wait */
+	outb(c, KBD98_DATA_REG);
+	outb(0, 0x5f);			/* wait */
+	outb(0x16, KBD98_COMMAND_REG);	/* disable send command */
+	outb(0, 0x5f);			/* wait */
+
+	spin_unlock_irqrestore(&kbd98io_lock, flags);
+
+	return 0;
+}
+
+/*
+ * kbd98_open() is called when a port is open by the higher layer.
+ * It allocates the interrupt and enables in in the chip.
+ */
+
+static int kbd98_open(struct serio *port)
+{
+	kbd98_flush();
+
+	if (request_irq(KBD98_IRQ, kbd98io_interrupt, 0, "kbd98", NULL)) {
+		printk(KERN_ERR "98kbd-io.c: Can't get irq %d for %s, unregistering the port.\n", KBD98_IRQ, "KBD");
+		serio_unregister_port(port);
+		return -1;
+	}
+
+	return 0;
+}
+
+static void kbd98_close(struct serio *port)
+{
+	free_irq(KBD98_IRQ, NULL);
+
+	kbd98_flush();
+}
+
+/*
+ * Structures for registering the devices in the serio.c module.
+ */
+
+static struct serio kbd98_port =
+{
+	.type =		SERIO_PC9800,
+	.write =	kbd98_write,
+	.open =		kbd98_open,
+	.close =	kbd98_close,
+	.driver =	NULL,
+	.name =		"PC-9801 Kbd Port",
+	.phys =		KBD98_PHYS_DESC,
+};
+
+/*
+ * kbd98io_interrupt() is the most important function in this driver -
+ * it handles the interrupts from keyboard, and sends incoming bytes
+ * to the upper layers.
+ */
+
+static void kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long flags;
+	unsigned char data;
+
+	spin_lock_irqsave(&kbd98io_lock, flags);
+
+	data = inb(KBD98_DATA_REG);
+	spin_unlock_irqrestore(&kbd98io_lock, flags);
+	serio_interrupt(&kbd98_port, data, 0, regs);
+
+}
+
+int __init kbd98io_init(void)
+{
+	serio_register_port(&kbd98_port);
+
+	printk(KERN_INFO "serio: PC-9801 %s port at %#lx,%#lx irq %d\n",
+	       "KBD",
+	       (unsigned long) KBD98_DATA_REG,
+	       (unsigned long) KBD98_COMMAND_REG,
+	       KBD98_IRQ);
+
+	return 0;
+}
+
+void __exit kbd98io_exit(void)
+{
+	serio_unregister_port(&kbd98_port);
+}
+
+module_init(kbd98io_init);
+module_exit(kbd98io_exit);
diff -Nru a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
--- a/drivers/input/serio/Kconfig	Sun Feb  9 17:29:49 2003
+++ b/drivers/input/serio/Kconfig	Thu Feb 20 08:30:53 2003
@@ -107,3 +107,15 @@
 	tristate "Intel SA1111 keyboard controller"
 	depends on SA1111 && SERIO
 
+config SERIO_98KBD
+	tristate "NEC PC-9800 keyboard controller"
+	depends on X86_PC9800 && SERIO
+	help
+	  Say Y here if you have the NEC PC-9801/PC-9821 and want to use its
+	  standard keyboard connected to its keyboard controller.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called rpckbd.o. If you want to compile it as a
+	  module, say M here and read <file:Documentation/modules.txt>.
+
diff -Nru a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
--- a/drivers/input/serio/Makefile	Mon Feb  3 14:19:36 2003
+++ b/drivers/input/serio/Makefile	Fri Feb 14 15:20:16 2003
@@ -13,3 +13,4 @@
 obj-$(CONFIG_SERIO_SA1111)	+= sa1111ps2.o
 obj-$(CONFIG_SERIO_AMBAKMI)	+= ambakmi.o
 obj-$(CONFIG_SERIO_Q40KBD)	+= q40kbd.o
+obj-$(CONFIG_SERIO_98KBD)	+= 98kbd-io.o
diff -Nru a/drivers/input/tsdev.c b/drivers/input/tsdev.c
--- a/drivers/input/tsdev.c	Thu Dec  5 18:56:47 2002
+++ b/drivers/input/tsdev.c	Sat Mar 22 09:03:17 2003
@@ -326,7 +326,7 @@
 
 	tsdev_table[minor] = tsdev;
 	tsdev->devfs =
-	    input_register_minor("ts%d", minor, TSDEV_MINOR_BASE);
+	    input_register_minor("input/ts%d", minor, TSDEV_MINOR_BASE);
 
 
 	return &tsdev->handle;
diff -Nru a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
--- a/drivers/isdn/i4l/isdn_common.c	Mon Dec  2 14:21:06 2002
+++ b/drivers/isdn/i4l/isdn_common.c	Sat Mar 22 07:38:04 2003
@@ -2186,7 +2186,7 @@
 	int i;
 #  endif
 
-	devfs_mk_dir (NULL, "isdn", NULL);
+	devfs_mk_dir("isdn");
 #  ifdef CONFIG_ISDN_PPP
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
 		char buf[16];
diff -Nru a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
--- a/drivers/macintosh/adb.c	Tue Feb 11 14:57:51 2003
+++ b/drivers/macintosh/adb.c	Sun Feb 16 05:52:54 2003
@@ -249,7 +249,7 @@
 	strcpy(current->comm, "kadbprobe");
 
 	sigfillset(&blocked);
-	sicprocmask(SIG_BLOCK, &blocked, NULL);	
+	sigprocmask(SIG_BLOCK, &blocked, NULL);	
 	flush_signals(current);
 
 	printk(KERN_INFO "adb: starting probe task...\n");
diff -Nru a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
--- a/drivers/macintosh/mac_hid.c	Tue Oct  8 03:51:31 2002
+++ b/drivers/macintosh/mac_hid.c	Sun Feb 16 15:46:38 2003
@@ -25,38 +25,56 @@
 
 #if defined(CONFIG_SYSCTL)
 /* file(s) in /proc/sys/dev/mac_hid */
-ctl_table mac_hid_files[] =
-{
-  {
-    DEV_MAC_HID_MOUSE_BUTTON_EMULATION,
-    "mouse_button_emulation", &mouse_emulate_buttons, sizeof(int),
-    0644, NULL, &proc_dointvec
-  },
-  {
-    DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE,
-    "mouse_button2_keycode", &mouse_button2_keycode, sizeof(int),
-    0644, NULL, &proc_dointvec
-  },
-  {
-    DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE,
-    "mouse_button3_keycode", &mouse_button3_keycode, sizeof(int),
-    0644, NULL, &proc_dointvec
-  },
-  { 0 }
+ctl_table mac_hid_files[] = {
+	{
+		.ctl_name	= DEV_MAC_HID_MOUSE_BUTTON_EMULATION,
+		.procname	= "mouse_button_emulation",
+		.data		= &mouse_emulate_buttons,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+	{
+		.ctl_name	= DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE,
+		.procname	= "mouse_button2_keycode",
+		.data		= &mouse_button2_keycode,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+	{
+		.ctl_name	= DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE,
+		.procname	= "mouse_button3_keycode",
+		.data		= &mouse_button3_keycode,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+	{ .ctl_name = 0 }
 };
 
 /* dir in /proc/sys/dev */
-ctl_table mac_hid_dir[] =
-{
-  { DEV_MAC_HID, "mac_hid", NULL, 0, 0555, mac_hid_files },
-  { 0 }
+ctl_table mac_hid_dir[] = {
+	{
+		.ctl_name	= DEV_MAC_HID,
+		.procname	= "mac_hid",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= mac_hid_files,
+	},
+	{ .ctl_name = 0 }
 };
 
 /* /proc/sys/dev itself, in case that is not there yet */
-ctl_table mac_hid_root_dir[] =
-{
-  { CTL_DEV, "dev", NULL, 0, 0555, mac_hid_dir },
-  { 0 }
+ctl_table mac_hid_root_dir[] = {
+	{
+		.ctl_name	= CTL_DEV,
+		.procname	= "dev",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= mac_hid_dir,
+	},
+	{ .ctl_name = 0 }
 };
 
 static struct ctl_table_header *mac_hid_sysctl_header;
diff -Nru a/drivers/macintosh/macserial.c b/drivers/macintosh/macserial.c
--- a/drivers/macintosh/macserial.c	Fri Feb 14 15:20:31 2003
+++ b/drivers/macintosh/macserial.c	Sun Mar 16 15:21:50 2003
@@ -441,12 +441,8 @@
 
 static void transmit_chars(struct mac_serial *info)
 {
-	unsigned long flags;
-
-	save_flags(flags);
-	cli();
 	if ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP) == 0)
-		goto out;
+		return;
 	info->tx_active = 0;
 
 	if (info->x_char && !info->power_wait) {
@@ -454,13 +450,13 @@
 		write_zsdata(info->zs_channel, info->x_char);
 		info->x_char = 0;
 		info->tx_active = 1;
-		goto out;
+		return;
 	}
 
 	if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tx_stopped
 	    || info->power_wait) {
 		write_zsreg(info->zs_channel, 0, RES_Tx_P);
-		goto out;
+		return;
 	}
 
 	/* Send char */
@@ -471,17 +467,17 @@
 
 	if (info->xmit_cnt < WAKEUP_CHARS)
 		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
-
- out:
-	restore_flags(flags);
 }
 
 static void powerup_done(unsigned long data)
 {
 	struct mac_serial *info = (struct mac_serial *) data;
+	unsigned long flags;
 
+	spin_lock_irqsave(&info->lock, flags);
 	info->power_wait = 0;
 	transmit_chars(info);
+	spin_unlock_irqrestore(&info->lock, flags);
 }
 
 static _INLINE_ void status_handle(struct mac_serial *info)
@@ -567,6 +563,7 @@
 	struct mac_serial *info = (struct mac_serial *) dev_id;
 	unsigned char zs_intreg;
 	int shift;
+	unsigned long flags;
 
 	if (!(info->flags & ZILOG_INITIALIZED)) {
 		printk(KERN_WARNING "rs_interrupt: irq %d, port not "
@@ -588,6 +585,7 @@
 	else
 		shift = 0;	/* Channel B */
 
+	spin_lock_irqsave(&info->lock, flags);
 	for (;;) {
 		zs_intreg = read_zsreg(info->zs_chan_a, 3) >> shift;
 #ifdef SERIAL_DEBUG_INTR
@@ -611,6 +609,7 @@
 		if (zs_intreg & CHBEXT)
 			status_handle(info);
 	}
+	spin_unlock_irqrestore(&info->lock, flags);
 }
 
 /* Transmit DMA interrupt - not used at present */
@@ -672,13 +671,13 @@
 		return;
 
 #if 0
-	save_flags(flags); cli();
+	spin_lock_irqsave(&info->lock, flags);
 	if (info->curregs[5] & TxENAB) {
 		info->curregs[5] &= ~TxENAB;
 		info->pendregs[5] &= ~TxENAB;
 		write_zsreg(info->zs_channel, 5, info->curregs[5]);
 	}
-	restore_flags(flags);
+	spin_unlock_irqrestore(&info->lock, flags);
 #endif
 }
 
@@ -695,7 +694,7 @@
 	if (serial_paranoia_check(info, tty->device, "rs_start"))
 		return;
 
-	save_flags(flags); cli();
+	spin_lock_irqsave(&info->lock, flags);
 #if 0
 	if (info->xmit_cnt && info->xmit_buf && !(info->curregs[5] & TxENAB)) {
 		info->curregs[5] |= TxENAB;
@@ -707,7 +706,7 @@
 		transmit_chars(info);
 	}
 #endif
-	restore_flags(flags);
+	spin_unlock_irqrestore(&info->lock, flags);
 }
 
 static void do_softint(void *private_)
@@ -754,12 +753,11 @@
 		unsigned long flags;
 
 		/* delay is in ms */
-		save_flags(flags);
-		cli();
+		spin_lock_irqsave(&info->lock, flags);
 		info->power_wait = 1;
 		mod_timer(&info->powerup_timer,
 			  jiffies + (delay * HZ + 999) / 1000);
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->lock, flags);
 	}
 
 	OPNDBG("enabling IRQ on ttyS%d (irq %d)...\n", info->line, info->irq);
@@ -1019,7 +1017,7 @@
 
 	OPNDBG("setting up ttyS%d SCC...\n", info->line);
 
-	save_flags(flags); cli(); /* Disable interrupts */
+	spin_lock_irqsave(&info->lock, flags);
 
 	/* Nice buggy HW ... */
 	fix_zero_bug_scc(info);
@@ -1091,6 +1089,8 @@
 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 
+	spin_unlock_irqrestore(&info->lock, flags);
+
 	/*
 	 * Set the speed of the serial port
 	 */
@@ -1099,8 +1099,6 @@
 	/* Save the current value of RR0 */
 	info->read_reg_zero = read_zsreg(info->zs_channel, 0);
 
-	restore_flags(flags);
-
 	if (info->dma_initted) {
 		spin_lock_irqsave(&info->rx_dma_lock, flags);
 		rxdma_start(info, 0);
@@ -1214,10 +1212,7 @@
 
 static void irda_rts_pulses(struct mac_serial *info, int w)
 {
-	unsigned long flags;
-
 	udelay(w);
-	save_flags(flags); cli();
 	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB);
 	udelay(2);
 	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS);
@@ -1225,7 +1220,6 @@
 	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB);
 	udelay(4);
 	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS);
-	restore_flags(flags);
 }
 
 /*
@@ -1234,7 +1228,6 @@
 static void irda_setup(struct mac_serial *info)
 {
 	int code, speed, t;
-	unsigned long flags;
 
 	speed = info->tty->termios->c_cflag & CBAUD;
 	if (speed < B2400 || speed > B115200)
@@ -1268,10 +1261,8 @@
 
 	/* set TxD low for ~104us and pulse RTS */
 	udelay(1000);
-	save_flags(flags); cli();
 	write_zsdata(info->zs_channel, 0xfe);
 	irda_rts_pulses(info, 150);
-	restore_flags(flags);
 	irda_rts_pulses(info, 180);
 	irda_rts_pulses(info, 50);
 	udelay(100);
@@ -1351,7 +1342,7 @@
 	else if (baud == 0)
 		baud = 38400;
 
-	save_flags(flags); cli();
+	spin_lock_irqsave(&info->lock, flags);
 	info->zs_baud = baud;
 	info->clk_divisor = 16;
 
@@ -1460,22 +1451,23 @@
 	/* Load up the new values */
 	load_zsregs(info->zs_channel, info->curregs);
 
-	restore_flags(flags);
+	spin_unlock_irqrestore(&info->lock, flags);
 }
 
 static void rs_flush_chars(struct tty_struct *tty)
 {
 	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
+	unsigned long flags;
 
 	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
 		return;
 
-	if (info->xmit_cnt <= 0 || tty->stopped || info->tx_stopped ||
-	    !info->xmit_buf)
-		return;
-
-	/* Enable transmitter */
-	transmit_chars(info);
+	spin_lock_irqsave(&info->lock, flags);
+	if (!(info->xmit_cnt <= 0 || tty->stopped || info->tx_stopped ||
+	      !info->xmit_buf))
+		/* Enable transmitter */
+		transmit_chars(info);
+	spin_unlock_irqrestore(&info->lock, flags);
 }
 
 static int rs_write(struct tty_struct * tty, int from_user,
@@ -1506,15 +1498,14 @@
 					ret = -EFAULT;
 				break;
 			}
-			save_flags(flags);
-			cli();
+			spin_lock_irqsave(&info->lock, flags);
 			c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
 				       SERIAL_XMIT_SIZE - info->xmit_head));
 			memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
 			info->xmit_head = ((info->xmit_head + c) &
 					   (SERIAL_XMIT_SIZE-1));
 			info->xmit_cnt += c;
-			restore_flags(flags);
+			spin_unlock_irqrestore(&info->lock, flags);
 			buf += c;
 			count -= c;
 			ret += c;
@@ -1522,28 +1513,29 @@
 		up(&tmp_buf_sem);
 	} else {
 		while (1) {
-			save_flags(flags);
-			cli();
+			spin_lock_irqsave(&info->lock, flags);
 			c = MIN(count,
 				MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
 				    SERIAL_XMIT_SIZE - info->xmit_head));
 			if (c <= 0) {
-				restore_flags(flags);
+				spin_unlock_irqrestore(&info->lock, flags);
 				break;
 			}
 			memcpy(info->xmit_buf + info->xmit_head, buf, c);
 			info->xmit_head = ((info->xmit_head + c) &
 					   (SERIAL_XMIT_SIZE-1));
 			info->xmit_cnt += c;
-			restore_flags(flags);
+			spin_unlock_irqrestore(&info->lock, flags);
 			buf += c;
 			count -= c;
 			ret += c;
 		}
 	}
+	spin_lock_irqsave(&info->lock, flags);
 	if (info->xmit_cnt && !tty->stopped && !info->tx_stopped
 	    && !info->tx_active)
 		transmit_chars(info);
+	spin_unlock_irqrestore(&info->lock, flags);
 	return ret;
 }
 
@@ -1576,9 +1568,9 @@
 
 	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
 		return;
-	save_flags(flags); cli();
+	spin_lock_irqsave(&info->lock, flags);
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-	restore_flags(flags);
+	spin_unlock_irqrestore(&info->lock, flags);
 	wake_up_interruptible(&tty->write_wait);
 	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 	    tty->ldisc.write_wakeup)
@@ -1605,11 +1597,11 @@
 		return;
 
 	if (I_IXOFF(tty)) {
-		save_flags(flags); cli();
+		spin_lock_irqsave(&info->lock, flags);
 		info->x_char = STOP_CHAR(tty);
 		if (!info->tx_active)
 			transmit_chars(info);
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->lock, flags);
 	}
 
 	if (C_CRTSCTS(tty)) {
@@ -1627,21 +1619,21 @@
 		 * drop RTS.
 		 */
 		if (info->is_internal_modem) {
-			save_flags(flags); cli();
+			spin_lock_irqsave(&info->lock, flags);
 			info->curregs[5] &= ~RTS;
 			info->pendregs[5] &= ~RTS;
 			write_zsreg(info->zs_channel, 5, info->curregs[5]);
-			restore_flags(flags);
+			spin_unlock_irqrestore(&info->lock, flags);
 		}
 	}
 	
 #ifdef CDTRCTS
 	if (tty->termios->c_cflag & CDTRCTS) {
-		save_flags(flags); cli();
+		spin_lock_irqsave(&info->lock, flags);
 		info->curregs[5] &= ~DTR;
 		info->pendregs[5] &= ~DTR;
 		write_zsreg(info->zs_channel, 5, info->curregs[5]);
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->lock, flags);
 	}
 #endif /* CDTRCTS */
 }
@@ -1659,7 +1651,7 @@
 		return;
 
 	if (I_IXOFF(tty)) {
-		save_flags(flags); cli();
+		spin_lock_irqsave(&info->lock, flags);
 		if (info->x_char)
 			info->x_char = 0;
 		else {
@@ -1667,26 +1659,26 @@
 			if (!info->tx_active)
 				transmit_chars(info);
 		}
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->lock, flags);
 	}
 
 	if (C_CRTSCTS(tty) && info->is_internal_modem) {
 		/* Assert RTS line */
-		save_flags(flags); cli();
+		spin_lock_irqsave(&info->lock, flags);
 		info->curregs[5] |= RTS;
 		info->pendregs[5] |= RTS;
 		write_zsreg(info->zs_channel, 5, info->curregs[5]);
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->lock, flags);
 	}
 
 #ifdef CDTRCTS
 	if (tty->termios->c_cflag & CDTRCTS) {
 		/* Assert DTR line */
-		save_flags(flags); cli();
+		spin_lock_irqsave(&info->lock, flags);
 		info->curregs[5] |= DTR;
 		info->pendregs[5] |= DTR;
 		write_zsreg(info->zs_channel, 5, info->curregs[5]);
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->lock, flags);
 	}
 #endif
 }
@@ -1779,9 +1771,9 @@
 	unsigned char status;
 	unsigned long flags;
 
-	save_flags(flags); cli();
+	spin_lock_irqsave(&info->lock, flags);
 	status = read_zsreg(info->zs_channel, 0);
-	restore_flags(flags);
+	spin_unlock_irqrestore(&info->lock, flags);
 	status = (status & Tx_BUF_EMP)? TIOCSER_TEMT: 0;
 	return put_user(status,value);
 }
@@ -1792,10 +1784,10 @@
 	unsigned int result;
 	unsigned long flags;
 
-	save_flags(flags); cli();
+	spin_lock_irqsave(&info->lock, flags);
 	control = info->curregs[5];
 	status = read_zsreg(info->zs_channel, 0);
-	restore_flags(flags);
+	spin_unlock_irqrestore(&info->lock, flags);
 	result =  ((control & RTS) ? TIOCM_RTS: 0)
 		| ((control & DTR) ? TIOCM_DTR: 0)
 		| ((status  & DCD) ? TIOCM_CAR: 0)
@@ -1812,7 +1804,7 @@
 	if (get_user(arg, value))
 		return -EFAULT;
 	bits = (arg & TIOCM_RTS? RTS: 0) + (arg & TIOCM_DTR? DTR: 0);
-	save_flags(flags); cli();
+	spin_lock_irqsave(&info->lock, flags);
 	switch (cmd) {
 	case TIOCMBIS:
 		info->curregs[5] |= bits;
@@ -1824,12 +1816,12 @@
 		info->curregs[5] = (info->curregs[5] & ~(DTR | RTS)) | bits;
 		break;
 	default:
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->lock, flags);
 		return -EINVAL;
 	}
 	info->pendregs[5] = info->curregs[5];
 	write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	restore_flags(flags);
+	spin_unlock_irqrestore(&info->lock, flags);
 	return 0;
 }
 
@@ -1844,13 +1836,13 @@
 	if (serial_paranoia_check(info, tty->device, "rs_break"))
 		return;
 
-	save_flags(flags); cli();
+	spin_lock_irqsave(&info->lock, flags);
 	if (break_state == -1)
 		info->curregs[5] |= SND_BRK;
 	else
 		info->curregs[5] &= ~SND_BRK;
 	write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	restore_flags(flags);
+	spin_unlock_irqrestore(&info->lock, flags);
 }
 
 static int rs_ioctl(struct tty_struct *tty, struct file * file,
@@ -1932,11 +1924,11 @@
 	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
 		return;
 
-	save_flags(flags); cli();
+	spin_lock_irqsave(&info->lock, flags);
 
 	if (tty_hung_up_p(filp)) {
 		MOD_DEC_USE_COUNT;
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->lock, flags);
 		return;
 	}
 
@@ -1960,7 +1952,7 @@
 	}
 	if (info->count) {
 		MOD_DEC_USE_COUNT;
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->lock, flags);
 		return;
 	}
 	info->flags |= ZILOG_CLOSING;
@@ -1979,9 +1971,9 @@
 	OPNDBG("waiting end of Tx... (timeout:%d)\n", info->closing_wait);
 	tty->closing = 1;
 	if (info->closing_wait != ZILOG_CLOSING_WAIT_NONE) {
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->lock, flags);
 		tty_wait_until_sent(tty, info->closing_wait);
-		save_flags(flags); cli();
+		spin_lock_irqsave(&info->lock, flags);
 	}
 
 	/*
@@ -2001,15 +1993,15 @@
 		 * has completely drained.
 		 */
 		OPNDBG("waiting end of Rx...\n");
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->lock, flags);
 		rs_wait_until_sent(tty, info->timeout);
-		save_flags(flags); cli();
+		spin_lock_irqsave(&info->lock, flags);
 	}
 
 	shutdown(info);
 	/* restore flags now since shutdown() will have disabled this port's
 	   specific irqs */
-	restore_flags(flags);
+	spin_unlock_irqrestore(&info->lock, flags);
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
@@ -2174,18 +2166,18 @@
 	add_wait_queue(&info->open_wait, &wait);
 	OPNDBG("block_til_ready before block: ttyS%d, count = %d\n",
 	       info->line, info->count);
-	cli();
+	spin_lock_irq(&info->lock);
 	if (!tty_hung_up_p(filp)) 
 		info->count--;
-	sti();
+	spin_unlock_irq(&info->lock);
 	info->blocked_open++;
 	while (1) {
-		cli();
+		spin_lock_irq(&info->lock);
 		if (!(info->flags & ZILOG_CALLOUT_ACTIVE) &&
 		    (tty->termios->c_cflag & CBAUD) &&
 		    !info->is_irda)
 			zs_rtsdtr(info, 1);
-		sti();
+		spin_unlock_irq(&info->lock);
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) ||
 		    !(info->flags & ZILOG_INITIALIZED)) {
@@ -2553,7 +2545,6 @@
 int macserial_init(void)
 {
 	int channel, i;
-	unsigned long flags;
 	struct mac_serial *info;
 
 	/* Find out how many Z8530 SCCs we have */
@@ -2570,7 +2561,6 @@
 	 * We also request the OF resources here as probe_sccs()
 	 * might be called too early for that
 	 */
-	save_flags(flags); cli();
 	for (i = 0; i < zs_channels_found; ++i) {
 		struct device_node* ch = zs_soft[i].dev_node;
 		if (!request_OF_resource(ch, 0, NULL)) {
@@ -2607,7 +2597,6 @@
 			       zs_soft[i].irq);
 		disable_irq(zs_soft[i].irq);
 	}
-	restore_flags(flags);
 
 	show_serial_version();
 
@@ -2723,6 +2712,7 @@
 		info->count = 0;
 		info->blocked_open = 0;
 		INIT_WORK(&info->tqueue, do_softint, info);
+		spin_lock_init(&info->lock);
 		info->callout_termios = callout_driver.init_termios;
 		info->normal_termios = serial_driver.init_termios;
 		init_waitqueue_head(&info->open_wait);
@@ -2753,7 +2743,7 @@
 
 	for (info = zs_chain, i = 0; info; info = info->zs_next, i++)
 		set_scc_power(info, 0);
-	save_flags(flags); cli();
+	spin_lock_irqsave(&info->lock, flags);
 	for (i = 0; i < zs_channels_found; ++i) {
 		free_irq(zs_soft[i].irq, &zs_soft[i]);
 		if (zs_soft[i].has_dma) {
@@ -2767,7 +2757,7 @@
 			release_OF_resource(ch, ch->n_addrs - 1);
 		}
 	}
-	restore_flags(flags);
+	spin_unlock_irqrestore(&info->lock, flags);
 	tty_unregister_driver(&callout_driver);
 	tty_unregister_driver(&serial_driver);
 
@@ -2944,7 +2934,7 @@
 	}
 	co->cflag = cflag;
 
-	save_flags(flags); cli();
+	spin_lock_irqsave(&info->lock, flags);
         memset(info->curregs, 0, sizeof(info->curregs));
 
 	info->zs_baud = baud;
@@ -3026,7 +3016,7 @@
 	/* Load up the new values */
 	load_zsregs(info->zs_channel, info->curregs);
 
-	restore_flags(flags);
+	spin_unlock_irqrestore(&info->lock, flags);
 
 	return 0;
 }
diff -Nru a/drivers/macintosh/macserial.h b/drivers/macintosh/macserial.h
--- a/drivers/macintosh/macserial.h	Tue Oct  1 22:24:47 2002
+++ b/drivers/macintosh/macserial.h	Sun Mar 16 15:21:50 2003
@@ -9,6 +9,8 @@
 #ifndef _MACSERIAL_H
 #define _MACSERIAL_H
 
+#include <linux/spinlock.h>
+
 #define NUM_ZSREGS    16
 
 struct serial_struct {
@@ -105,6 +107,7 @@
 	struct mac_zschannel *zs_chan_a;	/* A side registers */
 	unsigned char read_reg_zero;
 	struct device_node* dev_node;
+	spinlock_t lock;
 
 	char soft_carrier;  /* Use soft carrier on this channel */
 	char break_abort;   /* Is serial console in, so process brk/abrt */
diff -Nru a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
--- a/drivers/macintosh/mediabay.c	Mon Nov 11 05:18:24 2002
+++ b/drivers/macintosh/mediabay.c	Sat Mar 22 01:11:14 2003
@@ -23,6 +23,7 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/init.h>
+#include <linux/ide.h>
 #include <asm/prom.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
@@ -493,7 +494,7 @@
 			} while(--timeout);
 			printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i);
 			return -ENODEV;
-		} 
+		}
 #endif
 	
 	return -ENODEV;
@@ -567,9 +568,10 @@
 				hw_regs_t hw;
 
 				pmu_suspend();
-				ide_init_hwif_ports(&hw, (ide_ioreg_t) bay->cd_base, (ide_ioreg_t) 0, NULL);
+				ide_init_hwif_ports(&hw, (unsigned long) bay->cd_base, (unsigned long) 0, NULL);
 				hw.irq = bay->cd_irq;
-				bay->cd_index = ide_register_hw(&hw);
+				hw.chipset = ide_pmac;
+				bay->cd_index = ide_register_hw(&hw, NULL);
 				pmu_resume();
 			}
 			if (bay->cd_index == -1) {
@@ -834,4 +836,4 @@
 	return 0;
 }
 
-device_initcall(media_bay_init);
+subsys_initcall(media_bay_init);
diff -Nru a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
--- a/drivers/macintosh/via-cuda.c	Mon Nov 18 09:38:42 2002
+++ b/drivers/macintosh/via-cuda.c	Sun Mar  2 18:51:01 2003
@@ -176,8 +176,8 @@
     /* for us by the main VIA driver in arch/m68k/mac/via.c        */
 
 #ifndef CONFIG_MAC
-    via[IFR] = 0x7f; eieio();	/* clear interrupts by writing 1s */
-    via[IER] = IER_SET|SR_INT; eieio();	/* enable interrupt from SR */
+    out_8(&via[IFR], 0x7f);	/* clear interrupts by writing 1s */
+    out_8(&via[IER], IER_SET|SR_INT); /* enable interrupt from SR */
 #endif
 
     /* enable autopoll */
@@ -246,7 +246,8 @@
 #endif /* CONFIG_ADB */
 
 #define WAIT_FOR(cond, what)					\
-    do {							\
+    do {                                                        \
+    	int x;							\
 	for (x = 1000; !(cond); --x) {				\
 	    if (x == 0) {					\
 		printk("Timeout waiting for " what "\n");	\
@@ -259,40 +260,40 @@
 static int
 cuda_init_via()
 {
-    int x;
-
-    via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ;	/* TACK & TIP out */
-    via[B] |= TACK | TIP;				/* negate them */
-    via[ACR] = (via[ACR] & ~SR_CTRL) | SR_EXT;		/* SR data in */
-    eieio();
-    x = via[SR]; eieio();	/* clear any left-over data */
+    out_8(&via[DIRB], (in_8(&via[DIRB]) | TACK | TIP) & ~TREQ);	/* TACK & TIP out */
+    out_8(&via[B], in_8(&via[B]) | TACK | TIP);			/* negate them */
+    out_8(&via[ACR] ,(in_8(&via[ACR]) & ~SR_CTRL) | SR_EXT);	/* SR data in */
+    (void)in_8(&via[SR]);						/* clear any left-over data */
 #ifndef CONFIG_MAC
-    via[IER] = 0x7f; eieio();	/* disable interrupts from VIA */
+    out_8(&via[IER], 0x7f);					/* disable interrupts from VIA */
+    (void)in_8(&via[IER]);
 #endif
-    eieio();
 
     /* delay 4ms and then clear any pending interrupt */
     mdelay(4);
-    x = via[SR]; eieio();
+    (void)in_8(&via[SR]);
+    out_8(&via[IFR], in_8(&via[IFR]) & 0x7f);
 
     /* sync with the CUDA - assert TACK without TIP */
-    via[B] &= ~TACK; eieio();
+    out_8(&via[B], in_8(&via[B]) & ~TACK);
 
     /* wait for the CUDA to assert TREQ in response */
-    WAIT_FOR((via[B] & TREQ) == 0, "CUDA response to sync");
+    WAIT_FOR((in_8(&via[B]) & TREQ) == 0, "CUDA response to sync");
 
     /* wait for the interrupt and then clear it */
-    WAIT_FOR(via[IFR] & SR_INT, "CUDA response to sync (2)");
-    x = via[SR]; eieio();
+    WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (2)");
+    (void)in_8(&via[SR]);
+    out_8(&via[IFR], in_8(&via[IFR]) & 0x7f);
 
     /* finish the sync by negating TACK */
-    via[B] |= TACK; eieio();
+    out_8(&via[B], in_8(&via[B]) | TACK);
 
     /* wait for the CUDA to negate TREQ and the corresponding interrupt */
-    WAIT_FOR(via[B] & TREQ, "CUDA response to sync (3)");
-    WAIT_FOR(via[IFR] & SR_INT, "CUDA response to sync (4)");
-    x = via[SR]; eieio();
-    via[B] |= TIP; eieio();	/* should be unnecessary */
+    WAIT_FOR(in_8(&via[B]) & TREQ, "CUDA response to sync (3)");
+    WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (4)");
+    (void)in_8(&via[SR]);
+    out_8(&via[IFR], in_8(&via[IFR]) & 0x7f);
+    out_8(&via[B], in_8(&via[B]) | TIP);	/* should be unnecessary */
 
     return 0;
 }
@@ -415,55 +416,59 @@
     req = current_req;
     if (req == 0)
 	return;
-    if ((via[B] & TREQ) == 0)
+    if ((in_8(&via[B]) & TREQ) == 0)
 	return;			/* a byte is coming in from the CUDA */
 
     /* set the shift register to shift out and send a byte */
-    via[ACR] |= SR_OUT; eieio();
-    via[SR] = req->data[0]; eieio();
-    via[B] &= ~TIP;
+    out_8(&via[ACR], in_8(&via[ACR]) | SR_OUT);
+    out_8(&via[SR], req->data[0]);
+    out_8(&via[B], in_8(&via[B]) & ~TIP);
     cuda_state = sent_first_byte;
 }
 
 void
 cuda_poll()
 {
-    if (via[IFR] & SR_INT) {
-	unsigned long flags;
+    unsigned long flags;
 
-	/* cuda_interrupt only takes a normal lock, we disable
-	 * interrupts here to avoid re-entering and thus deadlocking.
-	 * An option would be to disable only the IRQ source with
-	 * disable_irq(), would that work on m68k ? --BenH
-	 */
-	local_irq_save(flags);
-	cuda_interrupt(0, 0, 0);
-	local_irq_restore(flags);
-    }
+    /* cuda_interrupt only takes a normal lock, we disable
+     * interrupts here to avoid re-entering and thus deadlocking.
+     * An option would be to disable only the IRQ source with
+     * disable_irq(), would that work on m68k ? --BenH
+     */
+    local_irq_save(flags);
+    cuda_interrupt(0, 0, 0);
+    local_irq_restore(flags);
 }
 
 static void
 cuda_interrupt(int irq, void *arg, struct pt_regs *regs)
 {
-    int x, status;
+    int status;
     struct adb_request *req = NULL;
     unsigned char ibuf[16];
     int ibuf_len = 0;
     int complete = 0;
+    unsigned char virq;
     
-    if ((via[IFR] & SR_INT) == 0)
-	return;
-
     spin_lock(&cuda_lock);
-    status = (~via[B] & (TIP|TREQ)) | (via[ACR] & SR_OUT); eieio();
+
+    virq = in_8(&via[IFR]) & 0x7f;
+    out_8(&via[IFR], virq);   
+    if ((virq & SR_INT) == 0) {
+        spin_unlock(&cuda_lock);
+	return;
+    }
+    
+    status = (~in_8(&via[B]) & (TIP|TREQ)) | (in_8(&via[ACR]) & SR_OUT);
     /* printk("cuda_interrupt: state=%d status=%x\n", cuda_state, status); */
     switch (cuda_state) {
     case idle:
 	/* CUDA has sent us the first byte of data - unsolicited */
 	if (status != TREQ)
 	    printk("cuda: state=idle, status=%x\n", status);
-	x = via[SR]; eieio();
-	via[B] &= ~TIP; eieio();
+	(void)in_8(&via[SR]);
+	out_8(&via[B], in_8(&via[B]) & ~TIP);
 	cuda_state = reading;
 	reply_ptr = cuda_rbuf;
 	reading_reply = 0;
@@ -473,8 +478,8 @@
 	/* CUDA has sent us the first byte of data of a reply */
 	if (status != TREQ)
 	    printk("cuda: state=awaiting_reply, status=%x\n", status);
-	x = via[SR]; eieio();
-	via[B] &= ~TIP; eieio();
+	(void)in_8(&via[SR]);
+	out_8(&via[B], in_8(&via[B]) & ~TIP);
 	cuda_state = reading;
 	reply_ptr = current_req->reply;
 	reading_reply = 1;
@@ -483,16 +488,16 @@
     case sent_first_byte:
 	if (status == TREQ + TIP + SR_OUT) {
 	    /* collision */
-	    via[ACR] &= ~SR_OUT; eieio();
-	    x = via[SR]; eieio();
-	    via[B] |= TIP | TACK; eieio();
+	    out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT);
+	    (void)in_8(&via[SR]);
+	    out_8(&via[B], in_8(&via[B]) | TIP | TACK);
 	    cuda_state = idle;
 	} else {
 	    /* assert status == TIP + SR_OUT */
 	    if (status != TIP + SR_OUT)
 		printk("cuda: state=sent_first_byte status=%x\n", status);
-	    via[SR] = current_req->data[1]; eieio();
-	    via[B] ^= TACK; eieio();
+	    out_8(&via[SR], current_req->data[1]);
+	    out_8(&via[B], in_8(&via[B]) ^ TACK);
 	    data_index = 2;
 	    cuda_state = sending;
 	}
@@ -501,9 +506,9 @@
     case sending:
 	req = current_req;
 	if (data_index >= req->nbytes) {
-	    via[ACR] &= ~SR_OUT; eieio();
-	    x = via[SR]; eieio();
-	    via[B] |= TACK | TIP; eieio();
+	    out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT);
+	    (void)in_8(&via[SR]);
+	    out_8(&via[B], in_8(&via[B]) | TACK | TIP);
 	    req->sent = 1;
 	    if (req->reply_expected) {
 		cuda_state = awaiting_reply;
@@ -515,27 +520,27 @@
 		cuda_start();
 	    }
 	} else {
-	    via[SR] = req->data[data_index++]; eieio();
-	    via[B] ^= TACK; eieio();
+	    out_8(&via[SR], req->data[data_index++]);
+	    out_8(&via[B], in_8(&via[B]) ^ TACK);
 	}
 	break;
 
     case reading:
-	*reply_ptr++ = via[SR]; eieio();
+	*reply_ptr++ = in_8(&via[SR]);
 	if (status == TIP) {
 	    /* that's all folks */
-	    via[B] |= TACK | TIP; eieio();
+	    out_8(&via[B], in_8(&via[B]) | TACK | TIP);
 	    cuda_state = read_done;
 	} else {
 	    /* assert status == TIP | TREQ */
 	    if (status != TIP + TREQ)
 		printk("cuda: state=reading status=%x\n", status);
-	    via[B] ^= TACK; eieio();
+	    out_8(&via[B], in_8(&via[B]) ^ TACK);
 	}
 	break;
 
     case read_done:
-	x = via[SR]; eieio();
+	(void)in_8(&via[SR]);
 	if (reading_reply) {
 	    req = current_req;
 	    req->reply_len = reply_ptr - req->reply;
@@ -564,7 +569,7 @@
 	    memcpy(ibuf, cuda_rbuf, ibuf_len);
 	}
 	if (status == TREQ) {
-	    via[B] &= ~TIP; eieio();
+	    out_8(&via[B], in_8(&via[B]) & ~TIP);
 	    cuda_state = reading;
 	    reply_ptr = cuda_rbuf;
 	    reading_reply = 0;
diff -Nru a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
--- a/drivers/macintosh/via-pmu.c	Mon Feb 24 10:09:53 2003
+++ b/drivers/macintosh/via-pmu.c	Sat Mar 22 22:14:58 2003
@@ -33,6 +33,7 @@
 #include <linux/pm.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
@@ -343,10 +344,6 @@
 	} else
 		pmu_kind = PMU_UNKNOWN;
 
-#ifdef CONFIG_PMAC_PBOOK
-	if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
-		can_sleep = 1;
-#endif /* CONFIG_PMAC_PBOOK */
 	via = (volatile unsigned char *) ioremap(vias->addrs->address, 0x2000);
 	
 	out_8(&via[IER], IER_CLR | 0x7f);	/* disable all intrs */
@@ -405,6 +402,8 @@
 	bright_req_3.complete = 1;
 #ifdef CONFIG_PMAC_PBOOK
 	batt_req.complete = 1;
+	if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
+		can_sleep = 1;
 #endif
 
 	if (request_irq(vias->intrs[0].line, via_pmu_interrupt, 0, "VIA-PMU",
@@ -457,12 +456,20 @@
 
 #ifdef CONFIG_PMAC_PBOOK
   	if (machine_is_compatible("AAPL,3400/2400") ||
-  		machine_is_compatible("AAPL,3500"))
+  		machine_is_compatible("AAPL,3500")) {
+		int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+			NULL, PMAC_MB_INFO_MODEL, 0);
 		pmu_battery_count = 1;
-	else if (machine_is_compatible("AAPL,PowerBook1998") ||
-		machine_is_compatible("PowerBook1,1"))
+		if (mb == PMAC_TYPE_COMET)
+			pmu_batteries[0].flags |= PMU_BATT_TYPE_COMET;
+		else
+			pmu_batteries[0].flags |= PMU_BATT_TYPE_HOOPER;
+	} else if (machine_is_compatible("AAPL,PowerBook1998") ||
+		machine_is_compatible("PowerBook1,1")) {
 		pmu_battery_count = 2;
-	else {
+		pmu_batteries[0].flags |= PMU_BATT_TYPE_SMART;
+		pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART;
+	} else {
 		struct device_node* prim = find_devices("power-mgt");
 		u32 *prim_info = NULL;
 		if (prim)
@@ -470,6 +477,9 @@
 		if (prim_info) {
 			/* Other stuffs here yet unknown */
 			pmu_battery_count = (prim_info[6] >> 16) & 0xff;
+			pmu_batteries[0].flags |= PMU_BATT_TYPE_SMART;
+			if (pmu_battery_count > 1)
+				pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART;
 		}
 	}
 #endif /* CONFIG_PMAC_PBOOK */
@@ -550,156 +560,30 @@
 	return 1;
 }
 
-int
+int __pmac
 pmu_get_model(void)
 {
 	return pmu_kind;
 }
 
-#ifdef CONFIG_PMAC_PBOOK
-
-/* 
- * WARNING ! This code probably needs some debugging... -- BenH.
- */
-#ifdef NEW_OHARE_CODE
-static void __pmac
-done_battery_state_ohare(struct adb_request* req)
+static inline void wakeup_decrementer(void)
 {
-	unsigned int bat_flags = 0;
-	int current = 0;
-	unsigned int capa, max, voltage, time;
-	int lrange[] = { 0, 275, 850, 1680, 2325, 
-				2765, 3160, 3500, 3830, 4115, 
-				4360, 4585, 4795, 4990, 5170, 
-				5340, 5510, 5710, 5930, 6150, 
-				6370, 6500
-				};
-	
-	if (req->reply[0] & 0x01)
-		pmu_power_flags |= PMU_PWR_AC_PRESENT;
-	else
-		pmu_power_flags &= ~PMU_PWR_AC_PRESENT;
+	set_dec(tb_ticks_per_jiffy);
+	/* No currently-supported powerbook has a 601,
+	 * so use get_tbl, not native
+	 */
+	last_jiffy_stamp(0) = tb_last_stamp = get_tbl();
+}
 
-	if (req->reply[0] & 0x04) {
-		int vb, i, j, k, charge, pcharge;
-		bat_flags |= PMU_BATT_PRESENT;
-		vb = (req->reply[1] << 8) | req->reply[2];
-		voltage = ((vb * 2650) + 726650)/100;
-		vb *= 100;
-		current = req->reply[5];
-		if ((req->reply[0] & 0x01) == 0 && (current > 200))
-			vb += (current - 200) * 15;
-		else if (req->reply[0] & 0x02)
-			vb = (vb - 2000);
-	  	i = (33000 - vb) / 10;
-	  	j = i - (i % 100);
-		k = j/100;
-		if (k <= 0)
-	       		charge = 0;
-		else if (k >= 21)
-	       		charge = 650000;
-	  	else
-			charge = (lrange[k + 1] - lrange[k]) * (i - j) + (lrange[k] * 100);
-		charge = (1000 - charge / 650) / 10;
-		if (req->reply[0] & 0x40) {
-			pcharge = (req->reply[6] << 8) + req->reply[7];
-			if (pcharge > 6500)
-				pcharge = 6500;
-			pcharge *= 100;
-			pcharge = (1000 - pcharge / 650) / 10;
-			if (pcharge < charge)
-				charge = pcharge;
-		}
-		capa = charge;
-		max = 100;
-		time = (charge * 16440) / current;
-		current = -current;
-		
-	} else
-		capa = max = current = voltage = time = 0;
 
-	if (req->reply[0] & 0x02)
-		bat_flags |= PMU_BATT_CHARGING;
+#ifdef CONFIG_PMAC_PBOOK
 
-	pmu_batteries[pmu_cur_battery].flags = bat_flags;
-	pmu_batteries[pmu_cur_battery].charge = capa;
-	pmu_batteries[pmu_cur_battery].max_charge = max;
-	pmu_batteries[pmu_cur_battery].current = current;
-	pmu_batteries[pmu_cur_battery].voltage = voltage;
-	pmu_batteries[pmu_cur_battery].time_remaining = time;
-}
-#else /* NEW_OHARE_CODE */
+/* This new version of the code for 2400/3400/3500 powerbooks
+ * is inspired from the implementation in gkrellm-pmu
+ */
 static void __pmac
 done_battery_state_ohare(struct adb_request* req)
 {
-	unsigned int bat_flags = 0;
-	int current = 0;
-	unsigned int capa, max, voltage, time;
-	int lrange[] = { 0, 275, 850, 1680, 2325, 
-				2765, 3160, 3500, 3830, 4115, 
-				4360, 4585, 4795, 4990, 5170, 
-				5340, 5510, 5710, 5930, 6150, 
-				6370, 6500
-				};
-	
-	if (req->reply[0] & 0x01)
-		pmu_power_flags |= PMU_PWR_AC_PRESENT;
-	else
-		pmu_power_flags &= ~PMU_PWR_AC_PRESENT;
-
-	if (req->reply[0] & 0x04) {
-		int vb, i, j, charge, pcharge;
-		bat_flags |= PMU_BATT_PRESENT;
-		vb = (req->reply[1] << 8) | req->reply[2];
-		voltage = ((vb * 2650) + 726650)/100;
-		current = *((signed char *)&req->reply[5]);
-		if ((req->reply[0] & 0x01) == 0 && (current > 200))
-			vb += (current - 200) * 15;
-		else if (req->reply[0] & 0x02)
-			vb = (vb - 10) * 100;
-	  	i = (33000 - vb) / 10;
-	  	j = i - (i % 100);
-	  	if (j <= 0)
-	       		charge = 0;
-	  	else if (j >= 21)
-	       		charge = 650000;
-	  	else
-			charge = (lrange[j + 1] - lrange[j]) * (i - j) + (lrange[j] * 100);
-		charge = (1000 - charge / 650) / 10;
-		if (req->reply[0] & 0x40) {
-			pcharge = (req->reply[6] << 8) + req->reply[7];
-			if (pcharge > 6500)
-				pcharge = 6500;
-			pcharge *= 100;
-			pcharge = (1000 - pcharge / 650) / 10;
-			if (pcharge < charge)
-				charge = pcharge;
-		}
-		capa = charge;
-		max = 100;
-		time = (charge * 274) / current;
-		current = -current;
-		
-	} else
-		capa = max = current = voltage = time = 0;
-
-	if ((req->reply[0] & 0x02) && (current > 0))
-		bat_flags |= PMU_BATT_CHARGING;
-	if (req->reply[0] & 0x04) /* CHECK THIS ONE */
-		bat_flags |= PMU_BATT_PRESENT;
-
-	pmu_batteries[pmu_cur_battery].flags = bat_flags;
-	pmu_batteries[pmu_cur_battery].charge = capa;
-	pmu_batteries[pmu_cur_battery].max_charge = max;
-	pmu_batteries[pmu_cur_battery].current = current;
-	pmu_batteries[pmu_cur_battery].voltage = voltage;
-	pmu_batteries[pmu_cur_battery].time_remaining = time;
-}
-#endif /* NEW_OHARE_CODE */
-
- static void __pmac
-done_battery_state_comet(struct adb_request* req)
-{
 	/* format:
 	 *  [0]    :  flags
 	 *    0x01 :  AC indicator
@@ -718,57 +602,62 @@
 	 *  [6][7] :  pcharge
 	 *              --tkoba
 	 */
+	unsigned int bat_flags = PMU_BATT_TYPE_HOOPER;
+	long pcharge, charge, vb, vmax, lmax;
+	long vmax_charging, vmax_charged;
+	long current, voltage, time, max;
+	int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+			NULL, PMAC_MB_INFO_MODEL, 0);
 
-	unsigned int bat_flags = 0;
-	int current = 0;
-	unsigned int max = 100;
-	unsigned int charge, voltage, time;
-	int lrange[] = { 0, 600, 750, 900, 1000, 1080, 
-				1180, 1250, 1300, 1340, 1360, 
-				1390, 1420, 1440, 1470, 1490, 
-				1520, 1550, 1580, 1610, 1650, 
-				1700
-				};
-	
 	if (req->reply[0] & 0x01)
 		pmu_power_flags |= PMU_PWR_AC_PRESENT;
 	else
 		pmu_power_flags &= ~PMU_PWR_AC_PRESENT;
+	
+	if (mb == PMAC_TYPE_COMET) {
+		vmax_charged = 189;
+		vmax_charging = 213;
+		lmax = 6500;
+	} else {
+		vmax_charged = 330;
+		vmax_charging = 330;
+		lmax = 6500;
+	}
+	vmax = vmax_charged;
 
-	if (req->reply[0] & 0x04) {	/* battery exist */
-		int vb, i;
+	/* If battery installed */
+	if (req->reply[0] & 0x04) {
 		bat_flags |= PMU_BATT_PRESENT;
+		if (req->reply[0] & 0x02)
+			bat_flags |= PMU_BATT_CHARGING;
 		vb = (req->reply[1] << 8) | req->reply[2];
-		voltage = ((vb * 2650) + 726650)/100;
-		vb *= 10;
+		voltage = (vb * 265 + 72665) / 10;
 		current = req->reply[5];
-		if ((req->reply[0] & 0x01) == 0 && (current > 200))
-			vb += ((current - 200) * 3);	/* vb = 500<->1800 */
-		else if (req->reply[0] & 0x02)
-			vb = ((vb - 800) * 1700/13)/100;	/*  in charging vb = 1300<->2130 */
-
-		if (req->reply[0] & 0x20) {	/* full charged */
-			charge = max;
-		} else {
-			if (lrange[21] < vb)
-				charge = max;
-			else {
-				if (vb < lrange[1])
-					charge = 0;
-				else {
-					for (i=21; vb < lrange[i]; --i);
-					charge = (i * 100)/21;
-				}
-			}
-			if (charge > max) charge = max;
+		if ((req->reply[0] & 0x01) == 0) {
+			if (current > 200)
+				vb += ((current - 200) * 15)/100;
+		} else if (req->reply[0] & 0x02) {
+			vb = (vb * 97) / 100;
+			vmax = vmax_charging;
+		}
+		charge = (100 * vb) / vmax;
+		if (req->reply[0] & 0x40) {
+			pcharge = (req->reply[6] << 8) + req->reply[7];
+			if (pcharge > lmax)
+				pcharge = lmax;
+			pcharge *= 100;
+			pcharge = 100 - pcharge / lmax;
+			if (pcharge < charge)
+				charge = pcharge;
 		}
-		time = (charge * 72);
+		if (current > 0)
+			time = (charge * 16440) / current;
+		else
+			time = 0;
+		max = 100;
 		current = -current;
 	} else
-		max = current = voltage = time = 0;
-
-	if (req->reply[0] & 0x02)
-		bat_flags |= PMU_BATT_CHARGING;
+		charge = max = current = voltage = time = 0;
 
 	pmu_batteries[pmu_cur_battery].flags = bat_flags;
 	pmu_batteries[pmu_cur_battery].charge = charge;
@@ -800,7 +689,7 @@
 	 *  [8][9] : voltage
 	 */
 	 
-	unsigned int bat_flags = 0;
+	unsigned int bat_flags = PMU_BATT_TYPE_SMART;
 	int current;
 	unsigned int capa, max, voltage;
 	
@@ -858,24 +747,17 @@
 {
 	if (!batt_req.complete)
 		return;
-	if (pmu_kind == PMU_OHARE_BASED) {
-		int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
-			NULL, PMAC_MB_INFO_MODEL, 0);
-
-		if (mb == PMAC_TYPE_COMET)
-			pmu_request(&batt_req, done_battery_state_comet,
-				1, PMU_BATTERY_STATE);
-		else
-			pmu_request(&batt_req, done_battery_state_ohare,
-				1, PMU_BATTERY_STATE);
-	} else
+	if (pmu_kind == PMU_OHARE_BASED)
+		pmu_request(&batt_req, done_battery_state_ohare,
+			1, PMU_BATTERY_STATE);
+	else
 		pmu_request(&batt_req, done_battery_state_smart,
 			2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1);
 }
 
 #endif /* CONFIG_PMAC_PBOOK */
 
-static int
+static int __pmac
 proc_get_info(char *page, char **start, off_t off,
 		int count, int *eof, void *data)
 {
@@ -893,7 +775,7 @@
 }
 
 #ifdef CONFIG_PMAC_PBOOK
-static int
+static int __pmac
 proc_get_batt(char *page, char **start, off_t off,
 		int count, int *eof, void *data)
 {
@@ -918,7 +800,7 @@
 }
 #endif /* CONFIG_PMAC_PBOOK */
 
-static int
+static int __pmac
 proc_read_options(char *page, char **start, off_t off,
 			int count, int *eof, void *data)
 {
@@ -932,7 +814,7 @@
 	return p - page;
 }
 			
-static int
+static int __pmac
 proc_write_options(struct file *file, const char *buffer,
 			unsigned long count, void *data)
 {
@@ -972,7 +854,7 @@
 
 #ifdef CONFIG_ADB
 /* Send an ADB command */
-static int __openfirmware
+static int __pmac
 pmu_send_request(struct adb_request *req, int sync)
 {
 	int i, ret;
@@ -1052,7 +934,7 @@
 }
 
 /* Enable/disable autopolling */
-static int __openfirmware
+static int __pmac
 pmu_adb_autopoll(int devs)
 {
 	struct adb_request req;
@@ -1075,7 +957,7 @@
 }
 
 /* Reset the ADB bus */
-static int __openfirmware
+static int __pmac
 pmu_adb_reset_bus(void)
 {
 	struct adb_request req;
@@ -1137,7 +1019,7 @@
 	return pmu_queue_request(req);
 }
 
-int __openfirmware
+int __pmac
 pmu_queue_request(struct adb_request *req)
 {
 	unsigned long flags;
@@ -1229,7 +1111,7 @@
 		(*done)(req);
 }
 
-static void __openfirmware
+static void __pmac
 pmu_start()
 {
 	struct adb_request *req;
@@ -1342,7 +1224,7 @@
 }
 
 /* Interrupt data could be the result data from an ADB cmd */
-static void __openfirmware
+static void __pmac
 pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs)
 {
 	asleep = 0;
@@ -1417,7 +1299,7 @@
 	}
 }
 
-static struct adb_request* __openfirmware
+static struct adb_request* __pmac
 pmu_sr_intr(struct pt_regs *regs)
 {
 	struct adb_request *req;
@@ -1511,7 +1393,7 @@
 	return NULL;
 }
 
-static void __openfirmware
+static void __pmac
 via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
 {
 	unsigned long flags;
@@ -1561,10 +1443,10 @@
 			wait_for_ack();
 			send_byte(PMU_INT_ACK);
 			adb_int_pending = 0;
-no_free_slot:			
 		} else if (current_req)
 			pmu_start();
 	}
+no_free_slot:			
 	/* Mark the oldest buffer for flushing */
 	if (int_data_state[!int_data_last] == int_data_ready) {
 		int_data_state[!int_data_last] = int_data_flush;
@@ -1593,7 +1475,7 @@
 	}
 }
 
-static void __openfirmware
+static void __pmac
 gpio1_interrupt(int irq, void *arg, struct pt_regs *regs)
 {
 	if ((in_8(gpio_reg + 0x9) & 0x02) == 0) {
@@ -1603,7 +1485,7 @@
 }
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-static int backlight_to_bright[] = {
+static int backlight_to_bright[] __pmacdata = {
 	0x7f, 0x46, 0x42, 0x3e, 0x3a, 0x36, 0x32, 0x2e,
 	0x2a, 0x26, 0x22, 0x1e, 0x1a, 0x16, 0x12, 0x0e
 };
@@ -1649,7 +1531,7 @@
 }
 #endif /* CONFIG_PMAC_BACKLIGHT */
 
-void __openfirmware
+void __pmac
 pmu_enable_irled(int on)
 {
 	struct adb_request req;
@@ -1665,7 +1547,7 @@
 		pmu_poll();
 }
 
-void __openfirmware
+void __pmac
 pmu_restart(void)
 {
 	struct adb_request req;
@@ -1688,7 +1570,7 @@
 		;
 }
 
-void __openfirmware
+void __pmac
 pmu_shutdown(void)
 {
 	struct adb_request req;
@@ -1723,7 +1605,7 @@
 static LIST_HEAD(sleep_notifiers);
 
 #ifdef CONFIG_PM
-static int
+static int __pmac
 generic_notify_sleep(struct pmu_sleep_notifier *self, int when)
 {
 	switch (when) {
@@ -1765,7 +1647,7 @@
 }
 
 /* Sleep is broadcast last-to-first */
-static int
+static int __pmac
 broadcast_sleep(int when, int fallback)
 {
 	int ret = PBOOK_SLEEP_OK;
@@ -1790,7 +1672,7 @@
 }
 
 /* Wake is broadcast first-to-last */
-static int
+static int __pmac
 broadcast_wake(void)
 {
 	int ret = PBOOK_SLEEP_OK;
@@ -1821,7 +1703,7 @@
 } *pbook_pci_saves;
 static int pbook_npci_saves;
 
-static void __openfirmware
+static void __pmac
 pbook_alloc_pci_save(void)
 {
 	int npci;
@@ -1838,7 +1720,7 @@
 	pbook_npci_saves = npci;
 }
 
-static void __openfirmware
+static void __pmac
 pbook_free_pci_save(void)
 {
 	if (pbook_pci_saves == NULL)
@@ -1848,7 +1730,7 @@
 	pbook_npci_saves = 0;
 }
 
-static void __openfirmware
+static void __pmac
 pbook_pci_save(void)
 {
 	struct pci_save *ps = pbook_pci_saves;
@@ -1879,7 +1761,7 @@
  * during boot, it will be in the pci dev list. If it's disabled at this point
  * (and it will probably be), then you can't access it's config space.
  */
-static void __openfirmware
+static void __pmac
 pbook_pci_restore(void)
 {
 	u16 cmd;
@@ -1927,7 +1809,7 @@
 
 #ifdef DEBUG_SLEEP
 /* N.B. This doesn't work on the 3400 */
-void
+void  __pmac
 pmu_blink(int n)
 {
 	struct adb_request req;
@@ -1966,8 +1848,10 @@
  * Put the powerbook to sleep.
  */
  
-static u32 save_via[8];
-static void save_via_state(void)
+static u32 save_via[8] __pmacdata;
+
+static void __pmac
+save_via_state(void)
 {
 	save_via[0] = in_8(&via[ANH]);
 	save_via[1] = in_8(&via[DIRA]);
@@ -1978,7 +1862,8 @@
 	save_via[6] = in_8(&via[T1CL]);
 	save_via[7] = in_8(&via[T1CH]);
 }
-static void restore_via_state(void)
+static void __pmac
+restore_via_state(void)
 {
 	out_8(&via[ANH], save_via[0]);
 	out_8(&via[DIRA], save_via[1]);
@@ -1993,23 +1878,15 @@
 	out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
 }
 
-static inline void wakeup_decrementer(void)
-{
-	set_dec(tb_ticks_per_jiffy);
-	/* No currently-supported powerbook has a 601,
-	 * so use get_tbl, not native
-	 */
-	last_jiffy_stamp(0) = tb_last_stamp = get_tbl();
-}
-
-extern int sys_sync(void);
+extern long sys_sync(void);
 
 #define	GRACKLE_PM	(1<<7)
 #define GRACKLE_DOZE	(1<<5)
 #define	GRACKLE_NAP	(1<<4)
 #define	GRACKLE_SLEEP	(1<<3)
 
-int __openfirmware powerbook_sleep_G3(void)
+int __pmac
+powerbook_sleep_G3(void)
 {
 	unsigned long save_l2cr;
 	unsigned short pmcr1;
@@ -2152,7 +2029,8 @@
 	return 0;
 }
 
-int __openfirmware powerbook_sleep_Core99(void)
+static int __pmac
+powerbook_sleep_Core99(void)
 {
 	unsigned long save_l2cr;
 	unsigned long save_l3cr;
@@ -2322,7 +2200,8 @@
 #define PB3400_MEM_CTRL		0xf8000000
 #define PB3400_MEM_CTRL_SLEEP	0x70
 
-int __openfirmware powerbook_sleep_3400(void)
+static int __pmac
+powerbook_sleep_3400(void)
 {
 	int ret, i, x;
 	unsigned int hid0;
@@ -2463,9 +2342,10 @@
 };
 
 static LIST_HEAD(all_pmu_pvt);
-static spinlock_t all_pvt_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t all_pvt_lock __pmacdata = SPIN_LOCK_UNLOCKED;
 
-static void pmu_pass_intr(unsigned char *data, int len)
+static void __pmac
+pmu_pass_intr(unsigned char *data, int len)
 {
 	struct pmu_private *pp;
 	struct list_head *list;
@@ -2493,7 +2373,8 @@
 	spin_unlock_irqrestore(&all_pvt_lock, flags);
 }
 
-static int __openfirmware pmu_open(struct inode *inode, struct file *file)
+static int __pmac
+pmu_open(struct inode *inode, struct file *file)
 {
 	struct pmu_private *pp;
 	unsigned long flags;
@@ -2514,7 +2395,8 @@
 	return 0;
 }
 
-static ssize_t __openfirmware pmu_read(struct file *file, char *buf,
+static ssize_t  __pmac
+pmu_read(struct file *file, char *buf,
 			size_t count, loff_t *ppos)
 {
 	struct pmu_private *pp = file->private_data;
@@ -2566,13 +2448,15 @@
 	return ret;
 }
 
-static ssize_t __openfirmware pmu_write(struct file *file, const char *buf,
+static ssize_t __pmac
+pmu_write(struct file *file, const char *buf,
 			 size_t count, loff_t *ppos)
 {
 	return 0;
 }
 
-static unsigned int pmu_fpoll(struct file *filp, poll_table *wait)
+static unsigned int __pmac
+pmu_fpoll(struct file *filp, poll_table *wait)
 {
 	struct pmu_private *pp = filp->private_data;
 	unsigned int mask = 0;
@@ -2588,7 +2472,8 @@
 	return mask;
 }
 
-static int pmu_release(struct inode *inode, struct file *file)
+static int __pmac
+pmu_release(struct inode *inode, struct file *file)
 {
 	struct pmu_private *pp = file->private_data;
 	unsigned long flags;
@@ -2613,7 +2498,8 @@
 }
 
 /* Note: removed __openfirmware here since it causes link errors */
-static int pmu_ioctl(struct inode * inode, struct file *filp,
+static int __pmac
+pmu_ioctl(struct inode * inode, struct file *filp,
 		     u_int cmd, u_long arg)
 {
 	struct pmu_private *pp = filp->private_data;
@@ -2687,7 +2573,7 @@
 	return -EINVAL;
 }
 
-static struct file_operations pmu_device_fops = {
+static struct file_operations pmu_device_fops __pmacdata = {
 	.read		= pmu_read,
 	.write		= pmu_write,
 	.poll		= pmu_fpoll,
@@ -2696,7 +2582,7 @@
 	.release	= pmu_release,
 };
 
-static struct miscdevice pmu_device = {
+static struct miscdevice pmu_device __pmacdata = {
 	PMU_MINOR, "pmu", &pmu_device_fops
 };
 
@@ -2710,7 +2596,8 @@
 #endif /* CONFIG_PMAC_PBOOK */
 
 #ifdef DEBUG_SLEEP
-static inline void polled_handshake(volatile unsigned char *via)
+static inline void  __pmac
+polled_handshake(volatile unsigned char *via)
 {
 	via[B] &= ~TREQ; eieio();
 	while ((via[B] & TACK) != 0)
@@ -2720,14 +2607,16 @@
 		;
 }
 
-static inline void polled_send_byte(volatile unsigned char *via, int x)
+static inline void  __pmac
+polled_send_byte(volatile unsigned char *via, int x)
 {
 	via[ACR] |= SR_OUT | SR_EXT; eieio();
 	via[SR] = x; eieio();
 	polled_handshake(via);
 }
 
-static inline int polled_recv_byte(volatile unsigned char *via)
+static inline int __pmac
+polled_recv_byte(volatile unsigned char *via)
 {
 	int x;
 
@@ -2738,7 +2627,7 @@
 	return x;
 }
 
-int
+int __pmac
 pmu_polled_request(struct adb_request *req)
 {
 	unsigned long flags;
diff -Nru a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
--- a/drivers/md/dm-ioctl.c	Thu Feb 27 09:21:54 2003
+++ b/drivers/md/dm-ioctl.c	Sat Mar 22 07:38:04 2003
@@ -56,7 +56,7 @@
 {
 	init_buckets(_name_buckets);
 	init_buckets(_uuid_buckets);
-	devfs_mk_dir(NULL, DM_DIR, NULL);
+	devfs_mk_dir(DM_DIR);
 	return 0;
 }
 
@@ -1089,8 +1089,6 @@
 	.owner	 = THIS_MODULE,
 };
 
-static devfs_handle_t _ctl_handle;
-
 static struct miscdevice _dm_misc = {
 	.minor = MISC_DYNAMIC_MINOR,
 	.name  = DM_NAME,
@@ -1115,8 +1113,7 @@
 		return r;
 	}
 
-	r = devfs_mk_symlink(NULL, DM_DIR "/control", DEVFS_FL_DEFAULT,
-			"../misc/" DM_NAME, &_ctl_handle, NULL);
+	r = devfs_mk_symlink(DM_DIR "/control", "../misc/" DM_NAME);
 	if (r) {
 		DMERR("devfs_mk_symlink failed for control device");
 		goto failed;
diff -Nru a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
--- a/drivers/md/dm-linear.c	Mon Dec 16 01:43:39 2002
+++ b/drivers/md/dm-linear.c	Sat Mar 22 22:14:13 2003
@@ -79,6 +79,7 @@
 			 char *result, int maxlen)
 {
 	struct linear_c *lc = (struct linear_c *) ti->private;
+	char b[BDEVNAME_SIZE];
 
 	switch (type) {
 	case STATUSTYPE_INFO:
@@ -87,7 +88,7 @@
 
 	case STATUSTYPE_TABLE:
 		snprintf(result, maxlen, "%s " SECTOR_FORMAT,
-			 bdevname(lc->dev->bdev), lc->start);
+			 bdevname(lc->dev->bdev, b), lc->start);
 		break;
 	}
 	return 0;
diff -Nru a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
--- a/drivers/md/dm-stripe.c	Mon Dec 16 01:40:53 2002
+++ b/drivers/md/dm-stripe.c	Sat Mar 22 22:14:13 2003
@@ -209,6 +209,7 @@
 	struct stripe_c *sc = (struct stripe_c *) ti->private;
 	int offset;
 	int i;
+	char b[BDEVNAME_SIZE];
 
 	switch (type) {
 	case STATUSTYPE_INFO:
@@ -222,7 +223,7 @@
 			offset +=
 			    snprintf(result + offset, maxlen - offset,
 				     " %s " SECTOR_FORMAT,
-		       bdevname(sc->stripe[i].dev->bdev),
+		       bdevname(sc->stripe[i].dev->bdev, b),
 				     sc->stripe[i].physical_start);
 		}
 		break;
diff -Nru a/drivers/md/linear.c b/drivers/md/linear.c
--- a/drivers/md/linear.c	Tue Mar 11 18:46:36 2003
+++ b/drivers/md/linear.c	Sat Mar 22 22:14:13 2003
@@ -197,8 +197,13 @@
     
 	if (unlikely(block >= (tmp_dev->size + tmp_dev->offset)
 		     || block < tmp_dev->offset)) {
-		printk ("linear_make_request: Block %llu out of bounds on dev %s size %ld offset %ld\n",
-			(unsigned long long)block, bdevname(tmp_dev->rdev->bdev), tmp_dev->size, tmp_dev->offset);
+		char b[BDEVNAME_SIZE];
+
+		printk ("linear_make_request: Block %llu out of bounds on "
+			"dev %s size %ld offset %ld\n",
+			(unsigned long long)block,
+			bdevname(tmp_dev->rdev->bdev, b),
+			tmp_dev->size, tmp_dev->offset);
 		bio_io_error(bio, bio->bi_size);
 		return 0;
 	}
diff -Nru a/drivers/md/md.c b/drivers/md/md.c
--- a/drivers/md/md.c	Sun Mar 16 22:35:11 2003
+++ b/drivers/md/md.c	Sat Mar 22 07:38:04 2003
@@ -1735,7 +1735,6 @@
 	mddev->safemode_delay = (20 * HZ)/1000 +1; /* 20 msec delay */
 	mddev->in_sync = 1;
 	
-	md_update_sb(mddev);
 	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	md_wakeup_thread(mddev->thread);
 	set_capacity(disk, md_size[mdidx(mddev)]<<1);
@@ -1763,7 +1762,6 @@
 			goto out;
 
 		mddev->safemode = 0;
-		md_update_sb(mddev);
 		mddev->ro = 0;
 		set_disk_ro(disk, 0);
 
@@ -3247,7 +3245,7 @@
 {
 	mddev_t *mddev2;
 	unsigned int max_sectors, currspeed = 0,
-		j, window, err;
+		j, window;
 	unsigned long mark[SYNC_MARKS];
 	unsigned long mark_cnt[SYNC_MARKS];
 	int last_mark,m;
@@ -3283,7 +3281,6 @@
 				if (wait_event_interruptible(resync_wait,
 							     mddev2->curr_resync < mddev->curr_resync)) {
 					flush_signals(current);
-					err = -EINTR;
 					mddev_put(mddev2);
 					goto skip;
 				}
@@ -3335,7 +3332,7 @@
 
 		sectors = mddev->pers->sync_request(mddev, j, currspeed < sysctl_speed_limit_min);
 		if (sectors < 0) {
-			err = sectors;
+			set_bit(MD_RECOVERY_ERR, &mddev->recovery);
 			goto out;
 		}
 		atomic_add(sectors, &mddev->recovery_active);
@@ -3372,7 +3369,7 @@
 			 */
 			printk(KERN_INFO "md: md_do_sync() got signal ... exiting\n");
 			flush_signals(current);
-			err = -EINTR;
+			set_bit(MD_RECOVERY_INTR, &mddev->recovery);
 			goto out;
 		}
 
@@ -3398,7 +3395,6 @@
 		}
 	}
 	printk(KERN_INFO "md: md%d: sync done.\n",mdidx(mddev));
-	err = 0;
 	/*
 	 * this also signals 'finished resyncing' to md_stop
 	 */
@@ -3408,8 +3404,6 @@
 	/* tell personality that we are finished */
 	mddev->pers->sync_request(mddev, max_sectors, 1);
 
-	if (err)
-		set_bit(MD_RECOVERY_ERR, &mddev->recovery);
 	if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) &&
 	    mddev->curr_resync > 2 &&
 	    mddev->curr_resync > mddev->recovery_cp) {
@@ -3603,7 +3597,7 @@
 	if (register_blkdev(MAJOR_NR, "md"))
 		return -1;
 
-	devfs_mk_dir(NULL, "md", NULL);
+	devfs_mk_dir("md");
 	blk_register_region(MKDEV(MAJOR_NR, 0), MAX_MD_DEVS, THIS_MODULE,
 				md_probe, NULL, NULL);
 	for (minor=0; minor < MAX_MD_DEVS; ++minor) {
diff -Nru a/drivers/md/raid1.c b/drivers/md/raid1.c
--- a/drivers/md/raid1.c	Tue Mar 11 18:46:36 2003
+++ b/drivers/md/raid1.c	Wed Mar 19 15:43:16 2003
@@ -840,7 +840,8 @@
 			 * we read from here, no need to write
 			 */
 			continue;
-		if (conf->mirrors[i].rdev->in_sync && mddev->in_sync)
+		if (conf->mirrors[i].rdev->in_sync && 
+			r1_bio->sector + (bio->bi_size>>9) <= mddev->recovery_cp)
 			/*
 			 * don't need to write this we are just rebuilding
 			 */
diff -Nru a/drivers/media/dvb/dvb-core/Kconfig b/drivers/media/dvb/dvb-core/Kconfig
--- a/drivers/media/dvb/dvb-core/Kconfig	Tue Oct 29 17:16:55 2002
+++ b/drivers/media/dvb/dvb-core/Kconfig	Tue Mar 18 08:56:51 2003
@@ -5,13 +5,3 @@
 	  DVB core utility functions for device handling, software fallbacks etc.
 
 	  Say Y when you have a DVB card and want to use it. If unsure say N.
-
-config DVB_DEVFS_ONLY
-	bool "devfs only"
-	depends on DVB_CORE=y && DEVFS_FS
-	help
-	  Drop support for old major/minor device scheme and support only devfs 
-	  systems. This saves some code.
-
-	  If unsure say N.
-
diff -Nru a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
--- a/drivers/media/dvb/dvb-core/dvb_demux.c	Tue Nov 12 17:26:41 2002
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c	Sun Mar  2 03:26:22 2003
@@ -221,7 +221,7 @@
 			return 0;
 		neq|=f->maskandnotmode[i]&xor;
 	}
-	if (f->doneq & !neq)
+	if (f->doneq && !neq)
 		return 0;
 
         return dvbdmxfeed->cb.sec(dvbdmxfeed->secbuf, dvbdmxfeed->seclen, 
diff -Nru a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
--- a/drivers/media/dvb/dvb-core/dvbdev.c	Mon Nov 25 07:57:37 2002
+++ b/drivers/media/dvb/dvb-core/dvbdev.c	Sat Mar 22 07:38:04 2003
@@ -21,8 +21,6 @@
  *
  */
 
-/*#define CONFIG_DVB_DEVFS_ONLY 1*/
-
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
@@ -56,17 +54,8 @@
 };
 
 
-#ifdef CONFIG_DVB_DEVFS_ONLY
-
-	#define DVB_MAX_IDS              ~0
-	#define nums2minor(num,type,id)  0
-	#define DVB_DEVFS_FLAGS          (DEVFS_FL_DEFAULT|DEVFS_FL_AUTO_DEVNUM)
-
-#else
-
-	#define DVB_MAX_IDS              4
-	#define nums2minor(num,type,id)  ((num << 6) | (id << 4) | type)
-	#define DVB_DEVFS_FLAGS          (DEVFS_FL_DEFAULT)
+#define DVB_MAX_IDS              4
+#define nums2minor(num,type,id)  ((num << 6) | (id << 4) | type)
 
 
 static
@@ -122,8 +111,6 @@
 	.owner =	THIS_MODULE,
 	.open =		dvb_device_open,
 };
-#endif /* CONFIG_DVB_DEVFS_ONLY */
-
 
 
 int dvb_generic_open(struct inode *inode, struct file *file)
@@ -234,8 +221,7 @@
 
 	sprintf(name, "%s%d", dnames[type], id);
 	dvbdev->devfs_handle = devfs_register(adap->devfs_handle, name,
-					      DVB_DEVFS_FLAGS,
-					      DVB_MAJOR,
+					      0, DVB_MAJOR,
 					      nums2minor(adap->num, type, id),
 					      S_IFCHR | S_IRUSR | S_IWUSR,
 					      dvbdev->fops, dvbdev);
@@ -283,7 +269,6 @@
 
 int dvb_register_adapter(struct dvb_adapter **padap, char *name)
 {
-	char dirname[16];
 	struct dvb_adapter *adap;
 	int num;
 
@@ -307,8 +292,7 @@
 
 	printk ("DVB: registering new adapter (%s).\n", name);
 	
-	sprintf(dirname, "dvb/adapter%d", num);
-	adap->devfs_handle = devfs_mk_dir(NULL, dirname, NULL);
+	adap->devfs_handle = devfs_mk_dir("dvb/adapter%d", num);
 	adap->num = num;
 
 	list_add_tail (&adap->list_head, &dvb_adapter_list);
@@ -335,7 +319,7 @@
 static
 int __init init_dvbdev(void)
 {
-	dvb_devfs_handle = devfs_mk_dir (NULL, "dvb", NULL);
+	dvb_devfs_handle = devfs_mk_dir ("dvb");
 #ifndef CONFIG_DVB_DEVFS_ONLY
 	if(register_chrdev(DVB_MAJOR,"DVB", &dvb_device_fops)) {
 		printk("video_dev: unable to get major %d\n", DVB_MAJOR);
diff -Nru a/drivers/media/radio/miropcm20-rds-core.c b/drivers/media/radio/miropcm20-rds-core.c
--- a/drivers/media/radio/miropcm20-rds-core.c	Tue Feb 25 02:44:08 2003
+++ b/drivers/media/radio/miropcm20-rds-core.c	Thu Mar 13 16:52:15 2003
@@ -13,8 +13,6 @@
  *        RDS support for MiroSound PCM20 radio
  */
 
-#define _NO_VERSION_
-
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/string.h>
diff -Nru a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c
--- a/drivers/media/radio/miropcm20-rds.c	Sun Mar 16 22:33:22 2003
+++ b/drivers/media/radio/miropcm20-rds.c	Sat Mar 22 07:37:12 2003
@@ -125,8 +125,8 @@
 	if (error)
 		return error;
 
-	error = devfs_mk_symlink(NULL, "v4l/rds/radiotext", 0,
-				 "../misc/radiotext", NULL, NULL);
+	error = devfs_mk_symlink("v4l/rds/radiotext",
+				 "../misc/radiotext");
 	if (error)
 		misc_deregister(&rds_miscdev);
 
diff -Nru a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
--- a/drivers/media/video/bttv-cards.c	Wed Mar 12 06:07:06 2003
+++ b/drivers/media/video/bttv-cards.c	Tue Mar 18 09:00:00 2003
@@ -24,8 +24,6 @@
     
 */
 
-#define __NO_VERSION__ 1
-
 #include <linux/version.h>
 #include <linux/delay.h>
 #include <linux/module.h>
diff -Nru a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
--- a/drivers/media/video/bttv-if.c	Wed Mar 12 06:07:06 2003
+++ b/drivers/media/video/bttv-if.c	Tue Mar 18 09:00:00 2003
@@ -25,8 +25,6 @@
     
 */
 
-#define __NO_VERSION__ 1
-
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
diff -Nru a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
--- a/drivers/media/video/bttv-risc.c	Wed Jan  8 01:59:58 2003
+++ b/drivers/media/video/bttv-risc.c	Thu Mar 13 16:52:15 2003
@@ -23,8 +23,6 @@
 
 */
 
-#define __NO_VERSION__ 1
-
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
diff -Nru a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
--- a/drivers/media/video/cpia.c	Mon Dec 30 20:26:12 2002
+++ b/drivers/media/video/cpia.c	Thu Mar  6 15:46:22 2003
@@ -23,7 +23,9 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* #define _CPIA_DEBUG_		define for verbose debug output */
+/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
+/* #define _CPIA_DEBUG_  1 */  
+
 #include <linux/config.h>
 
 #include <linux/module.h>
@@ -1796,7 +1798,7 @@
 
 	retval = cam->ops->transferCmd(cam->lowlevel_data, cmd, data);
 	if (retval)
-		LOG("%x - failed\n", command);
+		DBG("%x - failed\n", command);
 
 	return retval;
 }
@@ -2174,7 +2176,7 @@
 		}
 		if (ll == 1) {
 			if (*ibuf != EOL) {
-				LOG("EOL not found giving up after %d/%d"
+				DBG("EOL not found giving up after %d/%d"
 				    " bytes\n", origsize-size, origsize);
 				return -1;
 			}
@@ -3158,7 +3160,8 @@
 
 static void put_cam(struct cpia_camera_ops* ops)
 {
-	module_put(ops->owner);
+	if (ops->owner)
+		module_put(ops->owner);
 }
 
 /* ------------------------- V4L interface --------------------- */
@@ -3173,16 +3176,15 @@
 		return -ENODEV;
 	}
 
+	if (cam->open_count > 0) {
+		DBG("Camera already open\n");
+		return -EBUSY;
+	}
+
 	if (!try_module_get(cam->ops->owner))
 		return -ENODEV;
 
 	down(&cam->busy_lock);
-	err = -EBUSY;
-	if (cam->open_count > 0) {
-		DBG("Camera already open\n");
-		goto oops;
-	}
-	
 	err = -ENOMEM;
 	if (!cam->raw_image) {
 		cam->raw_image = rvmalloc(CPIA_MAX_IMAGE_SIZE);
@@ -3206,10 +3208,11 @@
 		cam->ops->close(cam->lowlevel_data);
 		goto oops;
 	}
-
-	if(signal_pending(current))
-		return -EINTR;
 	
+	err = -EINTR;
+	if(signal_pending(current))
+		goto oops;
+
 	/* Set ownership of /proc/cpia/videoX to current user */
 	if(cam->proc_entry)
 		cam->proc_entry->uid = current->uid;
@@ -3451,6 +3454,14 @@
 			cam->params.colourParams.contrast = 80;
 		}
 
+		/* Adjust flicker control if necessary */
+		if(cam->params.flickerControl.allowableOverExposure < 0)
+			cam->params.flickerControl.allowableOverExposure = 
+				-find_over_exposure(cam->params.colourParams.brightness);
+		if(cam->params.flickerControl.flickerMode != 0)
+			cam->cmd_queue |= COMMAND_SETFLICKERCTRL;
+		
+
 		/* queue command to update camera */
 		cam->cmd_queue |= COMMAND_SETCOLOURPARAMS;
 		up(&cam->param_lock);
@@ -3600,7 +3611,7 @@
 	{
 		int *frame = arg;
 
-		//DBG("VIDIOCSYNC: %d\n", frame);
+		//DBG("VIDIOCSYNC: %d\n", *frame);
 
 		if (*frame<0 || *frame >= FRAME_NUM) {
 			retval = -EINVAL;
@@ -3628,52 +3639,53 @@
 	}
 
 	case VIDIOCGCAPTURE:
+	{
+		struct video_capture *vc = arg;
+
 		DBG("VIDIOCGCAPTURE\n");
-		if (copy_to_user(arg, &cam->vc, sizeof(struct video_capture)))
-			retval = -EFAULT;
+
+		*vc = cam->vc;
+
 		break;
+	}	
 
 	case VIDIOCSCAPTURE:
 	{
-		struct video_capture vc;
+		struct video_capture *vc = arg;
 
 		DBG("VIDIOCSCAPTURE\n");
-		if (copy_from_user(&vc, arg, sizeof(vc))) {
-			retval = -EFAULT;
-			break;
-		}
 
-		if (vc.decimation != 0) {    /* How should this be used? */
+		if (vc->decimation != 0) {    /* How should this be used? */
 			retval = -EINVAL;
 			break;
 		}
-		if (vc.flags != 0) {     /* Even/odd grab not supported */
+		if (vc->flags != 0) {     /* Even/odd grab not supported */
 			retval = -EINVAL;
 			break;
 		}
 		
 		/* Clip to the resolution we can set for the ROI
 		   (every 8 columns and 4 rows) */
-		vc.x      = vc.x      & ~(__u32)7;
-		vc.y      = vc.y      & ~(__u32)3;
-		vc.width  = vc.width  & ~(__u32)7;
-		vc.height = vc.height & ~(__u32)3;
-
-		if(vc.width == 0 || vc.height == 0 ||
-		   vc.x + vc.width  > cam->vw.width ||
-		   vc.y + vc.height > cam->vw.height) {
+		vc->x      = vc->x      & ~(__u32)7;
+		vc->y      = vc->y      & ~(__u32)3;
+		vc->width  = vc->width  & ~(__u32)7;
+		vc->height = vc->height & ~(__u32)3;
+
+		if(vc->width == 0 || vc->height == 0 ||
+		   vc->x + vc->width  > cam->vw.width ||
+		   vc->y + vc->height > cam->vw.height) {
 			retval = -EINVAL;
 			break;
 		}
 
-		DBG("%d,%d/%dx%d\n", vc.x,vc.y,vc.width, vc.height);
+		DBG("%d,%d/%dx%d\n", vc->x,vc->y,vc->width, vc->height);
 		
 		down(&cam->param_lock);
 		
-		cam->vc.x      = vc.x;
-		cam->vc.y      = vc.y;
-		cam->vc.width  = vc.width;
-		cam->vc.height = vc.height;
+		cam->vc.x      = vc->x;
+		cam->vc.y      = vc->y;
+		cam->vc.width  = vc->width;
+		cam->vc.height = vc->height;
 		
 		set_vw_size(cam);
 		cam->cmd_queue |= COMMAND_SETFORMAT;
@@ -3688,16 +3700,20 @@
 	
 	case VIDIOCGUNIT:
 	{
-		struct video_unit vu;
-		vu.video    = cam->vdev.minor;
-		vu.vbi      = VIDEO_NO_UNIT;
-		vu.radio    = VIDEO_NO_UNIT;
-		vu.audio    = VIDEO_NO_UNIT;
-		vu.teletext = VIDEO_NO_UNIT;
+		struct video_unit *vu = arg;
+
+		DBG("VIDIOCGUNIT\n");
+
+		vu->video    = cam->vdev.minor;
+		vu->vbi      = VIDEO_NO_UNIT;
+		vu->radio    = VIDEO_NO_UNIT;
+		vu->audio    = VIDEO_NO_UNIT;
+		vu->teletext = VIDEO_NO_UNIT;
+
 		break;
 	}
-		
 
+		
 	/* pointless to implement overlay with this camera */
 	case VIDIOCCAPTURE:
 	case VIDIOCGFBUF:
@@ -3728,12 +3744,13 @@
 	return video_usercopy(inode, file, cmd, arg, cpia_do_ioctl);
 }
 
+
 /* FIXME */
 static int cpia_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	struct video_device *dev = file->private_data;
 	unsigned long start = vma->vm_start;
-	unsigned long size  = vma->vm_end-vma->vm_start;
+	unsigned long size  = vma->vm_end - vma->vm_start;
 	unsigned long page, pos;
 	struct cam_data *cam = dev->priv;
 	int retval;
@@ -3956,9 +3973,6 @@
 		printk(KERN_DEBUG "video_register_device failed\n");
 		return NULL;
 	}
-#ifdef CONFIG_PROC_FS
-	create_proc_cpia_cam(camera);
-#endif
 
 	/* get version information from camera: open/reset/close */
 
@@ -3975,6 +3989,10 @@
 	/* close cpia */
 	camera->ops->close(camera->lowlevel_data);
 
+#ifdef CONFIG_PROC_FS
+	create_proc_cpia_cam(camera);
+#endif
+
 	printk(KERN_INFO "  CPiA Version: %d.%02d (%d.%d)\n",
 	       camera->params.version.firmwareVersion,
 	       camera->params.version.firmwareRevision,
@@ -3997,6 +4015,7 @@
 	DBG("unregistering video\n");
 	video_unregister_device(&cam->vdev);
 	if (cam->open_count) {
+		put_cam(cam->ops);
 		DBG("camera open -- setting ops to NULL\n");
 		cam->ops = NULL;
 	}
@@ -4019,9 +4038,6 @@
 	proc_cpia_create();
 #endif
 
-#ifdef CONFIG_VIDEO_CPIA_PP
-	cpia_pp_init();
-#endif
 #ifdef CONFIG_KMOD
 #ifdef CONFIG_VIDEO_CPIA_PP_MODULE
 	request_module("cpia_pp");
@@ -4031,6 +4047,10 @@
 	request_module("cpia_usb");
 #endif
 #endif	/* CONFIG_KMOD */
+
+#ifdef CONFIG_VIDEO_CPIA_PP
+	cpia_pp_init();
+#endif
 #ifdef CONFIG_VIDEO_CPIA_USB
 	cpia_usb_init();
 #endif
diff -Nru a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h
--- a/drivers/media/video/cpia.h	Thu Jan  2 23:55:26 2003
+++ b/drivers/media/video/cpia.h	Thu Mar  6 15:46:22 2003
@@ -27,12 +27,16 @@
  */
 
 #define CPIA_MAJ_VER	1
-#define CPIA_MIN_VER    2
-#define CPIA_PATCH_VER	2
+#define CPIA_MIN_VER   2
+#define CPIA_PATCH_VER	3
 
-#define CPIA_PP_MAJ_VER       1
-#define CPIA_PP_MIN_VER       2
-#define CPIA_PP_PATCH_VER     2
+#define CPIA_PP_MAJ_VER       CPIA_MAJ_VER
+#define CPIA_PP_MIN_VER       CPIA_MIN_VER
+#define CPIA_PP_PATCH_VER     CPIA_PATCH_VER
+
+#define CPIA_USB_MAJ_VER      CPIA_MAJ_VER
+#define CPIA_USB_MIN_VER      CPIA_MIN_VER
+#define CPIA_USB_PATCH_VER    CPIA_PATCH_VER
 
 #define CPIA_MAX_FRAME_SIZE_UNALIGNED	(352 * 288 * 4)   /* CIF at RGB32 */
 #define CPIA_MAX_FRAME_SIZE	((CPIA_MAX_FRAME_SIZE_UNALIGNED + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) /* align above to PAGE_SIZE */
diff -Nru a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
--- a/drivers/media/video/cpia_pp.c	Tue Jan 14 11:46:09 2003
+++ b/drivers/media/video/cpia_pp.c	Thu Mar  6 15:46:22 2003
@@ -22,6 +22,9 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
+/* #define _CPIA_DEBUG_  1 */  
+
 #include <linux/config.h>
 #include <linux/version.h>
 
@@ -34,6 +37,7 @@
 #include <linux/delay.h>
 #include <linux/workqueue.h>
 #include <linux/smp_lock.h>
+#include <linux/sched.h>
 
 #include <linux/kmod.h>
 
@@ -49,68 +53,10 @@
 static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock);
 static int cpia_pp_close(void *privdata);
 
-#define ABOUT "Parallel port driver for Vision CPiA based cameras"
 
-/* IEEE 1284 Compatiblity Mode signal names 	*/
-#define nStrobe		PARPORT_CONTROL_STROBE	  /* inverted */
-#define nAutoFd		PARPORT_CONTROL_AUTOFD	  /* inverted */
-#define nInit		PARPORT_CONTROL_INIT
-#define nSelectIn	PARPORT_CONTROL_SELECT
-#define IntrEnable	PARPORT_CONTROL_INTEN	  /* normally zero for no IRQ */
-#define DirBit		PARPORT_CONTROL_DIRECTION /* 0 = Forward, 1 = Reverse	*/
-
-#define nFault		PARPORT_STATUS_ERROR
-#define Select		PARPORT_STATUS_SELECT
-#define PError		PARPORT_STATUS_PAPEROUT
-#define nAck		PARPORT_STATUS_ACK
-#define Busy		PARPORT_STATUS_BUSY	  /* inverted */	
-
-/* some more */
-#define HostClk		nStrobe
-#define HostAck		nAutoFd
-#define nReverseRequest	nInit
-#define Active_1284	nSelectIn
-#define nPeriphRequest	nFault
-#define XFlag		Select
-#define nAckReverse	PError
-#define PeriphClk	nAck
-#define PeriphAck	Busy
-
-/* these can be used to correct for the inversion on some bits */
-#define STATUS_INVERSION_MASK	(Busy)
-#define CONTROL_INVERSION_MASK	(nStrobe|nAutoFd|nSelectIn)
-
-#define ECR_empty	0x01
-#define ECR_full	0x02
-#define ECR_serviceIntr 0x04
-#define ECR_dmaEn	0x08
-#define ECR_nErrIntrEn	0x10
-
-#define ECR_mode_mask	0xE0
-#define ECR_SPP_mode	0x00
-#define ECR_PS2_mode	0x20
-#define ECR_FIFO_mode	0x40
-#define ECR_ECP_mode	0x60
-
-#define ECP_FIFO_SIZE	16
-#define DMA_BUFFER_SIZE               PAGE_SIZE
-	/* for 16bit DMA make sure DMA_BUFFER_SIZE is 16 bit aligned */
-#define PARPORT_CHUNK_SIZE	PAGE_SIZE/* >=2.3.x */
-				/* we read this many bytes at once */
-
-#define GetECRMasked(port,mask)	(parport_read_econtrol(port) & (mask))
-#define GetStatus(port)		((parport_read_status(port)^STATUS_INVERSION_MASK)&(0xf8))
-#define SetStatus(port,val)	parport_write_status(port,(val)^STATUS_INVERSION_MASK)
-#define GetControl(port)	((parport_read_control(port)^CONTROL_INVERSION_MASK)&(0x3f))
-#define SetControl(port,val)	parport_write_control(port,(val)^CONTROL_INVERSION_MASK)
-
-#define GetStatusMasked(port,mask)	(GetStatus(port) & (mask))
-#define GetControlMasked(port,mask)	(GetControl(port) & (mask))
-#define SetControlMasked(port,mask)	SetControl(port,GetControl(port) | (mask));
-#define ClearControlMasked(port,mask)	SetControl(port,GetControl(port)&~(mask));
-#define FrobControlBit(port,mask,value)	SetControl(port,(GetControl(port)&~(mask))|((value)&(mask)));
+#define ABOUT "Parallel port driver for Vision CPiA based cameras"
 
-#define PACKET_LENGTH 	8
+#define PACKET_LENGTH  8
 
 /* Magic numbers for defining port-device mappings */
 #define PPCPIA_PARPORT_UNSPEC -4
@@ -162,30 +108,7 @@
 };
 
 static LIST_HEAD(cam_list);
-static spinlock_t cam_list_lock_pp = SPIN_LOCK_UNLOCKED;
-
-#ifdef _CPIA_DEBUG_
-#define DEB_PORT(port) { \
-u8 controll = GetControl(port); \
-u8 statusss = GetStatus(port); \
-DBG("nsel %c per %c naut %c nstrob %c nak %c busy %c nfaul %c sel %c init %c dir %c\n",\
-((controll & nSelectIn)	? 'U' : 'D'), \
-((statusss & PError)	? 'U' : 'D'), \
-((controll & nAutoFd)	? 'U' : 'D'), \
-((controll & nStrobe)	? 'U' : 'D'), \
-((statusss & nAck)	? 'U' : 'D'), \
-((statusss & Busy)	? 'U' : 'D'), \
-((statusss & nFault)	? 'U' : 'D'), \
-((statusss & Select)	? 'U' : 'D'), \
-((controll & nInit)	? 'U' : 'D'), \
-((controll & DirBit)	? 'R' : 'F')  \
-); }
-#else
-#define DEB_PORT(port) {}
-#endif
-
-#define WHILE_OUT_TIMEOUT (HZ/10)
-#define DMA_TIMEOUT 10*HZ
+static spinlock_t cam_list_lock_pp;
 
 /* FIXME */
 static void cpia_parport_enable_irq( struct parport *port ) {
@@ -200,6 +123,205 @@
 	return;
 }
 
+/* Special CPiA PPC modes: These are invoked by using the 1284 Extensibility
+ * Link Flag during negotiation */  
+#define UPLOAD_FLAG  0x08
+#define NIBBLE_TRANSFER 0x01
+#define ECP_TRANSFER 0x03
+
+#define PARPORT_CHUNK_SIZE	PAGE_SIZE
+
+
+/****************************************************************************
+ *
+ *  CPiA-specific  low-level parport functions for nibble uploads
+ *
+ ***************************************************************************/
+/*  CPiA nonstandard "Nibble" mode (no nDataAvail signal after each byte). */
+/* The standard kernel parport_ieee1284_read_nibble() fails with the CPiA... */
+
+static size_t cpia_read_nibble (struct parport *port, 
+			 void *buffer, size_t len, 
+			 int flags)
+{
+	/* adapted verbatim, with one change, from 
+	   parport_ieee1284_read_nibble() in drivers/parport/ieee1284-ops.c */
+
+	unsigned char *buf = buffer;
+	int i;
+	unsigned char byte = 0;
+	
+	len *= 2; /* in nibbles */
+	for (i=0; i < len; i++) {
+		unsigned char nibble;
+
+		/* The CPiA firmware suppresses the use of nDataAvail (nFault LO)
+		 * after every second nibble to signal that more
+		 * data is available.  (the total number of Bytes that
+		 * should be sent is known; if too few are received, an error
+		 * will be recorded after a timeout).  
+		 * This is incompatible with parport_ieee1284_read_nibble(),
+		 * which expects to find nFault LO after every second nibble.
+		 */
+
+		/* Solution: modify cpia_read_nibble to only check for 
+		 * nDataAvail before the first nibble is sent.
+		 */
+
+		/* Does the error line indicate end of data? */
+		if (((i /*& 1*/) == 0) &&
+		    (parport_read_status(port) & PARPORT_STATUS_ERROR)) {
+			port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
+				DBG("%s: No more nibble data (%d bytes)\n",
+				port->name, i/2);
+
+			/* Go to reverse idle phase. */
+			parport_frob_control (port,
+					      PARPORT_CONTROL_AUTOFD,
+					      PARPORT_CONTROL_AUTOFD);
+			port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
+			break;
+		}
+
+		/* Event 7: Set nAutoFd low. */
+		parport_frob_control (port,
+				      PARPORT_CONTROL_AUTOFD,
+				      PARPORT_CONTROL_AUTOFD);
+
+		/* Event 9: nAck goes low. */
+		port->ieee1284.phase = IEEE1284_PH_REV_DATA;
+		if (parport_wait_peripheral (port,
+					     PARPORT_STATUS_ACK, 0)) {
+			/* Timeout -- no more data? */
+				 DBG("%s: Nibble timeout at event 9 (%d bytes)\n",
+				 port->name, i/2);
+			parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
+			break;
+		}
+
+
+		/* Read a nibble. */
+		nibble = parport_read_status (port) >> 3;
+		nibble &= ~8;
+		if ((nibble & 0x10) == 0)
+			nibble |= 8;
+		nibble &= 0xf;
+
+		/* Event 10: Set nAutoFd high. */
+		parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
+
+		/* Event 11: nAck goes high. */
+		if (parport_wait_peripheral (port,
+					     PARPORT_STATUS_ACK,
+					     PARPORT_STATUS_ACK)) {
+			/* Timeout -- no more data? */
+			DBG("%s: Nibble timeout at event 11\n",
+				 port->name);
+			break;
+		}
+
+		if (i & 1) {
+			/* Second nibble */
+			byte |= nibble << 4;
+			*buf++ = byte;
+		} else 
+			byte = nibble;
+	}
+
+	i /= 2; /* i is now in bytes */
+
+	if (i == len) {
+		/* Read the last nibble without checking data avail. */
+		port = port->physport;
+		if (parport_read_status (port) & PARPORT_STATUS_ERROR)
+			port->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
+		else
+			port->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
+	}
+
+	return i;
+}
+
+/* CPiA nonstandard "Nibble Stream" mode (2 nibbles per cycle, instead of 1)
+ * (See CPiA Data sheet p. 31) 
+ * 
+ * "Nibble Stream" mode used by CPiA for uploads to non-ECP ports is a 
+ * nonstandard variant of nibble mode which allows the same (mediocre) 
+ * data flow of 8 bits per cycle as software-enabled ECP by TRISTATE-capable 
+ * parallel ports, but works also for  non-TRISTATE-capable ports.
+ * (Standard nibble mode only send 4 bits per cycle)
+ *
+ */
+
+static size_t cpia_read_nibble_stream(struct parport *port, 
+			       void *buffer, size_t len, 
+			       int flags)
+{
+	int i;
+	unsigned char *buf = buffer;
+	int endseen = 0;
+
+	for (i=0; i < len; i++) {
+		unsigned char nibble[2], byte = 0;
+		int j;
+
+		/* Image Data is complete when 4 consecutive EOI bytes (0xff) are seen */ 
+		if (endseen > 3 )
+			break;
+
+		/* Event 7: Set nAutoFd low. */
+		parport_frob_control (port,
+				      PARPORT_CONTROL_AUTOFD,
+				      PARPORT_CONTROL_AUTOFD);
+		
+		/* Event 9: nAck goes low. */
+		port->ieee1284.phase = IEEE1284_PH_REV_DATA;
+		if (parport_wait_peripheral (port,
+					     PARPORT_STATUS_ACK, 0)) {
+			/* Timeout -- no more data? */
+				 DBG("%s: Nibble timeout at event 9 (%d bytes)\n",
+				 port->name, i/2);
+			parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
+			break;
+		}
+
+		/* Read lower nibble */
+		nibble[0] = parport_read_status (port) >>3;
+		
+		/* Event 10: Set nAutoFd high. */
+		parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
+
+		/* Event 11: nAck goes high. */
+		if (parport_wait_peripheral (port,
+					     PARPORT_STATUS_ACK,
+					     PARPORT_STATUS_ACK)) {
+			/* Timeout -- no more data? */
+			DBG("%s: Nibble timeout at event 11\n",
+				 port->name);
+			break;
+		}
+		
+		/* Read upper nibble */
+		nibble[1] = parport_read_status (port) >>3;
+		
+		/* reassemble the byte */
+		for (j = 0; j < 2 ; j++ ) {
+			nibble[j] &= ~8;
+			if ((nibble[j] & 0x10) == 0)
+				nibble[j] |= 8;
+			nibble[j] &= 0xf;
+		}
+		byte = (nibble[0] |(nibble[1] << 4));
+		*buf++ = byte;
+
+		if(byte == EOI)
+		  endseen++;
+		else
+		  endseen = 0;
+	}
+	return i;
+}
+
 /****************************************************************************
  *
  *  EndTransferMode
@@ -219,20 +341,25 @@
 {
 	int retry;
 	
-	/* After some commands the camera needs extra time before
-	 * it will respond again, so we try up to 3 times */
-	for(retry=0; retry<3; ++retry) {
+	/* The CPiA uses ECP protocol for Downloads from the Host to the camera. 
+	 * This will be software-emulated if ECP hardware is not present
+	 */
+
+	/* the usual camera maximum response time is 10ms, but after receiving
+	 * some commands, it needs up to 40ms. (Data Sheet p. 32)*/
+
+	for(retry = 0; retry < 4; ++retry) {
 		if(!parport_negotiate(cam->port, IEEE1284_MODE_ECP)) {
 			break;
 		}
+		mdelay(10);
 	}
-	if(retry == 3) {
-		DBG("Unable to negotiate ECP mode\n");
+	if(retry == 4) {
+		DBG("Unable to negotiate IEEE1284 ECP Download mode\n");
 		return -1;
 	}
 	return 0;
 }
-
 /****************************************************************************
  *
  *  ReverseSetup
@@ -241,24 +368,35 @@
 static int ReverseSetup(struct pp_cam_entry *cam, int extensibility)
 {
 	int retry;
-	int mode = IEEE1284_MODE_ECP;
-	if(extensibility) mode = 8|3|IEEE1284_EXT_LINK;
+	int upload_mode, mode = IEEE1284_MODE_ECP;
+	int transfer_mode = ECP_TRANSFER;
+
+	if (!(cam->port->modes & PARPORT_MODE_ECP) &&
+	     !(cam->port->modes & PARPORT_MODE_TRISTATE)) {
+		mode = IEEE1284_MODE_NIBBLE;
+		transfer_mode = NIBBLE_TRANSFER;
+	}
 
-	/* After some commands the camera needs extra time before
-	 * it will respond again, so we try up to 3 times */
-	for(retry=0; retry<3; ++retry) {
+	upload_mode = mode;
+	if(extensibility) mode = UPLOAD_FLAG|transfer_mode|IEEE1284_EXT_LINK;
+
+	/* the usual camera maximum response time is 10ms, but after 
+	 * receiving some commands, it needs up to 40ms. */
+		
+	for(retry = 0; retry < 4; ++retry) {
 		if(!parport_negotiate(cam->port, mode)) {
 			break;
 		}
+		mdelay(10);
 	}
-	if(retry == 3) {
+	if(retry == 4) {
 		if(extensibility)
-			DBG("Unable to negotiate extensibility mode\n");
+			DBG("Unable to negotiate upload extensibility mode\n");
 		else
-			DBG("Unable to negotiate ECP mode\n");
+			DBG("Unable to negotiate upload mode\n");
 		return -1;
 	}
-	if(extensibility) cam->port->ieee1284.mode = IEEE1284_MODE_ECP;
+	if(extensibility) cam->port->ieee1284.mode = upload_mode;
 	return 0;
 }
 
@@ -296,14 +434,21 @@
 static int ReadPacket(struct pp_cam_entry *cam, u8 *packet, size_t size)
 {
 	int retval=0;
+
 	if (packet == NULL) {
 		return -EINVAL;
 	}
 	if (ReverseSetup(cam, 0)) {
 		return -EIO;
 	}
-	if(parport_read(cam->port, packet, size) != size) {
-		retval = -EIO;
+
+	/* support for CPiA variant nibble reads */
+	if(cam->port->ieee1284.mode == IEEE1284_MODE_NIBBLE) {
+		if(cpia_read_nibble(cam->port, packet, size, 0) != size) 
+			retval = -EIO;			
+	} else {
+		if(parport_read(cam->port, packet, size) != size) 
+			retval = -EIO;
 	}
 	EndTransferMode(cam);
 	return retval;
@@ -347,11 +492,29 @@
  *  cpia_pp_streamRead
  *
  ***************************************************************************/
+static int cpia_pp_read(struct parport *port, u8 *buffer, int len)
+{
+	int bytes_read;
+
+	/* support for CPiA variant "nibble stream" reads */
+	if(port->ieee1284.mode == IEEE1284_MODE_NIBBLE)
+		bytes_read = cpia_read_nibble_stream(port,buffer,len,0);
+	else {
+		int new_bytes;
+		for(bytes_read=0; bytes_read<len; bytes_read += new_bytes) {
+			new_bytes = parport_read(port, buffer+bytes_read,
+						 len-bytes_read);
+			if(new_bytes < 0) break;
+		}
+	}
+	return bytes_read;
+}
+
 static int cpia_pp_streamRead(void *privdata, u8 *buffer, int noblock)
 {
 	struct pp_cam_entry *cam = privdata;
 	int read_bytes = 0;
-	int i, endseen;
+	int i, endseen, block_size, new_bytes;
 
 	if(cam == NULL) {
 		DBG("Internal driver error: cam is NULL\n");
@@ -380,27 +543,36 @@
 			return -EIO;
 		}
 	}
-	read_bytes = parport_read(cam->port, buffer, CPIA_MAX_IMAGE_SIZE );
-
-	EndTransferMode(cam);
-	DBG("read %d bytes\n", read_bytes);
-	if( read_bytes<0) return -EIO;
 	endseen = 0;
-	for( i=0; i<read_bytes && endseen<4; i++ ) {
-	  if( *buffer==EOI ) {
-	    endseen++;
-	  } else {
-	    endseen=0;
-	  }
-	  buffer++;
-	}
-	if( endseen>3 ) {
-	  cam->image_complete=1;
-	  DBG("endseen at %d bytes\n", i);
- 	}
+	block_size = PARPORT_CHUNK_SIZE;
+	while( !cam->image_complete ) {
+		cond_resched();
+		
+		new_bytes = cpia_pp_read(cam->port, buffer, block_size );
+		if( new_bytes <= 0 ) {
+			break;
+		}
+		i=-1;
+		while(++i<new_bytes && endseen<4) {
+	        	if(*buffer==EOI) {
+	                	endseen++;
+	                } else {
+	                	endseen=0;
+	                }
+			buffer++;
+		}
+		read_bytes += i;
+		if( endseen==4 ) {
+			cam->image_complete=1;
+			break;
+		}
+		if( CPIA_MAX_IMAGE_SIZE-read_bytes <= PARPORT_CHUNK_SIZE ) {
+			block_size=CPIA_MAX_IMAGE_SIZE-read_bytes;
+		}
+	}
+	EndTransferMode(cam);
 	return cam->image_complete ? read_bytes : -EIO;
 }
-
 /****************************************************************************
  *
  *  cpia_pp_transferCmd
@@ -530,9 +702,8 @@
 	struct pp_cam_entry *cam;
 	struct cam_data *cpia;
 
-	if (!(port->modes & PARPORT_MODE_ECP) &&
-	    !(port->modes & PARPORT_MODE_TRISTATE)) {
-		LOG("port is not ECP capable\n");
+	if (!(port->modes & PARPORT_MODE_PCSPP)) {
+		LOG("port is not supported by CPiA driver\n");
 		return -ENXIO;
 	}
 
@@ -575,29 +746,33 @@
 static void cpia_pp_detach (struct parport *port)
 {
 	struct list_head *tmp;
-	struct cam_data *cpia;
+	struct cam_data *cpia = NULL;
 	struct pp_cam_entry *cam;
 
 	spin_lock( &cam_list_lock_pp );
 	list_for_each (tmp, &cam_list) {
 		cpia = list_entry(tmp, struct cam_data, cam_data_list);
-		cam = cpia->lowlevel_data;
+		cam = (struct pp_cam_entry *) cpia->lowlevel_data;
 		if (cam && cam->port->number == port->number) {
 			list_del(&cpia->cam_data_list);
-			cpia_unregister_camera(cpia);
-			
-			if(cam->open_count > 0) {
-				cpia_pp_close(cam);
-			}
-
-			parport_unregister_device(cam->pdev);
-		
-			kfree(cam);
-			cpia->lowlevel_data = NULL;
 			break;
 		}
+		cpia = NULL;
 	}
 	spin_unlock( &cam_list_lock_pp );			
+
+	if (!cpia) {
+		DBG("cpia_pp_detach failed to find cam_data in cam_list\n");
+		return;
+	}
+	
+	cam = (struct pp_cam_entry *) cpia->lowlevel_data;	
+	cpia_unregister_camera(cpia);
+	if(cam->open_count > 0) 
+		cpia_pp_close(cam);
+	parport_unregister_device(cam->pdev);
+	cpia->lowlevel_data = NULL;	
+	kfree(cam);
 }
 
 static void cpia_pp_attach (struct parport *port)
@@ -645,11 +820,12 @@
 		return 0;
 	}
 	
+	spin_lock_init( &cam_list_lock_pp );
+
 	if (parport_register_driver (&cpia_pp_driver)) {
 		LOG ("unable to register with parport\n");
 		return -EIO;
 	}
-	
 	return 0;
 }
 
diff -Nru a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c
--- a/drivers/media/video/cpia_usb.c	Thu Jan  2 23:58:48 2003
+++ b/drivers/media/video/cpia_usb.c	Thu Mar  6 15:46:22 2003
@@ -21,11 +21,13 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+/* define _CPIA_DEBUG_ for verbose debug output (see cpia.h) */
+/* #define _CPIA_DEBUG_  1 */  
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/wait.h>
-#include <linux/sched.h>
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
@@ -105,7 +107,7 @@
 };
 
 static LIST_HEAD(cam_list);
-static spinlock_t cam_list_lock_usb = SPIN_LOCK_UNLOCKED;
+static spinlock_t cam_list_lock_usb;
 
 static void cpia_usb_complete(struct urb *urb, struct pt_regs *regs)
 {
@@ -464,12 +466,14 @@
 {
 	struct usb_cpia *ucpia = (struct usb_cpia *) privdata;
 
-	ucpia->open = 0;
+	if(!ucpia)
+		return -ENODEV;
 
-	cpia_usb_free_resources(ucpia, 1);
+	ucpia->open = 0;
 
-	if (!ucpia->present)
-		kfree(ucpia);
+	/* ucpia->present = 0 protects against trying to reset the
+	 * alt setting if camera is physically disconnected while open */
+	cpia_usb_free_resources(ucpia, ucpia->present);
 
 	return 0;
 }
@@ -565,7 +569,7 @@
 	vfree(ucpia->buffers[0]);
 	ucpia->buffers[0] = NULL;
 fail_alloc_0:
-
+	kfree(ucpia);
 	return -EIO;
 }
 
@@ -588,9 +592,6 @@
 	.id_table	= cpia_id_table,
 };
 
-/* don't use dev, it may be NULL! (see usb_cpia_cleanup) */
-/* _disconnect from usb_cpia_cleanup is not necessary since usb_deregister */
-/* will do it for us as well as passing a udev structure - jerdfelt */
 static void cpia_disconnect(struct usb_interface *intf)
 {
 	struct cam_data *cam = usb_get_intfdata(intf);
@@ -606,12 +607,11 @@
 	list_del(&cam->cam_data_list);
 	spin_unlock( &cam_list_lock_usb );
 	
-	/* Don't even try to reset the altsetting if we're disconnected */
-	cpia_usb_free_resources(ucpia, 0);
-
 	ucpia->present = 0;
 
 	cpia_unregister_camera(cam);
+	if(ucpia->open)
+		cpia_usb_close(cam->lowlevel_data);
 
 	ucpia->curbuff->status = FRAME_ERROR;
 
@@ -639,29 +639,25 @@
 		ucpia->buffers[0] = NULL;
 	}
 
-	if (!ucpia->open) {
- 		kfree(ucpia);
-		cam->lowlevel_data = NULL;
-	}
+	cam->lowlevel_data = NULL;
+	kfree(ucpia);
 }
 
 static int __init usb_cpia_init(void)
 {
+	printk(KERN_INFO "%s v%d.%d.%d\n",ABOUT, 
+	       CPIA_USB_MAJ_VER,CPIA_USB_MIN_VER,CPIA_USB_PATCH_VER);
+
+	spin_lock_init(&cam_list_lock_usb);
 	return usb_register(&cpia_driver);
 }
 
 static void __exit usb_cpia_cleanup(void)
 {
-/*
-	struct cam_data *cam;
-
-	while ((cam = cam_list) != NULL)
-		cpia_disconnect(NULL, cam);
-*/
-
 	usb_deregister(&cpia_driver);
 }
 
 
 module_init (usb_cpia_init);
 module_exit (usb_cpia_cleanup);
+
diff -Nru a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
--- a/drivers/media/video/saa7134/saa7134-i2c.c	Wed Mar 12 06:07:06 2003
+++ b/drivers/media/video/saa7134/saa7134-i2c.c	Tue Mar 18 09:00:14 2003
@@ -19,8 +19,6 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define __NO_VERSION__ 1
-
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
diff -Nru a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
--- a/drivers/media/video/saa7134/saa7134-oss.c	Wed Jan  8 01:59:59 2003
+++ b/drivers/media/video/saa7134/saa7134-oss.c	Thu Mar 13 16:52:15 2003
@@ -19,8 +19,6 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define __NO_VERSION__ 1
-
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
diff -Nru a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
--- a/drivers/media/video/saa7134/saa7134-ts.c	Wed Jan  8 01:59:59 2003
+++ b/drivers/media/video/saa7134/saa7134-ts.c	Thu Mar 13 16:52:15 2003
@@ -19,8 +19,6 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define __NO_VERSION__ 1
-
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
diff -Nru a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c	Tue Feb 11 14:57:51 2003
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c	Thu Mar 13 16:52:15 2003
@@ -19,8 +19,6 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define __NO_VERSION__ 1
-
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
diff -Nru a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
--- a/drivers/media/video/saa7134/saa7134-vbi.c	Wed Jan  8 01:59:59 2003
+++ b/drivers/media/video/saa7134/saa7134-vbi.c	Thu Mar 13 16:52:15 2003
@@ -19,8 +19,6 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define __NO_VERSION__ 1
-
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
diff -Nru a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
--- a/drivers/media/video/saa7134/saa7134-video.c	Wed Mar 12 06:07:06 2003
+++ b/drivers/media/video/saa7134/saa7134-video.c	Tue Mar 18 09:00:14 2003
@@ -19,8 +19,6 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define __NO_VERSION__ 1
-
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
diff -Nru a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
--- a/drivers/media/video/w9966.c	Sat Nov 30 09:28:18 2002
+++ b/drivers/media/video/w9966.c	Thu Mar  6 13:58:28 2003
@@ -742,7 +742,7 @@
 	case VIDIOCGTUNER:
 	{
 		struct video_tuner *vtune = arg;
-		if(vtune->tuner != 0);
+		if(vtune->tuner != 0)
 			return -EINVAL;
 		strcpy(vtune->name, "no tuner");
 		vtune->rangelow = 0;
diff -Nru a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
--- a/drivers/message/fusion/mptctl.c	Fri Feb 21 06:26:38 2003
+++ b/drivers/message/fusion/mptctl.c	Sat Mar 22 22:14:58 2003
@@ -2743,7 +2743,8 @@
 						      unsigned long,
 						      struct file *));
 int unregister_ioctl32_conversion(unsigned int cmd);
-extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
+extern asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd,
+				 unsigned long arg);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /* sparc32_XXX functions are used to provide a conversion between
diff -Nru a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig
--- a/drivers/message/i2o/Kconfig	Fri Feb 14 11:11:23 2003
+++ b/drivers/message/i2o/Kconfig	Thu Mar 20 10:44:46 2003
@@ -3,6 +3,7 @@
 
 config I2O
 	tristate "I2O support"
+	depends on PCI
 	---help---
 	  The Intelligent Input/Output (I2O) architecture allows hardware
 	  drivers to be split into two parts: an operating system specific
diff -Nru a/drivers/message/i2o/Makefile b/drivers/message/i2o/Makefile
--- a/drivers/message/i2o/Makefile	Fri Feb 14 11:11:44 2003
+++ b/drivers/message/i2o/Makefile	Thu Mar 13 12:40:07 2003
@@ -5,7 +5,6 @@
 # In the future, some of these should be built conditionally.
 #
 
-obj-$(CONFIG_I2O_PCI)	+= i2o_pci.o
 obj-$(CONFIG_I2O)	+= i2o_core.o i2o_config.o
 obj-$(CONFIG_I2O_BLOCK)	+= i2o_block.o
 obj-$(CONFIG_I2O_SCSI)	+= i2o_scsi.o
diff -Nru a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
--- a/drivers/message/i2o/i2o_block.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/message/i2o/i2o_block.c	Tue Mar 18 09:00:38 2003
@@ -754,7 +754,7 @@
 				 * hit the fan big time. The card seems to recover but loses
 				 * the pending writes. Deeply ungood except for testing fsck
 				 */
-				if(i2ob_dev[unit].i2odev->controller->bus.pci.promise)
+				if(i2ob_dev[unit].i2odev->controller->promise)
 					panic("I2O controller firmware failed. Reboot and force a filesystem check.\n");
 			default:
 				printk(KERN_INFO "%s: Received event 0x%X we didn't register for\n"
@@ -1140,10 +1140,10 @@
 		if(d->controller->battery == 0)
 			i2ob_dev[i].wcache = CACHE_WRITETHROUGH;
 
-		if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.promise)
+		if(d->controller->promise)
 			i2ob_dev[i].wcache = CACHE_WRITETHROUGH;
 
-		if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.short_req)
+		if(d->controller->short_req)
 		{
 			blk_queue_max_sectors(q, 8);
 			blk_queue_max_phys_segments(q, 8);
diff -Nru a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
--- a/drivers/message/i2o/i2o_config.c	Wed Feb 19 12:18:31 2003
+++ b/drivers/message/i2o/i2o_config.c	Sat Mar 22 12:41:45 2003
@@ -437,7 +437,7 @@
 	put_user(len, kcmd.reslen);
 	if(len > reslen)
 		ret = -ENOBUFS;
-	else if(copy_to_user(cmd->resbuf, res, len))
+	else if(copy_to_user(kcmd.resbuf, res, len))
 		ret = -EFAULT;
 
 	kfree(res);
diff -Nru a/drivers/message/i2o/i2o_core.c b/drivers/message/i2o/i2o_core.c
--- a/drivers/message/i2o/i2o_core.c	Tue Feb 25 10:47:06 2003
+++ b/drivers/message/i2o/i2o_core.c	Thu Mar 13 12:42:11 2003
@@ -50,6 +50,9 @@
 
 #include <asm/io.h>
 #include <linux/reboot.h>
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif // CONFIG_MTRR
 
 #include "i2o_lan.h"
 
@@ -103,6 +106,8 @@
 
 void i2o_report_controller_unit(struct i2o_controller *, struct i2o_device *);
 
+static void i2o_pci_dispose(struct i2o_controller *c);
+
 /*
  * I2O System Table.  Contains information about
  * all the IOPs in the system.  Used to inform IOPs
@@ -206,7 +211,6 @@
  */
 
 static int verbose;
-MODULE_PARM(verbose, "i");
 
 /*
  * I2O Core reply handler
@@ -549,7 +553,8 @@
 		if(__i2o_delete_device(c->devices)<0)
 		{
 			/* Shouldnt happen */
-			c->bus_disable(c);
+			I2O_IRQ_WRITE32(c, 0xFFFFFFFF);
+			c->enabled = 0;
 			up(&i2o_configuration_lock);
 			return -EBUSY;
 		}
@@ -584,7 +589,7 @@
 			i2o_reset_controller(c);
 
 			/* Release IRQ */
-			c->destructor(c);
+			i2o_pci_dispose(c);
 
 			*p=c->next;
 			up(&i2o_configuration_lock);
@@ -1651,7 +1656,7 @@
 
 	for (iop = i2o_controller_chain; iop; iop = iop->next)
 	{
-		if(iop->type != I2O_TYPE_PCI || !iop->bus.pci.dpt)
+		if(!iop->dpt)
 			i2o_quiesce_controller(iop);
 	}
 
@@ -1911,65 +1916,62 @@
 	u32 msg[12];
 	dma_addr_t sys_tbl_phys;
 	int ret;
+	struct resource *root;
 	u32 *privbuf = kmalloc(16, GFP_KERNEL);
 	if(privbuf == NULL)
 		return -ENOMEM;
 	
-	if(iop->type == I2O_TYPE_PCI)
-	{
-		struct resource *root;
 		
-		if(iop->status_block->current_mem_size < iop->status_block->desired_mem_size)
-		{
-			struct resource *res = &iop->mem_resource;
-			res->name = iop->pdev->bus->name;
-			res->flags = IORESOURCE_MEM;
-			res->start = 0;
-			res->end = 0;
-			printk("%s: requires private memory resources.\n", iop->name);
-			root = pci_find_parent_resource(iop->pdev, res);
-			if(root==NULL)
-				printk("Can't find parent resource!\n");
-			if(root && allocate_resource(root, res, 
-					iop->status_block->desired_mem_size,
-					iop->status_block->desired_mem_size,
-					iop->status_block->desired_mem_size,
-					1<<20,	/* Unspecified, so use 1Mb and play safe */
-					NULL,
-					NULL)>=0)
-			{
-				iop->mem_alloc = 1;
-				iop->status_block->current_mem_size = 1 + res->end - res->start;
-				iop->status_block->current_mem_base = res->start;
-				printk(KERN_INFO "%s: allocated %ld bytes of PCI memory at 0x%08lX.\n", 
-					iop->name, 1+res->end-res->start, res->start);
-			}
-		}
-		if(iop->status_block->current_io_size < iop->status_block->desired_io_size)
-		{
-			struct resource *res = &iop->io_resource;
-			res->name = iop->pdev->bus->name;
-			res->flags = IORESOURCE_IO;
-			res->start = 0;
-			res->end = 0;
-			printk("%s: requires private memory resources.\n", iop->name);
-			root = pci_find_parent_resource(iop->pdev, res);
-			if(root==NULL)
-				printk("Can't find parent resource!\n");
-			if(root &&  allocate_resource(root, res, 
-					iop->status_block->desired_io_size,
-					iop->status_block->desired_io_size,
-					iop->status_block->desired_io_size,
-					1<<20,	/* Unspecified, so use 1Mb and play safe */
-					NULL,
-					NULL)>=0)
-			{
-				iop->io_alloc = 1;
-				iop->status_block->current_io_size = 1 + res->end - res->start;
-				iop->status_block->current_mem_base = res->start;
-				printk(KERN_INFO "%s: allocated %ld bytes of PCI I/O at 0x%08lX.\n", 
-					iop->name, 1+res->end-res->start, res->start);
-			}
+	if(iop->status_block->current_mem_size < iop->status_block->desired_mem_size)
+	{
+		struct resource *res = &iop->mem_resource;
+		res->name = iop->pdev->bus->name;
+		res->flags = IORESOURCE_MEM;
+		res->start = 0;
+		res->end = 0;
+		printk("%s: requires private memory resources.\n", iop->name);
+		root = pci_find_parent_resource(iop->pdev, res);
+		if(root==NULL)
+			printk("Can't find parent resource!\n");
+		if(root && allocate_resource(root, res, 
+				iop->status_block->desired_mem_size,
+				iop->status_block->desired_mem_size,
+				iop->status_block->desired_mem_size,
+				1<<20,	/* Unspecified, so use 1Mb and play safe */
+				NULL,
+				NULL)>=0)
+		{
+			iop->mem_alloc = 1;
+			iop->status_block->current_mem_size = 1 + res->end - res->start;
+			iop->status_block->current_mem_base = res->start;
+			printk(KERN_INFO "%s: allocated %ld bytes of PCI memory at 0x%08lX.\n", 
+				iop->name, 1+res->end-res->start, res->start);
+		}
+	}
+	if(iop->status_block->current_io_size < iop->status_block->desired_io_size)
+	{
+		struct resource *res = &iop->io_resource;
+		res->name = iop->pdev->bus->name;
+		res->flags = IORESOURCE_IO;
+		res->start = 0;
+		res->end = 0;
+		printk("%s: requires private memory resources.\n", iop->name);
+		root = pci_find_parent_resource(iop->pdev, res);
+		if(root==NULL)
+			printk("Can't find parent resource!\n");
+		if(root &&  allocate_resource(root, res, 
+				iop->status_block->desired_io_size,
+				iop->status_block->desired_io_size,
+				iop->status_block->desired_io_size,
+				1<<20,	/* Unspecified, so use 1Mb and play safe */
+				NULL,
+				NULL)>=0)
+		{
+			iop->io_alloc = 1;
+			iop->status_block->current_io_size = 1 + res->end - res->start;
+			iop->status_block->current_mem_base = res->start;
+			printk(KERN_INFO "%s: allocated %ld bytes of PCI I/O at 0x%08lX.\n", 
+				iop->name, 1+res->end-res->start, res->start);
 		}
 	}
 	else
@@ -3427,48 +3429,256 @@
 }
 
 
-EXPORT_SYMBOL(i2o_controller_chain);
-EXPORT_SYMBOL(i2o_num_controllers);
-EXPORT_SYMBOL(i2o_find_controller);
-EXPORT_SYMBOL(i2o_unlock_controller);
-EXPORT_SYMBOL(i2o_status_get);
 
-EXPORT_SYMBOL(i2o_install_handler);
-EXPORT_SYMBOL(i2o_remove_handler);
 
-EXPORT_SYMBOL(i2o_install_controller);
-EXPORT_SYMBOL(i2o_delete_controller);
-EXPORT_SYMBOL(i2o_run_queue);
+/**
+ *	i2o_pci_dispose		-	Free bus specific resources
+ *	@c: I2O controller
+ *
+ *	Disable interrupts and then free interrupt, I/O and mtrr resources 
+ *	used by this controller. Called by the I2O core on unload.
+ */
+ 
+static void i2o_pci_dispose(struct i2o_controller *c)
+{
+	I2O_IRQ_WRITE32(c,0xFFFFFFFF);
+	if(c->irq > 0)
+		free_irq(c->irq, c);
+	iounmap(((u8 *)c->post_port)-0x40);
 
-EXPORT_SYMBOL(i2o_claim_device);
-EXPORT_SYMBOL(i2o_release_device);
-EXPORT_SYMBOL(i2o_device_notify_on);
-EXPORT_SYMBOL(i2o_device_notify_off);
+#ifdef CONFIG_MTRR
+	if(c->mtrr_reg0 > 0)
+		mtrr_del(c->mtrr_reg0, 0, 0);
+	if(c->mtrr_reg1 > 0)
+		mtrr_del(c->mtrr_reg1, 0, 0);
+#endif
+}
 
-EXPORT_SYMBOL(i2o_post_this);
-EXPORT_SYMBOL(i2o_post_wait);
-EXPORT_SYMBOL(i2o_post_wait_mem);
+/**
+ *	i2o_pci_interrupt	-	Bus specific interrupt handler
+ *	@irq: interrupt line
+ *	@dev_id: cookie
+ *
+ *	Handle an interrupt from a PCI based I2O controller. This turns out
+ *	to be rather simple. We keep the controller pointer in the cookie.
+ */
+ 
+static void i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r)
+{
+	struct i2o_controller *c = dev_id;
+	i2o_run_queue(c);
+}	
 
-EXPORT_SYMBOL(i2o_query_scalar);
-EXPORT_SYMBOL(i2o_set_scalar);
-EXPORT_SYMBOL(i2o_query_table);
-EXPORT_SYMBOL(i2o_clear_table);
-EXPORT_SYMBOL(i2o_row_add_table);
-EXPORT_SYMBOL(i2o_issue_params);
+/**
+ *	i2o_pci_install		-	Install a PCI i2o controller
+ *	@dev: PCI device of the I2O controller
+ *
+ *	Install a PCI (or in theory AGP) i2o controller. Devices are
+ *	initialized, configured and registered with the i2o core subsystem. Be
+ *	very careful with ordering. There may be pending interrupts.
+ *
+ *	To Do: Add support for polled controllers
+ */
 
-EXPORT_SYMBOL(i2o_event_register);
-EXPORT_SYMBOL(i2o_event_ack);
+int __init i2o_pci_install(struct pci_dev *dev)
+{
+	struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller),
+						GFP_KERNEL);
+	unsigned long mem;
+	u32 memptr = 0;
+	u32 size;
+	
+	int i;
 
-EXPORT_SYMBOL(i2o_report_status);
-EXPORT_SYMBOL(i2o_dump_message);
+	if(c==NULL)
+	{
+		printk(KERN_ERR "i2o: Insufficient memory to add controller.\n");
+		return -ENOMEM;
+	}
+	memset(c, 0, sizeof(*c));
 
-EXPORT_SYMBOL(i2o_get_class_name);
+	for(i=0; i<6; i++)
+	{
+		/* Skip I/O spaces */
+		if(!(pci_resource_flags(dev, i) & IORESOURCE_IO))
+		{
+			memptr = pci_resource_start(dev, i);
+			break;
+		}
+	}
+	
+	if(i==6)
+	{
+		printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n");
+		kfree(c);
+		return -EINVAL;
+	}
+	
+	size = dev->resource[i].end-dev->resource[i].start+1;	
+	/* Map the I2O controller */
+	
+	printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size);
+	mem = (unsigned long)ioremap(memptr, size);
+	if(mem==0)
+	{
+		printk(KERN_ERR "i2o: Unable to map controller.\n");
+		kfree(c);
+		return -EINVAL;
+	}
 
-EXPORT_SYMBOL_GPL(i2o_sys_init);
+	c->irq = -1;
+	c->dpt = 0;
+	c->short_req = 0;
+	c->pdev = dev;
+
+	c->irq_mask = mem+0x34;
+	c->post_port = mem+0x40;
+	c->reply_port = mem+0x44;
 
-MODULE_AUTHOR("Red Hat Software");
-MODULE_DESCRIPTION("I2O Core");
-MODULE_LICENSE("GPL");
+	c->mem_phys = memptr;
+	c->mem_offset = mem;
+	
+	/*
+	 *	Cards that fall apart if you hit them with large I/O
+	 *	loads...
+	 */
+	 
+	if(dev->vendor == PCI_VENDOR_ID_NCR && dev->device == 0x0630)
+	{
+		c->short_req = 1;
+		printk(KERN_INFO "I2O: Symbios FC920 workarounds activated.\n");
+	}
+	if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE)
+	{
+		c->promise = 1;
+		printk(KERN_INFO "I2O: Promise workarounds activated.\n");
+	}
+
+	/*
+	 *	Cards that go bananas if you quiesce them before you reset
+	 *	them
+	 */
+	 
+	if(dev->vendor == PCI_VENDOR_ID_DPT)
+		c->dpt=1;
+	
+	/* 
+	 * Enable Write Combining MTRR for IOP's memory region
+	 */
+#ifdef CONFIG_MTRR
+	c->mtrr_reg0 =
+		mtrr_add(c->mem_phys, size, MTRR_TYPE_WRCOMB, 1);
+	/*
+	 * If it is an INTEL i960 I/O processor then set the first 64K to
+	 * Uncacheable since the region contains the Messaging unit which
+	 * shouldn't be cached.
+	 */
+	c->mtrr_reg1 = -1;
+	if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT)
+	{
+		printk(KERN_INFO "I2O: MTRR workaround for Intel i960 processor\n"); 
+		c->mtrr_reg1 =	mtrr_add(c->mem_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
+		if(c->mtrr_reg1< 0)
+		{
+			printk(KERN_INFO "i2o_pci: Error in setting MTRR_TYPE_UNCACHABLE\n");
+			mtrr_del(c->mtrr_reg0, c->mem_phys, size);
+			c->mtrr_reg0 = -1;
+		}
+	}
+
+#endif
+
+	I2O_IRQ_WRITE32(c,0xFFFFFFFF);
+
+	i = i2o_install_controller(c);
+	
+	if(i<0)
+	{
+		printk(KERN_ERR "i2o: Unable to install controller.\n");
+		kfree(c);
+		iounmap((void *)mem);
+		return i;
+	}
+
+	c->irq = dev->irq;
+	if(c->irq)
+	{
+		i=request_irq(dev->irq, i2o_pci_interrupt, SA_SHIRQ,
+			c->name, c);
+		if(i<0)
+		{
+			printk(KERN_ERR "%s: unable to allocate interrupt %d.\n",
+				c->name, dev->irq);
+			c->irq = -1;
+			i2o_delete_controller(c);
+			iounmap((void *)mem);
+			return -EBUSY;
+		}
+	}
+
+	printk(KERN_INFO "%s: Installed at IRQ%d\n", c->name, dev->irq);
+	I2O_IRQ_WRITE32(c,0x0);
+	c->enabled = 1;
+	return 0;	
+}
+
+static int dpt;
+
+/**
+ *	i2o_pci_scan	-	Scan the pci bus for controllers
+ *	
+ *	Scan the PCI devices on the system looking for any device which is a 
+ *	memory of the Intelligent, I2O class. We attempt to set up each such device
+ *	and register it with the core.
+ *
+ *	Returns the number of controllers registered
+ *
+ *	Note; Do not change this to a hot plug interface. I2O 1.5 itself
+ *	does not support hot plugging.
+ */
+ 
+int __init i2o_pci_scan(void)
+{
+	struct pci_dev *dev;
+	int count=0;
+	
+	printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n");
+
+	pci_for_each_dev(dev)	
+	{
+		if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O)
+			continue;
+		if(dev->vendor == PCI_VENDOR_ID_DPT && !dpt)
+		{
+			if(dev->device == 0xA501 || dev->device == 0xA511)
+			{
+				printk(KERN_INFO "i2o: Skipping Adaptec/DPT I2O raid with preferred native driver.\n");
+				continue;
+			}
+		}
+		if((dev->class&0xFF)>1)
+		{
+			printk(KERN_INFO "i2o: I2O Controller found but does not support I2O 1.5 (skipping).\n");
+			continue;
+		}
+		if (pci_enable_device(dev))
+			continue;
+		printk(KERN_INFO "i2o: I2O controller on bus %d at %d.\n",
+			dev->bus->number, dev->devfn);
+		if(pci_set_dma_mask(dev, 0xffffffff))
+		{
+			printk(KERN_WARNING "I2O controller on bus %d at %d : No suitable DMA available\n", dev->bus->number, dev->devfn);
+		 	continue;
+		}
+		pci_set_master(dev);
+		if(i2o_pci_install(dev)==0)
+			count++;
+	}
+	if(count)
+		printk(KERN_INFO "i2o: %d I2O controller%s found and installed.\n", count,
+			count==1?"":"s");
+	return count?count:-ENODEV;
+}
 
 static int i2o_core_init(void)
 {
@@ -3496,6 +3706,7 @@
 	else
 		printk(KERN_INFO "I2O: Event thread created as pid %d\n", evt_pid);
 
+	i2o_pci_scan();
 	if(i2o_num_controllers)
 		i2o_sys_init();
 
@@ -3532,3 +3743,40 @@
 module_init(i2o_core_init);
 module_exit(i2o_core_exit);
 
+MODULE_PARM(dpt, "i");
+MODULE_PARM_DESC(dpt, "Set this if you want to drive DPT cards normally handled by dpt_i2o");
+MODULE_PARM(verbose, "i");
+MODULE_PARM_DESC(verbose, "Verbose diagnostics");
+
+MODULE_AUTHOR("Red Hat Software");
+MODULE_DESCRIPTION("I2O Core");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(i2o_controller_chain);
+EXPORT_SYMBOL(i2o_num_controllers);
+EXPORT_SYMBOL(i2o_find_controller);
+EXPORT_SYMBOL(i2o_unlock_controller);
+EXPORT_SYMBOL(i2o_status_get);
+EXPORT_SYMBOL(i2o_install_handler);
+EXPORT_SYMBOL(i2o_remove_handler);
+EXPORT_SYMBOL(i2o_install_controller);
+EXPORT_SYMBOL(i2o_delete_controller);
+EXPORT_SYMBOL(i2o_run_queue);
+EXPORT_SYMBOL(i2o_claim_device);
+EXPORT_SYMBOL(i2o_release_device);
+EXPORT_SYMBOL(i2o_device_notify_on);
+EXPORT_SYMBOL(i2o_device_notify_off);
+EXPORT_SYMBOL(i2o_post_this);
+EXPORT_SYMBOL(i2o_post_wait);
+EXPORT_SYMBOL(i2o_post_wait_mem);
+EXPORT_SYMBOL(i2o_query_scalar);
+EXPORT_SYMBOL(i2o_set_scalar);
+EXPORT_SYMBOL(i2o_query_table);
+EXPORT_SYMBOL(i2o_clear_table);
+EXPORT_SYMBOL(i2o_row_add_table);
+EXPORT_SYMBOL(i2o_issue_params);
+EXPORT_SYMBOL(i2o_event_register);
+EXPORT_SYMBOL(i2o_event_ack);
+EXPORT_SYMBOL(i2o_report_status);
+EXPORT_SYMBOL(i2o_dump_message);
+EXPORT_SYMBOL(i2o_get_class_name);
diff -Nru a/drivers/message/i2o/i2o_pci.c b/drivers/message/i2o/i2o_pci.c
--- a/drivers/message/i2o/i2o_pci.c	Wed Nov 20 17:15:31 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,397 +0,0 @@
-/*
- *	Find I2O capable controllers on the PCI bus, and register/install
- *	them with the I2O layer
- *
- *	(C) Copyright 1999-2002   Red Hat Software
- *	
- *	Written by Alan Cox, Building Number Three Ltd
- * 	Modified by Deepak Saxena <deepak@plexity.net>
- * 	Modified by Boji T Kannanthanam <boji.t.kannanthanam@intel.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.
- *
- *	Ported to Linux 2.5 by Alan Cox <alan@redhat.com>
- *
- *	TODO:
- *		Support polled I2O PCI controllers. 
- *		Finish verifying 64bit/bigendian clean
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/i2o.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-
-#include <asm/io.h>
-
-#ifdef CONFIG_MTRR
-#include <asm/mtrr.h>
-#endif // CONFIG_MTRR
-
-static int dpt;
-
-
-/**
- *	i2o_pci_dispose		-	Free bus specific resources
- *	@c: I2O controller
- *
- *	Disable interrupts and then free interrupt, I/O and mtrr resources 
- *	used by this controller. Called by the I2O core on unload.
- */
- 
-static void i2o_pci_dispose(struct i2o_controller *c)
-{
-	I2O_IRQ_WRITE32(c,0xFFFFFFFF);
-	if(c->bus.pci.irq > 0)
-		free_irq(c->bus.pci.irq, c);
-	iounmap(((u8 *)c->post_port)-0x40);
-
-#ifdef CONFIG_MTRR
-	if(c->bus.pci.mtrr_reg0 > 0)
-		mtrr_del(c->bus.pci.mtrr_reg0, 0, 0);
-	if(c->bus.pci.mtrr_reg1 > 0)
-		mtrr_del(c->bus.pci.mtrr_reg1, 0, 0);
-#endif
-}
-
-/**
- *	i2o_pci_bind		-	Bind controller and devices
- *	@c: i2o controller
- *	@dev: i2o device
- *
- *	Bind a device driver to a controller. In the case of PCI all we need to do
- *	is module housekeeping.
- */
- 
-static int i2o_pci_bind(struct i2o_controller *c, struct i2o_device *dev)
-{
-	MOD_INC_USE_COUNT;
-	return 0;
-}
-
-/**
- *	i2o_pci_unbind		-	Bind controller and devices
- *	@c: i2o controller
- *	@dev: i2o device
- *
- *	Unbind a device driver from a controller. In the case of PCI all we need to do
- *	is module housekeeping.
- */
- 
-
-static int i2o_pci_unbind(struct i2o_controller *c, struct i2o_device *dev)
-{
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-/**
- *	i2o_pci_enable		-	Enable controller
- *	@c: controller
- *
- *	Called by the I2O core code in order to enable bus specific
- *	resources for this controller. In our case that means unmasking the 
- *	interrupt line.
- */
-
-static void i2o_pci_enable(struct i2o_controller *c)
-{
-	I2O_IRQ_WRITE32(c, 0);
-	c->enabled = 1;
-}
-
-/**
- *	i2o_pci_disable		-	Enable controller
- *	@c: controller
- *
- *	Called by the I2O core code in order to enable bus specific
- *	resources for this controller. In our case that means masking the 
- *	interrupt line.
- */
-
-static void i2o_pci_disable(struct i2o_controller *c)
-{
-	I2O_IRQ_WRITE32(c, 0xFFFFFFFF);
-	c->enabled = 0;
-}
-
-/**
- *	i2o_pci_interrupt	-	Bus specific interrupt handler
- *	@irq: interrupt line
- *	@dev_id: cookie
- *
- *	Handle an interrupt from a PCI based I2O controller. This turns out
- *	to be rather simple. We keep the controller pointer in the cookie.
- */
- 
-static void i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r)
-{
-	struct i2o_controller *c = dev_id;
-	i2o_run_queue(c);
-}	
-
-/**
- *	i2o_pci_install		-	Install a PCI i2o controller
- *	@dev: PCI device of the I2O controller
- *
- *	Install a PCI (or in theory AGP) i2o controller. Devices are
- *	initialized, configured and registered with the i2o core subsystem. Be
- *	very careful with ordering. There may be pending interrupts.
- *
- *	To Do: Add support for polled controllers
- */
-
-int __init i2o_pci_install(struct pci_dev *dev)
-{
-	struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller),
-						GFP_KERNEL);
-	unsigned long mem;
-	u32 memptr = 0;
-	u32 size;
-	
-	int i;
-
-	if(c==NULL)
-	{
-		printk(KERN_ERR "i2o: Insufficient memory to add controller.\n");
-		return -ENOMEM;
-	}
-	memset(c, 0, sizeof(*c));
-
-	for(i=0; i<6; i++)
-	{
-		/* Skip I/O spaces */
-		if(!(pci_resource_flags(dev, i) & IORESOURCE_IO))
-		{
-			memptr = pci_resource_start(dev, i);
-			break;
-		}
-	}
-	
-	if(i==6)
-	{
-		printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n");
-		kfree(c);
-		return -EINVAL;
-	}
-	
-	size = dev->resource[i].end-dev->resource[i].start+1;	
-	/* Map the I2O controller */
-	
-	printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size);
-	mem = (unsigned long)ioremap(memptr, size);
-	if(mem==0)
-	{
-		printk(KERN_ERR "i2o: Unable to map controller.\n");
-		kfree(c);
-		return -EINVAL;
-	}
-
-	c->bus.pci.irq = -1;
-	c->bus.pci.dpt = 0;
-	c->bus.pci.short_req = 0;
-	c->pdev = dev;
-
-	c->irq_mask = mem+0x34;
-	c->post_port = mem+0x40;
-	c->reply_port = mem+0x44;
-
-	c->mem_phys = memptr;
-	c->mem_offset = mem;
-	c->destructor = i2o_pci_dispose;
-	
-	c->bind = i2o_pci_bind;
-	c->unbind = i2o_pci_unbind;
-	c->bus_enable = i2o_pci_enable;
-	c->bus_disable = i2o_pci_disable;
-	
-	c->type = I2O_TYPE_PCI;
-
-	/*
-	 *	Cards that fall apart if you hit them with large I/O
-	 *	loads...
-	 */
-	 
-	if(dev->vendor == PCI_VENDOR_ID_NCR && dev->device == 0x0630)
-	{
-		c->bus.pci.short_req = 1;
-		printk(KERN_INFO "I2O: Symbios FC920 workarounds activated.\n");
-	}
-	if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE)
-	{
-		c->bus.pci.promise = 1;
-		printk(KERN_INFO "I2O: Promise workarounds activated.\n");
-	}
-
-	/*
-	 *	Cards that go bananas if you quiesce them before you reset
-	 *	them
-	 */
-	 
-	if(dev->vendor == PCI_VENDOR_ID_DPT)
-		c->bus.pci.dpt=1;
-	
-	/* 
-	 * Enable Write Combining MTRR for IOP's memory region
-	 */
-#ifdef CONFIG_MTRR
-	c->bus.pci.mtrr_reg0 =
-		mtrr_add(c->mem_phys, size, MTRR_TYPE_WRCOMB, 1);
-	/*
-	 * If it is an INTEL i960 I/O processor then set the first 64K to
-	 * Uncacheable since the region contains the Messaging unit which
-	 * shouldn't be cached.
-	 */
-	c->bus.pci.mtrr_reg1 = -1;
-	if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT)
-	{
-		printk(KERN_INFO "I2O: MTRR workaround for Intel i960 processor\n"); 
-		c->bus.pci.mtrr_reg1 =	mtrr_add(c->mem_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
-		if(c->bus.pci.mtrr_reg1< 0)
-		{
-			printk(KERN_INFO "i2o_pci: Error in setting MTRR_TYPE_UNCACHABLE\n");
-			mtrr_del(c->bus.pci.mtrr_reg0, c->mem_phys, size);
-			c->bus.pci.mtrr_reg0 = -1;
-		}
-	}
-
-#endif
-
-	I2O_IRQ_WRITE32(c,0xFFFFFFFF);
-
-	i = i2o_install_controller(c);
-	
-	if(i<0)
-	{
-		printk(KERN_ERR "i2o: Unable to install controller.\n");
-		kfree(c);
-		iounmap((void *)mem);
-		return i;
-	}
-
-	c->bus.pci.irq = dev->irq;
-	if(c->bus.pci.irq)
-	{
-		i=request_irq(dev->irq, i2o_pci_interrupt, SA_SHIRQ,
-			c->name, c);
-		if(i<0)
-		{
-			printk(KERN_ERR "%s: unable to allocate interrupt %d.\n",
-				c->name, dev->irq);
-			c->bus.pci.irq = -1;
-			i2o_delete_controller(c);
-			iounmap((void *)mem);
-			return -EBUSY;
-		}
-	}
-
-	printk(KERN_INFO "%s: Installed at IRQ%d\n", c->name, dev->irq);
-	I2O_IRQ_WRITE32(c,0x0);
-	c->enabled = 1;
-	return 0;	
-}
-
-/**
- *	i2o_pci_scan	-	Scan the pci bus for controllers
- *	
- *	Scan the PCI devices on the system looking for any device which is a 
- *	memory of the Intelligent, I2O class. We attempt to set up each such device
- *	and register it with the core.
- *
- *	Returns the number of controllers registered
- *
- *	Note; Do not change this to a hot plug interface. I2O 1.5 itself
- *	does not support hot plugging.
- */
- 
-int __init i2o_pci_scan(void)
-{
-	struct pci_dev *dev;
-	int count=0;
-	
-	printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n");
-
-	pci_for_each_dev(dev)	
-	{
-		if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O)
-			continue;
-		if(dev->vendor == PCI_VENDOR_ID_DPT && !dpt)
-		{
-			if(dev->device == 0xA501 || dev->device == 0xA511)
-			{
-				printk(KERN_INFO "i2o: Skipping Adaptec/DPT I2O raid with preferred native driver.\n");
-				continue;
-			}
-		}
-		if((dev->class&0xFF)>1)
-		{
-			printk(KERN_INFO "i2o: I2O Controller found but does not support I2O 1.5 (skipping).\n");
-			continue;
-		}
-		if (pci_enable_device(dev))
-			continue;
-		printk(KERN_INFO "i2o: I2O controller on bus %d at %d.\n",
-			dev->bus->number, dev->devfn);
-		if(pci_set_dma_mask(dev, 0xffffffff))
-		{
-			printk(KERN_WARNING "I2O controller on bus %d at %d : No suitable DMA available\n", dev->bus->number, dev->devfn);
-		 	continue;
-		}
-		pci_set_master(dev);
-		if(i2o_pci_install(dev)==0)
-			count++;
-	}
-	if(count)
-		printk(KERN_INFO "i2o: %d I2O controller%s found and installed.\n", count,
-			count==1?"":"s");
-	return count?count:-ENODEV;
-}
-
-
-/**
- *	i2o_pci_core_attach	-	PCI initialisation for I2O
- *
- *	Find any I2O controllers and if present initialise them and bring up
- *	the I2O subsystem.
- *
- *	Returns 0 on success or an error code
- */
- 
-static int i2o_pci_core_attach(void)
-{
-	printk(KERN_INFO "Linux I2O PCI support (c) 1999-2002 Red Hat.\n");
-	if(i2o_pci_scan()>0)
-	{
-		i2o_sys_init();
-		return 0;
-	}
-	return -ENODEV;
-}
-
-/**
- *	i2o_pci_core_detach	-	PCI unload for I2O
- *
- *	Free up any resources not released when the controllers themselves were
- *	shutdown and unbound from the bus and drivers
- */
- 
-static void i2o_pci_core_detach(void)
-{
-}
-
-MODULE_AUTHOR("Red Hat");
-MODULE_DESCRIPTION("I2O PCI Interface");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(dpt, "i");
-MODULE_PARM_DESC(dpt, "Set this if you want to drive DPT cards normally handled by dpt_i2o");
-module_init(i2o_pci_core_attach);
-module_exit(i2o_pci_core_detach);
diff -Nru a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
--- a/drivers/message/i2o/i2o_proc.c	Mon Oct  7 16:42:09 2002
+++ b/drivers/message/i2o/i2o_proc.c	Thu Mar 13 16:46:20 2003
@@ -836,10 +836,14 @@
 		u16 row_count;
 		u16 more_flag;
 		i2o_exec_execute_ddm_table ddm_table[MAX_I2O_MODULES];
-	} result;
+	} *result;
 
 	i2o_exec_execute_ddm_table ddm_table;
 
+	result = kmalloc(sizeof(*result), GFP_KERNEL);
+	if(!result)
+		return -ENOMEM;
+
 	spin_lock(&i2o_proc_lock);
 	len = 0;
 
@@ -847,18 +851,17 @@
 				c, ADAPTER_TID, 
 				0x0003, -1,
 				NULL, 0,
-				&result, sizeof(result));
+				result, sizeof(*result));
 
 	if (token < 0) {
 		len += i2o_report_query_status(buf+len, token,"0x0003 Executing DDM List");
-		spin_unlock(&i2o_proc_lock);
-		return len;
+		goto out;
 	}
 
 	len += sprintf(buf+len, "Tid   Module_type     Vendor Mod_id  Module_name             Vrs  Data_size Code_size\n");
-	ddm_table=result.ddm_table[0];
+	ddm_table=result->ddm_table[0];
 
-	for(i=0; i < result.row_count; ddm_table=result.ddm_table[++i])
+	for(i=0; i < result->row_count; ddm_table=result->ddm_table[++i])
 	{
 		len += sprintf(buf+len, "0x%03x ", ddm_table.ddm_tid & 0xFFF);
 
@@ -882,9 +885,9 @@
 
 		len += sprintf(buf+len, "\n");
 	}
-
+out:
 	spin_unlock(&i2o_proc_lock);
-
+	kfree(result);
 	return len;
 }
 
@@ -1047,7 +1050,11 @@
 		u16 row_count;
 		u16 more_flag;
 		i2o_group_info group[256];
-	} result;
+	} *result;
+
+	result = kmalloc(sizeof(*result), GFP_KERNEL);
+	if(!result)
+		return -ENOMEM;
 
 	spin_lock(&i2o_proc_lock);
 
@@ -1055,24 +1062,23 @@
 
 	token = i2o_query_table(I2O_PARAMS_TABLE_GET,
 				d->controller, d->lct_data.tid, 0xF000, -1, NULL, 0,
-				&result, sizeof(result));
+				result, sizeof(*result));
 
 	if (token < 0) {
 		len = i2o_report_query_status(buf+len, token, "0xF000 Params Descriptor");
-		spin_unlock(&i2o_proc_lock);
-		return len;
+		goto out;
 	}
 
 	len += sprintf(buf+len, "#  Group   FieldCount RowCount Type   Add Del Clear\n");
 
-	for (i=0; i < result.row_count; i++)
+	for (i=0; i < result->row_count; i++)
 	{
 		len += sprintf(buf+len, "%-3d", i);
-		len += sprintf(buf+len, "0x%04X ", result.group[i].group_number);
-		len += sprintf(buf+len, "%10d ", result.group[i].field_count);
-		len += sprintf(buf+len, "%8d ",  result.group[i].row_count);
+		len += sprintf(buf+len, "0x%04X ", result->group[i].group_number);
+		len += sprintf(buf+len, "%10d ", result->group[i].field_count);
+		len += sprintf(buf+len, "%8d ",  result->group[i].row_count);
 
-		properties = result.group[i].properties;
+		properties = result->group[i].properties;
 		if (properties & 0x1)	len += sprintf(buf+len, "Table  ");
 				else	len += sprintf(buf+len, "Scalar ");
 		if (properties & 0x2)	len += sprintf(buf+len, " + ");
@@ -1085,11 +1091,11 @@
 		len += sprintf(buf+len, "\n");
 	}
 
-	if (result.more_flag)
+	if (result->more_flag)
 		len += sprintf(buf+len, "There is more...\n");
-
+out:
 	spin_unlock(&i2o_proc_lock);
-
+	kfree(result);
 	return len;
 }
 
@@ -1220,7 +1226,11 @@
 		u16 row_count;
 		u16 more_flag;
 		i2o_user_table user[64];
-	} result;
+	} *result;
+
+	result = kmalloc(sizeof(*result), GFP_KERNEL);
+	if(!result)
+		return -ENOMEM;
 
 	spin_lock(&i2o_proc_lock);
 	len = 0;
@@ -1228,28 +1238,28 @@
 	token = i2o_query_table(I2O_PARAMS_TABLE_GET,
 				d->controller, d->lct_data.tid,
 				0xF003, -1, NULL, 0,
-				&result, sizeof(result));
+				result, sizeof(*result));
 
 	if (token < 0) {
 		len += i2o_report_query_status(buf+len, token,"0xF003 User Table");
-		spin_unlock(&i2o_proc_lock);
-		return len;
+		goto out;
 	}
 
 	len += sprintf(buf+len, "#  Instance UserTid ClaimType\n");
 
-	for(i=0; i < result.row_count; i++)
+	for(i=0; i < result->row_count; i++)
 	{
 		len += sprintf(buf+len, "%-3d", i);
-		len += sprintf(buf+len, "%#8x ", result.user[i].instance);
-		len += sprintf(buf+len, "%#7x ", result.user[i].user_tid);
-		len += sprintf(buf+len, "%#9x\n", result.user[i].claim_type);
+		len += sprintf(buf+len, "%#8x ", result->user[i].instance);
+		len += sprintf(buf+len, "%#7x ", result->user[i].user_tid);
+		len += sprintf(buf+len, "%#9x\n", result->user[i].claim_type);
 	}
 
-	if (result.more_flag)
+	if (result->more_flag)
 		len += sprintf(buf+len, "There is more...\n");
-
+out:
 	spin_unlock(&i2o_proc_lock);
+	kfree(result);
 	return len;
 }
 
@@ -2264,24 +2274,27 @@
 		u16 row_count;
 		u16 more_flag;
 		u8  mc_addr[256][8];
-	} result;	
+	} *result;	
+
+	result = kmalloc(sizeof(*result), GFP_KERNEL);
+	if(!result)
+		return -ENOMEM;
 
 	spin_lock(&i2o_proc_lock);	
 	len = 0;
 
 	token = i2o_query_table(I2O_PARAMS_TABLE_GET,
 				d->controller, d->lct_data.tid, 0x0002, -1, 
-				NULL, 0, &result, sizeof(result));
+				NULL, 0, result, sizeof(*result));
 
 	if (token < 0) {
 		len += i2o_report_query_status(buf+len, token,"0x002 LAN Multicast MAC Address");
-		spin_unlock(&i2o_proc_lock);
-		return len;
+		goto out;
 	}
 
-	for (i = 0; i < result.row_count; i++)
+	for (i = 0; i < result->row_count; i++)
 	{
-		memcpy(mc_addr, result.mc_addr[i], 8);
+		memcpy(mc_addr, result->mc_addr[i], 8);
 
 		len += sprintf(buf+len, "MC MAC address[%d]: "
 			       "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
@@ -2289,8 +2302,9 @@
 			       mc_addr[3], mc_addr[4], mc_addr[5],
 			       mc_addr[6], mc_addr[7]);
 	}
-
+out:
 	spin_unlock(&i2o_proc_lock);
+	kfree(result);
 	return len;
 }
 
@@ -2495,32 +2509,36 @@
 		u16 row_count;
 		u16 more_flag;
 		u8  alt_addr[256][8];
-	} result;	
+	} *result;	
+
+	result = kmalloc(sizeof(*result), GFP_KERNEL);
+	if(!result)
+		return -ENOMEM;
 
 	spin_lock(&i2o_proc_lock);	
 	len = 0;
 
 	token = i2o_query_table(I2O_PARAMS_TABLE_GET,
 				d->controller, d->lct_data.tid,
-				0x0006, -1, NULL, 0, &result, sizeof(result));
+				0x0006, -1, NULL, 0, result, sizeof(*result));
 
 	if (token < 0) {
 		len += i2o_report_query_status(buf+len, token, "0x0006 LAN Alternate Address (optional)");
-		spin_unlock(&i2o_proc_lock);
-		return len;
+		goto out;
 	}
 
-	for (i=0; i < result.row_count; i++)
+	for (i=0; i < result->row_count; i++)
 	{
-		memcpy(alt_addr,result.alt_addr[i],8);
+		memcpy(alt_addr,result->alt_addr[i],8);
 		len += sprintf(buf+len, "Alternate address[%d]: "
 			       "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
 			       i, alt_addr[0], alt_addr[1], alt_addr[2],
 			       alt_addr[3], alt_addr[4], alt_addr[5],
 			       alt_addr[6], alt_addr[7]);
 	}
-
+out:
 	spin_unlock(&i2o_proc_lock);
+	kfree(result);
 	return len;
 }
 
diff -Nru a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
--- a/drivers/message/i2o/i2o_scsi.c	Fri Feb 14 11:14:46 2003
+++ b/drivers/message/i2o/i2o_scsi.c	Thu Mar 13 17:14:29 2003
@@ -85,7 +85,7 @@
 static u32 *retry[32];
 static struct i2o_controller *retry_ctrl[32];
 static struct timer_list retry_timer;
-static spinlock_t retry_lock;
+static spinlock_t retry_lock = SPIN_LOCK_UNLOCKED;
 static int retry_ct = 0;
 
 static atomic_t queue_depth;
diff -Nru a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
--- a/drivers/mtd/devices/blkmtd.c	Tue Feb 25 02:44:19 2003
+++ b/drivers/mtd/devices/blkmtd.c	Sat Mar 22 22:14:13 2003
@@ -166,6 +166,7 @@
   int sectornr, sectors, i;
   struct kiobuf *iobuf;
   sector_t *blocks;
+  char b[BDEVNAME_SIZE];
 
   if(!rawdevice) {
     printk("blkmtd: readpage: PANIC file->private_data == NULL\n");
@@ -173,7 +174,7 @@
   }
 
   DEBUG(2, "blkmtd: readpage called, dev = `%s' page = %p index = %ld\n",
-	bdevname(rawdevice->binding), page, page->index);
+	bdevname(rawdevice->binding, b), page, page->index);
 
   if(PageUptodate(page)) {
     DEBUG(2, "blkmtd: readpage page %ld is already upto date\n", page->index);
@@ -523,6 +524,7 @@
   size_t from;
   u_long len;
   int err = 0;
+  char b[BDEVNAME_SIZE];
 
   /* check readonly */
   if(rawdevice->readonly) {
@@ -537,7 +539,7 @@
 
   /* check erase region has valid start and length */
   DEBUG(2, "blkmtd: erase: dev = `%s' from = 0x%x len = 0x%lx\n",
-	bdevname(rawdevice->binding), from, len);
+	bdevname(rawdevice->binding, b), from, len);
   while(numregions) {
     DEBUG(3, "blkmtd: checking erase region = 0x%08X size = 0x%X num = 0x%x\n",
 	  einfo->offset, einfo->erasesize, einfo->numblocks);
@@ -635,11 +637,12 @@
   int err = 0;
   int offset;
   int pagenr, pages;
+  char b[BDEVNAME_SIZE];
 
   *retlen = 0;
 
   DEBUG(2, "blkmtd: read: dev = `%s' from = %ld len = %d buf = %p\n",
-	bdevname(rawdevice->binding), (long int)from, len, buf);
+	bdevname(rawdevice->binding, b), (long int)from, len, buf);
 
   pagenr = from >> PAGE_SHIFT;
   offset = from - (pagenr << PAGE_SHIFT);
@@ -706,10 +709,11 @@
   size_t len1 = 0, len2 = 0, len3 = 0;
   struct page **pages;
   int pagecnt = 0;
-
+  char b[BDEVNAME_SIZE];
+21 e3 
   *retlen = 0;
   DEBUG(2, "blkmtd: write: dev = `%s' to = %ld len = %d buf = %p\n",
-	bdevname(rawdevice->binding), (long int)to, len, buf);
+	bdevname(rawdevice->binding, b), (long int)to, len, buf);
 
   /* handle readonly and out of range numbers */
 
@@ -1060,6 +1064,7 @@
   int err;
   int mode;
   int regions;
+  char b[BDEVNAME_SIZE];
 
   /* Check args */
   if(device == 0) {
@@ -1128,7 +1133,7 @@
   if (err)
     return 1;
 
-  DEBUG(1, "blkmtd: devname = %s\n", bdevname(bdev));
+  DEBUG(1, "blkmtd: devname = %s\n", bdevname(bdev, b));
   blocksize = BLOCK_SIZE;
 
   blocksize = bs ? bs : block_size(bdev);
diff -Nru a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
--- a/drivers/mtd/mtdblock.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/mtd/mtdblock.c	Sat Mar 22 07:38:04 2003
@@ -575,7 +575,7 @@
 		return -EAGAIN;
 
 #ifdef CONFIG_DEVFS_FS
-	devfs_mk_dir(NULL, DEVICE_NAME, NULL);
+	devfs_mk_dir(DEVICE_NAME);
 #endif
 	register_mtd_user(&notifier);
 	
diff -Nru a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
--- a/drivers/mtd/mtdchar.c	Wed Feb 26 04:10:18 2003
+++ b/drivers/mtd/mtdchar.c	Sat Mar 22 07:38:05 2003
@@ -497,7 +497,7 @@
 	}
 
 #ifdef CONFIG_DEVFS_FS
-	devfs_mk_dir(NULL, "mtd", NULL);
+	devfs_mk_dir("mtd");
 
 	register_mtd_user(&notifier);
 #endif
diff -Nru a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
--- a/drivers/mtd/nftlmount.c	Tue Feb  5 07:23:01 2002
+++ b/drivers/mtd/nftlmount.c	Thu Mar 13 16:52:15 2003
@@ -21,7 +21,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#define __NO_VERSION__
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <asm/errno.h>
diff -Nru a/drivers/net/3c501.c b/drivers/net/3c501.c
--- a/drivers/net/3c501.c	Mon Feb 24 12:31:17 2003
+++ b/drivers/net/3c501.c	Thu Mar  6 15:14:17 2003
@@ -955,7 +955,7 @@
  * init_module:
  *
  * When the driver is loaded as a module this function is called. We fake up
- * a device structure with the base I/O and interrupt set as if it was being
+ * a device structure with the base I/O and interrupt set as if it were being
  * called from Space.c. This minimises the extra code that would otherwise
  * be required.
  *
diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c
--- a/drivers/net/3c509.c	Tue Feb 25 11:50:50 2003
+++ b/drivers/net/3c509.c	Tue Mar  4 18:45:08 2003
@@ -56,6 +56,10 @@
 		v1.19b 08Nov2002 Marc Zyngier <maz@wild-wind.fr.eu.org>
 		    - Introduce driver model for EISA cards.
 */
+/*
+  FIXES for PC-9800:
+  Shu Iwanaga: 3c569B(PC-9801 C-bus) support
+*/
 
 #define DRV_NAME	"3c509"
 #define DRV_VERSION	"1.19b"
@@ -257,7 +261,7 @@
 };
 #endif /* CONFIG_MCA */
 
-#ifdef __ISAPNP__
+#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
 static struct isapnp_device_id el3_isapnp_adapters[] __initdata = {
 	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
 		ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5090),
@@ -350,7 +354,7 @@
 		if (lp->pmdev)
 			pm_unregister(lp->pmdev);
 #endif
-#ifdef __ISAPNP__
+#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
 		if (lp->type == EL3_PNP)
 			pnp_device_detach(to_pnp_dev(lp->dev));
 #endif
@@ -368,12 +372,12 @@
 	int ioaddr, irq, if_port;
 	u16 phys_addr[3];
 	static int current_tag;
-#ifdef __ISAPNP__
+#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
 	static int pnp_cards;
 	struct pnp_dev *idev = NULL;
 #endif /* __ISAPNP__ */
 
-#ifdef __ISAPNP__
+#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
 	if (nopnp == 1)
 		goto no_pnp;
 
@@ -421,6 +425,9 @@
 no_pnp:
 #endif /* __ISAPNP__ */
 
+#ifdef CONFIG_X86_PC9800
+	id_port = 0x71d0;
+#else
 	/* Select an open I/O location at 0x1*0 to do contention select. */
 	for ( ; id_port < 0x200; id_port += 0x10) {
 		if (check_region(id_port, 1))
@@ -435,6 +442,7 @@
 		printk(" WARNING: No I/O port available for 3c509 activation.\n");
 		return -ENODEV;
 	}
+#endif /* CONFIG_X86_PC9800 */
 	/* Next check for all ISA bus boards by sending the ID sequence to the
 	   ID_PORT.  We find cards past the first by setting the 'current_tag'
 	   on cards as they are found.  Cards with their tag set will not
@@ -465,7 +473,7 @@
 		phys_addr[i] = htons(id_read_eeprom(i));
 	}
 
-#ifdef __ISAPNP__
+#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
 	if (nopnp == 0) {
 		/* The ISA PnP 3c509 cards respond to the ID sequence.
 		   This check is needed in order not to register them twice. */
@@ -490,9 +498,19 @@
 	{
 		unsigned int iobase = id_read_eeprom(8);
 		if_port = iobase >> 14;
+#ifdef CONFIG_X86_PC9800
+		ioaddr = 0x40d0 + ((iobase & 0x1f) << 8);
+#else
 		ioaddr = 0x200 + ((iobase & 0x1f) << 4);
+#endif
 	}
 	irq = id_read_eeprom(9) >> 12;
+#ifdef CONFIG_X86_PC9800
+	if (irq == 7)
+		irq = 6;
+	else if (irq == 15)
+		irq = 13;
+#endif
 
 	if (!(dev = init_etherdev(NULL, sizeof(struct el3_private))))
 			return -ENOMEM;
@@ -522,7 +540,11 @@
 	outb(0xd0 + ++current_tag, id_port);
 
 	/* Activate the adaptor at the EEPROM location. */
+#ifdef CONFIG_X86_PC9800
+	outb((ioaddr >> 8) | 0xe0, id_port);
+#else
 	outb((ioaddr >> 4) | 0xe0, id_port);
+#endif
 
 	EL3WINDOW(0);
 	if (inw(ioaddr) != 0x6d50) {
@@ -534,7 +556,7 @@
 	/* Free the interrupt so that some other card can use it. */
 	outw(0x0f00, ioaddr + WN0_IRQ);
 
-#ifdef __ISAPNP__	
+#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
  found:							/* PNP jumps here... */
 #endif /* __ISAPNP__ */
 
@@ -543,7 +565,7 @@
 	dev->irq = irq;
 	dev->if_port = if_port;
 	lp = dev->priv;
-#ifdef __ISAPNP__
+#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
 	lp->dev = &idev->dev;
 #endif
 
@@ -1388,6 +1410,12 @@
 	outw(0x0001, ioaddr + 4);
 
 	/* Set the IRQ line. */
+#ifdef CONFIG_X86_PC9800
+	if (dev->irq == 6)
+		dev->irq = 7;
+	else if (dev->irq == 13)
+		dev->irq = 15;
+#endif
 	outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
 
 	/* Set the station address in window 2 each time opened. */
@@ -1550,7 +1578,7 @@
 MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
 MODULE_PARM_DESC(xcvr,"transceiver(s) (0=internal, 1=external)");
 MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt");
-#ifdef __ISAPNP__
+#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
 MODULE_PARM(nopnp, "i");
 MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)");
 MODULE_DEVICE_TABLE(isapnp, el3_isapnp_adapters);
diff -Nru a/drivers/net/82596.c b/drivers/net/82596.c
--- a/drivers/net/82596.c	Fri Jan 10 12:04:06 2003
+++ b/drivers/net/82596.c	Wed Feb  5 08:51:16 2003
@@ -646,7 +646,7 @@
 
 	/* change the scp address */
 
-	MPU_PORT(dev, PORT_ALTSCP, (void *)virt_to_bus(&lp->scp));
+	MPU_PORT(dev, PORT_ALTSCP, (void *)virt_to_bus((void *)&lp->scp));
 
 #elif defined(ENABLE_APRICOT)
 
@@ -677,8 +677,8 @@
 		lp->scp.sysbus = 0x00440000;
 #endif
 
-	lp->scp.iscp = WSWAPiscp(virt_to_bus(&(lp->iscp)));
-	lp->iscp.scb = WSWAPscb(virt_to_bus(&(lp->scb)));
+	lp->scp.iscp = WSWAPiscp(virt_to_bus((void *)&lp->iscp));
+	lp->iscp.scb = WSWAPscb(virt_to_bus((void *)&lp->scb));
 	lp->iscp.stat = ISCP_BUSY;
 	lp->cmd_backlog = 0;
 
diff -Nru a/drivers/net/8390.h b/drivers/net/8390.h
--- a/drivers/net/8390.h	Sat Jul 27 07:57:02 2002
+++ b/drivers/net/8390.h	Tue Oct 15 07:03:22 2002
@@ -123,7 +123,8 @@
 #define inb_p(port)   in_8(port)
 #define outb_p(val,port)  out_8(port,val)
 
-#elif defined(CONFIG_ARM_ETHERH) || defined(CONFIG_ARM_ETHERH_MODULE)
+#elif defined(CONFIG_ARM_ETHERH) || defined(CONFIG_ARM_ETHERH_MODULE) || \
+      defined(CONFIG_NET_CBUS)
 #define EI_SHIFT(x)	(ei_local->reg_offset[x])
 #else
 #define EI_SHIFT(x)	(x)
diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	Mon Feb 24 10:24:37 2003
+++ b/drivers/net/Kconfig	Thu Mar 20 20:48:42 2003
@@ -663,7 +663,7 @@
 	  as <file:Documentation/networking/net-modules.txt>.
 
 config EL3
-	tristate "3c509/3c529 (MCA)/3c579 \"EtherLink III\" support"
+	tristate "3c509/3c529 (MCA)/3c569B (98)/3c579 \"EtherLink III\" support"
 	depends on NET_VENDOR_3COM && (ISA || EISA || MCA)
 	---help---
 	  If you have a network (Ethernet) card belonging to the 3Com
@@ -932,7 +932,7 @@
 source "drivers/net/tulip/Kconfig"
 
 config AT1700
-	tristate "AT1700/1720 support (EXPERIMENTAL)"
+	tristate "AT1700/1720/RE1000Plus(C-Bus) support (EXPERIMENTAL)"
 	depends on NET_ETHERNET && (ISA || MCA) && EXPERIMENTAL
 	---help---
 	  If you have a network (Ethernet) card of this type, say Y and read
@@ -978,7 +978,7 @@
 
 config NET_ISA
 	bool "Other ISA cards"
-	depends on NET_ETHERNET && ISA
+	depends on NET_ETHERNET && ISA && !X86_PC9800
 	---help---
 	  If your network (Ethernet) card hasn't been mentioned yet and its
 	  bus system (that's the way the cards talks to the other components
@@ -1176,6 +1176,55 @@
 	  the Ethernet-HOWTO, available from
 	  <http://www.linuxdoc.org/docs.html#howto>.
 
+config NET_CBUS
+	bool "NEC PC-9800 C-bus cards"
+	depends on NET_ETHERNET && ISA && X86_PC9800
+	---help---
+	  If your network (Ethernet) card hasn't been mentioned yet and its
+	  bus system (that's the way the cards talks to the other components
+	  of your computer) is NEC PC-9800 C-Bus, say Y.
+
+config NE2K_CBUS
+	tristate "Most NE2000-based Ethernet support"
+	depends on NET_CBUS
+
+config NE2K_CBUS_EGY98
+	bool "Melco EGY-98 support"
+	depends on NE2K_CBUS
+
+config NE2K_CBUS_LGY98
+	bool "Melco LGY-98 support"
+	depends on NE2K_CBUS
+
+config NE2K_CBUS_ICM
+	bool "ICM IF-27xxET support"
+	depends on NE2K_CBUS
+
+config NE2K_CBUS_IOLA98
+	bool "I-O DATA LA-98 support"
+	depends on NE2K_CBUS
+
+config NE2K_CBUS_CNET98EL
+	bool "Contec C-NET(98)E/L support"
+	depends on NE2K_CBUS
+
+config NE2K_CBUS_CNET98EL_IO_BASE
+	hex "C-NET(98)E/L I/O base address (0xaaed or 0x55ed)"
+	depends on NE2K_CBUS_CNET98EL
+	default "0xaaed"
+
+config NE2K_CBUS_ATLA98
+	bool "Allied Telesis LA-98 Support"
+	depends on NE2K_CBUS
+
+config NE2K_CBUS_BDN
+	bool "ELECOM Laneed LD-BDN[123]A Support"
+	depends on NE2K_CBUS
+
+config NE2K_CBUS_NEC108
+	bool "NEC PC-9801-108 Support"
+	depends on NE2K_CBUS
+
 config SKMC
 	tristate "SKnet MCA support"
 	depends on NET_ETHERNET && MCA
@@ -1904,6 +1953,7 @@
 	  82544       PRO/1000 XF Server Adapter           A50484-xxx
 	  82544       PRO/1000 T Desktop Adapter           A62947-xxx
 	  82540       PRO/1000 MT Desktop Adapter          A78408-xxx
+	  82541       PRO/1000 MT Desktop Adapter          C91016-xxx
 	  82545       PRO/1000 MT Server Adapter           A92165-xxx
 	  82546       PRO/1000 MT Dual Port Server Adapter A92111-xxx
 	  82545       PRO/1000 MF Server Adapter           A91622-xxx
diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile
--- a/drivers/net/Makefile	Tue Feb 18 17:26:56 2003
+++ b/drivers/net/Makefile	Thu Mar 13 00:06:03 2003
@@ -81,6 +81,7 @@
 obj-$(CONFIG_WD80x3) += wd.o 8390.o
 obj-$(CONFIG_EL2) += 3c503.o 8390.o
 obj-$(CONFIG_NE2000) += ne.o 8390.o
+obj-$(CONFIG_NE2K_CBUS) += ne2k_cbus.o 8390.o
 obj-$(CONFIG_NE2_MCA) += ne2.o 8390.o
 obj-$(CONFIG_HPLAN) += hp.o 8390.o
 obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390.o
diff -Nru a/drivers/net/Makefile.lib b/drivers/net/Makefile.lib
--- a/drivers/net/Makefile.lib	Thu Feb 13 22:59:20 2003
+++ b/drivers/net/Makefile.lib	Tue Oct 15 07:03:22 2002
@@ -19,6 +19,7 @@
 obj-$(CONFIG_MACMACE)		+= crc32.o
 obj-$(CONFIG_MIPS_AU1000_ENET)	+= crc32.o
 obj-$(CONFIG_NATSEMI)		+= crc32.o	
+obj-$(CONFIG_NE2K_CBUS)		+= crc32.o
 obj-$(CONFIG_PCMCIA_FMVJ18X)	+= crc32.o
 obj-$(CONFIG_PCMCIA_SMC91C92)	+= crc32.o
 obj-$(CONFIG_PCMCIA_XIRTULIP)	+= crc32.o
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c	Fri Feb 14 01:03:31 2003
+++ b/drivers/net/Space.c	Thu Mar  6 20:30:51 2003
@@ -233,7 +233,7 @@
 #ifdef CONFIG_E2100		/* Cabletron E21xx series. */
 	{e2100_probe, 0},
 #endif
-#ifdef CONFIG_NE2000		/* ISA (use ne2k-pci for PCI cards) */
+#if defined(CONFIG_NE2000) || defined(CONFIG_NE2K_CBUS)	/* ISA & PC-9800 CBUS (use ne2k-pci for PCI cards) */
 	{ne_probe, 0},
 #endif
 #ifdef CONFIG_LANCE		/* ISA/VLB (use pcnet32 for PCI cards) */
diff -Nru a/drivers/net/apne.c b/drivers/net/apne.c
--- a/drivers/net/apne.c	Thu Nov 21 04:30:14 2002
+++ b/drivers/net/apne.c	Tue Feb 18 12:30:00 2003
@@ -111,9 +111,6 @@
 #define MANUAL_HWADDR5 0x9a
 */
 
-#define WORDSWAP(a) ( (((a)>>8)&0xff) | ((a)<<8) )
-
-
 static const char version[] =
     "apne.c:v1.1 7/10/98 Alain Malek (Alain.Malek@cryogen.ch)\n";
 
@@ -402,10 +399,9 @@
     }
 
     outb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr. */
-
-    hdr->count = WORDSWAP(hdr->count);
-
     ei_status.dmaing &= ~0x01;
+
+    le16_to_cpus(&hdr->count);
 }
 
 /* Block input and output, similar to the Crynwr packet driver.  If you
diff -Nru a/drivers/net/at1700.c b/drivers/net/at1700.c
--- a/drivers/net/at1700.c	Fri Jan 10 12:04:15 2003
+++ b/drivers/net/at1700.c	Fri Mar 14 19:54:58 2003
@@ -34,6 +34,10 @@
 	only is it difficult to detect, it also moves around in I/O space in
 	response to inb()s from other device probes!
 */
+/*
+	99/03/03  Allied Telesis RE1000 Plus support by T.Hagawa
+	99/12/30	port to 2.3.35 by K.Takai
+*/
 
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -76,10 +80,17 @@
  *	ISA
  */
 
+#ifndef CONFIG_X86_PC9800
 static int at1700_probe_list[] __initdata = {
 	0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
 };
 
+#else /* CONFIG_X86_PC9800 */
+static int at1700_probe_list[] __initdata = {
+	0x1d6, 0x1d8, 0x1da, 0x1d4, 0xd4, 0xd2, 0xd8, 0xd0, 0
+};
+
+#endif /* CONFIG_X86_PC9800 */
 /*
  *	MCA
  */
@@ -122,6 +133,7 @@
 
 
 /* Offsets from the base address. */
+#ifndef CONFIG_X86_PC9800
 #define STATUS			0
 #define TX_STATUS		0
 #define RX_STATUS		1
@@ -136,6 +148,7 @@
 #define TX_START		10
 #define COL16CNTL		11		/* Controll Reg for 16 collisions */
 #define MODE13			13
+#define RX_CTRL			14
 /* Configuration registers only on the '865A/B chips. */
 #define EEPROM_Ctrl 	16
 #define EEPROM_Data 	17
@@ -144,8 +157,39 @@
 #define IOCONFIG		18		/* Either read the jumper, or move the I/O. */
 #define IOCONFIG1		19
 #define	SAPROM			20		/* The station address PROM, if no EEPROM. */
+#define MODE24			24
 #define RESET			31		/* Write to reset some parts of the chip. */
 #define AT1700_IO_EXTENT	32
+#define PORT_OFFSET(o) (o)
+#else /* CONFIG_X86_PC9800 */
+#define STATUS			(0x0000)
+#define TX_STATUS		(0x0000)
+#define RX_STATUS		(0x0001)
+#define TX_INTR			(0x0200)/* Bit-mapped interrupt enable registers. */
+#define RX_INTR			(0x0201)
+#define TX_MODE			(0x0400)
+#define RX_MODE			(0x0401)
+#define CONFIG_0		(0x0600)/* Misc. configuration settings. */
+#define CONFIG_1		(0x0601)
+/* Run-time register bank 2 definitions. */
+#define DATAPORT		(0x0800)/* Word-wide DMA or programmed-I/O dataport. */
+#define TX_START		(0x0a00)
+#define COL16CNTL		(0x0a01)/* Controll Reg for 16 collisions */
+#define MODE13			(0x0c01)
+#define RX_CTRL			(0x0e00)
+/* Configuration registers only on the '865A/B chips. */
+#define EEPROM_Ctrl 	(0x1000)
+#define EEPROM_Data 	(0x1200)
+#define CARDSTATUS	16			/* FMV-18x Card Status */
+#define CARDSTATUS1	17			/* FMV-18x Card Status */
+#define IOCONFIG		(0x1400)/* Either read the jumper, or move the I/O. */
+#define IOCONFIG1		(0x1600)
+#define	SAPROM			20		/* The station address PROM, if no EEPROM. */
+#define	MODE24			(0x1800)/* The station address PROM, if no EEPROM. */
+#define RESET			(0x1e01)/* Write to reset some parts of the chip. */
+#define PORT_OFFSET(o) ({ int _o_ = (o); (_o_ & ~1) * 0x100 + (_o_ & 1); })
+#endif /* CONFIG_X86_PC9800 */
+
 
 #define TX_TIMEOUT		10
 
@@ -225,8 +269,20 @@
 	int slot, ret = -ENODEV;
 	struct net_local *lp;
 	
+#ifndef CONFIG_X86_PC9800
 	if (!request_region(ioaddr, AT1700_IO_EXTENT, dev->name))
 		return -EBUSY;
+#else
+	for (i = 0; i < 0x2000; i += 0x0200) {
+		if (!request_region(ioaddr + i, 2, dev->name)) {
+			while (i > 0) {
+				i -= 0x0200;
+				release_region(ioaddr + i, 2);
+			}
+			return -EBUSY;
+		}
+	}
+#endif
 
 		/* Resetting the chip doesn't reset the ISA interface, so don't bother.
 	   That means we have to be careful with the register values we probe for.
@@ -317,10 +373,17 @@
 		/* Reset the internal state machines. */
 	outb(0, ioaddr + RESET);
 
-	if (is_at1700)
+	if (is_at1700) {
+#ifndef CONFIG_X86_PC9800
 		irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04)
 						   | (read_eeprom(ioaddr, 0)>>14)];
-	else {
+#else
+		{
+			char re1000plus_irqmap[4] = {3, 5, 6, 12};
+			irq = re1000plus_irqmap[inb(ioaddr + IOCONFIG1) >> 6];
+		}
+#endif
+	} else {
 		/* Check PnP mode for FMV-183/184/183A/184A. */
 		/* This PnP routine is very poor. IO and IRQ should be known. */
 		if (inb(ioaddr + CARDSTATUS1) & 0x20) {
@@ -392,18 +455,22 @@
 	/* Set the station address in bank zero. */
 	outb(0x00, ioaddr + CONFIG_1);
 	for (i = 0; i < 6; i++)
-		outb(dev->dev_addr[i], ioaddr + 8 + i);
+		outb(dev->dev_addr[i], ioaddr + PORT_OFFSET(8 + i));
 
 	/* Switch to bank 1 and set the multicast table to accept none. */
 	outb(0x04, ioaddr + CONFIG_1);
 	for (i = 0; i < 8; i++)
-		outb(0x00, ioaddr + 8 + i);
+		outb(0x00, ioaddr + PORT_OFFSET(8 + i));
 
 
 	/* Switch to bank 2 */
 	/* Lock our I/O address, and set manual processing mode for 16 collisions. */
 	outb(0x08, ioaddr + CONFIG_1);
+#ifndef CONFIG_X86_PC9800
 	outb(dev->if_port, ioaddr + MODE13);
+#else
+	outb(0, ioaddr + MODE13);
+#endif
 	outb(0x00, ioaddr + COL16CNTL);
 
 	if (net_debug)
@@ -447,7 +514,12 @@
 	kfree(dev->priv);
 	dev->priv = NULL;
 err_out:
+#ifndef CONFIG_X86_PC9800
 	release_region(ioaddr, AT1700_IO_EXTENT);
+#else
+	for (i = 0; i < 0x2000; i += 0x0200)
+		release_region(ioaddr + i, 2);
+#endif
 	return ret;
 }
 
@@ -459,7 +531,11 @@
 #define EE_DATA_READ	0x80	/* EEPROM chip data out, in reg. 17. */
 
 /* Delay between EEPROM clock transitions. */
+#ifndef CONFIG_X86_PC9800
 #define eeprom_delay()	do { } while (0)
+#else
+#define eeprom_delay()	__asm__ ("out%B0 %%al,%0" :: "N"(0x5f))
+#endif
 
 /* The EEPROM commands include the alway-set leading bit. */
 #define EE_WRITE_CMD	(5 << 6)
@@ -542,12 +618,12 @@
 		inw (ioaddr + STATUS), inb (ioaddr + TX_STATUS) & 0x80
 		? "IRQ conflict" : "network cable problem");
 	printk ("%s: timeout registers: %04x %04x %04x %04x %04x %04x %04x %04x.\n",
-	 dev->name, inw (ioaddr + 0), inw (ioaddr + 2), inw (ioaddr + 4),
-		inw (ioaddr + 6), inw (ioaddr + 8), inw (ioaddr + 10),
-		inw (ioaddr + 12), inw (ioaddr + 14));
+	 dev->name, inw(ioaddr + TX_STATUS), inw(ioaddr + TX_INTR), inw(ioaddr + TX_MODE),
+		inw(ioaddr + CONFIG_0), inw(ioaddr + DATAPORT), inw(ioaddr + TX_START),
+		inw(ioaddr + MODE13 - 1), inw(ioaddr + RX_CTRL));
 	lp->stats.tx_errors++;
 	/* ToDo: We should try to restart the adaptor... */
-	outw (0xffff, ioaddr + 24);
+	outw(0xffff, ioaddr + MODE24);
 	outw (0xffff, ioaddr + TX_STATUS);
 	outb (0x5a, ioaddr + CONFIG_0);
 	outb (0xe8, ioaddr + CONFIG_1);
@@ -704,7 +780,7 @@
 				   dev->name, inb(ioaddr + RX_MODE), status);
 #ifndef final_version
 		if (status == 0) {
-			outb(0x05, ioaddr + 14);
+			outb(0x05, ioaddr + RX_CTRL);
 			break;
 		}
 #endif
@@ -724,7 +800,7 @@
 					   dev->name, pkt_len);
 				/* Prime the FIFO and then flush the packet. */
 				inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
-				outb(0x05, ioaddr + 14);
+				outb(0x05, ioaddr + RX_CTRL);
 				lp->stats.rx_errors++;
 				break;
 			}
@@ -734,7 +810,7 @@
 					   dev->name, pkt_len);
 				/* Prime the FIFO and then flush the packet. */
 				inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
-				outb(0x05, ioaddr + 14);
+				outb(0x05, ioaddr + RX_CTRL);
 				lp->stats.rx_dropped++;
 				break;
 			}
@@ -761,7 +837,7 @@
 			if ((inb(ioaddr + RX_MODE) & 0x40) == 0x40)
 				break;
 			inw(ioaddr + DATAPORT);				/* dummy status read */
-			outb(0x05, ioaddr + 14);
+			outb(0x05, ioaddr + RX_CTRL);
 		}
 
 		if (net_debug > 5)
@@ -844,24 +920,28 @@
 		outb(0x02, ioaddr + RX_MODE);	/* Use normal mode. */
 	}
 
-	save_flags(flags);
-	cli();
+	spin_lock_irqsave (&lp->lock, flags);
 	if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
 		int saved_bank = inw(ioaddr + CONFIG_0);
 		/* Switch to bank 1 and set the multicast table. */
 		outw((saved_bank & ~0x0C00) | 0x0480, ioaddr + CONFIG_0);
 		for (i = 0; i < 8; i++)
-			outb(mc_filter[i], ioaddr + 8 + i);
+			outb(mc_filter[i], ioaddr + PORT_OFFSET(8 + i));
 		memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter));
 		outw(saved_bank, ioaddr + CONFIG_0);
 	}
-	restore_flags(flags);
+	spin_unlock_irqrestore (&lp->lock, flags);
 	return;
 }
 
 #ifdef MODULE
 static struct net_device dev_at1700;
+#ifndef CONFIG_X86_PC9800
 static int io = 0x260;
+#else
+static int io = 0xd0;
+#endif
+
 static int irq;
 
 MODULE_PARM(io, "i");
@@ -901,7 +981,15 @@
 
 	/* If we don't do this, we can't re-insmod it later. */
 	free_irq(dev_at1700.irq, NULL);
+#ifndef CONFIG_X86_PC9800
 	release_region(dev_at1700.base_addr, AT1700_IO_EXTENT);
+#else
+	{
+		int i;
+		for (i = 0; i < 0x2000; i += 0x200)
+			release_region(dev_at1700.base_addr + i, 2);
+	}
+#endif
 }
 #endif /* MODULE */
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/net/e100/e100.h b/drivers/net/e100/e100.h
--- a/drivers/net/e100/e100.h	Sun Mar  2 18:12:52 2003
+++ b/drivers/net/e100/e100.h	Sun Mar 16 20:39:20 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -57,6 +57,8 @@
 #include <linux/if.h>
 #include <asm/uaccess.h>
 #include <linux/ip.h>
+#include <linux/if_vlan.h>
+#include <linux/mii.h>
 
 #define E100_REGS_LEN 1
 /*
@@ -301,6 +303,9 @@
 
 /* EEPROM bit definitions */
 /*- EEPROM control register bits */
+#define EEPROM_FLAG_ASF  0x8000
+#define EEPROM_FLAG_GCL  0x4000
+
 #define EN_TRNF          0x10	/* Enable turnoff */
 #define EEDO             0x08	/* EEPROM data out */
 #define EEDI             0x04	/* EEPROM data in (set for writing data) */
@@ -319,6 +324,8 @@
 #define EEPROM_COMPATIBILITY_WORD       3
 #define EEPROM_PWA_NO                   8
 #define EEPROM_ID_WORD			0x0A
+#define EEPROM_CONFIG_ASF		0x0D
+#define EEPROM_SMBUS_ADDR		0x90
 
 #define EEPROM_SUM                      0xbaba
 
@@ -358,7 +365,7 @@
 #define CB_STATUS_MASK          BIT_12_15	/* CB Status Mask (4-bits) */
 #define CB_STATUS_COMPLETE      BIT_15	/* CB Complete Bit */
 #define CB_STATUS_OK            BIT_13	/* CB OK Bit */
-#define CB_STATUS_UNDERRUN      BIT_12	/* CB A Bit */
+#define CB_STATUS_VLAN          BIT_12 /* CB Valn detected Bit */
 #define CB_STATUS_FAIL          BIT_11	/* CB Fail (F) Bit */
 
 /*misc command bits */
@@ -851,6 +858,7 @@
 };
 
 struct e100_private {
+	struct vlan_group *vlgrp;
 	u32 flags;		/* board management flags */
 	u32 tx_per_underrun;	/* number of good tx frames per underrun */
 	unsigned int tx_count;	/* count of tx frames, so we can request an interrupt */
@@ -886,7 +894,6 @@
 	struct driver_stats drv_stats;
 
 	u8 rev_id;		/* adapter PCI revision ID */
-	unsigned long device_type;	/* device type from e100_vendor.h */
 
 	unsigned int phy_addr;	/* address of PHY component */
 	unsigned int PhyId;	/* ID of PHY component */
@@ -922,8 +929,6 @@
 	u8 ifs_value;
 
 	struct cfg_params params;	/* adapter's command line parameters */
-
-	char *id_string;
 
 	u32 speed_duplex_caps;	/* adapter's speed/duplex capabilities */
 
diff -Nru a/drivers/net/e100/e100_config.c b/drivers/net/e100/e100_config.c
--- a/drivers/net/e100/e100_config.c	Mon Feb 24 10:29:17 2003
+++ b/drivers/net/e100/e100_config.c	Sun Mar 16 20:39:21 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -518,6 +518,25 @@
 	}
 
 	E100_CONFIG(bdp, 19);
+	spin_unlock_bh(&(bdp->config_lock));
+}
+
+void
+e100_config_vlan_drop(struct e100_private *bdp, unsigned char enable)
+{
+	spin_lock_bh(&(bdp->config_lock));
+	if (enable) {
+		if (!(bdp->config[22] & CB_CFIG_VLAN_DROP_ENABLE)) {
+			bdp->config[22] |= CB_CFIG_VLAN_DROP_ENABLE;
+			E100_CONFIG(bdp, 22);
+		}
+
+	} else {
+		if ((bdp->config[22] & CB_CFIG_VLAN_DROP_ENABLE)) {
+			bdp->config[22] &= ~CB_CFIG_VLAN_DROP_ENABLE;
+			E100_CONFIG(bdp, 22);
+		}
+	}
 	spin_unlock_bh(&(bdp->config_lock));
 }
 
diff -Nru a/drivers/net/e100/e100_config.h b/drivers/net/e100/e100_config.h
--- a/drivers/net/e100/e100_config.h	Tue Aug 27 17:03:04 2002
+++ b/drivers/net/e100/e100_config.h	Sun Mar 16 20:39:21 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -163,5 +163,5 @@
 extern u8 e100_config_loopback_mode(struct e100_private *bdp, u8 mode);
 extern u8 e100_config_dynamic_tbd(struct e100_private *bdp, u8 enable);
 extern u8 e100_config_tcb_ext_enable(struct e100_private *bdp, u8 enable);
-
+extern void e100_config_vlan_drop(struct e100_private *bdp, unsigned char enable);
 #endif /* _E100_CONFIG_INC_ */
diff -Nru a/drivers/net/e100/e100_eeprom.c b/drivers/net/e100/e100_eeprom.c
--- a/drivers/net/e100/e100_eeprom.c	Mon Feb 24 10:14:56 2003
+++ b/drivers/net/e100/e100_eeprom.c	Sun Mar 16 20:39:22 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
diff -Nru a/drivers/net/e100/e100_main.c b/drivers/net/e100/e100_main.c
--- a/drivers/net/e100/e100_main.c	Sun Mar 16 22:33:15 2003
+++ b/drivers/net/e100/e100_main.c	Sun Mar 16 21:00:50 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -45,8 +45,22 @@
 **********************************************************************/
 
 /* Change Log
- *
- * 2.1.29	12/20/02
+ * 
+ * 2.2.21	02/11/03
+ * o Removed marketing brand strings. Instead, Using generic string 
+ *   "Intel(R) PRO/100 Network Connection" for all adapters.
+ * o Implemented ethtool -S option
+ * o Strip /proc/net/PRO_LAN_Adapters files for kernel driver
+ * o Bug fix: Read wrong byte in EEPROM when offset is odd number
+ * o Bug fix: PHY loopback test fails on ICH devices
+ * o Bug fix: System panic on e100_close when repeating Hot Remove and 
+ *   Add in a team
+ * o Bug fix: Linux Bonding driver claims adapter's link loss because of
+ *   not updating last_rx field
+ * o Bug fix: e100 does not check validity of MAC address
+ * o New feature: added ICH5 support
+ * 
+ * 2.1.27	11/20/02
  *   o Bug fix: Device command timeout due to SMBus processing during init
  *   o Bug fix: Not setting/clearing I (Interrupt) bit in tcb correctly
  *   o Bug fix: Not using EEPROM WoL setting as default in ethtool
@@ -62,15 +76,6 @@
  *     ifconfig down, rmmod and insmod
  *
  * 2.1.24       10/7/02
- *   o Bug fix: Wrong files under /proc/net/PRO_LAN_Adapters/ when interface
- *     name is changed
- *   o Bug fix: Rx skb corruption when Rx polling code and Rx interrupt code
- *     are executing during stress traffic at shared interrupt system. 
- *     Removed Rx polling code
- *   o Added detailed printk if selftest failed when insmod
- *   o Removed misleading printks
- *
- * 2.1.12       8/2/02
  */
  
 #include <linux/config.h>
@@ -81,7 +86,8 @@
 #include "e100_ucode.h"
 #include "e100_config.h"
 #include "e100_phy.h"
-#include "e100_vendor.h"
+
+extern void e100_force_speed_duplex_to_phy(struct e100_private *bdp);
 
 static char e100_gstrings_stats[][ETH_GSTRING_LEN] = {
 	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
@@ -127,7 +133,6 @@
 
 static int e100_ethtool_led_blink(struct net_device *, struct ifreq *);
 
-#include <linux/mii.h>
 static int e100_mii_ioctl(struct net_device *, struct ifreq *, int);
 
 static unsigned char e100_delayed_exec_non_cu_cmd(struct e100_private *,
@@ -136,11 +141,15 @@
 static void e100_non_tx_background(unsigned long);
 
 /* Global Data structures and variables */
-char e100_copyright[] __devinitdata = "Copyright (c) 2002 Intel Corporation";
-char e100_driver_version[]="2.1.29-k4";
+char e100_copyright[] __devinitdata = "Copyright (c) 2003 Intel Corporation";
+char e100_driver_version[]="2.2.21-k1";
 const char *e100_full_driver_name = "Intel(R) PRO/100 Network Driver";
 char e100_short_driver_name[] = "e100";
 static int e100nics = 0;
+static void e100_vlan_rx_register(struct net_device *netdev, struct vlan_group
+		*grp);
+static void e100_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
+static void e100_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
 
 #ifdef CONFIG_PM
 static int e100_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
@@ -186,7 +195,6 @@
 static void e100_set_multi(struct net_device *);
 void e100_set_speed_duplex(struct e100_private *);
 
-char *e100_get_brand_msg(struct e100_private *);
 static u8 e100_pci_setup(struct pci_dev *, struct e100_private *);
 static u8 e100_sw_init(struct e100_private *);
 static void e100_tco_workaround(struct e100_private *);
@@ -220,6 +228,7 @@
 				 char *);
 unsigned char e100_wait_exec_cmplx(struct e100_private *, u32, u8, u8);
 void e100_exec_cmplx(struct e100_private *, u32, u8);
+static unsigned char e100_asf_enabled(struct e100_private *bdp);
 
 /**
  * e100_get_rx_struct - retrieve cell to hold skb buff from the pool
@@ -607,7 +616,9 @@
 	}
 
 	if (((bdp->pdev->device > 0x1030)
-	     && (bdp->pdev->device < 0x103F))
+	       && (bdp->pdev->device < 0x103F))
+	    || ((bdp->pdev->device >= 0x1050)
+	       && (bdp->pdev->device <= 0x1057))
 	    || (bdp->pdev->device == 0x2449)
 	    || (bdp->pdev->device == 0x2459)
 	    || (bdp->pdev->device == 0x245D)) {
@@ -646,6 +657,9 @@
                 goto err_pci;
 	}
 	
+	dev->vlan_rx_register = e100_vlan_rx_register;
+	dev->vlan_rx_add_vid = e100_vlan_rx_add_vid;
+	dev->vlan_rx_kill_vid = e100_vlan_rx_kill_vid;
 	dev->irq = pcid->irq;
 	dev->open = &e100_open;
 	dev->hard_start_xmit = &e100_xmit_frame;
@@ -655,9 +669,11 @@
 	dev->set_multicast_list = &e100_set_multi;
 	dev->set_mac_address = &e100_set_mac;
 	dev->do_ioctl = &e100_ioctl;
-	if (bdp->flags & USE_IPCB) {
-		dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-	}
+
+	if (bdp->flags & USE_IPCB)
+	dev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
+			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+		
 	e100nics++;
 
 	e100_get_speed_duplex_caps(bdp);
@@ -668,25 +684,24 @@
         memcpy(bdp->ifname, dev->name, IFNAMSIZ);
         bdp->ifname[IFNAMSIZ-1] = 0;	
 
-	bdp->device_type = ent->driver_data;
 	printk(KERN_NOTICE
 	       "e100: %s: %s\n", 
-	       bdp->device->name, e100_get_brand_msg(bdp));
+	       bdp->device->name, "Intel(R) PRO/100 Network Connection");
 	e100_print_brd_conf(bdp);
-	bdp->id_string = e100_get_brand_msg(bdp);
 
 	bdp->wolsupported = 0;
 	bdp->wolopts = 0;
 	
 	/* Check if WoL is enabled on EEPROM */
 	if (e100_eeprom_read(bdp, EEPROM_ID_WORD) & BIT_5) {
+		/* Magic Packet WoL is enabled on device by default */
+		/* if EEPROM WoL bit is TRUE                        */
+		bdp->wolsupported = WAKE_MAGIC;
+		bdp->wolopts = WAKE_MAGIC;
 		if (bdp->rev_id >= D101A4_REV_ID)
 			bdp->wolsupported = WAKE_PHY | WAKE_MAGIC;
 		if (bdp->rev_id >= D101MA_REV_ID)
 			bdp->wolsupported |= WAKE_UCAST | WAKE_ARP;
-		/* Magic Packet WoL is enabled on device by default */
-		/* if EEPROM WoL bit is TRUE                        */
-		bdp->wolopts = WAKE_MAGIC;
 	}
 
 	printk(KERN_NOTICE "\n");
@@ -752,6 +767,34 @@
 	--e100nics;
 }
 
+static struct pci_device_id e100_id_table[] __devinitdata = {
+	{0x8086, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+  	{0x8086, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	
+	{0x8086, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, 
+	{0x8086, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, 
+	{0x8086, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, 
+	{0x8086, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x1051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x1052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x1053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x1054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x1055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0x8086, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{0,} /* This has to be the last entry*/
+};
 MODULE_DEVICE_TABLE(pci, e100_id_table);
 
 static struct pci_driver e100_driver = {
@@ -994,13 +1037,14 @@
 {
 	struct e100_private *bdp = dev->priv;
 
+	e100_disable_clear_intr(bdp);
+	free_irq(dev->irq, dev);
 	bdp->intr_mask = SCB_INT_MASK;
 	e100_isolate_driver(bdp);
 
 	netif_carrier_off(bdp->device);
 	bdp->cur_line_speed = 0;
 	bdp->cur_dplx_mode = 0;
-	free_irq(dev->irq, dev);
 	e100_clear_pools(bdp);
 
 	return 0;
@@ -1097,6 +1141,8 @@
 	int rc = -1;
 	struct sockaddr *p_sockaddr = (struct sockaddr *) addr;
 
+	if (!is_valid_ether_addr(p_sockaddr->sa_data))
+		return -EADDRNOTAVAIL;
 	bdp = dev->priv;
 
 	if (e100_setup_iaaddr(bdp, (u8 *) (p_sockaddr->sa_data))) {
@@ -1231,6 +1277,10 @@
 
 	/* read the MAC address from the eprom */
 	e100_rd_eaddr(bdp);
+	if (!is_valid_ether_addr(bdp->device->dev_addr)) {
+		printk(KERN_ERR "e100: Invalid Ethernet address\n");
+		return false;
+	}
 	/* read NIC's part number */
 	e100_rd_pwa_no(bdp);
 
@@ -1670,6 +1720,11 @@
 	} else {
 		if (netif_running(dev))
 			netif_stop_queue(dev);
+		/* When changing to non-autoneg, device may lose  */
+		/* link with some switches. e100 will try to      */
+		/* revover link by sending command to PHY layer   */
+		if (bdp->params.e100_speed_duplex != E100_AUTONEG)
+			e100_force_speed_duplex_to_phy(bdp);
 	}
 
 	rmb();
@@ -1793,7 +1848,8 @@
 	bdp = dev->priv;
 
 	intr_status = readw(&bdp->scb->scb_status);
-	if (!intr_status || (intr_status == 0xffff)) {
+	/* If not my interrupt, just return */
+	if (!(intr_status & SCB_STATUS_ACK_MASK) || (intr_status == 0xffff)) {
 		return;
 	}
 
@@ -1993,17 +2049,15 @@
 		} else {
 			skb->ip_summed = CHECKSUM_NONE;
 		}
-		switch (netif_rx(skb)) {
-		case NET_RX_BAD:
-		case NET_RX_DROP:
-		case NET_RX_CN_MOD:
-		case NET_RX_CN_HIGH:
-			break;
-		default:
-			bdp->drv_stats.net_stats.rx_bytes += skb->len;
-			break;
-		}
 
+		if(bdp->vlgrp && (rfd_status & CB_STATUS_VLAN)) {
+			vlan_hwaccel_rx(skb, bdp->vlgrp, be16_to_cpu(rfd->vlanid));
+		} else {
+			netif_rx(skb);
+		}
+		dev->last_rx = jiffies;
+		bdp->drv_stats.net_stats.rx_bytes += skb->len;
+		
 		rfd_cnt++;
 	}			/* end of rfd loop */
 
@@ -2096,6 +2150,11 @@
 		tcb->tcbu.ipcb.ip_schedule &= ~IPCB_TCPUDP_CHECKSUM_ENABLE;
 	}
 
+	if(bdp->vlgrp && vlan_tx_tag_present(skb)) {
+		(tcb->tcbu).ipcb.ip_activation_high |= IPCB_INSERTVLAN_ENABLE;
+		(tcb->tcbu).ipcb.vlan = cpu_to_be16(vlan_tx_tag_get(skb));
+	}
+	
 	tcb->tcb_hdr.cb_status = 0;
 	tcb->tcb_thrshld = bdp->tx_thld;
 	tcb->tcb_hdr.cb_cmd |= __constant_cpu_to_le16(CB_S_BIT);
@@ -2114,7 +2173,8 @@
 
 		if ((ip->protocol == IPPROTO_TCP) ||
 		    (ip->protocol == IPPROTO_UDP)) {
-			tcb->tcbu.ipcb.ip_activation_high =
+
+			tcb->tcbu.ipcb.ip_activation_high |=
 				IPCB_HARDWAREPARSING_ENABLE;
 			tcb->tcbu.ipcb.ip_schedule |=
 				IPCB_TCPUDP_CHECKSUM_ENABLE;
@@ -2682,13 +2742,12 @@
 		udelay(20);
 	}
 
-	/* Mask off our interrupt line -- its unmasked after reset */
+	/* Mask off our interrupt line -- it is unmasked after reset */
 	e100_disable_clear_intr(bdp);
 #ifdef E100_CU_DEBUG	
 	bdp->last_cmd = 0;
 	bdp->last_sub_cmd = 0;
 #endif	
-
 }
 
 /**
@@ -2901,27 +2960,6 @@
 }
 
 /**
- * e100_get_brand_msg
- * @bdp: atapter's private data struct
- *
- * This routine checks if there is specified branding message for a given board
- * type and returns a pointer to the string containing the branding message.
- */
-char *
-e100_get_brand_msg(struct e100_private *bdp)
-{
-	int i;
-
-	for (i = 0; e100_vendor_info_array[i].idstr != NULL; i++) {
-		if (e100_vendor_info_array[i].device_type == bdp->device_type) {
-			return e100_vendor_info_array[i].idstr;
-		}
-	}
-
-	return e100_vendor_info_array[E100_ALL_BOARDS].idstr;
-}
-
-/**
  * e100_pci_setup - setup the adapter's PCI information
  * @pcid: adapter's pci_dev struct
  * @bdp: atapter's private data struct
@@ -3004,12 +3042,17 @@
 void
 e100_set_speed_duplex(struct e100_private *bdp)
 {
-	if (netif_carrier_ok(bdp->device))
+	int carrier_ok;
+	/* Device may lose link with some siwtches when */
+	/* changing speed/duplex to non-autoneg. e100   */
+	/* needs to remember carrier state in order to  */
+	/* start watchdog timer for recovering link     */
+	if ((carrier_ok = netif_carrier_ok(bdp->device)))
 		e100_isolate_driver(bdp);
 	e100_phy_set_speed_duplex(bdp, true);
 	e100_config_fc(bdp);	/* re-config flow-control if necessary */
 	e100_config(bdp);	
-	if (netif_carrier_ok(bdp->device))
+	if (carrier_ok)
 		e100_deisolate_driver(bdp, false);
 }
 
@@ -3426,6 +3469,7 @@
 	u16 first_word, last_word;
 	int i, max_len;
 	void *ptr;
+	u8 *eeprom_data_bytes = (u8 *)eeprom_data;
 
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
@@ -3461,7 +3505,9 @@
 		if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
 			return -EFAULT;
 
-		if (copy_to_user(usr_eeprom_ptr, eeprom_data, ecmd.len))
+		if(ecmd.offset & 1)
+			eeprom_data_bytes++;
+		if (copy_to_user(usr_eeprom_ptr, eeprom_data_bytes, ecmd.len))
 			return -EFAULT;
 	} else {
 		if (ecmd.magic != E100_EEPROM_MAGIC)
@@ -3754,7 +3800,8 @@
 		return -EFAULT;
 
 	switch (info.string_set) {
-	case ETH_SS_TEST:
+	case ETH_SS_TEST: {
+		int ret = 0;
 		if (info.len > E100_MAX_TEST_RES)
 			info.len = E100_MAX_TEST_RES;
 		strings = kmalloc(info.len * ETH_GSTRING_LEN, GFP_ATOMIC);
@@ -3766,7 +3813,13 @@
 			sprintf(strings + i * ETH_GSTRING_LEN, "%-31s",
 				test_strings[i]);
 		}
-		break;
+		if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
+			ret = -EFAULT;
+		if (copy_to_user(usr_strings, strings, info.len * ETH_GSTRING_LEN))
+			ret = -EFAULT;
+		kfree(strings);
+		return ret;
+	}
 	case ETH_SS_STATS: {
 		char *strings = NULL;
 		void *addr = ifr->ifr_data;
@@ -3783,19 +3836,6 @@
 	default:
 		return -EOPNOTSUPP;
 	}
-
-	if (copy_to_user(ifr->ifr_data, &info, sizeof (info))) {
-		kfree(strings);
-		return -EFAULT;
-	}
-
-	if (copy_to_user(usr_strings, strings, info.len * ETH_GSTRING_LEN)) {
-		kfree(strings);
-		return -EFAULT;
-	}
-
-	kfree(strings);
-	return 0;
 }
 
 static int
@@ -4022,6 +4062,45 @@
 	spin_unlock_bh(&(bdp->bd_non_tx_lock));
 }
 
+static void
+e100_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
+{
+	struct e100_private *bdp = netdev->priv;
+
+	e100_disable_clear_intr(bdp);
+	bdp->vlgrp = grp;
+
+	if(grp) {
+		/* enable VLAN tag insert/strip */
+		e100_config_vlan_drop(bdp, true);
+
+	} else {
+		/* disable VLAN tag insert/strip */
+		e100_config_vlan_drop(bdp, false);
+	}
+
+	e100_config(bdp);
+	e100_set_intr_mask(bdp);
+}
+
+static void
+e100_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+{
+	/* We don't do Vlan filtering */
+	return;
+}
+
+static void
+e100_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+{
+	struct e100_private *bdp = netdev->priv;
+
+	if(bdp->vlgrp)
+		bdp->vlgrp->vlan_devices[vid] = NULL;
+	/* We don't do Vlan filtering */
+	return;
+}
+
 #ifdef CONFIG_PM
 static int
 e100_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
@@ -4057,7 +4136,7 @@
 	e100_do_wol(pcid, bdp);
 	
 	/* If wol is enabled */
-	if (bdp->wolopts) {
+	if (bdp->wolopts || e100_asf_enabled(bdp)) {
 		pci_enable_wake(pcid, 3, 1);	/* Enable PME for power state D3 */
 		pci_set_power_state(pcid, 3);	/* Set power state to D3.        */
 	} else {
@@ -4084,6 +4163,31 @@
 	return 0;
 }
 #endif /* CONFIG_PM */
+
+/**
+ * e100_asf_enabled - checks if ASF is configured on the current adaper
+ *                    by reading registers 0xD and 0x90 in the EEPROM 
+ * @bdp: atapter's private data struct
+ *
+ * Returns: true if ASF is enabled
+ */
+static unsigned char
+e100_asf_enabled(struct e100_private *bdp)
+{
+	u16 asf_reg;
+	u16 smbus_addr_reg;
+	if ((bdp->pdev->device >= 0x1050) && (bdp->pdev->device <= 0x1055)) {
+		asf_reg = e100_eeprom_read(bdp, EEPROM_CONFIG_ASF);
+		if ((asf_reg & EEPROM_FLAG_ASF)
+		    && !(asf_reg & EEPROM_FLAG_GCL)) {
+			smbus_addr_reg = 
+				e100_eeprom_read(bdp, EEPROM_SMBUS_ADDR);
+			if ((smbus_addr_reg & 0xFF) != 0xFE) 
+				return true;
+		}
+	}
+	return false;
+}
 
 #ifdef E100_CU_DEBUG
 unsigned char
diff -Nru a/drivers/net/e100/e100_phy.c b/drivers/net/e100/e100_phy.c
--- a/drivers/net/e100/e100_phy.c	Wed Aug 28 14:37:26 2002
+++ b/drivers/net/e100/e100_phy.c	Sun Mar 16 20:39:23 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -636,7 +636,6 @@
 	control &= ~BMCR_ANENABLE;
 	control &= ~BMCR_LOOPBACK;
 
-	/* Check e100.c values */
 	switch (bdp->params.e100_speed_duplex) {
 	case E100_SPEED_10_HALF:
 		control &= ~BMCR_SPEED100;
@@ -680,6 +679,41 @@
 		}
 
 	} while (true);
+}
+
+void
+e100_force_speed_duplex_to_phy(struct e100_private *bdp)
+{
+	u16 control;
+
+	e100_mdi_read(bdp, MII_BMCR, bdp->phy_addr, &control);
+	control &= ~BMCR_ANENABLE;
+	control &= ~BMCR_LOOPBACK;
+
+	switch (bdp->params.e100_speed_duplex) {
+	case E100_SPEED_10_HALF:
+		control &= ~BMCR_SPEED100;
+		control &= ~BMCR_FULLDPLX;
+		break;
+
+	case E100_SPEED_10_FULL:
+		control &= ~BMCR_SPEED100;
+		control |= BMCR_FULLDPLX;
+		break;
+
+	case E100_SPEED_100_HALF:
+		control |= BMCR_SPEED100;
+		control &= ~BMCR_FULLDPLX;
+		break;
+
+	case E100_SPEED_100_FULL:
+		control |= BMCR_SPEED100;
+		control |= BMCR_FULLDPLX;
+		break;
+	}
+
+	/* Send speed/duplex command to PHY layer. */
+	e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, control);
 }
 
 /* 
diff -Nru a/drivers/net/e100/e100_phy.h b/drivers/net/e100/e100_phy.h
--- a/drivers/net/e100/e100_phy.h	Tue Aug 27 17:03:43 2002
+++ b/drivers/net/e100/e100_phy.h	Sun Mar 16 20:39:23 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -29,8 +29,6 @@
 #define _E100_PHY_INC_
 
 #include "e100.h"
-
-#include <linux/mii.h>
 
 /*
  * Auto-polarity enable/disable
diff -Nru a/drivers/net/e100/e100_test.c b/drivers/net/e100/e100_test.c
--- a/drivers/net/e100/e100_test.c	Fri Jan  3 13:07:40 2003
+++ b/drivers/net/e100/e100_test.c	Sun Mar 16 20:39:24 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -242,6 +242,9 @@
 		 *dynamic_tbd = e100_config_dynamic_tbd(bdp,*dynamic_tbd);
 
 	if (set_loopback) {
+		/* ICH PHY loopback is broken */
+		if (bdp->flags & IS_ICH && loopback_mode == PHY_LOOPBACK)
+			loopback_mode = MAC_LOOPBACK;
 		/* Configure loopback on MAC */
 		e100_config_loopback_mode(bdp,loopback_mode);
 	} else {
diff -Nru a/drivers/net/e100/e100_ucode.h b/drivers/net/e100/e100_ucode.h
--- a/drivers/net/e100/e100_ucode.h	Tue Aug 27 17:03:04 2002
+++ b/drivers/net/e100/e100_ucode.h	Sun Mar 16 20:39:24 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
diff -Nru a/drivers/net/e100/e100_vendor.h b/drivers/net/e100/e100_vendor.h
--- a/drivers/net/e100/e100_vendor.h	Tue Aug 27 17:03:04 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,311 +0,0 @@
-/*******************************************************************************
-
-  
-  Copyright(c) 1999 - 2002 Intel Corporation. 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 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.
-  
-  The full GNU General Public License is included in this distribution in the
-  file called LICENSE.
-  
-  Contact Information:
-  Linux NICS <linux.nics@intel.com>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-*******************************************************************************/
-
-#ifndef E100_VENDOR_ID_INFO
-#define E100_VENDOR_ID_INFO
-/* ====================================================================== */
-/*                              vendor_info                               */
-/* ====================================================================== */
-
-struct e100_vendor_info {
-	unsigned long device_type;
-	char *idstr;
-};
-
-enum e100_device_type {
-	E100_BRD_100TX = 1,
-	E100_BRD_100T4,
-	E100_BRD_10T,
-	E100_BRD_100WFM,
-	E100_BRD_82557,
-	E100_BRD_82557_WOL,
-	E100_BRD_82558,
-	E100_BRD_82558_WOL,
-	E100_BRD_100,
-	E100_BRD_100M,
-	E100_BRD_AOL2,
-	E100_BRD_AOL,
-	E100_PROS_M,
-	E100_PROS_AM,
-	E100_PROS_AM_AOL,
-	E100_PROS_DT,
-	E100_PRO_DT,
-	E100_PROM_DT,
-	E100_PRO_SRV,
-	E100_PRO_SRVP,
-	E100_PROS_SRV,
-	E100_PRO_DUAL,
-	E100_PROS_DUAL,
-	E100_PROP_DUAL,
-	E100_PROP_WOL,
-	E100_PROS_MOB,
-	E100_PRO_CB,
-	E100_PRO_CB_M,
-	E100_PROSR_MOB,
-	E100_PROS_MC,
-	E100_PROSR_MC,
-	E100_PROP_MC,
-	E100_PROSP_MC,
-	E100_PROP_MOB,
-	E100_PROSP_MOB,
-	E100_PRO_MINI,
-	E100_PRO_NET,
-	E100_PROS_NET,
-	E100_PROVM_NET,
-	E100_PROVE_D,
-	E100_82559_LOM,
-	E100_82559_LOM_AOL,
-	E100_82559_LOM_AOL2,
-	E100_82559_LOM_DELL,
-	E100_IBM_MDS,
-	E100_CMPQ_S,
-	E100_PROVE_DA,
-	E100_PROVM_DA,
-	E100_PROVE_LOM,
-	E100_PROVE_NET,
-	E100_82562,
-	E100_82551QM,
-	E100_ALL_BOARDS
-};
-
-struct e100_vendor_info e100_vendor_info_array[] = {
-	{ E100_BRD_100TX, "Intel(R) PRO/100B PCI Adapter (TX)"},
-	{ E100_BRD_100T4, "Intel(R) PRO/100B PCI Adapter (T4)"},
-	{ E100_BRD_10T, "Intel(R) PRO/10+ PCI Adapter"},
-	{ E100_BRD_100WFM, "Intel(R) PRO/100 WfM PCI Adapter"},
-	{ E100_BRD_82557, "Intel(R) 82557-based Integrated Ethernet PCI (10/100)"},
-	{ E100_BRD_82557_WOL, "Intel(R) 82557-based Integrated Ethernet with Wake on LAN*"},
-	{ E100_BRD_82558, "Intel(R) 82558-based Integrated Ethernet"},
-	{ E100_BRD_82558_WOL, "Intel(R) 82558-based Integrated Ethernet with Wake on LAN*"},
-	{ E100_BRD_100, "Intel(R) PRO/100+ PCI Adapter"},
-	{ E100_BRD_100M, "Intel(R) PRO/100+ Management Adapter"},
-	{ E100_BRD_AOL2, "Intel(R) PRO/100+ Alert on LAN* 2 Management Adapter"},
-	{ E100_82559_LOM_DELL, "Intel(R) 8255x Based Network Connection"},
-	{ E100_BRD_AOL, "Intel(R) PRO/100+ Alert on LAN* Management Adapter"},
-	{ E100_PROS_M, "Intel(R) PRO/100 S Management Adapter"},
-	{ E100_PROS_AM, "Intel(R) PRO/100 S Advanced Management Adapter"},
-	{ E100_PROS_AM_AOL, "Intel(R) PRO/100+ Management Adapter with Alert On LAN* GC"},
-	{ E100_PROS_DT, "Intel(R) PRO/100 S Desktop Adapter"},
-	{ E100_PRO_DT, "Intel(R) PRO/100 Desktop Adapter"},
-	{ E100_PROM_DT, "Intel(R) PRO/100 M Desktop Adapter"},
-	{ E100_PRO_SRV, "Intel(R) PRO/100+ Server Adapter"},
-	{ E100_PRO_SRVP, "Intel(R) PRO/100+ Server Adapter (PILA8470B)"},
-	{ E100_PROS_SRV, "Intel(R) PRO/100 S Server Adapter"},
-	{ E100_PRO_DUAL, "Intel(R) PRO/100 Dual Port Server Adapter"},
-	{ E100_PROS_DUAL, "Intel(R) PRO/100 S Dual Port Server Adapter"},
-	{ E100_PROP_DUAL, "Intel(R) PRO/100+ Dual Port Server Adapter"},
-	{ E100_PROP_WOL, "Intel(R) PRO/100+ Management Adapter with Alert On LAN* G Server"},
-	{ E100_PROS_MOB, "Intel(R) PRO/100 S Mobile Adapter"},
-	{ E100_PRO_CB, "Intel(R) PRO/100 CardBus II"},
-	{ E100_PRO_CB_M, "Intel(R) PRO/100 LAN+Modem56 CardBus II"},
-	{ E100_PROSR_MOB, "Intel(R) PRO/100 SR Mobile Adapter"},
-	{ E100_PROS_MC, "Intel(R) PRO/100 S Mobile Combo Adapter"},
-	{ E100_PROSR_MC, "Intel(R) PRO/100 SR Mobile Combo Adapter"},
-	{ E100_PROP_MC, "Intel(R) PRO/100 P Mobile Combo Adapter"},
-	{ E100_PROSP_MC, "Intel(R) PRO/100 SP Mobile Combo Adapter"},
-	{ E100_PROP_MOB, "Intel(R) PRO/100 P Mobile Adapter"},
-	{ E100_PROSP_MOB, "Intel(R) PRO/100 SP Mobile Adapter"},
-	{ E100_PRO_MINI, "Intel(R) PRO/100+ Mini PCI"},
-	{ E100_PRO_NET, "Intel(R) PRO/100 Network Connection" },
-	{ E100_PROS_NET, "Intel(R) PRO/100 S Network Connection" },
-	{ E100_PROVM_NET, "Intel(R) PRO/100 VM Network Connection"},
-	{ E100_PROVE_D, "Intel(R) PRO/100 VE Desktop Connection"},
-	{ E100_82559_LOM, "Intel(R) 82559 Fast Ethernet LAN on Motherboard"},
-	{ E100_82559_LOM_AOL, "Intel(R) 82559 Fast Ethernet LOM with Alert on LAN*" },
-	{ E100_82559_LOM_AOL2, "Intel(R) 82559 Fast Ethernet LOM with Alert on LAN* 2" },
-	{ E100_IBM_MDS, "IBM Mobile, Desktop & Server Adapters"},
-	{ E100_CMPQ_S, "Compaq Fast Ethernet Server Adapter" },
-	{ E100_PROVE_DA, "Intel(R) PRO/100 VE Desktop Adapter"},
-	{ E100_PROVM_DA, "Intel(R) PRO/100 VM Desktop Adapter"},
-	{ E100_PROVE_LOM, "Intel(R) PRO/100 VE Network ConnectionPLC LOM" },
-	{ E100_PROVE_NET, "Intel(R) PRO/100 VE Network Connection"},
-	{ E100_82562, "Intel(R)82562 based Fast Ethernet Connection"},
-	{ E100_82551QM, "Intel(R) PRO/100 M Mobile Connection"},
-	{ E100_ALL_BOARDS, "Intel(R) 8255x-based Ethernet Adapter"},
-	{0,NULL}
-};
-
-static struct pci_device_id e100_id_table[] __devinitdata = {
-	{0x8086, 0x1229, 0x8086, 0x0001, 0, 0, E100_BRD_100TX},
-	{0x8086, 0x1229, 0x8086, 0x0002, 0, 0, E100_BRD_100T4},
-	{0x8086, 0x1229, 0x8086, 0x0003, 0, 0, E100_BRD_10T},
-	{0x8086, 0x1229, 0x8086, 0x0004, 0, 0, E100_BRD_100WFM},
-	{0x8086, 0x1229, 0x8086, 0x0005, 0, 0, E100_BRD_82557},
-	{0x8086, 0x1229, 0x8086, 0x0006, 0, 0, E100_BRD_82557_WOL},
-	{0x8086, 0x1229, 0x8086, 0x0002, 0, 0, E100_BRD_100T4},
-	{0x8086, 0x1229, 0x8086, 0x0003, 0, 0, E100_BRD_10T},
-	{0x8086, 0x1229, 0x8086, 0x0004, 0, 0, E100_BRD_100WFM},
-	{0x8086, 0x1229, 0x8086, 0x0005, 0, 0, E100_BRD_82557},
-	{0x8086, 0x1229, 0x8086, 0x0006, 0, 0, E100_BRD_82557_WOL},
-	{0x8086, 0x1229, 0x8086, 0x0007, 0, 0, E100_BRD_82558},
-	{0x8086, 0x1229, 0x8086, 0x0008, 0, 0, E100_BRD_82558_WOL},
-	{0x8086, 0x1229, 0x8086, 0x0009, 0, 0, E100_BRD_100},
-	{0x8086, 0x1229, 0x8086, 0x000A, 0, 0, E100_BRD_100M},
-	{0x8086, 0x1229, 0x8086, 0x000B, 0, 0, E100_BRD_100},
-	{0x8086, 0x1229, 0x8086, 0x000C, 0, 0, E100_BRD_100M},
-	{0x8086, 0x1229, 0x8086, 0x000D, 0, 0, E100_BRD_AOL2},
-	{0x8086, 0x1229, 0x8086, 0x000E, 0, 0, E100_BRD_AOL},
-	{0x8086, 0x1229, 0x8086, 0x0010, 0, 0, E100_PROS_M},
-	{0x8086, 0x1229, 0x8086, 0x0011, 0, 0, E100_PROS_M},
-	{0x8086, 0x1229, 0x8086, 0x0012, 0, 0, E100_PROS_AM},
-	{0x8086, 0x1229, 0x8086, 0x0013, 0, 0, E100_PROS_AM},
-	{0x8086, 0x1229, 0x8086, 0x0030, 0, 0, E100_PROS_AM_AOL},
-	{0x8086, 0x1229, 0x8086, 0x0040, 0, 0, E100_PROS_DT},
-	{0x8086, 0x1229, 0x8086, 0x0041, 0, 0, E100_PROS_DT},
-	{0x8086, 0x1229, 0x8086, 0x0042, 0, 0, E100_PRO_DT},
-	{0x8086, 0x1229, 0x8086, 0x0050, 0, 0, E100_PROS_DT},
-	{0x8086, 0x1229, 0x8086, 0x0070, 0, 0, E100_PROM_DT},
-	{0x8086, 0x1229, 0x8086, 0x1009, 0, 0, E100_PRO_SRV},
-	{0x8086, 0x1229, 0x8086, 0x100C, 0, 0, E100_PRO_SRVP},
-	{0x8086, 0x1229, 0x8086, 0x1012, 0, 0, E100_PROS_SRV},
-	{0x8086, 0x1229, 0x8086, 0x1013, 0, 0, E100_PROS_SRV},
-	{0x8086, 0x1229, 0x8086, 0x1014, 0, 0, E100_PRO_DUAL},
-	{0x8086, 0x1229, 0x8086, 0x1015, 0, 0, E100_PROS_DUAL},
-	{0x8086, 0x1229, 0x8086, 0x1016, 0, 0, E100_PROS_DUAL},
-	{0x8086, 0x1229, 0x8086, 0x1017, 0, 0, E100_PROP_DUAL},
-	{0x8086, 0x1229, 0x8086, 0x1030, 0, 0, E100_PROP_WOL},
-	{0x8086, 0x1229, 0x8086, 0x1040, 0, 0, E100_PROS_SRV},
-	{0x8086, 0x1229, 0x8086, 0x1041, 0, 0, E100_PROS_SRV},
-	{0x8086, 0x1229, 0x8086, 0x1042, 0, 0, E100_PRO_SRV},
-	{0x8086, 0x1229, 0x8086, 0x1050, 0, 0, E100_PROS_SRV},
-	{0x8086, 0x1229, 0x8086, 0x10F0, 0, 0, E100_PROP_DUAL}, 
-	{0x8086, 0x1229, 0x8086, 0x10F0, 0, 0, E100_PROP_DUAL}, 
-	{0x8086, 0x1229, 0x8086, 0x2009, 0, 0, E100_PROS_MOB},
-	{0x8086, 0x1229, 0x8086, 0x200D, 0, 0, E100_PRO_CB},
-	{0x8086, 0x1229, 0x8086, 0x200E, 0, 0, E100_PRO_CB_M},
-	{0x8086, 0x1229, 0x8086, 0x200F, 0, 0, E100_PROSR_MOB},
-	{0x8086, 0x1229, 0x8086, 0x2010, 0, 0, E100_PROS_MC},
-	{0x8086, 0x1229, 0x8086, 0x2013, 0, 0, E100_PROSR_MC},
-	{0x8086, 0x1229, 0x8086, 0x2016, 0, 0, E100_PROS_MOB},
-	{0x8086, 0x1229, 0x8086, 0x2017, 0, 0, E100_PROS_MC},
-	{0x8086, 0x1229, 0x8086, 0x2018, 0, 0, E100_PROSR_MOB},
-	{0x8086, 0x1229, 0x8086, 0x2019, 0, 0, E100_PROSR_MC},
-	{0x8086, 0x1229, 0x8086, 0x2101, 0, 0, E100_PROP_MOB},
-	{0x8086, 0x1229, 0x8086, 0x2102, 0, 0, E100_PROSP_MOB},
-	{0x8086, 0x1229, 0x8086, 0x2103, 0, 0, E100_PROSP_MOB},
-	{0x8086, 0x1229, 0x8086, 0x2104, 0, 0, E100_PROSP_MOB},
-	{0x8086, 0x1229, 0x8086, 0x2105, 0, 0, E100_PROSP_MOB},
-	{0x8086, 0x1229, 0x8086, 0x2106, 0, 0, E100_PROP_MOB},
-	{0x8086, 0x1229, 0x8086, 0x2107, 0, 0, E100_PRO_NET},
-	{0x8086, 0x1229, 0x8086, 0x2108, 0, 0, E100_PRO_NET},
-	{0x8086, 0x1229, 0x8086, 0x2200, 0, 0, E100_PROP_MC},
-	{0x8086, 0x1229, 0x8086, 0x2201, 0, 0, E100_PROP_MC},
-	{0x8086, 0x1229, 0x8086, 0x2202, 0, 0, E100_PROSP_MC},
-	{0x8086, 0x1229, 0x8086, 0x2203, 0, 0, E100_PRO_MINI},
-	{0x8086, 0x1229, 0x8086, 0x2204, 0, 0, E100_PRO_MINI},
-	{0x8086, 0x1229, 0x8086, 0x2205, 0, 0, E100_PROSP_MC},
-	{0x8086, 0x1229, 0x8086, 0x2206, 0, 0, E100_PROSP_MC},
-	{0x8086, 0x1229, 0x8086, 0x2207, 0, 0, E100_PROSP_MC},
-	{0x8086, 0x1229, 0x8086, 0x2208, 0, 0, E100_PROP_MC},
-	{0x8086, 0x1229, 0x8086, 0x2408, 0, 0, E100_PRO_MINI},
-	{0x8086, 0x1229, 0x8086, 0x240F, 0, 0, E100_PRO_MINI},
-	{0x8086, 0x1229, 0x8086, 0x2411, 0, 0, E100_PRO_MINI},
-	{0x8086, 0x1229, 0x8086, 0x3400, 0, 0, E100_82559_LOM},
-	{0x8086, 0x1229, 0x8086, 0x3000, 0, 0, E100_82559_LOM},
-	{0x8086, 0x1229, 0x8086, 0x3001, 0, 0, E100_82559_LOM_AOL},
-	{0x8086, 0x1229, 0x8086, 0x3002, 0, 0, E100_82559_LOM_AOL2},
-	{0x8086, 0x1229, 0x8086, 0x3006, 0, 0, E100_PROS_NET},
-	{0x8086, 0x1229, 0x8086, 0x3007, 0, 0, E100_PROS_NET},
-	{0x8086, 0x1229, 0x8086, 0x3008, 0, 0, E100_PRO_NET},
-	{0x8086, 0x1229, 0x8086, 0x3010, 0, 0, E100_PROS_NET},
-	{0x8086, 0x1229, 0x8086, 0x3011, 0, 0, E100_PROS_NET},
-	{0x8086, 0x1229, 0x8086, 0x3012, 0, 0, E100_PRO_NET},
-	{0x8086, 0x1229, 0x1014, 0x005C, 0, 0, E100_IBM_MDS},   
-	{0x8086, 0x1229, 0x1014, 0x305C, 0, 0, E100_IBM_MDS},   
-	{0x8086, 0x1229, 0x1014, 0x405C, 0, 0, E100_IBM_MDS},   
-	{0x8086, 0x1229, 0x1014, 0x605C, 0, 0, E100_IBM_MDS},   
-	{0x8086, 0x1229, 0x1014, 0x505C, 0, 0, E100_IBM_MDS},   
-	{0x8086, 0x1229, 0x1014, 0x105C, 0, 0, E100_IBM_MDS},   
-	{0x8086, 0x1229, 0x1014, 0x805C, 0, 0, E100_IBM_MDS},   
-	{0x8086, 0x1229, 0x1014, 0x705C, 0, 0, E100_IBM_MDS},   
-	{0x8086, 0x1229, 0x1014, 0x01F1, 0, 0, E100_IBM_MDS},   
-	{0x8086, 0x1229, 0x1014, 0x0232, 0, 0, E100_IBM_MDS},   
-	{0x8086, 0x1229, 0x1014, 0x0207, 0, 0, E100_PRO_NET},     
-	{0x8086, 0x1229, 0x1014, 0x023F, 0, 0, E100_PRO_NET},   
-	{0x8086, 0x1229, 0x1014, 0x01BC, 0, 0, E100_PRO_NET},     
-	{0x8086, 0x1229, 0x1014, 0x01CE, 0, 0, E100_PRO_NET},     
-	{0x8086, 0x1229, 0x1014, 0x01DC, 0, 0, E100_PRO_NET},     
-	{0x8086, 0x1229, 0x1014, 0x01EB, 0, 0, E100_PRO_NET},     
-	{0x8086, 0x1229, 0x1014, 0x01EC, 0, 0, E100_PRO_NET},     
-	{0x8086, 0x1229, 0x1014, 0x0202, 0, 0, E100_PRO_NET},     
-	{0x8086, 0x1229, 0x1014, 0x0205, 0, 0, E100_PRO_NET},     
-	{0x8086, 0x1229, 0x1014, 0x0217, 0, 0, E100_PRO_NET},     
-	{0x8086, 0x1229, 0x0E11, 0xB01E, 0, 0, E100_CMPQ_S},         
-	{0x8086, 0x1229, 0x0E11, 0xB02F, 0, 0, E100_CMPQ_S},     
-	{0x8086, 0x1229, 0x0E11, 0xB04A, 0, 0, E100_CMPQ_S},     
-	{0x8086, 0x1229, 0x0E11, 0xB0C6, 0, 0, E100_CMPQ_S},     
-	{0x8086, 0x1229, 0x0E11, 0xB0C7, 0, 0, E100_CMPQ_S},     
-	{0x8086, 0x1229, 0x0E11, 0xB0D7, 0, 0, E100_CMPQ_S},     
-	{0x8086, 0x1229, 0x0E11, 0xB0DD, 0, 0, E100_CMPQ_S},     
-	{0x8086, 0x1229, 0x0E11, 0xB0DE, 0, 0, E100_CMPQ_S},     
-	{0x8086, 0x1229, 0x0E11, 0xB0E1, 0, 0, E100_CMPQ_S},     
-	{0x8086, 0x1229, 0x0E11, 0xB134, 0, 0, E100_CMPQ_S},     
-	{0x8086, 0x1229, 0x0E11, 0xB13C, 0, 0, E100_CMPQ_S},     
-	{0x8086, 0x1229, 0x0E11, 0xB144, 0, 0, E100_CMPQ_S},     
-	{0x8086, 0x1229, 0x0E11, 0xB163, 0, 0, E100_CMPQ_S},     
-	{0x8086, 0x1229, 0x0E11, 0xB164, 0, 0, E100_CMPQ_S},
-	{0x8086, 0x1229, 0x1028, PCI_ANY_ID, 0, 0, E100_82559_LOM_DELL},
-	{0x8086, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
-
-	{0x8086, 0x2449, 0x1014, 0x0265, 0, 0, E100_PROVE_D},
-	{0x8086, 0x2449, 0x1014, 0x0267, 0, 0, E100_PROVE_D},
-	{0x8086, 0x2449, 0x1014, 0x026A, 0, 0, E100_PROVE_D},
-	{0x8086, 0x2449, 0x8086, 0x3010, 0, 0, E100_PROVE_DA},
-	{0x8086, 0x2449, 0x8086, 0x3011, 0, 0, E100_PROVM_DA},
-	{0x8086, 0x2449, 0x8086, 0x3013, 0, 0, E100_PROVE_NET},
-	{0x8086, 0x2449, 0x8086, 0x3014, 0, 0, E100_PROVM_NET},
-	{0x8086, 0x2449, 0x8086, 0x3016, 0, 0, E100_PROP_MC},
-	{0x8086, 0x2449, 0x8086, 0x3017, 0, 0, E100_PROP_MOB},
-	{0x8086, 0x2449, 0x8086, 0x3018, 0, 0, E100_PRO_NET},
-	{0x8086, 0x2449, 0x0E11, PCI_ANY_ID, 0, 0, E100_PROVM_NET},
-	{0x8086, 0x2449, 0x1014, PCI_ANY_ID, 0, 0, E100_PROVE_D},	
-	{0x8086, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
-	
-	{0x8086, 0x1059, 0x1179, 0x0005, 0, 0, E100_82551QM},
-	{0x8086, 0x1059, 0x1033, 0x8191, 0, 0, E100_82551QM},
-	{0x8086, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_82551QM},
-	
-	{0x8086, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
-  	{0x8086, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
-	{0x8086, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},	
-	{0x8086, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVE_NET}, 
-	{0x8086, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVE_NET},
-	{0x8086, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVM_NET}, 
-	{0x8086, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVM_NET}, 
-	{0x8086, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVM_NET},
-	{0x8086, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVE_NET},
-	{0x8086, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVE_NET},
-	{0x8086, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVM_NET},
-	{0x8086, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVM_NET},
-	{0x8086, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVE_NET},
-	{0x8086, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_PROVM_NET},
-	{0x8086, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_82562},
-	{0x8086, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_82562},
-	{0,} /* This has to be the last entry*/
-};
-
-#endif /* E100_VENDOR_ID_INFO */
diff -Nru a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
--- a/drivers/net/e1000/e1000.h	Fri Jan 24 18:44:28 2003
+++ b/drivers/net/e1000/e1000.h	Mon Mar 17 13:03:59 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -65,6 +65,7 @@
 #include <linux/reboot.h>
 #include <net/checksum.h>
 #include <linux/workqueue.h>
+#include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
 
@@ -95,6 +96,15 @@
 #define E1000_RXBUFFER_8192  8192
 #define E1000_RXBUFFER_16384 16384
 
+/* SmartSpeed delimiters */
+#define E1000_SMARTSPEED_DOWNSHIFT 3
+#define E1000_SMARTSPEED_MAX       15
+
+/* Packet Buffer allocations */
+#define E1000_TX_FIFO_SIZE_SHIFT 0xA
+#define E1000_TX_HEAD_ADDR_SHIFT 7
+#define E1000_PBA_TX_MASK 0xFFFF0000
+
 /* Flow Control High-Watermark: 43464 bytes */
 #define E1000_FC_HIGH_THRESH 0xA9C8
 
@@ -107,10 +117,7 @@
 /* How many Tx Descriptors do we need to call netif_wake_queue ? */
 #define E1000_TX_QUEUE_WAKE	16
 /* How many Rx Buffers do we bundle into one write to the hardware ? */
-#define E1000_RX_BUFFER_WRITE	16
-
-#define E1000_JUMBO_PBA      0x00000028
-#define E1000_DEFAULT_PBA    0x00000030
+#define E1000_RX_BUFFER_WRITE	16	/* Must be power of 2 */
 
 #define AUTO_ALL_MODES       0
 #define E1000_EEPROM_APME    4
@@ -145,7 +152,8 @@
 };
 
 #define E1000_DESC_UNUSED(R) \
-((((R)->next_to_clean + (R)->count) - ((R)->next_to_use + 1)) % ((R)->count))
+	((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
+	(R)->next_to_clean - (R)->next_to_use - 1)
 
 #define E1000_GET_DESC(R, i, type)	(&(((struct type *)((R).desc))[i]))
 #define E1000_RX_DESC(R, i)		E1000_GET_DESC(R, i, e1000_rx_desc)
@@ -155,6 +163,7 @@
 /* board specific private data structure */
 
 struct e1000_adapter {
+	struct timer_list tx_fifo_stall_timer;
 	struct timer_list watchdog_timer;
 	struct timer_list phy_info_timer;
 	struct vlan_group *vlgrp;
@@ -163,6 +172,7 @@
 	uint32_t rx_buffer_len;
 	uint32_t part_num;
 	uint32_t wol;
+	uint32_t smartspeed;
 	uint16_t link_speed;
 	uint16_t link_duplex;
 	spinlock_t stats_lock;
@@ -177,7 +187,11 @@
 	uint32_t txd_cmd;
 	uint32_t tx_int_delay;
 	uint32_t tx_abs_int_delay;
-	int max_data_per_txd;
+	uint32_t gotcl;
+	uint32_t tx_fifo_head;
+	uint32_t tx_head_addr;
+	uint32_t tx_fifo_size;
+	atomic_t tx_fifo_stall;
 
 	/* RX */
 	struct e1000_desc_ring rx_ring;
@@ -186,6 +200,10 @@
 	uint32_t rx_int_delay;
 	uint32_t rx_abs_int_delay;
 	boolean_t rx_csum;
+	uint32_t gorcl;
+
+	/* Interrupt Throttle Rate */
+	uint32_t itr;
 
 	/* OS defined structs */
 	struct net_device *netdev;
diff -Nru a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
--- a/drivers/net/e1000/e1000_ethtool.c	Fri Jan 24 18:45:02 2003
+++ b/drivers/net/e1000/e1000_ethtool.c	Mon Mar 17 13:03:59 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -38,6 +38,7 @@
 extern int e1000_up(struct e1000_adapter *adapter);
 extern void e1000_down(struct e1000_adapter *adapter);
 extern void e1000_reset(struct e1000_adapter *adapter);
+extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
 
 static char e1000_gstrings_stats[][ETH_GSTRING_LEN] = {
 	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
@@ -129,30 +130,9 @@
 		hw->autoneg = 1;
 		hw->autoneg_advertised = 0x002F;
 		ecmd->advertising = 0x002F;
-	} else {
-		hw->autoneg = 0;
-		switch(ecmd->speed + ecmd->duplex) {
-		case SPEED_10 + DUPLEX_HALF:
-			hw->forced_speed_duplex = e1000_10_half;
-			break;
-		case SPEED_10 + DUPLEX_FULL:
-			hw->forced_speed_duplex = e1000_10_full;
-			break;
-		case SPEED_100 + DUPLEX_HALF:
-			hw->forced_speed_duplex = e1000_100_half;
-			break;
-		case SPEED_100 + DUPLEX_FULL:
-			hw->forced_speed_duplex = e1000_100_full;
-			break;
-		case SPEED_1000 + DUPLEX_FULL:
-			hw->autoneg = 1;
-			hw->autoneg_advertised = ADVERTISE_1000_FULL;
-			break;
-		case SPEED_1000 + DUPLEX_HALF: /* not supported */
-		default:
+	} else
+		if(e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex))
 			return -EINVAL;
-		}
-	}
 
 	/* reset the link */
 
@@ -165,16 +145,6 @@
 	return 0;
 }
 
-static inline int
-e1000_eeprom_size(struct e1000_hw *hw)
-{
-	if((hw->mac_type > e1000_82544) &&
-	   (E1000_READ_REG(hw, EECD) & E1000_EECD_SIZE))
-		return 512;
-	else
-		return 128;
-}
-
 static void
 e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
                        struct ethtool_drvinfo *drvinfo)
@@ -186,7 +156,7 @@
 	drvinfo->n_stats = E1000_STATS_LEN;
 #define E1000_REGS_LEN 32
 	drvinfo->regdump_len  = E1000_REGS_LEN * sizeof(uint32_t);
-	drvinfo->eedump_len  = e1000_eeprom_size(&adapter->hw);
+	drvinfo->eedump_len = adapter->hw.eeprom.word_size * 2;
 }
 
 static void
@@ -220,9 +190,8 @@
                       struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff)
 {
 	struct e1000_hw *hw = &adapter->hw;
-	int max_len, first_word, last_word;
+	int first_word, last_word;
 	int ret_val = 0;
-	int i;
 
 	if(eeprom->len == 0) {
 		ret_val = -EINVAL;
@@ -231,22 +200,28 @@
 
 	eeprom->magic = hw->vendor_id | (hw->device_id << 16);
 
-	max_len = e1000_eeprom_size(hw);
-
 	if(eeprom->offset > eeprom->offset + eeprom->len) {
 		ret_val = -EINVAL;
 		goto geeprom_error;
 	}
 
-	if((eeprom->offset + eeprom->len) > max_len)
-		eeprom->len = (max_len - eeprom->offset);
+	if((eeprom->offset + eeprom->len) > (hw->eeprom.word_size * 2))
+		eeprom->len = ((hw->eeprom.word_size * 2) - eeprom->offset);
 
 	first_word = eeprom->offset >> 1;
 	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
 
-	for(i = 0; i <= (last_word - first_word); i++)
-		e1000_read_eeprom(hw, first_word + i, &eeprom_buff[i]);
-
+	if(hw->eeprom.type == e1000_eeprom_spi)
+		ret_val = e1000_read_eeprom(hw, first_word,
+					    last_word - first_word + 1,
+					    eeprom_buff);
+	else {
+		uint16_t i;
+		for (i = 0; i < last_word - first_word + 1; i++)
+			if((ret_val = e1000_read_eeprom(hw, first_word + i, 1,
+						       &eeprom_buff[i])))
+				break;
+	}
 geeprom_error:
 	return ret_val;
 }
@@ -257,9 +232,8 @@
 {
 	struct e1000_hw *hw = &adapter->hw;
 	uint16_t *eeprom_buff;
-	int max_len, first_word, last_word;
 	void *ptr;
-	int i;
+	int max_len, first_word, last_word, ret_val = 0;
 
 	if(eeprom->len == 0)
 		return -EOPNOTSUPP;
@@ -267,7 +241,7 @@
 	if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
 		return -EFAULT;
 
-	max_len = e1000_eeprom_size(hw);
+	max_len = hw->eeprom.word_size * 2;
 
 	if((eeprom->offset + eeprom->len) > max_len)
 		eeprom->len = (max_len - eeprom->offset);
@@ -283,30 +257,31 @@
 	if(eeprom->offset & 1) {
 		/* need read/modify/write of first changed EEPROM word */
 		/* only the second byte of the word is being modified */
-		e1000_read_eeprom(hw, first_word, &eeprom_buff[0]);
+		ret_val = e1000_read_eeprom(hw, first_word, 1,
+					    &eeprom_buff[0]);
 		ptr++;
 	}
-	if((eeprom->offset + eeprom->len) & 1) {
+	if(((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
 		/* need read/modify/write of last changed EEPROM word */
 		/* only the first byte of the word is being modified */
-		e1000_read_eeprom(hw, last_word,
+		ret_val = e1000_read_eeprom(hw, last_word, 1,
 		                  &eeprom_buff[last_word - first_word]);
 	}
-	if(copy_from_user(ptr, user_data, eeprom->len)) {
-		kfree(eeprom_buff);
-		return -EFAULT;
+	if((ret_val != 0) || copy_from_user(ptr, user_data, eeprom->len)) {
+		ret_val = -EFAULT;
+		goto seeprom_error;
 	}
 
-	for(i = 0; i <= (last_word - first_word); i++)
-		e1000_write_eeprom(hw, first_word + i, eeprom_buff[i]);
+	ret_val = e1000_write_eeprom(hw, first_word,
+				     last_word - first_word + 1, eeprom_buff);
 
 	/* Update the checksum over the first part of the EEPROM if needed */
-	if(first_word <= EEPROM_CHECKSUM_REG)
+	if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG)
 		e1000_update_eeprom_checksum(hw);
 
+seeprom_error:
 	kfree(eeprom_buff);
-
-	return 0;
+	return ret_val;
 }
 
 static void
@@ -333,8 +308,8 @@
 		/* Fall Through */
 
 	default:
-		wol->supported = WAKE_UCAST | WAKE_MCAST
-			         | WAKE_BCAST | WAKE_MAGIC;
+		wol->supported = WAKE_UCAST | WAKE_MCAST |
+				 WAKE_BCAST | WAKE_MAGIC;
 
 		wol->wolopts = 0;
 		if(adapter->wol & E1000_WUFC_EX)
@@ -368,7 +343,7 @@
 		/* Fall Through */
 
 	default:
-		if(wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | WAKE_PHY))
+		if(wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
 			return -EOPNOTSUPP;
 
 		adapter->wol = 0;
@@ -542,13 +517,12 @@
 	}
 	case ETHTOOL_GEEPROM: {
 		struct ethtool_eeprom eeprom = {ETHTOOL_GEEPROM};
+		struct e1000_hw *hw = &adapter->hw;
 		uint16_t *eeprom_buff;
 		void *ptr;
-		int max_len, err = 0;
-
-		max_len = e1000_eeprom_size(&adapter->hw);
+		int err = 0;
 
-		eeprom_buff = kmalloc(max_len, GFP_KERNEL);
+		eeprom_buff = kmalloc(hw->eeprom.word_size * 2, GFP_KERNEL);
 
 		if(eeprom_buff == NULL)
 			return -ENOMEM;
diff -Nru a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
--- a/drivers/net/e1000/e1000_hw.c	Fri Oct 18 15:05:05 2002
+++ b/drivers/net/e1000/e1000_hw.c	Wed Mar 19 18:38:35 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -32,6 +32,8 @@
 
 #include "e1000_hw.h"
 
+static int32_t e1000_set_phy_type(struct e1000_hw *hw);
+static void e1000_phy_init_script(struct e1000_hw *hw);
 static int32_t e1000_setup_fiber_link(struct e1000_hw *hw);
 static int32_t e1000_setup_copper_link(struct e1000_hw *hw);
 static int32_t e1000_phy_force_speed_duplex(struct e1000_hw *hw);
@@ -42,19 +44,103 @@
 static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count);
 static uint16_t e1000_shift_in_mdi_bits(struct e1000_hw *hw);
 static int32_t e1000_phy_reset_dsp(struct e1000_hw *hw);
+static int32_t e1000_write_eeprom_spi(struct e1000_hw *hw, uint16_t offset,
+                                      uint16_t words, uint16_t *data);
+static int32_t e1000_write_eeprom_microwire(struct e1000_hw *hw,
+                                            uint16_t offset, uint16_t words,
+                                            uint16_t *data);
+static int32_t e1000_spi_eeprom_ready(struct e1000_hw *hw);
 static void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
 static void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
 static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count);
-static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw);
-static void e1000_setup_eeprom(struct e1000_hw *hw);
-static void e1000_clock_eeprom(struct e1000_hw *hw);
-static void e1000_cleanup_eeprom(struct e1000_hw *hw);
+static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count);
+static int32_t e1000_acquire_eeprom(struct e1000_hw *hw);
+static void e1000_release_eeprom(struct e1000_hw *hw);
 static void e1000_standby_eeprom(struct e1000_hw *hw);
 static int32_t e1000_id_led_init(struct e1000_hw * hw);
 
+
+
+/******************************************************************************
+ * Set the phy type member in the hw struct.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+int32_t
+e1000_set_phy_type(struct e1000_hw *hw)
+{
+    DEBUGFUNC("e1000_set_phy_type");
+
+    switch(hw->phy_id) {
+    case M88E1000_E_PHY_ID:
+    case M88E1000_I_PHY_ID:
+    case M88E1011_I_PHY_ID:
+        hw->phy_type = e1000_phy_m88;
+        break;
+    case IGP01E1000_I_PHY_ID:
+        hw->phy_type = e1000_phy_igp;
+        break;
+    default:
+        /* Should never have loaded on this device */
+        hw->phy_type = e1000_phy_undefined;
+        return -E1000_ERR_PHY_TYPE;
+    }
+
+    return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * IGP phy init script - initializes the GbE PHY
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_phy_init_script(struct e1000_hw *hw)
+{
+    DEBUGFUNC("e1000_phy_init_script");
+
+    if(hw->phy_init_script) {
+        msec_delay(10);
+
+        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);
+        e1000_write_phy_reg(hw,0x0000,0x0140);
+
+        msec_delay(5);
+        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F95);
+        e1000_write_phy_reg(hw,0x0015,0x0001);
+
+        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F71);
+        e1000_write_phy_reg(hw,0x0011,0xBD21);
+
+        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F79);
+        e1000_write_phy_reg(hw,0x0019,0x0018);
+
+        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F30);
+        e1000_write_phy_reg(hw,0x0010,0x1600);
+
+        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F31);
+        e1000_write_phy_reg(hw,0x0011,0x0014);
+
+        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F32);
+        e1000_write_phy_reg(hw,0x0012,0x161C);
+
+        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F94);
+        e1000_write_phy_reg(hw,0x0014,0x0003);
+
+        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F96);
+        e1000_write_phy_reg(hw,0x0016,0x003F);
+
+        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x2010);
+        e1000_write_phy_reg(hw,0x0010,0x0008);
+
+        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);
+        e1000_write_phy_reg(hw,0x0000,0x3300);
+    }
+}
+
 /******************************************************************************
  * Set the mac type member in the hw struct.
- * 
+ *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
 int32_t
@@ -101,10 +187,19 @@
     case E1000_DEV_ID_82546EB_FIBER:
         hw->mac_type = e1000_82546;
         break;
+    case E1000_DEV_ID_82541EI:
+    case E1000_DEV_ID_82541EP:
+        hw->mac_type = e1000_82541;
+        break;
+    case E1000_DEV_ID_82547EI:
+        hw->mac_type = e1000_82547;
+        break;
     default:
         /* Should never have loaded on this device */
         return -E1000_ERR_MAC_TYPE;
     }
+
+
     return E1000_SUCCESS;
 }
 /******************************************************************************
@@ -119,9 +214,10 @@
     uint32_t ctrl_ext;
     uint32_t icr;
     uint32_t manc;
+    uint32_t led_ctrl;
 
     DEBUGFUNC("e1000_reset_hw");
-    
+
     /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
     if(hw->mac_type == e1000_82542_rev2_0) {
         DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
@@ -145,7 +241,7 @@
 
     /* Delay to allow any outstanding PCI transactions to complete before
      * resetting the device
-     */ 
+     */
     msec_delay(10);
 
     /* Issue a global reset to the MAC.  This will reset the chip's
@@ -156,6 +252,12 @@
     DEBUGOUT("Issuing a global reset to MAC\n");
     ctrl = E1000_READ_REG(hw, CTRL);
 
+    /* Must reset the PHY before resetting the MAC */
+    if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+        E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
+	msec_delay(5);
+    }
+
     if(hw->mac_type > e1000_82543)
         E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
     else
@@ -173,13 +275,25 @@
         msec_delay(2);
     } else {
         /* Wait for EEPROM reload (it happens automatically) */
-        msec_delay(4);
+        msec_delay(5);
         /* Dissable HW ARPs on ASF enabled adapters */
         manc = E1000_READ_REG(hw, MANC);
         manc &= ~(E1000_MANC_ARP_EN);
         E1000_WRITE_REG(hw, MANC, manc);
     }
-    
+
+    if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+        e1000_phy_init_script(hw);
+
+        /* Configure activity LED after PHY reset */
+        led_ctrl = E1000_READ_REG(hw, LEDCTL);
+        led_ctrl &= IGP_ACTIVITY_LED_MASK;
+        led_ctrl |= IGP_ACTIVITY_LED_ENABLE;
+        if(hw->mac_type == e1000_82547)
+            led_ctrl |= IGP_LED3_MODE;
+        E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
+    }
+
     /* Clear interrupt mask to stop board from generating interrupts */
     DEBUGOUT("Masking off all interrupts\n");
     E1000_WRITE_REG(hw, IMC, 0xffffffff);
@@ -198,8 +312,8 @@
  * Performs basic configuration of the adapter.
  *
  * hw - Struct containing variables accessed by shared code
- * 
- * Assumes that the controller has previously been reset and is in a 
+ *
+ * Assumes that the controller has previously been reset and is in a
  * post-reset uninitialized state. Initializes the receive address registers,
  * multicast table, and VLAN filter table. Calls routines to setup link
  * configuration and flow control settings. Clears all on-chip counters. Leaves
@@ -224,7 +338,7 @@
         DEBUGOUT("Error Initializing Identification LED\n");
         return ret_val;
     }
-    
+
     /* Set the Media Type and exit with error if it is not valid. */
     if(hw->mac_type != e1000_82543) {
         /* tbi_compatibility is only valid on 82543 */
@@ -327,13 +441,13 @@
 
 /******************************************************************************
  * Configures flow control and link settings.
- * 
+ *
  * hw - Struct containing variables accessed by shared code
- * 
+ *
  * Determines which flow control settings to use. Calls the apropriate media-
  * specific link configuration function. Configures the flow control settings.
  * Assuming the adapter has a valid link partner, a valid link should be
- * established. Assumes the hardware has previously been reset and the 
+ * established. Assumes the hardware has previously been reset and the
  * transmitter and receiver are not enabled.
  *****************************************************************************/
 int32_t
@@ -353,7 +467,7 @@
      * control setting, then the variable hw->fc will
      * be initialized based on a value in the EEPROM.
      */
-    if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, &eeprom_data) < 0) {
+    if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data) < 0) {
         DEBUGOUT("EEPROM Read Error\n");
         return -E1000_ERR_EEPROM;
     }
@@ -361,7 +475,7 @@
     if(hw->fc == e1000_fc_default) {
         if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
             hw->fc = e1000_fc_none;
-        else if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 
+        else if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
                 EEPROM_WORD0F_ASM_DIR)
             hw->fc = e1000_fc_tx_pause;
         else
@@ -390,7 +504,7 @@
      * or e1000_phy_setup() is called.
      */
     if(hw->mac_type == e1000_82543) {
-        ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) << 
+        ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
                     SWDPIO__EXT_SHIFT);
         E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
     }
@@ -416,7 +530,7 @@
      * these registers will be set to a default threshold that may be
      * adjusted later by the driver's runtime code.  However, if the
      * ability to transmit pause frames in not enabled, then these
-     * registers will be set to 0. 
+     * registers will be set to 0.
      */
     if(!(hw->fc & e1000_fc_tx_pause)) {
         E1000_WRITE_REG(hw, FCRTL, 0);
@@ -445,7 +559,7 @@
  * link. Assumes the hardware has been previously reset and the transmitter
  * and receiver are not enabled.
  *****************************************************************************/
-static int32_t 
+static int32_t
 e1000_setup_fiber_link(struct e1000_hw *hw)
 {
     uint32_t ctrl;
@@ -457,29 +571,29 @@
 
     DEBUGFUNC("e1000_setup_fiber_link");
 
-    /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be 
-     * set when the optics detect a signal. On older adapters, it will be 
+    /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
+     * set when the optics detect a signal. On older adapters, it will be
      * cleared when there is a signal
      */
     ctrl = E1000_READ_REG(hw, CTRL);
     if(hw->mac_type > e1000_82544) signal = E1000_CTRL_SWDPIN1;
     else signal = 0;
-   
+
     /* Take the link out of reset */
     ctrl &= ~(E1000_CTRL_LRST);
-    
+
     e1000_config_collision_dist(hw);
 
     /* Check for a software override of the flow control settings, and setup
      * the device accordingly.  If auto-negotiation is enabled, then software
      * will have to set the "PAUSE" bits to the correct value in the Tranmsit
      * Config Word Register (TXCW) and re-start auto-negotiation.  However, if
-     * auto-negotiation is disabled, then software will have to manually 
+     * auto-negotiation is disabled, then software will have to manually
      * configure the two flow control enable bits in the CTRL register.
      *
      * The possible values of the "fc" parameter are:
      *      0:  Flow control is completely disabled
-     *      1:  Rx flow control is enabled (we can receive pause frames, but 
+     *      1:  Rx flow control is enabled (we can receive pause frames, but
      *          not send pause frames).
      *      2:  Tx flow control is enabled (we can send pause frames but we do
      *          not support receiving pause frames).
@@ -491,8 +605,8 @@
         txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
         break;
     case e1000_fc_rx_pause:
-        /* RX Flow control is enabled and TX Flow control is disabled by a 
-         * software over-ride. Since there really isn't a way to advertise 
+        /* RX Flow control is enabled and TX Flow control is disabled by a
+         * software over-ride. Since there really isn't a way to advertise
          * that we are capable of RX Pause ONLY, we will advertise that we
          * support both symmetric and asymmetric RX PAUSE. Later, we will
          *  disable the adapter's ability to send PAUSE frames.
@@ -500,7 +614,7 @@
         txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
         break;
     case e1000_fc_tx_pause:
-        /* TX Flow control is enabled, and RX Flow control is disabled, by a 
+        /* TX Flow control is enabled, and RX Flow control is disabled, by a
          * software over-ride.
          */
         txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
@@ -531,8 +645,8 @@
     msec_delay(1);
 
     /* If we have a signal (the cable is plugged in) then poll for a "Link-Up"
-     * indication in the Device Status Register.  Time-out if a link isn't 
-     * seen in 500 milliseconds seconds (Auto-negotiation should complete in 
+     * indication in the Device Status Register.  Time-out if a link isn't
+     * seen in 500 milliseconds seconds (Auto-negotiation should complete in
      * less than 500 milliseconds even if the other end is doing it in SW).
      */
     if((E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
@@ -543,7 +657,7 @@
             if(status & E1000_STATUS_LU) break;
         }
         if(i == (LINK_UP_TIMEOUT / 10)) {
-            /* AutoNeg failed to achieve a link, so we'll call 
+            /* AutoNeg failed to achieve a link, so we'll call
              * e1000_check_for_link. This routine will force the link up if we
              * detect a signal. This will allow us to communicate with
              * non-autonegotiating link partners.
@@ -571,10 +685,10 @@
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-static int32_t 
+static int32_t
 e1000_setup_copper_link(struct e1000_hw *hw)
 {
-    uint32_t ctrl;
+    uint32_t ctrl, led_ctrl;
     int32_t ret_val;
     uint16_t i;
     uint16_t phy_data;
@@ -604,80 +718,148 @@
     }
     DEBUGOUT1("Phy ID = %x \n", hw->phy_id);
 
-    /* Enable CRS on TX. This must be set for half-duplex operation. */
-    if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
-    phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+    if (hw->phy_type == e1000_phy_igp) {
 
-    /* Options:
-     *   MDI/MDI-X = 0 (default)
-     *   0 - Auto for all speeds
-     *   1 - MDI mode
-     *   2 - MDI-X mode
-     *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
-     */
-    phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+        ret_val = e1000_phy_reset(hw);
+        if(ret_val < 0) {
+            DEBUGOUT("Error Resetting the PHY\n");
+            return ret_val;
+        }
 
-    switch (hw->mdix) {
-    case 1:
-        phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
-        break;
-    case 2:
-        phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
-        break;
-    case 3:
-        phy_data |= M88E1000_PSCR_AUTO_X_1000T;
-        break;
-    case 0:
-    default:
-        phy_data |= M88E1000_PSCR_AUTO_X_MODE;
-        break;
-    }
+        /* Wait 10ms for MAC to configure PHY from eeprom settings */
+        msec_delay(15);
 
-    /* Options:
-     *   disable_polarity_correction = 0 (default)
-     *       Automatic Correction for Reversed Cable Polarity
-     *   0 - Disabled
-     *   1 - Enabled
-     */
-    phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
-    if(hw->disable_polarity_correction == 1)
-        phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
-    if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
-        DEBUGOUT("PHY Write Error\n");
-        return -E1000_ERR_PHY;
-    }
+        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0000) < 0) {
+            DEBUGOUT("PHY Write Error\n");
+            return -E1000_ERR_PHY;
+        }
 
-    /* Force TX_CLK in the Extended PHY Specific Control Register
-     * to 25MHz clock.
-     */
-    if(e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
-    phy_data |= M88E1000_EPSCR_TX_CLK_25;
+        /* Configure activity LED after PHY reset */
+        led_ctrl = E1000_READ_REG(hw, LEDCTL);
+        led_ctrl &= IGP_ACTIVITY_LED_MASK;
+        led_ctrl |= IGP_ACTIVITY_LED_ENABLE;
+        if(hw->mac_type == e1000_82547)
+            led_ctrl |= IGP_LED3_MODE;
+        E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
+
+        if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
+            /* Disable SmartSpeed */
+            if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                  &phy_data) < 0) {
+                DEBUGOUT("PHY Read Error\n");
+                return -E1000_ERR_PHY;
+            }
+            phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+            if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                   phy_data) < 0) {
+                DEBUGOUT("PHY Write Error\n");
+                return -E1000_ERR_PHY;
+            }
+            /* Set auto Master/Slave resolution process */
+            if(e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data) < 0) {
+                DEBUGOUT("PHY Read Error\n");
+                return -E1000_ERR_PHY;
+            }
+            phy_data &= ~CR_1000T_MS_ENABLE;
+            if(e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data) < 0) {
+                DEBUGOUT("PHY Write Error\n");
+                return -E1000_ERR_PHY;
+            }
+        }
 
-    if (hw->phy_revision < M88E1011_I_REV_4) {
-        /* Configure Master and Slave downshift values */
-        phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
-                      M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
-        phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
-                     M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
-        if(e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data) < 0) {
+        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data) < 0) {
+            DEBUGOUT("PHY Read Error\n");
+            return -E1000_ERR_PHY;
+        }
+
+        /* Force MDI for IGP PHY */
+        phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX |
+                      IGP01E1000_PSCR_FORCE_MDI_MDIX);
+
+        hw->mdix = 1;
+
+        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data) < 0) {
             DEBUGOUT("PHY Write Error\n");
             return -E1000_ERR_PHY;
         }
-    }
 
-    /* SW Reset the PHY so all changes take effect */
-    ret_val = e1000_phy_reset(hw);
-    if(ret_val < 0) {
-        DEBUGOUT("Error Resetting the PHY\n");
-        return ret_val;
+    } else {
+        /* Enable CRS on TX. This must be set for half-duplex operation. */
+        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
+            DEBUGOUT("PHY Read Error\n");
+            return -E1000_ERR_PHY;
+        }
+        phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+
+        /* Options:
+         *   MDI/MDI-X = 0 (default)
+         *   0 - Auto for all speeds
+         *   1 - MDI mode
+         *   2 - MDI-X mode
+         *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
+         */
+        phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+
+        switch (hw->mdix) {
+        case 1:
+            phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
+            break;
+        case 2:
+            phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
+            break;
+        case 3:
+            phy_data |= M88E1000_PSCR_AUTO_X_1000T;
+            break;
+        case 0:
+        default:
+            phy_data |= M88E1000_PSCR_AUTO_X_MODE;
+            break;
+        }
+
+        /* Options:
+         *   disable_polarity_correction = 0 (default)
+         *       Automatic Correction for Reversed Cable Polarity
+         *   0 - Disabled
+         *   1 - Enabled
+         */
+        phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
+        if(hw->disable_polarity_correction == 1)
+            phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
+        if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
+            DEBUGOUT("PHY Write Error\n");
+            return -E1000_ERR_PHY;
+        }
+
+        /* Force TX_CLK in the Extended PHY Specific Control Register
+         * to 25MHz clock.
+         */
+        if(e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) {
+            DEBUGOUT("PHY Read Error\n");
+            return -E1000_ERR_PHY;
+        }
+        phy_data |= M88E1000_EPSCR_TX_CLK_25;
+
+        if (hw->phy_revision < M88E1011_I_REV_4) {
+            /* Configure Master and Slave downshift values */
+            phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
+                          M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
+            phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
+                         M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
+            if(e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+                                   phy_data) < 0) {
+                DEBUGOUT("PHY Write Error\n");
+                return -E1000_ERR_PHY;
+            }
+        }
+
+        /* SW Reset the PHY so all changes take effect */
+        ret_val = e1000_phy_reset(hw);
+        if(ret_val < 0) {
+            DEBUGOUT("Error Resetting the PHY\n");
+            return ret_val;
+        }
     }
-    
+
     /* Options:
      *   autoneg = 1 (default)
      *      PHY will advertise value(s) parsed from
@@ -736,6 +918,7 @@
                 return ret_val;
             }
         }
+        hw->get_link_status = TRUE;
     } else {
         DEBUGOUT("Forcing speed and duplex\n");
         ret_val = e1000_phy_force_speed_duplex(hw);
@@ -1014,23 +1197,41 @@
     /* Write the configured values back to the Device Control Reg. */
     E1000_WRITE_REG(hw, CTRL, ctrl);
 
-    if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
+    if (hw->phy_type == e1000_phy_m88) {
+        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
+            DEBUGOUT("PHY Read Error\n");
+            return -E1000_ERR_PHY;
+        }
 
-    /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
-     * forced whenever speed are duplex are forced.
-     */
-    phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
-    if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
-        DEBUGOUT("PHY Write Error\n");
-        return -E1000_ERR_PHY;
-    }
-    DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data);
+        /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
+         * forced whenever speed are duplex are forced.
+         */
+        phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+        if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
+            DEBUGOUT("PHY Write Error\n");
+            return -E1000_ERR_PHY;
+        }
+        DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data);
+
+        /* Need to reset the PHY or these changes will be ignored */
+        mii_ctrl_reg |= MII_CR_RESET;
+    } else {
+        /* Clear Auto-Crossover to force MDI manually.  IGP requires MDI
+         * forced whenever speed or duplex are forced.
+         */
+        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data) < 0) {
+            DEBUGOUT("PHY Read Error\n");
+            return -E1000_ERR_PHY;
+        }
 
-    /* Need to reset the PHY or these changes will be ignored */
-    mii_ctrl_reg |= MII_CR_RESET;
+        phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
+        phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
+
+        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data) < 0) {
+            DEBUGOUT("PHY Write Error\n");
+            return -E1000_ERR_PHY;
+        }
+    }
 
     /* Write back the modified PHY MII control register. */
     if(e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg) < 0) {
@@ -1069,7 +1270,7 @@
         }
         if(i == 0) { /* We didn't get link */
             /* Reset the DSP and wait again for link. */
-            
+
             ret_val = e1000_phy_reset_dsp(hw);
             if(ret_val < 0) {
                 DEBUGOUT("Error Resetting PHY DSP\n");
@@ -1093,32 +1294,34 @@
             }
         }
     }
-    
-    /* Because we reset the PHY above, we need to re-force TX_CLK in the
-     * Extended PHY Specific Control Register to 25MHz clock.  This value
-     * defaults back to a 2.5MHz clock when the PHY is reset.
-     */
-    if(e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
-    phy_data |= M88E1000_EPSCR_TX_CLK_25;
-    if(e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data) < 0) {
-        DEBUGOUT("PHY Write Error\n");
-        return -E1000_ERR_PHY;
-    }
 
-    /* In addition, because of the s/w reset above, we need to enable CRS on
-     * TX.  This must be set for both full and half duplex operation.
-     */
-    if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
-    phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
-    if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
-        DEBUGOUT("PHY Write Error\n");
-        return -E1000_ERR_PHY;
+    if (hw->phy_type == e1000_phy_m88) {
+        /* Because we reset the PHY above, we need to re-force TX_CLK in the
+         * Extended PHY Specific Control Register to 25MHz clock.  This value
+         * defaults back to a 2.5MHz clock when the PHY is reset.
+         */
+        if(e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) {
+            DEBUGOUT("PHY Read Error\n");
+            return -E1000_ERR_PHY;
+        }
+        phy_data |= M88E1000_EPSCR_TX_CLK_25;
+        if(e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data) < 0) {
+            DEBUGOUT("PHY Write Error\n");
+            return -E1000_ERR_PHY;
+        }
+
+        /* In addition, because of the s/w reset above, we need to enable CRS on
+         * TX.  This must be set for both full and half duplex operation.
+         */
+        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
+            DEBUGOUT("PHY Read Error\n");
+            return -E1000_ERR_PHY;
+        }
+        phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+        if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
+            DEBUGOUT("PHY Write Error\n");
+            return -E1000_ERR_PHY;
+        }
     }
     return 0;
 }
@@ -1136,6 +1339,8 @@
 {
     uint32_t tctl;
 
+    DEBUGFUNC("e1000_config_collision_dist");
+
     tctl = E1000_READ_REG(hw, TCTL);
 
     tctl &= ~E1000_TCTL_COLD;
@@ -1172,22 +1377,43 @@
     /* Set up duplex in the Device Control and Transmit Control
      * registers depending on negotiated values.
      */
-    if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
-    if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD;
-    else ctrl &= ~E1000_CTRL_FD;
+    if (hw->phy_type == e1000_phy_igp) {
+        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0) {
+            DEBUGOUT("PHY Read Error\n");
+            return -E1000_ERR_PHY;
+        }
+        if(phy_data & IGP01E1000_PSSR_FULL_DUPLEX) ctrl |= E1000_CTRL_FD;
+        else ctrl &= ~E1000_CTRL_FD;
 
-    e1000_config_collision_dist(hw);
+        e1000_config_collision_dist(hw);
 
-    /* Set up speed in the Device Control register depending on
-     * negotiated values.
-     */
-    if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
-        ctrl |= E1000_CTRL_SPD_1000;
-    else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
-        ctrl |= E1000_CTRL_SPD_100;
+        /* Set up speed in the Device Control register depending on
+         * negotiated values.
+         */
+        if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
+           IGP01E1000_PSSR_SPEED_1000MBPS)
+            ctrl |= E1000_CTRL_SPD_1000;
+        else if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
+                IGP01E1000_PSSR_SPEED_100MBPS)
+            ctrl |= E1000_CTRL_SPD_100;
+    } else {
+        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
+            DEBUGOUT("PHY Read Error\n");
+            return -E1000_ERR_PHY;
+        }
+        if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD;
+        else ctrl &= ~E1000_CTRL_FD;
+
+        e1000_config_collision_dist(hw);
+
+        /* Set up speed in the Device Control register depending on
+         * negotiated values.
+         */
+        if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
+            ctrl |= E1000_CTRL_SPD_1000;
+        else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
+            ctrl |= E1000_CTRL_SPD_100;
+    }
     /* Write the configured values back to the Device Control Reg. */
     E1000_WRITE_REG(hw, CTRL, ctrl);
     return 0;
@@ -1195,7 +1421,7 @@
 
 /******************************************************************************
  * Forces the MAC's flow control settings.
- * 
+ *
  * hw - Struct containing variables accessed by shared code
  *
  * Sets the TFCE and RFCE bits in the device control register to reflect
@@ -1262,7 +1488,7 @@
 
 /******************************************************************************
  * Configures flow control settings after link is established
- * 
+ *
  * hw - Struct containing variables accessed by shared code
  *
  * Should be called immediately after a valid link has been established.
@@ -1484,9 +1710,9 @@
     uint16_t lp_capability;
 
     DEBUGFUNC("e1000_check_for_link");
-    
-    /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be 
-     * set when the optics detect a signal. On older adapters, it will be 
+
+    /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
+     * set when the optics detect a signal. On older adapters, it will be
      * cleared when there is a signal
      */
     if(hw->mac_type > e1000_82544) signal = E1000_CTRL_SWDPIN1;
@@ -1519,6 +1745,10 @@
 
         if(phy_data & MII_SR_LINK_STATUS) {
             hw->get_link_status = FALSE;
+            /* Check if there was DownShift, must be checked immediately after
+             * link-up */
+            e1000_check_downshift(hw);
+
         } else {
             /* No link detected */
             return 0;
@@ -1547,7 +1777,7 @@
             }
         }
 
-        /* Configure Flow Control now that Auto-Neg has completed. First, we 
+        /* Configure Flow Control now that Auto-Neg has completed. First, we
          * need to restore the desired flow control settings because we may
          * have had to re-autoneg with a different link partner.
          */
@@ -1576,7 +1806,7 @@
                                 NWAY_LPAR_100TX_HD_CAPS |
                                 NWAY_LPAR_100TX_FD_CAPS |
                                 NWAY_LPAR_100T4_CAPS)) {
-                /* If our link partner advertises anything in addition to 
+                /* If our link partner advertises anything in addition to
                  * gigabit, we do not need to enable TBI compatibility.
                  */
                 if(hw->tbi_compatibility_on) {
@@ -1780,7 +2010,7 @@
     uint32_t mask;
 
     /* We need to shift "count" number of bits out to the PHY. So, the value
-     * in the "data" parameter will be shifted out to the PHY one bit at a 
+     * in the "data" parameter will be shifted out to the PHY one bit at a
      * time. In order to do this, "data" must be broken down into bits.
      */
     mask = 0x01;
@@ -1817,7 +2047,7 @@
 *
 * hw - Struct containing variables accessed by shared code
 *
-* Bits are shifted in in MSB to LSB order. 
+* Bits are shifted in in MSB to LSB order.
 ******************************************************************************/
 static uint16_t
 e1000_shift_in_mdi_bits(struct e1000_hw *hw)
@@ -1832,7 +2062,7 @@
      * These two bits are ignored by us and thrown away. Bits are "shifted in"
      * by raising the input to the Management Data Clock (setting the MDC bit),
      * and then reading the value of the MDIO bit.
-     */ 
+     */
     ctrl = E1000_READ_REG(hw, CTRL);
 
     /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
@@ -1892,7 +2122,7 @@
          * PHY to retrieve the desired data.
          */
         mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
-                (phy_addr << E1000_MDIC_PHY_SHIFT) | 
+                (phy_addr << E1000_MDIC_PHY_SHIFT) |
                 (E1000_MDIC_OP_READ));
 
         E1000_WRITE_REG(hw, MDIC, mdic);
@@ -1930,7 +2160,7 @@
          * READ operation is performed.  These two bits are thrown away
          * followed by a shift in of 16 bits which contains the desired data.
          */
-        mdic = ((reg_addr) | (phy_addr << 5) | 
+        mdic = ((reg_addr) | (phy_addr << 5) |
                 (PHY_OP_READ << 10) | (PHY_SOF << 12));
 
         e1000_shift_out_mdi_bits(hw, mdic, 14);
@@ -1974,7 +2204,7 @@
          */
         mdic = (((uint32_t) phy_data) |
                 (reg_addr << E1000_MDIC_REG_SHIFT) |
-                (phy_addr << E1000_MDIC_PHY_SHIFT) | 
+                (phy_addr << E1000_MDIC_PHY_SHIFT) |
                 (E1000_MDIC_OP_WRITE));
 
         E1000_WRITE_REG(hw, MDIC, mdic);
@@ -1992,12 +2222,12 @@
     } else {
         /* We'll need to use the SW defined pins to shift the write command
          * out to the PHY. We first send a preamble to the PHY to signal the
-         * beginning of the MII instruction.  This is done by sending 32 
+         * beginning of the MII instruction.  This is done by sending 32
          * consecutive "1" bits.
          */
         e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
 
-        /* Now combine the remaining required fields that will indicate a 
+        /* Now combine the remaining required fields that will indicate a
          * write operation. We use this method instead of calling the
          * e1000_shift_out_mdi_bits routine for each field in the command. The
          * format of a MII write instruction is as follows:
@@ -2010,6 +2240,7 @@
 
         e1000_shift_out_mdi_bits(hw, mdic, 32);
     }
+
     return 0;
 }
 
@@ -2021,8 +2252,7 @@
 void
 e1000_phy_hw_reset(struct e1000_hw *hw)
 {
-    uint32_t ctrl;
-    uint32_t ctrl_ext;
+    uint32_t ctrl, ctrl_ext, led_ctrl;
 
     DEBUGFUNC("e1000_phy_hw_reset");
 
@@ -2053,6 +2283,21 @@
         E1000_WRITE_FLUSH(hw);
     }
     udelay(150);
+
+    if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0000) < 0) {
+            DEBUGOUT("PHY Write Error\n");
+            return;
+        }
+
+        /* Configure activity LED after PHY reset */
+        led_ctrl = E1000_READ_REG(hw, LEDCTL);
+        led_ctrl &= IGP_ACTIVITY_LED_MASK;
+        led_ctrl |= IGP_ACTIVITY_LED_ENABLE;
+        if(hw->mac_type == e1000_82547)
+            led_ctrl |= IGP_LED3_MODE;
+        E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
+    }
 }
 
 /******************************************************************************
@@ -2079,6 +2324,9 @@
         return -E1000_ERR_PHY;
     }
     udelay(1);
+    if (hw->phy_type == e1000_phy_igp) {
+        e1000_phy_init_script(hw);
+    }
     return 0;
 }
 
@@ -2092,6 +2340,7 @@
 {
     uint16_t phy_id_high, phy_id_low;
     boolean_t match = FALSE;
+    int32_t phy_init_status;
 
     DEBUGFUNC("e1000_detect_gig_phy");
 
@@ -2101,7 +2350,7 @@
         return -E1000_ERR_PHY;
     }
     hw->phy_id = (uint32_t) (phy_id_high << 16);
-    udelay(2);
+    udelay(20);
     if(e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low) < 0) {
         DEBUGOUT("PHY Read Error\n");
         return -E1000_ERR_PHY;
@@ -2121,11 +2370,17 @@
     case e1000_82546:
         if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE;
         break;
+    case e1000_82541:
+    case e1000_82547:
+        if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
+        break;
     default:
         DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type);
         return -E1000_ERR_CONFIG;
     }
-    if(match) {
+    phy_init_status = e1000_set_phy_type(hw);
+
+    if ((match) && (phy_init_status == E1000_SUCCESS)) {
         DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
         return 0;
     }
@@ -2143,7 +2398,7 @@
 {
     int32_t ret_val = -E1000_ERR_PHY;
     DEBUGFUNC("e1000_phy_reset_dsp");
-    
+
     do {
         if(e1000_write_phy_reg(hw, 29, 0x001d) < 0) break;
         if(e1000_write_phy_reg(hw, 30, 0x00c1) < 0) break;
@@ -2156,6 +2411,133 @@
 }
 
 /******************************************************************************
+* Get PHY information from various PHY registers for igp PHY only.
+*
+* hw - Struct containing variables accessed by shared code
+* phy_info - PHY information structure
+******************************************************************************/
+int32_t
+e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
+{
+    uint16_t phy_data, polarity, min_length, max_length, average;
+
+    DEBUGFUNC("e1000_phy_igp_get_info");
+
+    /* The downshift status is checked only once, after link is established,
+     * and it stored in the hw->speed_downgraded parameter. */
+    phy_info->downshift = hw->speed_downgraded;
+
+    /* IGP01E1000 does not need to support it. */
+    phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
+
+    /* IGP01E1000 always correct polarity reversal */
+    phy_info->polarity_correction = e1000_polarity_reversal_enabled;
+
+    /* Check polarity status */
+    if(e1000_check_polarity(hw, &polarity) < 0)
+        return -E1000_ERR_PHY;
+
+    phy_info->cable_polarity = polarity;
+
+    if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0)
+        return -E1000_ERR_PHY;
+
+    phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >>
+                          IGP01E1000_PSSR_MDIX_SHIFT;
+
+    if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
+       IGP01E1000_PSSR_SPEED_1000MBPS) {
+        /* Local/Remote Receiver Information are only valid at 1000 Mbps */
+        if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0)
+            return -E1000_ERR_PHY;
+
+        phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+                             SR_1000T_LOCAL_RX_STATUS_SHIFT;
+        phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
+                              SR_1000T_REMOTE_RX_STATUS_SHIFT;
+
+        /* Get cable length */
+        if(e1000_get_cable_length(hw, &min_length, &max_length) < 0)
+            return -E1000_ERR_PHY;
+
+        /* transalte to old method */
+        average = (max_length + min_length) / 2;
+
+        if(average <= e1000_igp_cable_length_50)
+            phy_info->cable_length = e1000_cable_length_50;
+        else if(average <= e1000_igp_cable_length_80)
+            phy_info->cable_length = e1000_cable_length_50_80;
+        else if(average <= e1000_igp_cable_length_110)
+            phy_info->cable_length = e1000_cable_length_80_110;
+        else if(average <= e1000_igp_cable_length_140)
+            phy_info->cable_length = e1000_cable_length_110_140;
+        else
+            phy_info->cable_length = e1000_cable_length_140;
+    }
+
+    return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Get PHY information from various PHY registers fot m88 PHY only.
+*
+* hw - Struct containing variables accessed by shared code
+* phy_info - PHY information structure
+******************************************************************************/
+int32_t
+e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
+{
+    uint16_t phy_data, polarity;
+
+    DEBUGFUNC("e1000_phy_m88_get_info");
+
+    /* The downshift status is checked only once, after link is established,
+     * and it stored in the hw->speed_downgraded parameter. */
+    phy_info->downshift = hw->speed_downgraded;
+
+    if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0)
+        return -E1000_ERR_PHY;
+
+    phy_info->extended_10bt_distance =
+        (phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
+        M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT;
+    phy_info->polarity_correction =
+        (phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
+        M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
+
+    /* Check polarity status */
+    if(e1000_check_polarity(hw, &polarity) < 0)
+        return -E1000_ERR_PHY;
+
+    phy_info->cable_polarity = polarity;
+
+    if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
+        return -E1000_ERR_PHY;
+
+    phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
+                          M88E1000_PSSR_MDIX_SHIFT;
+
+    if(phy_data & M88E1000_PSSR_1000MBS) {
+        /* Cable Length Estimation and Local/Remote Receiver Informatoion
+         * are only valid at 1000 Mbps
+         */
+        phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+                                  M88E1000_PSSR_CABLE_LENGTH_SHIFT);
+
+        if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0)
+            return -E1000_ERR_PHY;
+
+        phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
+                             SR_1000T_LOCAL_RX_STATUS_SHIFT;
+
+        phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
+                              SR_1000T_REMOTE_RX_STATUS_SHIFT;
+    }
+
+    return E1000_SUCCESS;
+}
+
+/******************************************************************************
 * Get PHY information from various PHY registers
 *
 * hw - Struct containing variables accessed by shared code
@@ -2165,7 +2547,6 @@
 e1000_phy_get_info(struct e1000_hw *hw,
                    struct e1000_phy_info *phy_info)
 {
-    int32_t ret_val = -E1000_ERR_PHY;
     uint16_t phy_data;
 
     DEBUGFUNC("e1000_phy_get_info");
@@ -2173,6 +2554,7 @@
     phy_info->cable_length = e1000_cable_length_undefined;
     phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_undefined;
     phy_info->cable_polarity = e1000_rev_polarity_undefined;
+    phy_info->downshift = e1000_downshift_undefined;
     phy_info->polarity_correction = e1000_polarity_reversal_undefined;
     phy_info->mdix_mode = e1000_auto_x_mode_undefined;
     phy_info->local_rx = e1000_1000t_rx_status_undefined;
@@ -2183,47 +2565,23 @@
         return -E1000_ERR_CONFIG;
     }
 
-    do {
-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) break;
-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) break;
-        if((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
-            DEBUGOUT("PHY info is only valid if link is up\n");
-            return -E1000_ERR_CONFIG;
-        }
-
-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0)
-            break;
-        phy_info->extended_10bt_distance =
-            (phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
-            M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT;
-        phy_info->polarity_correction =
-            (phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
-            M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
-
-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
-            break;
-        phy_info->cable_polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
-            M88E1000_PSSR_REV_POLARITY_SHIFT;
-        phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
-            M88E1000_PSSR_MDIX_SHIFT;
-        if(phy_data & M88E1000_PSSR_1000MBS) {
-            /* Cable Length Estimation and Local/Remote Receiver Informatoion
-             * are only valid at 1000 Mbps
-             */
-            phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
-                                      M88E1000_PSSR_CABLE_LENGTH_SHIFT);
-            if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0) 
-                break;
-            phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
-                SR_1000T_LOCAL_RX_STATUS_SHIFT;
-            phy_info->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) >>
-                SR_1000T_REMOTE_RX_STATUS_SHIFT;
-        }
-        ret_val = 0;
-    } while(0);
+    if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+        DEBUGOUT("PHY Read Error\n");
+        return -E1000_ERR_PHY;
+    }
+    if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
+        DEBUGOUT("PHY Read Error\n");
+        return -E1000_ERR_PHY;
+    }
+    if((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
+        DEBUGOUT("PHY info is only valid if link is up\n");
+        return -E1000_ERR_CONFIG;
+    }
 
-    if(ret_val < 0) DEBUGOUT("PHY Read Error\n");
-    return ret_val;
+    if (hw->phy_type == e1000_phy_igp)
+        return e1000_phy_igp_get_info(hw, phy_info);
+    else
+        return e1000_phy_m88_get_info(hw, phy_info);
 }
 
 int32_t
@@ -2239,6 +2597,109 @@
     return 0;
 }
 
+
+/******************************************************************************
+ * Sets up eeprom variables in the hw struct.  Must be called after mac_type
+ * is configured.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+void
+e1000_init_eeprom_params(struct e1000_hw *hw)
+{
+    struct e1000_eeprom_info *eeprom = &hw->eeprom;
+    uint32_t eecd = E1000_READ_REG(hw, EECD);
+    uint16_t eeprom_size;
+
+    DEBUGFUNC("e1000_init_eeprom_params");
+
+    switch (hw->mac_type) {
+    case e1000_82542_rev2_0:
+    case e1000_82542_rev2_1:
+    case e1000_82543:
+    case e1000_82544:
+        eeprom->type = e1000_eeprom_microwire;
+        eeprom->word_size = 64;
+        eeprom->opcode_bits = 3;
+        eeprom->address_bits = 6;
+        eeprom->delay_usec = 50;
+        break;
+    case e1000_82540:
+    case e1000_82545:
+    case e1000_82546:
+        eeprom->type = e1000_eeprom_microwire;
+        eeprom->opcode_bits = 3;
+        eeprom->delay_usec = 50;
+        if(eecd & E1000_EECD_SIZE) {
+            eeprom->word_size = 256;
+            eeprom->address_bits = 8;
+        } else {
+            eeprom->word_size = 64;
+            eeprom->address_bits = 6;
+        }
+        break;
+    case e1000_82541:
+    case e1000_82547:
+    default:
+        if (eecd & E1000_EECD_TYPE) {
+            eeprom->type = e1000_eeprom_spi;
+            eeprom->opcode_bits = 8;
+            eeprom->delay_usec = 1;
+            if (eecd & E1000_EECD_ADDR_BITS) {
+                eeprom->page_size = 32;
+                eeprom->address_bits = 16;
+            } else {
+                eeprom->page_size = 8;
+                eeprom->address_bits = 8;
+            }
+        } else {
+            eeprom->type = e1000_eeprom_microwire;
+            eeprom->opcode_bits = 3;
+            eeprom->delay_usec = 50;
+            if (eecd & E1000_EECD_ADDR_BITS) {
+                eeprom->word_size = 256;
+                eeprom->address_bits = 8;
+            } else {
+                eeprom->word_size = 64;
+                eeprom->address_bits = 6;
+            }
+        }
+        break;
+    }
+
+    if (eeprom->type == e1000_eeprom_spi) {
+        eeprom->word_size = 64;
+        if (e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size) == 0) {
+            eeprom_size &= EEPROM_SIZE_MASK;
+
+            switch (eeprom_size) {
+                case EEPROM_SIZE_16KB:
+                    eeprom->word_size = 8192;
+                    break;
+                case EEPROM_SIZE_8KB:
+                    eeprom->word_size = 4096;
+                    break;
+                case EEPROM_SIZE_4KB:
+                    eeprom->word_size = 2048;
+                    break;
+                case EEPROM_SIZE_2KB:
+                    eeprom->word_size = 1024;
+                    break;
+                case EEPROM_SIZE_1KB:
+                    eeprom->word_size = 512;
+                    break;
+                case EEPROM_SIZE_512B:
+                    eeprom->word_size = 256;
+                    break;
+                case EEPROM_SIZE_128B:
+                default:
+                    eeprom->word_size = 64;
+                    break;
+            }
+        }
+    }
+}
+
 /******************************************************************************
  * Raises the EEPROM's clock input.
  *
@@ -2255,26 +2716,26 @@
     *eecd = *eecd | E1000_EECD_SK;
     E1000_WRITE_REG(hw, EECD, *eecd);
     E1000_WRITE_FLUSH(hw);
-    udelay(50);
+    udelay(hw->eeprom.delay_usec);
 }
 
 /******************************************************************************
  * Lowers the EEPROM's clock input.
  *
- * hw - Struct containing variables accessed by shared code 
+ * hw - Struct containing variables accessed by shared code
  * eecd - EECD's current value
  *****************************************************************************/
 static void
 e1000_lower_ee_clk(struct e1000_hw *hw,
                    uint32_t *eecd)
 {
-    /* Lower the clock input to the EEPROM (by clearing the SK bit), and then 
-     * wait 50 microseconds. 
+    /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
+     * wait 50 microseconds.
      */
     *eecd = *eecd & ~E1000_EECD_SK;
     E1000_WRITE_REG(hw, EECD, *eecd);
     E1000_WRITE_FLUSH(hw);
-    udelay(50);
+    udelay(hw->eeprom.delay_usec);
 }
 
 /******************************************************************************
@@ -2289,16 +2750,21 @@
                         uint16_t data,
                         uint16_t count)
 {
+    struct e1000_eeprom_info *eeprom = &hw->eeprom;
     uint32_t eecd;
     uint32_t mask;
 
     /* We need to shift "count" bits out to the EEPROM. So, value in the
      * "data" parameter will be shifted out to the EEPROM one bit at a time.
-     * In order to do this, "data" must be broken down into bits. 
+     * In order to do this, "data" must be broken down into bits.
      */
     mask = 0x01 << (count - 1);
     eecd = E1000_READ_REG(hw, EECD);
-    eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
+    if (eeprom->type == e1000_eeprom_microwire) {
+        eecd &= ~E1000_EECD_DO;
+    } else if (eeprom->type == e1000_eeprom_spi) {
+        eecd |= E1000_EECD_DO;
+    }
     do {
         /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
          * and then raising and then lowering the clock (the SK bit controls
@@ -2313,7 +2779,7 @@
         E1000_WRITE_REG(hw, EECD, eecd);
         E1000_WRITE_FLUSH(hw);
 
-        udelay(50);
+        udelay(eeprom->delay_usec);
 
         e1000_raise_ee_clk(hw, &eecd);
         e1000_lower_ee_clk(hw, &eecd);
@@ -2333,7 +2799,7 @@
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
 static uint16_t
-e1000_shift_in_ee_bits(struct e1000_hw *hw)
+e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count)
 {
     uint32_t eecd;
     uint32_t i;
@@ -2351,7 +2817,7 @@
     eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
     data = 0;
 
-    for(i = 0; i < 16; i++) {
+    for(i = 0; i < count; i++) {
         data = data << 1;
         e1000_raise_ee_clk(hw, &eecd);
 
@@ -2372,104 +2838,196 @@
  *
  * hw - Struct containing variables accessed by shared code
  *
- * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This 
+ * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
  * function should be called before issuing a command to the EEPROM.
  *****************************************************************************/
-static void
-e1000_setup_eeprom(struct e1000_hw *hw)
+static int32_t
+e1000_acquire_eeprom(struct e1000_hw *hw)
 {
-    uint32_t eecd;
+    struct e1000_eeprom_info *eeprom = &hw->eeprom;
+    uint32_t eecd, i=0;
+
+    DEBUGFUNC("e1000_acquire_eeprom");
 
     eecd = E1000_READ_REG(hw, EECD);
 
-    /* Clear SK and DI */
-    eecd &= ~(E1000_EECD_SK | E1000_EECD_DI);
-    E1000_WRITE_REG(hw, EECD, eecd);
+    /* Request EEPROM Access */
+    if(hw->mac_type > e1000_82544) {
+        eecd |= E1000_EECD_REQ;
+        E1000_WRITE_REG(hw, EECD, eecd);
+        eecd = E1000_READ_REG(hw, EECD);
+        while((!(eecd & E1000_EECD_GNT)) &&
+              (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
+            i++;
+            udelay(5);
+            eecd = E1000_READ_REG(hw, EECD);
+        }
+        if(!(eecd & E1000_EECD_GNT)) {
+            eecd &= ~E1000_EECD_REQ;
+            E1000_WRITE_REG(hw, EECD, eecd);
+            DEBUGOUT("Could not acquire EEPROM grant\n");
+            return -E1000_ERR_EEPROM;
+        }
+    }
 
-    /* Set CS */
-    eecd |= E1000_EECD_CS;
-    E1000_WRITE_REG(hw, EECD, eecd);
+    /* Setup EEPROM for Read/Write */
+
+    if (eeprom->type == e1000_eeprom_microwire) {
+        /* Clear SK and DI */
+        eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
+        E1000_WRITE_REG(hw, EECD, eecd);
+
+        /* Set CS */
+        eecd |= E1000_EECD_CS;
+        E1000_WRITE_REG(hw, EECD, eecd);
+    } else if (eeprom->type == e1000_eeprom_spi) {
+        /* Clear SK and CS */
+        eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
+        E1000_WRITE_REG(hw, EECD, eecd);
+        udelay(1);
+    }
+
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
  * Returns EEPROM to a "standby" state
- * 
+ *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
 static void
 e1000_standby_eeprom(struct e1000_hw *hw)
 {
+    struct e1000_eeprom_info *eeprom = &hw->eeprom;
     uint32_t eecd;
 
     eecd = E1000_READ_REG(hw, EECD);
 
-    /* Deselct EEPROM */
-    eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
-    E1000_WRITE_REG(hw, EECD, eecd);
-    E1000_WRITE_FLUSH(hw);
-    udelay(50);
+    if(eeprom->type == e1000_eeprom_microwire) {
+        eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
+        E1000_WRITE_REG(hw, EECD, eecd);
+        E1000_WRITE_FLUSH(hw);
+        udelay(eeprom->delay_usec);
 
-    /* Clock high */
-    eecd |= E1000_EECD_SK;
-    E1000_WRITE_REG(hw, EECD, eecd);
-    E1000_WRITE_FLUSH(hw);
-    udelay(50);
+        /* Clock high */
+        eecd |= E1000_EECD_SK;
+        E1000_WRITE_REG(hw, EECD, eecd);
+        E1000_WRITE_FLUSH(hw);
+        udelay(eeprom->delay_usec);
 
-    /* Select EEPROM */
-    eecd |= E1000_EECD_CS;
-    E1000_WRITE_REG(hw, EECD, eecd);
-    E1000_WRITE_FLUSH(hw);
-    udelay(50);
+        /* Select EEPROM */
+        eecd |= E1000_EECD_CS;
+        E1000_WRITE_REG(hw, EECD, eecd);
+        E1000_WRITE_FLUSH(hw);
+        udelay(eeprom->delay_usec);
 
-    /* Clock low */
-    eecd &= ~E1000_EECD_SK;
-    E1000_WRITE_REG(hw, EECD, eecd);
-    E1000_WRITE_FLUSH(hw);
-    udelay(50);
+        /* Clock low */
+        eecd &= ~E1000_EECD_SK;
+        E1000_WRITE_REG(hw, EECD, eecd);
+        E1000_WRITE_FLUSH(hw);
+        udelay(eeprom->delay_usec);
+    } else if(eeprom->type == e1000_eeprom_spi) {
+        /* Toggle CS to flush commands */
+        eecd |= E1000_EECD_CS;
+        E1000_WRITE_REG(hw, EECD, eecd);
+        E1000_WRITE_FLUSH(hw);
+        udelay(eeprom->delay_usec);
+        eecd &= ~E1000_EECD_CS;
+        E1000_WRITE_REG(hw, EECD, eecd);
+        E1000_WRITE_FLUSH(hw);
+        udelay(eeprom->delay_usec);
+    }
 }
 
 /******************************************************************************
- * Raises then lowers the EEPROM's clock pin
+ * Terminates a command by inverting the EEPROM's chip select pin
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
 static void
-e1000_clock_eeprom(struct e1000_hw *hw)
+e1000_release_eeprom(struct e1000_hw *hw)
 {
     uint32_t eecd;
 
+    DEBUGFUNC("e1000_release_eeprom");
+
     eecd = E1000_READ_REG(hw, EECD);
 
-    /* Rising edge of clock */
-    eecd |= E1000_EECD_SK;
-    E1000_WRITE_REG(hw, EECD, eecd);
-    E1000_WRITE_FLUSH(hw);
-    udelay(50);
+    if (hw->eeprom.type == e1000_eeprom_spi) {
+        eecd |= E1000_EECD_CS;  /* Pull CS high */
+        eecd &= ~E1000_EECD_SK; /* Lower SCK */
 
-    /* Falling edge of clock */
-    eecd &= ~E1000_EECD_SK;
-    E1000_WRITE_REG(hw, EECD, eecd);
-    E1000_WRITE_FLUSH(hw);
-    udelay(50);
+        E1000_WRITE_REG(hw, EECD, eecd);
+
+        udelay(hw->eeprom.delay_usec);
+    } else if(hw->eeprom.type == e1000_eeprom_microwire) {
+        /* cleanup eeprom */
+
+        /* CS on Microwire is active-high */
+        eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
+
+        E1000_WRITE_REG(hw, EECD, eecd);
+
+        /* Rising edge of clock */
+        eecd |= E1000_EECD_SK;
+        E1000_WRITE_REG(hw, EECD, eecd);
+        E1000_WRITE_FLUSH(hw);
+        udelay(hw->eeprom.delay_usec);
+
+        /* Falling edge of clock */
+        eecd &= ~E1000_EECD_SK;
+        E1000_WRITE_REG(hw, EECD, eecd);
+        E1000_WRITE_FLUSH(hw);
+        udelay(hw->eeprom.delay_usec);
+    }
+
+    /* Stop requesting EEPROM access */
+    if(hw->mac_type > e1000_82544) {
+        eecd &= ~E1000_EECD_REQ;
+        E1000_WRITE_REG(hw, EECD, eecd);
+    }
 }
 
 /******************************************************************************
- * Terminates a command by lowering the EEPROM's chip select pin
+ * Reads a 16 bit word from the EEPROM.
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void
-e1000_cleanup_eeprom(struct e1000_hw *hw)
+int32_t
+e1000_spi_eeprom_ready(struct e1000_hw *hw)
 {
-    uint32_t eecd;
+    uint16_t retry_count = 0;
+    uint8_t spi_stat_reg;
 
-    eecd = E1000_READ_REG(hw, EECD);
+    DEBUGFUNC("e1000_spi_eeprom_ready");
+
+    /* Read "Status Register" repeatedly until the LSB is cleared.  The
+     * EEPROM will signal that the command has been completed by clearing
+     * bit 0 of the internal status register.  If it's not cleared within
+     * 5 milliseconds, then error out.
+     */
+    retry_count = 0;
+    do {
+        e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
+                                hw->eeprom.opcode_bits);
+        spi_stat_reg = (uint8_t)e1000_shift_in_ee_bits(hw, 8);
+        if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
+            break;
 
-    eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
+        udelay(5);
+        retry_count += 5;
 
-    E1000_WRITE_REG(hw, EECD, eecd);
+    } while(retry_count < EEPROM_MAX_RETRY_SPI);
+
+    /* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
+     * only 0-5mSec on 5V devices)
+     */
+    if(retry_count >= EEPROM_MAX_RETRY_SPI) {
+        DEBUGOUT("SPI EEPROM Status error\n");
+        return -E1000_ERR_EEPROM;
+    }
 
-    e1000_clock_eeprom(hw);
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -2477,71 +3035,76 @@
  *
  * hw - Struct containing variables accessed by shared code
  * offset - offset of  word in the EEPROM to read
- * data - word read from the EEPROM 
+ * data - word read from the EEPROM
+ * words - number of words to read
  *****************************************************************************/
 int32_t
 e1000_read_eeprom(struct e1000_hw *hw,
                   uint16_t offset,
+                  uint16_t words,
                   uint16_t *data)
 {
-    uint32_t eecd;
+    struct e1000_eeprom_info *eeprom = &hw->eeprom;
     uint32_t i = 0;
-    boolean_t large_eeprom = FALSE;
 
     DEBUGFUNC("e1000_read_eeprom");
 
-    /* Request EEPROM Access */
-    if(hw->mac_type > e1000_82544) {
-        eecd = E1000_READ_REG(hw, EECD);
-        if(eecd & E1000_EECD_SIZE) large_eeprom = TRUE;
-        eecd |= E1000_EECD_REQ;
-        E1000_WRITE_REG(hw, EECD, eecd);
-        eecd = E1000_READ_REG(hw, EECD);
-        while((!(eecd & E1000_EECD_GNT)) && (i < 100)) {
-            i++;
-            udelay(5);
-            eecd = E1000_READ_REG(hw, EECD);
-        }
-        if(!(eecd & E1000_EECD_GNT)) {
-            eecd &= ~E1000_EECD_REQ;
-            E1000_WRITE_REG(hw, EECD, eecd);
-            DEBUGOUT("Could not acquire EEPROM grant\n");
-            return -E1000_ERR_EEPROM;
-        }
+    /* A check for invalid values:  offset too large, too many words, and not
+     * enough words.
+     */
+    if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) ||
+       (words == 0)) {
+        DEBUGOUT("\"words\" parameter out of bounds\n");
+        return -E1000_ERR_EEPROM;
     }
 
-    /*  Prepare the EEPROM for reading  */
-    e1000_setup_eeprom(hw);
+    /* Prepare the EEPROM for reading  */
+    if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+        return -E1000_ERR_EEPROM;
 
-    /*  Send the READ command (opcode + addr)  */
-    e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE, 3);
-    if(large_eeprom) {
-        /* If we have a 256 word EEPROM, there are 8 address bits */
-        e1000_shift_out_ee_bits(hw, offset, 8);
-    } else {
-        /* If we have a 64 word EEPROM, there are 6 address bits */
-        e1000_shift_out_ee_bits(hw, offset, 6);
-    }
+    if(eeprom->type == e1000_eeprom_spi) {
+        uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
 
-    /* Read the data */
-    *data = e1000_shift_in_ee_bits(hw);
+        if(e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;
 
-    /* End this read operation */
-    e1000_standby_eeprom(hw);
+        e1000_standby_eeprom(hw);
 
-    /* Stop requesting EEPROM access */
-    if(hw->mac_type > e1000_82544) {
-        eecd = E1000_READ_REG(hw, EECD);
-        eecd &= ~E1000_EECD_REQ;
-        E1000_WRITE_REG(hw, EECD, eecd);
+        /* Some SPI eeproms use the 8th address bit embedded in the opcode */
+        if((eeprom->address_bits == 8) && (offset >= 128))
+            read_opcode |= EEPROM_A8_OPCODE_SPI;
+
+        /* Send the READ command (opcode + addr)  */
+        e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
+        e1000_shift_out_ee_bits(hw, (uint16_t)(offset*2), eeprom->address_bits);
+    }
+    else if(eeprom->type == e1000_eeprom_microwire) {
+        /* Send the READ command (opcode + addr)  */
+        e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
+                                eeprom->opcode_bits);
+        e1000_shift_out_ee_bits(hw, offset, eeprom->address_bits);
+    }
+
+    /* Read the data.  The address of the eeprom internally increments with
+     * each word (microwire) or byte (spi) being read, saving on the overhead
+     * of eeprom setup and tear-down.  The address counter will roll over if
+     * reading beyond the size of the eeprom, thus allowing the entire memory
+     * to be read starting from any offset. */
+    for (i = 0; i < words; i++) {
+        uint16_t word_in = e1000_shift_in_ee_bits(hw, 16);
+        if (eeprom->type == e1000_eeprom_spi)
+            word_in = (word_in >> 8) | (word_in << 8);
+        data[i] = word_in;
     }
 
+    /* End this read operation */
+    e1000_release_eeprom(hw);
+
     return 0;
 }
 
 /******************************************************************************
  * Verifies that the EEPROM has a valid checksum
- * 
+ *
  * hw - Struct containing variables accessed by shared code
  *
  * Reads the first 64 16 bit words of the EEPROM and sums the values read.
@@ -2557,7 +3120,7 @@
     DEBUGFUNC("e1000_validate_eeprom_checksum");
 
     for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
-        if(e1000_read_eeprom(hw, i, &eeprom_data) < 0) {
+        if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
             DEBUGOUT("EEPROM Read Error\n");
             return -E1000_ERR_EEPROM;
         }
@@ -2567,7 +3130,7 @@
     if(checksum == (uint16_t) EEPROM_SUM) {
         return 0;
     } else {
-        DEBUGOUT("EEPROM Checksum Invalid\n");    
+        DEBUGOUT("EEPROM Checksum Invalid\n");
         return -E1000_ERR_EEPROM;
     }
 }
@@ -2589,14 +3152,14 @@
     DEBUGFUNC("e1000_update_eeprom_checksum");
 
     for(i = 0; i < EEPROM_CHECKSUM_REG; i++) {
-        if(e1000_read_eeprom(hw, i, &eeprom_data) < 0) {
+        if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
             DEBUGOUT("EEPROM Read Error\n");
             return -E1000_ERR_EEPROM;
         }
         checksum += eeprom_data;
     }
     checksum = (uint16_t) EEPROM_SUM - checksum;
-    if(e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, checksum) < 0) {
+    if(e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
         DEBUGOUT("EEPROM Write Error\n");
         return -E1000_ERR_EEPROM;
     }
@@ -2604,118 +3167,201 @@
 }
 
 /******************************************************************************
- * Writes a 16 bit word to a given offset in the EEPROM.
+ * Parent function for writing words to the different EEPROM types.
  *
  * hw - Struct containing variables accessed by shared code
  * offset - offset within the EEPROM to be written to
- * data - 16 bit word to be writen to the EEPROM
+ * words - number of words to write
+ * data - 16 bit word to be written to the EEPROM
  *
- * If e1000_update_eeprom_checksum is not called after this function, the 
+ * If e1000_update_eeprom_checksum is not called after this function, the
  * EEPROM will most likely contain an invalid checksum.
  *****************************************************************************/
 int32_t
 e1000_write_eeprom(struct e1000_hw *hw,
                    uint16_t offset,
-                   uint16_t data)
+                   uint16_t words,
+                   uint16_t *data)
 {
-    uint32_t eecd;
-    uint32_t i = 0;
+    struct e1000_eeprom_info *eeprom = &hw->eeprom;
     int32_t status = 0;
-    boolean_t large_eeprom = FALSE;
 
     DEBUGFUNC("e1000_write_eeprom");
 
-    /* Request EEPROM Access */
-    if(hw->mac_type > e1000_82544) {
-        eecd = E1000_READ_REG(hw, EECD);
-        if(eecd & E1000_EECD_SIZE) large_eeprom = TRUE;
-        eecd |= E1000_EECD_REQ;
-        E1000_WRITE_REG(hw, EECD, eecd);
-        eecd = E1000_READ_REG(hw, EECD);
-        while((!(eecd & E1000_EECD_GNT)) && (i < 100)) {
-            i++;
-            udelay(5);
-            eecd = E1000_READ_REG(hw, EECD);
-        }
-        if(!(eecd & E1000_EECD_GNT)) {
-            eecd &= ~E1000_EECD_REQ;
-            E1000_WRITE_REG(hw, EECD, eecd);
-            DEBUGOUT("Could not acquire EEPROM grant\n");
-            return -E1000_ERR_EEPROM;
-        }
+    /* A check for invalid values:  offset too large, too many words, and not
+     * enough words.
+     */
+    if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) ||
+       (words == 0)) {
+        DEBUGOUT("\"words\" parameter out of bounds\n");
+        return -E1000_ERR_EEPROM;
     }
 
     /* Prepare the EEPROM for writing  */
-    e1000_setup_eeprom(hw);
+    if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+        return -E1000_ERR_EEPROM;
 
-    /* Send the 9-bit (or 11-bit on large EEPROM) EWEN (write enable) command
-     * to the EEPROM (5-bit opcode plus 4/6-bit dummy). This puts the EEPROM
-     * into write/erase mode. 
-     */
-    e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE, 5);
-    if(large_eeprom) 
-        e1000_shift_out_ee_bits(hw, 0, 6);
+    if(eeprom->type == e1000_eeprom_microwire)
+        status = e1000_write_eeprom_microwire(hw, offset, words, data);
     else
-        e1000_shift_out_ee_bits(hw, 0, 4);
+        status = e1000_write_eeprom_spi(hw, offset, words, data);
 
-    /* Prepare the EEPROM */
-    e1000_standby_eeprom(hw);
+    /* Done with writing */
+    e1000_release_eeprom(hw);
 
-    /* Send the Write command (3-bit opcode + addr) */
-    e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE, 3);
-    if(large_eeprom) 
-        /* If we have a 256 word EEPROM, there are 8 address bits */
-        e1000_shift_out_ee_bits(hw, offset, 8);
-    else
-        /* If we have a 64 word EEPROM, there are 6 address bits */
-        e1000_shift_out_ee_bits(hw, offset, 6);
+    return status;
+}
 
-    /* Send the data */
-    e1000_shift_out_ee_bits(hw, data, 16);
+/******************************************************************************
+ * Writes a 16 bit word to a given offset in an SPI EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * offset - offset within the EEPROM to be written to
+ * words - number of words to write
+ * data - pointer to array of 8 bit words to be written to the EEPROM
+ *
+ *****************************************************************************/
+int32_t
+e1000_write_eeprom_spi(struct e1000_hw *hw,
+                       uint16_t offset,
+                       uint16_t words,
+                       uint16_t *data)
+{
+    struct e1000_eeprom_info *eeprom = &hw->eeprom;
+    uint16_t widx = 0;
 
-    /* Toggle the CS line.  This in effect tells to EEPROM to actually execute 
-     * the command in question.
-     */
-    e1000_standby_eeprom(hw);
+    DEBUGFUNC("e1000_write_eeprom_spi");
 
-    /* Now read DO repeatedly until is high (equal to '1').  The EEEPROM will
-     * signal that the command has been completed by raising the DO signal.
-     * If DO does not go high in 10 milliseconds, then error out.
-     */
-    for(i = 0; i < 200; i++) {
-        eecd = E1000_READ_REG(hw, EECD);
-        if(eecd & E1000_EECD_DO) break;
-        udelay(50);
-    }
-    if(i == 200) {
-        DEBUGOUT("EEPROM Write did not complete\n");
-        status = -E1000_ERR_EEPROM;
+    while (widx < words) {
+        uint8_t write_opcode = EEPROM_WRITE_OPCODE_SPI;
+
+        if(e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;
+
+        e1000_standby_eeprom(hw);
+
+        /*  Send the WRITE ENABLE command (8 bit opcode )  */
+        e1000_shift_out_ee_bits(hw, EEPROM_WREN_OPCODE_SPI,
+                                    eeprom->opcode_bits);
+
+        e1000_standby_eeprom(hw);
+
+        /* Some SPI eeproms use the 8th address bit embedded in the opcode */
+        if((eeprom->address_bits == 8) && (offset >= 128))
+            write_opcode |= EEPROM_A8_OPCODE_SPI;
+
+        /* Send the Write command (8-bit opcode + addr) */
+        e1000_shift_out_ee_bits(hw, write_opcode, eeprom->opcode_bits);
+
+        e1000_shift_out_ee_bits(hw, (uint16_t)((offset + widx)*2),
+                                eeprom->address_bits);
+
+        /* Send the data */
+
+        /* Loop to allow for up to whole page write (32 bytes) of eeprom */
+        while (widx < words) {
+            uint16_t word_out = data[widx];
+            word_out = (word_out >> 8) | (word_out << 8);
+            e1000_shift_out_ee_bits(hw, word_out, 16);
+            widx++;
+
+            /* Some larger eeprom sizes are capable of a 32-byte PAGE WRITE
+             * operation, while the smaller eeproms are capable of an 8-byte
+             * PAGE WRITE operation.  Break the inner loop to pass new address
+             */
+            if((((offset + widx)*2) % eeprom->page_size) == 0) {
+                e1000_standby_eeprom(hw);
+                break;
+            }
+        }
     }
 
-    /* Recover from write */
+    return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Writes a 16 bit word to a given offset in a Microwire EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * offset - offset within the EEPROM to be written to
+ * words - number of words to write
+ * data - pointer to array of 16 bit words to be written to the EEPROM
+ *
+ *****************************************************************************/
+int32_t
+e1000_write_eeprom_microwire(struct e1000_hw *hw,
+                             uint16_t offset,
+                             uint16_t words,
+                             uint16_t *data)
+{
+    struct e1000_eeprom_info *eeprom = &hw->eeprom;
+    uint32_t eecd;
+    uint16_t words_written = 0;
+    uint16_t i = 0;
+
+    DEBUGFUNC("e1000_write_eeprom_microwire");
+
+    /* Send the write enable command to the EEPROM (3-bit opcode plus
+     * 6/8-bit dummy address beginning with 11).  It's less work to include
+     * the 11 of the dummy address as part of the opcode than it is to shift
+     * it over the correct number of bits for the address.  This puts the
+     * EEPROM into write/erase mode.
+     */
+    e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE_MICROWIRE,
+                            (uint16_t)(eeprom->opcode_bits + 2));
+
+    e1000_shift_out_ee_bits(hw, 0, (uint16_t)(eeprom->address_bits - 2));
+
+    /* Prepare the EEPROM */
     e1000_standby_eeprom(hw);
 
-    /* Send the 9-bit (or 11-bit on large EEPROM) EWDS (write disable) command
-     * to the EEPROM (5-bit opcode plus 4/6-bit dummy). This takes the EEPROM
-     * out of write/erase mode.
-     */
-    e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE, 5);
-    if(large_eeprom) 
-        e1000_shift_out_ee_bits(hw, 0, 6);
-    else
-        e1000_shift_out_ee_bits(hw, 0, 4);
+    while (words_written < words) {
+        /* Send the Write command (3-bit opcode + addr) */
+        e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE_MICROWIRE,
+                                eeprom->opcode_bits);
 
-    /* Done with writing */
-    e1000_cleanup_eeprom(hw);
+        e1000_shift_out_ee_bits(hw, (uint16_t)(offset + words_written),
+                                eeprom->address_bits);
 
-    /* Stop requesting EEPROM access */
-    if(hw->mac_type > e1000_82544) {
-        eecd = E1000_READ_REG(hw, EECD);
-        eecd &= ~E1000_EECD_REQ;
-        E1000_WRITE_REG(hw, EECD, eecd);
+        /* Send the data */
+        e1000_shift_out_ee_bits(hw, data[words_written], 16);
+
+        /* Toggle the CS line.  This in effect tells the EEPROM to execute
+         * the previous command.
+         */
+        e1000_standby_eeprom(hw);
+
+        /* Read DO repeatedly until it is high (equal to '1').  The EEPROM will
+         * signal that the command has been completed by raising the DO signal.
+         * If DO does not go high in 10 milliseconds, then error out.
+         */
+        for(i = 0; i < 200; i++) {
+            eecd = E1000_READ_REG(hw, EECD);
+            if(eecd & E1000_EECD_DO) break;
+            udelay(50);
+        }
+        if(i == 200) {
+            DEBUGOUT("EEPROM Write did not complete\n");
+            return -E1000_ERR_EEPROM;
+        }
+
+        /* Recover from write */
+        e1000_standby_eeprom(hw);
+
+        words_written++;
     }
 
-    return status;
+    /* Send the write disable command to the EEPROM (3-bit opcode plus
+     * 6/8-bit dummy address beginning with 10).  It's less work to include
+     * the 10 of the dummy address as part of the opcode than it is to shift
+     * it over the correct number of bits for the address.  This takes the
+     * EEPROM out of write/erase mode.
+     */
+    e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE_MICROWIRE,
+                            (uint16_t)(eeprom->opcode_bits + 2));
+
+    e1000_shift_out_ee_bits(hw, 0, (uint16_t)(eeprom->address_bits - 2));
+
+    return 0;
 }
 
 /******************************************************************************
@@ -2734,7 +3380,7 @@
     DEBUGFUNC("e1000_read_part_num");
 
     /* Get word 0 from EEPROM */
-    if(e1000_read_eeprom(hw, offset, &eeprom_data) < 0) {
+    if(e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
         DEBUGOUT("EEPROM Read Error\n");
         return -E1000_ERR_EEPROM;
     }
@@ -2742,7 +3388,7 @@
     *part_num = (uint32_t) (eeprom_data << 16);
 
     /* Get word 1 from EEPROM */
-    if(e1000_read_eeprom(hw, ++offset, &eeprom_data) < 0) {
+    if(e1000_read_eeprom(hw, ++offset, 1, &eeprom_data) < 0) {
         DEBUGOUT("EEPROM Read Error\n");
         return -E1000_ERR_EEPROM;
     }
@@ -2768,7 +3414,7 @@
 
     for(i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
         offset = i >> 1;
-        if(e1000_read_eeprom(hw, offset, &eeprom_data) < 0) {
+        if(e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
             DEBUGOUT("EEPROM Read Error\n");
             return -E1000_ERR_EEPROM;
         }
@@ -2790,7 +3436,7 @@
 /******************************************************************************
  * Initializes receive address filters.
  *
- * hw - Struct containing variables accessed by shared code 
+ * hw - Struct containing variables accessed by shared code
  *
  * Places the MAC address in receive address register 0 and clears the rest
  * of the receive addresss registers. Clears the multicast table. Assumes
@@ -2835,7 +3481,7 @@
  *
  * The given list replaces any existing list. Clears the last 15 receive
  * address registers and the multicast table. Uses receive address registers
- * for the first 15 multicast addresses, and hashes the rest into the 
+ * for the first 15 multicast addresses, and hashes the rest into the
  * multicast table.
  *****************************************************************************/
 void
@@ -2884,7 +3530,7 @@
         DEBUGOUT1(" Hash value = 0x%03X\n", hash_value);
 
         /* Place this multicast address in the RAR if there is room, *
-         * else put it in the MTA            
+         * else put it in the MTA
          */
         if(rar_used_count < E1000_RAR_ENTRIES) {
             e1000_rar_set(hw,
@@ -2902,7 +3548,7 @@
  * Hashes an address to determine its location in the multicast table
  *
  * hw - Struct containing variables accessed by shared code
- * mc_addr - the multicast address to hash 
+ * mc_addr - the multicast address to hash
  *****************************************************************************/
 uint32_t
 e1000_hash_mc_addr(struct e1000_hw *hw,
@@ -2911,7 +3557,7 @@
     uint32_t hash_value = 0;
 
     /* The portion of the address that is used for the hash table is
-     * determined by the mc_filter_type setting.  
+     * determined by the mc_filter_type setting.
      */
     switch (hw->mc_filter_type) {
     /* [0] [1] [2] [3] [4] [5]
@@ -2954,12 +3600,12 @@
     uint32_t mta;
     uint32_t temp;
 
-    /* The MTA is a register array of 128 32-bit registers.  
-     * It is treated like an array of 4096 bits.  We want to set 
+    /* The MTA is a register array of 128 32-bit registers.
+     * It is treated like an array of 4096 bits.  We want to set
      * bit BitArray[hash_value]. So we figure out what register
      * the bit is in, read it, OR in the new bit, then write
-     * back the new value.  The register is determined by the 
-     * upper 7 bits of the hash value and the bit within that 
+     * back the new value.  The register is determined by the
+     * upper 7 bits of the hash value and the bit within that
      * register are determined by the lower 5 bits of the value.
      */
     hash_reg = (hash_value >> 5) & 0x7F;
@@ -2997,7 +3643,7 @@
     uint32_t rar_low, rar_high;
 
     /* HW expects these in little endian so we reverse the byte order
-     * from network order (big endian) to little endian              
+     * from network order (big endian) to little endian
      */
     rar_low = ((uint32_t) addr[0] |
                ((uint32_t) addr[1] << 8) |
@@ -3055,24 +3701,24 @@
     const uint32_t ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
     uint16_t eeprom_data, i, temp;
     const uint16_t led_mask = 0x0F;
-        
+
     DEBUGFUNC("e1000_id_led_init");
-    
+
     if(hw->mac_type < e1000_82540) {
         /* Nothing to do */
         return 0;
     }
-    
+
     ledctl = E1000_READ_REG(hw, LEDCTL);
     hw->ledctl_default = ledctl;
     hw->ledctl_mode1 = hw->ledctl_default;
     hw->ledctl_mode2 = hw->ledctl_default;
-        
-    if(e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, &eeprom_data) < 0) {
+
+    if(e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) {
         DEBUGOUT("EEPROM Read Error\n");
         return -E1000_ERR_EEPROM;
     }
-    if((eeprom_data== ID_LED_RESERVED_0000) || 
+    if((eeprom_data== ID_LED_RESERVED_0000) ||
        (eeprom_data == ID_LED_RESERVED_FFFF)) eeprom_data = ID_LED_DEFAULT;
     for(i = 0; i < 4; i++) {
         temp = (eeprom_data >> (i << 2)) & led_mask;
@@ -3123,9 +3769,9 @@
 e1000_setup_led(struct e1000_hw *hw)
 {
     uint32_t ledctl;
- 
+
     DEBUGFUNC("e1000_setup_led");
-   
+
     switch(hw->device_id) {
     case E1000_DEV_ID_82542:
     case E1000_DEV_ID_82543GC_FIBER:
@@ -3143,7 +3789,7 @@
         hw->ledctl_default = ledctl;
         /* Turn off LED0 */
         ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
-                    E1000_LEDCTL_LED0_BLINK | 
+                    E1000_LEDCTL_LED0_BLINK |
                     E1000_LEDCTL_LED0_MODE_MASK);
         ledctl |= (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT);
         E1000_WRITE_REG(hw, LEDCTL, ledctl);
@@ -3155,6 +3801,9 @@
     case E1000_DEV_ID_82540EM_LOM:
     case E1000_DEV_ID_82545EM_COPPER:
     case E1000_DEV_ID_82546EB_COPPER:
+    case E1000_DEV_ID_82541EI:
+    case E1000_DEV_ID_82541EP:
+    case E1000_DEV_ID_82547EI:
         E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
         break;
     default:
@@ -3193,6 +3842,9 @@
     case E1000_DEV_ID_82545EM_FIBER:
     case E1000_DEV_ID_82546EB_COPPER:
     case E1000_DEV_ID_82546EB_FIBER:
+    case E1000_DEV_ID_82541EI:
+    case E1000_DEV_ID_82541EP:
+    case E1000_DEV_ID_82547EI:
         /* Restore LEDCTL settings */
         E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_default);
         break;
@@ -3202,7 +3854,7 @@
     }
     return 0;
 }
-    
+
 /******************************************************************************
  * Turns on the software controllable LED
  *
@@ -3244,6 +3896,9 @@
     case E1000_DEV_ID_82540EM_LOM:
     case E1000_DEV_ID_82545EM_COPPER:
     case E1000_DEV_ID_82546EB_COPPER:
+    case E1000_DEV_ID_82541EI:
+    case E1000_DEV_ID_82541EP:
+    case E1000_DEV_ID_82547EI:
         E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2);
         break;
     default:
@@ -3294,6 +3949,9 @@
     case E1000_DEV_ID_82540EM_LOM:
     case E1000_DEV_ID_82545EM_COPPER:
     case E1000_DEV_ID_82546EB_COPPER:
+    case E1000_DEV_ID_82541EI:
+    case E1000_DEV_ID_82541EP:
+    case E1000_DEV_ID_82547EI:
         E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
         break;
     default:
@@ -3304,7 +3962,7 @@
 }
 
 /******************************************************************************
- * Clears all hardware statistics counters. 
+ * Clears all hardware statistics counters.
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
@@ -3423,7 +4081,7 @@
     DEBUGFUNC("e1000_update_adaptive");
 
     if(hw->adaptive_ifs) {
-        if((hw->collision_delta * hw->ifs_ratio) > 
+        if((hw->collision_delta * hw->ifs_ratio) >
            hw->tx_packet_delta) {
             if(hw->tx_packet_delta > MIN_NUM_XMITS) {
                 hw->in_ifs_mode = TRUE;
@@ -3436,7 +4094,7 @@
                 }
             }
         } else {
-            if((hw->in_ifs_mode == TRUE) && 
+            if((hw->in_ifs_mode == TRUE) &&
                (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
                 hw->current_ifs_val = 0;
                 hw->in_ifs_mode = FALSE;
@@ -3450,7 +4108,7 @@
 
 /******************************************************************************
  * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
- * 
+ *
  * hw - Struct containing variables accessed by shared code
  * frame_len - The length of the frame in question
  * mac_addr - The Ethernet destination address of the frame in question
@@ -3478,16 +4136,16 @@
     carry_bit = 0x80000000 & stats->gorcl;
     stats->gorcl += frame_len;
     /* If the high bit of Gorcl (the low 32 bits of the Good Octets
-     * Received Count) was one before the addition, 
-     * AND it is zero after, then we lost the carry out, 
+     * Received Count) was one before the addition,
+     * AND it is zero after, then we lost the carry out,
      * need to add one to Gorch (Good Octets Received Count High).
-     * This could be simplified if all environments supported 
+     * This could be simplified if all environments supported
      * 64-bit integers.
      */
     if(carry_bit && ((stats->gorcl & 0x80000000) == 0))
         stats->gorch++;
     /* Is this a broadcast or multicast?  Check broadcast first,
-     * since the test for a multicast frame will test positive on 
+     * since the test for a multicast frame will test positive on
      * a broadcast frame.
      */
     if((mac_addr[0] == (uint8_t) 0xff) && (mac_addr[1] == (uint8_t) 0xff))
@@ -3606,5 +4264,223 @@
 
     e1000_io_write(hw, io_addr, offset);
     e1000_io_write(hw, io_data, value);
+}
+
+
+/******************************************************************************
+ * Estimates the cable length.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * min_length - The estimated minimum length
+ * max_length - The estimated maximum length
+ *
+ * returns: E1000_SUCCESS / -E1000_ERR_XXX
+ *
+ * This function always returns a ranged length (minimum & maximum).
+ * So for M88 phy's, this function interprets the one value returned from the
+ * register to the minimum and maximum range.
+ * For IGP phy's, the function calculates the range by the AGC registers.
+ *****************************************************************************/
+int32_t
+e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length,
+                       uint16_t *max_length)
+{
+    uint16_t agc_value = 0;
+    uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
+    uint16_t i, phy_data;
+
+    DEBUGFUNC("e1000_get_cable_length");
+
+    *min_length = *max_length = 0;
+
+    /* Use old method for Phy older than IGP */
+    if(hw->phy_type == e1000_phy_m88) {
+        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
+            return -E1000_ERR_PHY;
+
+        /* Convert the enum value to ranged values */
+        switch((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+               M88E1000_PSSR_CABLE_LENGTH_SHIFT) {
+        case e1000_cable_length_50:
+            *min_length = 0;
+            *max_length = e1000_igp_cable_length_50;
+            break;
+        case e1000_cable_length_50_80:
+            *min_length = e1000_igp_cable_length_50;
+            *max_length = e1000_igp_cable_length_80;
+            break;
+        case e1000_cable_length_80_110:
+            *min_length = e1000_igp_cable_length_80;
+            *max_length = e1000_igp_cable_length_110;
+            break;
+        case e1000_cable_length_110_140:
+            *min_length = e1000_igp_cable_length_110;
+            *max_length = e1000_igp_cable_length_140;
+            break;
+        case e1000_cable_length_140:
+            *min_length = e1000_igp_cable_length_140;
+            *max_length = e1000_igp_cable_length_170;
+            break;
+        default:
+            return -E1000_ERR_PHY;
+            break;
+        }
+    } else if(hw->phy_type == e1000_phy_igp) { /* For IGP PHY */
+        uint16_t agc_reg_array[IGP01E1000_PHY_AGC_NUM] = {IGP01E1000_PHY_AGC_A,
+                                                          IGP01E1000_PHY_AGC_B,
+                                                          IGP01E1000_PHY_AGC_C,
+                                                          IGP01E1000_PHY_AGC_D};
+        /* Read the AGC registers for all channels */
+        for(i = 0; i < IGP01E1000_PHY_AGC_NUM; i++) {
+            if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
+                                   agc_reg_array[i]) != E1000_SUCCESS)
+                return -E1000_ERR_PHY;
+            if(e1000_read_phy_reg(hw, agc_reg_array[i] &
+                                  IGP01E1000_PHY_PAGE_SELECT, &phy_data) !=
+                                  E1000_SUCCESS)
+                return -E1000_ERR_PHY;
+
+            cur_agc = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
+
+            /* Array bound check. */
+            if((cur_agc >= IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1) ||
+               (cur_agc == 0))
+                return -E1000_ERR_PHY;
+
+            agc_value += cur_agc;
+
+            /* Update minimal AGC value. */
+            if(min_agc > cur_agc)
+                min_agc = cur_agc;
+        }
+
+        /* Return to page 0 */
+        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0) !=
+           E1000_SUCCESS)
+            return -E1000_ERR_PHY;
+
+        /* Remove the minimal AGC result for length < 50m */
+        if(agc_value < IGP01E1000_PHY_AGC_NUM * e1000_igp_cable_length_50) {
+            agc_value -= min_agc;
+
+            /* Get the average length of the remaining 3 channels */
+            agc_value /= (IGP01E1000_PHY_AGC_NUM - 1);
+        } else {
+            /* Get the average length of all the 4 channels. */
+            agc_value /= IGP01E1000_PHY_AGC_NUM;
+        }
+
+        /* Set the range of the calculated length. */
+        *min_length = ((e1000_igp_cable_length_table[agc_value] -
+                       IGP01E1000_AGC_RANGE) > 0) ?
+                       (e1000_igp_cable_length_table[agc_value] -
+                       IGP01E1000_AGC_RANGE) : 0;
+        *max_length = e1000_igp_cable_length_table[agc_value] +
+                      IGP01E1000_AGC_RANGE;
+    }
+
+    return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Check the cable polarity
+ *
+ * hw - Struct containing variables accessed by shared code
+ * polarity - output parameter : 0 - Polarity is not reversed
+ *                               1 - Polarity is reversed.
+ *
+ * returns: E1000_SUCCESS / -E1000_ERR_XXX
+ *
+ * For phy's older then IGP, this function simply reads the polarity bit in the
+ * Phy Status register.  For IGP phy's, this bit is valid only if link speed is
+ * 10 Mbps.  If the link speed is 100 Mbps there is no polarity so this bit will
+ * return 0.  If the link speed is 1000 Mbps the polarity status is in the
+ * IGP01E1000_PHY_PCS_INIT_REG.
+ *****************************************************************************/
+int32_t
+e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity)
+{
+    uint16_t phy_data;
+
+    DEBUGFUNC("e1000_check_polarity");
+
+    if(hw->phy_type == e1000_phy_m88) {
+        /* return the Polarity bit in the Status register. */
+        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
+            return -E1000_ERR_PHY;
+        *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
+                    M88E1000_PSSR_REV_POLARITY_SHIFT;
+    } else if(hw->phy_type == e1000_phy_igp) {
+        /* Read the Status register to check the speed */
+        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0)
+            return -E1000_ERR_PHY;
+
+        /* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
+         * find the polarity status */
+        if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
+           IGP01E1000_PSSR_SPEED_1000MBPS) {
+
+            /* Read the GIG initialization PCS register (0x00B4) */
+            if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
+                                   IGP01E1000_PHY_PCS_INIT_REG) < 0)
+                return -E1000_ERR_PHY;
+
+            if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG &
+                                  IGP01E1000_PHY_PAGE_SELECT, &phy_data) < 0)
+                return -E1000_ERR_PHY;
+
+            /* Return to page 0 */
+            if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0) !=
+               E1000_SUCCESS)
+                return -E1000_ERR_PHY;
+
+            /* Check the polarity bits */
+            *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ? 1 : 0;
+        } else {
+            /* For 10 Mbps, read the polarity bit in the status register. (for
+             * 100 Mbps this bit is always 0) */
+            *polarity = phy_data & IGP01E1000_PSSR_POLARITY_REVERSED;
+        }
+    }
+    return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Check if Downshift occured
+ *
+ * hw - Struct containing variables accessed by shared code
+ * downshift - output parameter : 0 - No Downshift ocured.
+ *                                1 - Downshift ocured.
+ *
+ * returns: E1000_SUCCESS / -E1000_ERR_XXX
+ *
+ * For phy's older then IGP, this function reads the Downshift bit in the Phy
+ * Specific Status register.  For IGP phy's, it reads the Downgrade bit in the
+ * Link Health register.  In IGP this bit is latched high, so the driver must
+ * read it immediately after link is established.
+ *****************************************************************************/
+int32_t
+e1000_check_downshift(struct e1000_hw *hw)
+{
+    uint16_t phy_data;
+
+    DEBUGFUNC("e1000_check_downshift");
+
+    if(hw->phy_type == e1000_phy_igp) {
+        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH, &phy_data) < 0) {
+            DEBUGOUT("PHY Read Error\n");
+            return -E1000_ERR_PHY;
+        }
+        hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
+    }
+    else if(hw->phy_type == e1000_phy_m88) {
+        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
+            DEBUGOUT("PHY Read Error\n");
+            return -E1000_ERR_PHY;
+        }
+        hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
+                                M88E1000_PSSR_DOWNSHIFT_SHIFT;
+    }
+    return E1000_SUCCESS;
 }
 
diff -Nru a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
--- a/drivers/net/e1000/e1000_hw.h	Fri Oct 18 14:59:28 2002
+++ b/drivers/net/e1000/e1000_hw.h	Mon Mar 17 14:23:14 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -33,6 +33,7 @@
 #ifndef _E1000_HW_H_
 #define _E1000_HW_H_
 
+
 #include "e1000_osdep.h"
 
 /* Forward declarations of structures used by the shared code */
@@ -50,9 +51,18 @@
     e1000_82540,
     e1000_82545,
     e1000_82546,
+    e1000_82541,
+    e1000_82547,
     e1000_num_macs
 } e1000_mac_type;
 
+typedef enum {
+    e1000_eeprom_uninitialized = 0,
+    e1000_eeprom_spi,
+    e1000_eeprom_microwire,
+    e1000_num_eeprom_types
+} e1000_eeprom_type;
+
 /* Media Types */
 typedef enum {
     e1000_media_type_copper = 0,
@@ -111,6 +121,27 @@
 } e1000_cable_length;
 
 typedef enum {
+    e1000_igp_cable_length_10  = 10,
+    e1000_igp_cable_length_20  = 20,
+    e1000_igp_cable_length_30  = 30,
+    e1000_igp_cable_length_40  = 40,
+    e1000_igp_cable_length_50  = 50,
+    e1000_igp_cable_length_60  = 60,
+    e1000_igp_cable_length_70  = 70,
+    e1000_igp_cable_length_80  = 80,
+    e1000_igp_cable_length_90  = 90,
+    e1000_igp_cable_length_100 = 100,
+    e1000_igp_cable_length_110 = 110,
+    e1000_igp_cable_length_120 = 120,
+    e1000_igp_cable_length_130 = 130,
+    e1000_igp_cable_length_140 = 140,
+    e1000_igp_cable_length_150 = 150,
+    e1000_igp_cable_length_160 = 160,
+    e1000_igp_cable_length_170 = 170,
+    e1000_igp_cable_length_180 = 180
+} e1000_igp_cable_length;
+
+typedef enum {
     e1000_10bt_ext_dist_enable_normal = 0,
     e1000_10bt_ext_dist_enable_lower,
     e1000_10bt_ext_dist_enable_undefined = 0xFF
@@ -123,6 +154,12 @@
 } e1000_rev_polarity;
 
 typedef enum {
+    e1000_downshift_normal = 0,
+    e1000_downshift_activated,
+    e1000_downshift_undefined = 0xFF
+} e1000_downshift;
+
+typedef enum {
     e1000_polarity_reversal_enabled = 0,
     e1000_polarity_reversal_disabled,
     e1000_polarity_reversal_undefined = 0xFF
@@ -142,10 +179,17 @@
     e1000_1000t_rx_status_undefined = 0xFF
 } e1000_1000t_rx_status;
 
+typedef enum {
+    e1000_phy_m88 = 0,
+    e1000_phy_igp,
+    e1000_phy_undefined = 0xFF
+} e1000_phy_type;
+
 struct e1000_phy_info {
     e1000_cable_length cable_length;
     e1000_10bt_ext_dist_enable extended_10bt_distance;
     e1000_rev_polarity cable_polarity;
+    e1000_downshift downshift;
     e1000_polarity_reversal polarity_correction;
     e1000_auto_x_mode mdix_mode;
     e1000_1000t_rx_status local_rx;
@@ -157,6 +201,15 @@
     uint32_t receive_errors;
 };
 
+struct e1000_eeprom_info {
+    e1000_eeprom_type type;
+    uint16_t word_size;
+    uint16_t opcode_bits;
+    uint16_t address_bits;
+    uint16_t delay_usec;
+    uint16_t page_size;
+};
+
 
 
 /* Error Codes */
@@ -166,6 +219,7 @@
 #define E1000_ERR_CONFIG   3
 #define E1000_ERR_PARAM    4
 #define E1000_ERR_MAC_TYPE 5
+#define E1000_ERR_PHY_TYPE 6
 
 /* Function prototypes */
 /* Initialization */
@@ -189,13 +243,19 @@
 int32_t e1000_phy_reset(struct e1000_hw *hw);
 int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
 int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+int32_t e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+int32_t e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+int32_t e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length, uint16_t *max_length);
+int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
+int32_t e1000_check_downshift(struct e1000_hw *hw);
 int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
 
 /* EEPROM Functions */
-int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t *data);
+void e1000_init_eeprom_params(struct e1000_hw *hw);
+int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
 int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
 int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw);
-int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t data);
+int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
 int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num);
 int32_t e1000_read_mac_addr(struct e1000_hw * hw);
 
@@ -231,6 +291,7 @@
 uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset);
 void e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value);
 void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
+
 #define E1000_READ_REG_IO(a, reg) \
     e1000_read_reg_io((a), E1000_##reg)
 #define E1000_WRITE_REG_IO(a, reg, val) \
@@ -253,7 +314,10 @@
 #define E1000_DEV_ID_82545EM_FIBER       0x1011
 #define E1000_DEV_ID_82546EB_COPPER      0x1010
 #define E1000_DEV_ID_82546EB_FIBER       0x1012
-#define NUM_DEV_IDS 16
+#define E1000_DEV_ID_82541EI             0x1013
+#define E1000_DEV_ID_82541EP             0x1018
+#define E1000_DEV_ID_82547EI             0x1019
+#define NUM_DEV_IDS 19
 
 #define NODE_ADDRESS_SIZE 6
 #define ETH_LENGTH_OF_ADDRESS 6
@@ -298,7 +362,7 @@
 /* This defines the bits that are set in the Interrupt Mask
  * Set/Read Register.  Each bit is documented below:
  *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
- *   o RXSEQ  = Receive Sequence Error 
+ *   o RXSEQ  = Receive Sequence Error
  */
 #define POLL_IMS_ENABLE_MASK ( \
     E1000_IMS_RXDMT0 |         \
@@ -322,9 +386,9 @@
 /* The number of high/low register pairs in the RAR. The RAR (Receive Address
  * Registers) holds the directed and multicast addresses that we monitor. We
  * reserve one of these spots for our directed address, allowing us room for
- * E1000_RAR_ENTRIES - 1 multicast addresses. 
+ * E1000_RAR_ENTRIES - 1 multicast addresses.
  */
-#define E1000_RAR_ENTRIES 16
+#define E1000_RAR_ENTRIES 15
 
 #define MIN_NUMBER_OF_DESCRIPTORS 8
 #define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
@@ -523,7 +587,7 @@
 /* Register Set. (82543, 82544)
  *
  * Registers are defined to be 32 bits and  should be accessed as 32 bit values.
- * These registers are physically located on the NIC, but are mapped into the 
+ * These registers are physically located on the NIC, but are mapped into the
  * host memory address space.
  *
  * RW - register is both readable and writable
@@ -537,6 +601,7 @@
 #define E1000_EECD     0x00010  /* EEPROM/Flash Control - RW */
 #define E1000_EERD     0x00014  /* EEPROM Read - RW */
 #define E1000_CTRL_EXT 0x00018  /* Extended Device Control - RW */
+#define E1000_FLA      0x0001C  /* Flash Access Register - RW */
 #define E1000_MDIC     0x00020  /* MDI Control - RW */
 #define E1000_FCAL     0x00028  /* Flow Control Address Low - RW */
 #define E1000_FCAH     0x0002C  /* Flow Control Address High -RW */
@@ -569,6 +634,11 @@
 #define E1000_RADV     0x0282C  /* RX Interrupt Absolute Delay Timer - RW */
 #define E1000_RSRPD    0x02C00  /* RX Small Packet Detect - RW */
 #define E1000_TXDMAC   0x03000  /* TX DMA Control - RW */
+#define E1000_TDFH     0x03410  /* TX Data FIFO Head - RW */
+#define E1000_TDFT     0x03418  /* TX Data FIFO Tail - RW */
+#define E1000_TDFHS    0x03420  /* TX Data FIFO Head Saved - RW */
+#define E1000_TDFTS    0x03428  /* TX Data FIFO Tail Saved - RW */
+#define E1000_TDFPC    0x03430  /* TX Data FIFO Packet Count - RW */
 #define E1000_TDBAL    0x03800  /* TX Descriptor Base Address Low - RW */
 #define E1000_TDBAH    0x03804  /* TX Descriptor Base Address High - RW */
 #define E1000_TDLEN    0x03808  /* TX Descriptor Length - RW */
@@ -664,6 +734,7 @@
 #define E1000_82542_EECD     E1000_EECD
 #define E1000_82542_EERD     E1000_EERD
 #define E1000_82542_CTRL_EXT E1000_CTRL_EXT
+#define E1000_82542_FLA      E1000_FLA
 #define E1000_82542_MDIC     E1000_MDIC
 #define E1000_82542_FCAL     E1000_FCAL
 #define E1000_82542_FCAH     E1000_FCAH
@@ -705,6 +776,9 @@
 #define E1000_82542_RADV     E1000_RADV
 #define E1000_82542_RSRPD    E1000_RSRPD
 #define E1000_82542_TXDMAC   E1000_TXDMAC
+#define E1000_82542_TDFHS    E1000_TDFHS
+#define E1000_82542_TDFTS    E1000_TDFTS
+#define E1000_82542_TDFPC    E1000_TDFPC
 #define E1000_82542_TXDCTL   E1000_TXDCTL
 #define E1000_82542_TADV     E1000_TADV
 #define E1000_82542_TSPMT    E1000_TSPMT
@@ -777,6 +851,8 @@
 #define E1000_82542_WUPL     E1000_WUPL
 #define E1000_82542_WUPM     E1000_WUPM
 #define E1000_82542_FFLT     E1000_FFLT
+#define E1000_82542_TDFH     0x08010
+#define E1000_82542_TDFT     0x08018
 #define E1000_82542_FFMT     E1000_FFMT
 #define E1000_82542_FFVT     E1000_FFVT
 
@@ -846,12 +922,15 @@
 struct e1000_hw {
     uint8_t *hw_addr;
     e1000_mac_type mac_type;
+    e1000_phy_type phy_type;
+    uint32_t phy_init_script;
     e1000_media_type media_type;
     void *back;
     e1000_fc_type fc;
     e1000_bus_speed bus_speed;
     e1000_bus_width bus_width;
     e1000_bus_type bus_type;
+    struct e1000_eeprom_info eeprom;
     uint32_t io_base;
     uint32_t phy_id;
     uint32_t phy_revision;
@@ -891,6 +970,7 @@
     uint8_t mac_addr[NODE_ADDRESS_SIZE];
     uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
     boolean_t disable_polarity_correction;
+    boolean_t speed_downgraded;
     boolean_t get_link_status;
     boolean_t tbi_compatibility_en;
     boolean_t tbi_compatibility_on;
@@ -967,14 +1047,20 @@
 #define E1000_EECD_CS        0x00000002 /* EEPROM Chip Select */
 #define E1000_EECD_DI        0x00000004 /* EEPROM Data In */
 #define E1000_EECD_DO        0x00000008 /* EEPROM Data Out */
-#define E1000_EECD_FWE_MASK  0x00000030 
+#define E1000_EECD_FWE_MASK  0x00000030
 #define E1000_EECD_FWE_DIS   0x00000010 /* Disable FLASH writes */
 #define E1000_EECD_FWE_EN    0x00000020 /* Enable FLASH writes */
 #define E1000_EECD_FWE_SHIFT 4
-#define E1000_EECD_SIZE      0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
 #define E1000_EECD_REQ       0x00000040 /* EEPROM Access Request */
 #define E1000_EECD_GNT       0x00000080 /* EEPROM Access Grant */
 #define E1000_EECD_PRES      0x00000100 /* EEPROM Present */
+#define E1000_EECD_SIZE      0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
+#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
+					 * (0-small, 1-large) */
+#define E1000_EECD_TYPE      0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
+#ifndef E1000_EEPROM_GRANT_ATTEMPTS
+#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
+#endif
 
 /* EEPROM Read */
 #define E1000_EERD_START      0x00000001 /* Start Read */
@@ -984,8 +1070,15 @@
 #define E1000_EERD_DATA_SHIFT 16
 #define E1000_EERD_DATA_MASK  0xFFFF0000 /* Read Data */
 
+/* SPI EEPROM Status Register */
+#define EEPROM_STATUS_RDY_SPI  0x01
+#define EEPROM_STATUS_WEN_SPI  0x02
+#define EEPROM_STATUS_BP0_SPI  0x04
+#define EEPROM_STATUS_BP1_SPI  0x08
+#define EEPROM_STATUS_WPEN_SPI 0x80
+
 /* Extended Device Control */
-#define E1000_CTRL_EXT_GPI0_EN   0x00000001 /* Maps SDP4 to GPI0 */ 
+#define E1000_CTRL_EXT_GPI0_EN   0x00000001 /* Maps SDP4 to GPI0 */
 #define E1000_CTRL_EXT_GPI1_EN   0x00000002 /* Maps SDP5 to GPI1 */
 #define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN
 #define E1000_CTRL_EXT_GPI2_EN   0x00000004 /* Maps SDP6 to GPI2 */
@@ -1239,6 +1332,7 @@
 #define E1000_WUC_PME_EN     0x00000002 /* PME Enable */
 #define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */
 #define E1000_WUC_APMPME     0x00000008 /* Assert PME on APM Wakeup */
+#define E1000_WUC_SPM        0x80000000 /* Enable SPM */
 
 /* Wake Up Filter Control */
 #define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
@@ -1282,7 +1376,7 @@
 #define E1000_MANC_IPV6_EN       0x00000800 /* Enable IPv6 */
 #define E1000_MANC_SNAP_EN       0x00001000 /* Accept LLC/SNAP */
 #define E1000_MANC_ARP_EN        0x00002000 /* Enable ARP Request Filtering */
-#define E1000_MANC_NEIGHBOR_EN   0x00004000 /* Enable Neighbor Discovery 
+#define E1000_MANC_NEIGHBOR_EN   0x00004000 /* Enable Neighbor Discovery
                                              * Filtering */
 #define E1000_MANC_TCO_RESET     0x00010000 /* TCO Reset Occurred */
 #define E1000_MANC_RCV_TCO_EN    0x00020000 /* Receive TCO Packets Enabled */
@@ -1302,18 +1396,40 @@
 
 #define E1000_MDALIGN          4096
 
-/* EEPROM Commands */
-#define EEPROM_READ_OPCODE  0x6  /* EERPOM read opcode */
-#define EEPROM_WRITE_OPCODE 0x5  /* EERPOM write opcode */
-#define EEPROM_ERASE_OPCODE 0x7  /* EERPOM erase opcode */
-#define EEPROM_EWEN_OPCODE  0x13 /* EERPOM erase/write enable */
-#define EEPROM_EWDS_OPCODE  0x10 /* EERPOM erast/write disable */
+/* EEPROM Commands - Microwire */
+#define EEPROM_READ_OPCODE_MICROWIRE  0x6  /* EEPROM read opcode */
+#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5  /* EEPROM write opcode */
+#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7  /* EEPROM erase opcode */
+#define EEPROM_EWEN_OPCODE_MICROWIRE  0x13 /* EEPROM erase/write enable */
+#define EEPROM_EWDS_OPCODE_MICROWIRE  0x10 /* EEPROM erast/write disable */
+
+/* EEPROM Commands - SPI */
+#define EEPROM_MAX_RETRY_SPI    5000 /* Max wait of 5ms, for RDY signal */
+#define EEPROM_READ_OPCODE_SPI  0x3  /* EEPROM read opcode */
+#define EEPROM_WRITE_OPCODE_SPI 0x2  /* EEPROM write opcode */
+#define EEPROM_A8_OPCODE_SPI    0x8  /* opcode bit-3 = address bit-8 */
+#define EEPROM_WREN_OPCODE_SPI  0x6  /* EEPROM set Write Enable latch */
+#define EEPROM_WRDI_OPCODE_SPI  0x4  /* EEPROM reset Write Enable latch */
+#define EEPROM_RDSR_OPCODE_SPI  0x5  /* EEPROM read Status register */
+#define EEPROM_WRSR_OPCODE_SPI  0x1  /* EEPROM write Status register */
+
+/* EEPROM Size definitions */
+#define EEPROM_SIZE_16KB        0x1800
+#define EEPROM_SIZE_8KB         0x1400
+#define EEPROM_SIZE_4KB         0x1000
+#define EEPROM_SIZE_2KB         0x0C00
+#define EEPROM_SIZE_1KB         0x0800
+#define EEPROM_SIZE_512B        0x0400
+#define EEPROM_SIZE_128B        0x0000
+#define EEPROM_SIZE_MASK        0x1C00
+
 
 /* EEPROM Word Offsets */
 #define EEPROM_COMPAT              0x0003
 #define EEPROM_ID_LED_SETTINGS     0x0004
 #define EEPROM_INIT_CONTROL1_REG   0x000A
 #define EEPROM_INIT_CONTROL2_REG   0x000F
+#define EEPROM_CFG                 0x0012
 #define EEPROM_FLASH_VERSION       0x0032
 #define EEPROM_CHECKSUM_REG        0x003F
 
@@ -1334,9 +1450,10 @@
 #define ID_LED_OFF1_ON2      0x8
 #define ID_LED_OFF1_OFF2     0x9
 
-/* Mask bits for fields in Word 0x03 of the EEPROM */
-#define EEPROM_COMPAT_SERVER 0x0400
-#define EEPROM_COMPAT_CLIENT 0x0200
+#define IGP_ACTIVITY_LED_MASK   0xFFFFF0FF
+#define IGP_ACTIVITY_LED_ENABLE 0x0300
+#define IGP_LED3_MODE           0x07000000
+
 
 /* Mask bits for fields in Word 0x0a of the EEPROM */
 #define EEPROM_WORD0A_ILOS   0x0010
@@ -1409,7 +1526,9 @@
 
 /* PBA constants */
 #define E1000_PBA_16K 0x0010    /* 16KB, default TX allocation */
+#define E1000_PBA_22K 0x0016
 #define E1000_PBA_24K 0x0018
+#define E1000_PBA_30K 0x001E
 #define E1000_PBA_40K 0x0028
 #define E1000_PBA_48K 0x0030    /* 48KB, default RX allocation */
 
@@ -1438,26 +1557,26 @@
 
 /* The number of bits that we need to shift right to move the "pause"
  * bits from the EEPROM (bits 13:12) to the "pause" (bits 8:7) field
- * in the TXCW register 
+ * in the TXCW register
  */
 #define PAUSE_SHIFT 5
 
 /* The number of bits that we need to shift left to move the "SWDPIO"
  * bits from the EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field
- * in the CTRL register 
+ * in the CTRL register
  */
 #define SWDPIO_SHIFT 17
 
 /* The number of bits that we need to shift left to move the "SWDPIO_EXT"
  * bits from the EEPROM word F (bits 7:4) to the bits 11:8 of The
  * Extended CTRL register.
- * in the CTRL register 
+ * in the CTRL register
  */
 #define SWDPIO__EXT_SHIFT 4
 
 /* The number of bits that we need to shift left to move the "ILOS"
  * bit from the EEPROM (bit 4) to the "ILOS" (bit 7) field
- * in the CTRL register 
+ * in the CTRL register
  */
 #define ILOS_SHIFT  3
 
@@ -1475,7 +1594,7 @@
 /* TBI_ACCEPT macro definition:
  *
  * This macro requires:
- *      adapter = a pointer to struct e1000_hw 
+ *      adapter = a pointer to struct e1000_hw
  *      status = the 8 bit status field of the RX descriptor with EOP set
  *      error = the 8 bit error field of the RX descriptor with EOP set
  *      length = the sum of all the length fields of the RX descriptors that
@@ -1484,7 +1603,7 @@
  *      max_frame_length = the maximum frame length we want to accept.
  *      min_frame_length = the minimum frame length we want to accept.
  *
- * This macro is a conditional that should be used in the interrupt 
+ * This macro is a conditional that should be used in the interrupt
  * handler's Rx processing routine when RxErrors have been detected.
  *
  * Typical use:
@@ -1547,6 +1666,29 @@
 #define M88E1000_EXT_PHY_SPEC_CTRL 0x14  /* Extended PHY Specific Control */
 #define M88E1000_RX_ERR_CNTR       0x15  /* Receive Error Counter */
 
+/* IGP01E1000 Specific Registers */
+#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* PHY Specific Port Config Register */
+#define IGP01E1000_PHY_PORT_STATUS 0x11 /* PHY Specific Status Register */
+#define IGP01E1000_PHY_PORT_CTRL   0x12 /* PHY Specific Control Register */
+#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health Register */
+#define IGP01E1000_GMII_FIFO       0x14 /* GMII FIFO Register */
+#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality Register */
+#define IGP01E1000_PHY_PAGE_SELECT     0x1F /* PHY Page Select Core Register */
+
+/* IGP01E1000 AGC Registers - stores the cable length values*/
+#define IGP01E1000_PHY_AGC_A        0x1172
+#define IGP01E1000_PHY_AGC_B        0x1272
+#define IGP01E1000_PHY_AGC_C        0x1472
+#define IGP01E1000_PHY_AGC_D        0x1872
+
+/* Number of AGC registers */
+#define IGP01E1000_PHY_AGC_NUM     4
+
+/* IGP01E1000 PCS Initialization register - stores the polarity status when
+ * speed = 1000 Mbps. */
+#define IGP01E1000_PHY_PCS_INIT_REG  0x00B4
+
+
 #define MAX_PHY_REG_ADDRESS 0x1F        /* 5 bit address bus (0-0x1F) */
 
 /* PHY Control Register */
@@ -1608,7 +1750,7 @@
 #define NWAY_ER_PAGE_RXD          0x0002 /* LP is 10T   Half Duplex Capable */
 #define NWAY_ER_NEXT_PAGE_CAPS    0x0004 /* LP is 10T   Full Duplex Capable */
 #define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP is 100TX Half Duplex Capable */
-#define NWAY_ER_PAR_DETECT_FAULT  0x0100 /* LP is 100TX Full Duplex Capable */
+#define NWAY_ER_PAR_DETECT_FAULT  0x0010 /* LP is 100TX Full Duplex Capable */
 
 /* Next Page TX Register */
 #define NPTX_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */
@@ -1619,7 +1761,7 @@
                                     * 0 = cannot comply with msg
                                     */
 #define NPTX_MSG_PAGE       0x2000 /* formatted(1)/unformatted(0) pg */
-#define NPTX_NEXT_PAGE      0x8000 /* 1 = addition NP will follow 
+#define NPTX_NEXT_PAGE      0x8000 /* 1 = addition NP will follow
                                     * 0 = sending last NP
                                     */
 
@@ -1628,13 +1770,13 @@
 #define LP_RNPR_TOGGLE         0x0800 /* Toggles between exchanges
                                        * of different NP
                                        */
-#define LP_RNPR_ACKNOWLDGE2    0x1000 /* 1 = will comply with msg 
+#define LP_RNPR_ACKNOWLDGE2    0x1000 /* 1 = will comply with msg
                                        * 0 = cannot comply with msg
                                        */
 #define LP_RNPR_MSG_PAGE       0x2000  /* formatted(1)/unformatted(0) pg */
 #define LP_RNPR_ACKNOWLDGE     0x4000  /* 1 = ACK / 0 = NO ACK */
 #define LP_RNPR_NEXT_PAGE      0x8000  /* 1 = addition NP will follow
-                                        * 0 = sending last NP 
+                                        * 0 = sending last NP
                                         */
 
 /* 1000BASE-T Control Register */
@@ -1681,20 +1823,20 @@
 #define M88E1000_PSCR_JABBER_DISABLE    0x0001 /* 1=Jabber Function disabled */
 #define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
 #define M88E1000_PSCR_SQE_TEST          0x0004 /* 1=SQE Test enabled */
-#define M88E1000_PSCR_CLK125_DISABLE    0x0010 /* 1=CLK125 low, 
+#define M88E1000_PSCR_CLK125_DISABLE    0x0010 /* 1=CLK125 low,
                                                 * 0=CLK125 toggling
                                                 */
 #define M88E1000_PSCR_MDI_MANUAL_MODE  0x0000  /* MDI Crossover Mode bits 6:5 */
                                                /* Manual MDI configuration */
 #define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020  /* Manual MDIX configuration */
 #define M88E1000_PSCR_AUTO_X_1000T     0x0040  /* 1000BASE-T: Auto crossover,
-                                                *  100BASE-TX/10BASE-T: 
+                                                *  100BASE-TX/10BASE-T:
                                                 *  MDI Mode
                                                 */
-#define M88E1000_PSCR_AUTO_X_MODE      0x0060  /* Auto crossover enabled 
-                                                * all speeds. 
+#define M88E1000_PSCR_AUTO_X_MODE      0x0060  /* Auto crossover enabled
+                                                * all speeds.
                                                 */
-#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080 
+#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080
                                         /* 1=Enable Extended 10BASE-T distance
                                          * (Lower 10BASE-T RX Threshold)
                                          * 0=Normal 10BASE-T RX Threshold */
@@ -1712,6 +1854,7 @@
 /* M88E1000 PHY Specific Status Register */
 #define M88E1000_PSSR_JABBER             0x0001 /* 1=Jabber */
 #define M88E1000_PSSR_REV_POLARITY       0x0002 /* 1=Polarity reversed */
+#define M88E1000_PSSR_DOWNSHIFT          0x0020 /* 1=Downshifted */
 #define M88E1000_PSSR_MDIX               0x0040 /* 1=MDIX; 0=MDI */
 #define M88E1000_PSSR_CABLE_LENGTH       0x0380 /* 0=<50M;1=50-80M;2=80-110M;
                                             * 3=110-140M;4=>140M */
@@ -1725,6 +1868,7 @@
 #define M88E1000_PSSR_1000MBS            0x8000 /* 10=1000Mbs */
 
 #define M88E1000_PSSR_REV_POLARITY_SHIFT 1
+#define M88E1000_PSSR_DOWNSHIFT_SHIFT    5
 #define M88E1000_PSSR_MDIX_SHIFT         6
 #define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
 
@@ -1733,12 +1877,12 @@
 #define M88E1000_EPSCR_DOWN_NO_IDLE   0x8000 /* 1=Lost lock detect enabled.
                                               * Will assert lost lock and bring
                                               * link down if idle not seen
-                                              * within 1ms in 1000BASE-T 
+                                              * within 1ms in 1000BASE-T
                                               */
 /* Number of times we will attempt to autonegotiate before downshifting if we
  * are the master */
 #define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X   0x0000    
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X   0x0000
 #define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X   0x0400
 #define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X   0x0800
 #define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X   0x0C00
@@ -1753,10 +1897,93 @@
 #define M88E1000_EPSCR_TX_CLK_25      0x0070 /* 25  MHz TX_CLK */
 #define M88E1000_EPSCR_TX_CLK_0       0x0000 /* NO  TX_CLK */
 
+
+/* IGP01E1000 Specific Port Config Register - R/W */
+#define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT  0x0010
+#define IGP01E1000_PSCFR_PRE_EN                0x0020
+#define IGP01E1000_PSCFR_SMART_SPEED           0x0080
+#define IGP01E1000_PSCFR_DISABLE_TPLOOPBACK    0x0100
+#define IGP01E1000_PSCFR_DISABLE_JABBER        0x0400
+#define IGP01E1000_PSCFR_DISABLE_TRANSMIT      0x2000
+
+/* IGP01E1000 Specific Port Status Register - R/O */
+#define IGP01E1000_PSSR_AUTONEG_FAILED         0x0001 /* RO LH SC */
+#define IGP01E1000_PSSR_POLARITY_REVERSED      0x0002
+#define IGP01E1000_PSSR_CABLE_LENGTH           0x007C
+#define IGP01E1000_PSSR_FULL_DUPLEX            0x0200
+#define IGP01E1000_PSSR_LINK_UP                0x0400
+#define IGP01E1000_PSSR_MDIX                   0x0800
+#define IGP01E1000_PSSR_SPEED_MASK             0xC000 /* speed bits mask */
+#define IGP01E1000_PSSR_SPEED_10MBPS           0x4000
+#define IGP01E1000_PSSR_SPEED_100MBPS          0x8000
+#define IGP01E1000_PSSR_SPEED_1000MBPS         0xC000
+#define IGP01E1000_PSSR_CABLE_LENGTH_SHIFT     0x0002 /* shift right 2 */
+#define IGP01E1000_PSSR_MDIX_SHIFT             0x000B /* shift right 11 */
+
+/* IGP01E1000 Specific Port Control Register - R/W */
+#define IGP01E1000_PSCR_TP_LOOPBACK            0x0001
+#define IGP01E1000_PSCR_CORRECT_NC_SCMBLR      0x0200
+#define IGP01E1000_PSCR_TEN_CRS_SELECT         0x0400
+#define IGP01E1000_PSCR_FLIP_CHIP              0x0800
+#define IGP01E1000_PSCR_AUTO_MDIX              0x1000
+#define IGP01E1000_PSCR_FORCE_MDI_MDIX         0x2000 /* 0-MDI, 1-MDIX */
+
+/* IGP01E1000 Specific Port Link Health Register */
+#define IGP01E1000_PLHR_SS_DOWNGRADE           0x8000
+#define IGP01E1000_PLHR_GIG_SCRAMBLER_ERROR    0x4000
+#define IGP01E1000_PLHR_GIG_REM_RCVR_NOK       0x0800 /* LH */
+#define IGP01E1000_PLHR_IDLE_ERROR_CNT_OFLOW   0x0400 /* LH */
+#define IGP01E1000_PLHR_DATA_ERR_1             0x0200 /* LH */
+#define IGP01E1000_PLHR_DATA_ERR_0             0x0100
+#define IGP01E1000_PLHR_AUTONEG_FAULT          0x0010
+#define IGP01E1000_PLHR_AUTONEG_ACTIVE         0x0008
+#define IGP01E1000_PLHR_VALID_CHANNEL_D        0x0004
+#define IGP01E1000_PLHR_VALID_CHANNEL_C        0x0002
+#define IGP01E1000_PLHR_VALID_CHANNEL_B        0x0001
+#define IGP01E1000_PLHR_VALID_CHANNEL_A        0x0000
+
+/* IGP01E1000 Channel Quality Register */
+#define IGP01E1000_MSE_CHANNEL_D        0x000F
+#define IGP01E1000_MSE_CHANNEL_C        0x00F0
+#define IGP01E1000_MSE_CHANNEL_B        0x0F00
+#define IGP01E1000_MSE_CHANNEL_A        0xF000
+
+/* IGP01E1000 AGC Registers */
+
+#define IGP01E1000_AGC_LENGTH_SHIFT 7         /* Coarse - 13:11, Fine - 10:7 */
+
+/* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
+#define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
+
+/* The precision of the length is +/- 10 meters */
+#define IGP01E1000_AGC_RANGE    10
+
+/* IGP cable length table */
+static const
+uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
+    { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+      5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,
+      25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,
+      40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,
+      60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,
+      90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+      100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+      110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};
+
+/* IGP01E1000 PCS Initialization register */
+/* bits 3:6 in the PCS registers stores the channels polarity */
+#define IGP01E1000_PHY_POLARITY_MASK    0x0078
+
+/* IGP01E1000 GMII FIFO Register */
+#define IGP01E1000_GMII_FLEX_SPD               0x10 /* Enable flexible speed
+                                                     * on Link-Up */
+#define IGP01E1000_GMII_SPD                    0x20 /* Enable SPD */
+
 /* Bit definitions for valid PHY IDs. */
 #define M88E1000_E_PHY_ID  0x01410C50
 #define M88E1000_I_PHY_ID  0x01410C30
 #define M88E1011_I_PHY_ID  0x01410C20
+#define IGP01E1000_I_PHY_ID  0x02A80380
 #define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
 #define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
 #define M88E1011_I_REV_4   0x04
diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
--- a/drivers/net/e1000/e1000_main.c	Tue Feb 18 10:38:27 2003
+++ b/drivers/net/e1000/e1000_main.c	Mon Mar 17 23:05:21 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -30,7 +30,22 @@
 
 /* Change Log
  *
- * 4.4.19       11/27/02
+ * 5.0.43	3/5/03
+ *   o Feature: Added support for 82541 and 82547 hardware.
+ *   o Feature: Added support for Intel Gigabit PHY (IGP) and a variety of
+ *   eeproms.
+ *   o Feature: Added support for TCP Segmentation Offload (TSO).
+ *   o Feature: Added MII ioctl.
+ *   o Feature: Added support for statistics reporting through ethtool.
+ *   o Cleanup: Removed proprietary hooks for ANS.
+ *   o Cleanup: Miscellaneous code changes to improve CPU utilization.
+ *   	- Replaced "%" with conditionals and "+-" operators.
+ *   	- Implemented dynamic Interrupt Throttle Rate (ITR).
+ *   	- Reduced expensive PCI reads of ICR in interrupt.
+ *   o Bug fix: Request IRQ after descriptor ring setup to avoid panic in
+ *   shared interrupt instances.
+ *
+ * 4.4.18       11/27/02
  *   o Feature: Added user-settable knob for interrupt throttle rate (ITR).
  *   o Cleanup: removed large static array allocations.
  *   o Cleanup: C99 struct initializer format.
@@ -42,25 +57,12 @@
  *   o Bug fix: Make ethtool EEPROM acceses work on older versions of ethtool.
  * 
  * 4.4.12       10/15/02
- *   o Clean up: use members of pci_device rather than direct calls to
- *     pci_read_config_word.
- *   o Bug fix: changed default flow control settings.
- *   o Clean up: ethtool file now has an inclusive list for adapters in the
- *     Wake-On-LAN capabilities instead of an exclusive list.
- *   o Bug fix: miscellaneous WoL bug fixes.
- *   o Added software interrupt for clearing rx ring
- *   o Bug fix: easier to undo "forcing" of 1000/fd using ethtool.
- *   o Now setting netdev->mem_end in e1000_probe.
- *   o Clean up: Moved tx_timeout from interrupt context to process context
- *     using schedule_task.
- * 
- * 4.3.15       8/9/02
  */
 
 char e1000_driver_name[] = "e1000";
 char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-char e1000_driver_version[] = "4.4.19-k3";
-char e1000_copyright[] = "Copyright (c) 1999-2002 Intel Corporation.";
+char e1000_driver_version[] = "5.0.43-k1";
+char e1000_copyright[] = "Copyright (c) 1999-2003 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
  *
@@ -104,6 +106,8 @@
 	{0x8086, 0x1016, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x8086, 0x1017, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	/* required last entry */
 	{0,}
 };
@@ -112,7 +116,7 @@
 
 static char *e1000_strings[] = {
 	"Intel(R) PRO/1000 Network Connection",
-	"Compaq Gigabit Ethernet Server Adapter",
+	"HP Gigabit Ethernet Server Adapter",
 	"IBM Mobile, Desktop & Server Adapters"
 };
 
@@ -121,6 +125,7 @@
 int e1000_up(struct e1000_adapter *adapter);
 void e1000_down(struct e1000_adapter *adapter);
 void e1000_reset(struct e1000_adapter *adapter);
+int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
 
 static int e1000_init_module(void);
 static void e1000_exit_module(void);
@@ -141,6 +146,7 @@
 static void e1000_set_multi(struct net_device *netdev);
 static void e1000_update_phy_info(unsigned long data);
 static void e1000_watchdog(unsigned long data);
+static void e1000_82547_tx_fifo_stall(unsigned long data);
 static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
 static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
 static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
@@ -149,14 +155,18 @@
 static inline void e1000_irq_disable(struct e1000_adapter *adapter);
 static inline void e1000_irq_enable(struct e1000_adapter *adapter);
 static void e1000_intr(int irq, void *data, struct pt_regs *regs);
-static void e1000_clean_tx_irq(struct e1000_adapter *adapter);
 #ifdef CONFIG_E1000_NAPI
-static int e1000_poll(struct net_device *netdev, int *budget);
+static int e1000_clean(struct net_device *netdev, int *budget);
+static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
+                                    int *work_done, int work_to_do);
 #else
-static void e1000_clean_rx_irq(struct e1000_adapter *adapter);
+static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter);
 #endif
+static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter);
 static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter);
 static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
+static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
+			   int cmd);
 static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
 static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
 static inline void e1000_rx_checksum(struct e1000_adapter *adapter,
@@ -164,6 +174,9 @@
                                      struct sk_buff *skb);
 static void e1000_tx_timeout(struct net_device *dev);
 static void e1000_tx_timeout_task(struct net_device *dev);
+static void e1000_smartspeed(struct e1000_adapter *adapter);
+static inline int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
+					      struct sk_buff *skb);
 
 static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
 static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
@@ -182,6 +195,7 @@
 	.priority	= 0
 };
 
+
 /* Exported from other modules */
 
 extern void e1000_check_options(struct e1000_adapter *adapter);
@@ -249,13 +263,10 @@
 {
 	struct net_device *netdev = adapter->netdev;
 
-	if(request_irq(netdev->irq, &e1000_intr, SA_SHIRQ | SA_SAMPLE_RANDOM,
-	               netdev->name, netdev))
-		return -1;
-
 	/* hardware has been reset, we need to reload some things */
 
 	e1000_set_multi(netdev);
+
 	e1000_restore_vlan(adapter);
 
 	e1000_configure_tx(adapter);
@@ -263,6 +274,14 @@
 	e1000_configure_rx(adapter);
 	e1000_alloc_rx_buffers(adapter);
 
+	if(request_irq(netdev->irq, &e1000_intr, SA_SHIRQ | SA_SAMPLE_RANDOM,
+		       netdev->name, netdev)) {
+		e1000_reset_hw(&adapter->hw);
+		e1000_free_tx_resources(adapter);
+		e1000_free_rx_resources(adapter);
+		return -1;
+	}
+
 	mod_timer(&adapter->watchdog_timer, jiffies);
 	e1000_irq_enable(adapter);
 
@@ -276,6 +295,7 @@
 
 	e1000_irq_disable(adapter);
 	free_irq(netdev->irq, netdev);
+	del_timer_sync(&adapter->tx_fifo_stall_timer);
 	del_timer_sync(&adapter->watchdog_timer);
 	del_timer_sync(&adapter->phy_info_timer);
 	adapter->link_speed = 0;
@@ -291,14 +311,28 @@
 void
 e1000_reset(struct e1000_adapter *adapter)
 {
+	uint32_t pba;
 	/* Repartition Pba for greater than 9k mtu
 	 * To take effect CTRL.RST is required.
 	 */
 
-	if(adapter->rx_buffer_len > E1000_RXBUFFER_8192)
-		E1000_WRITE_REG(&adapter->hw, PBA, E1000_JUMBO_PBA);
-	else
-		E1000_WRITE_REG(&adapter->hw, PBA, E1000_DEFAULT_PBA);
+	if(adapter->hw.mac_type < e1000_82547) {
+		if(adapter->rx_buffer_len > E1000_RXBUFFER_8192)
+			pba = E1000_PBA_40K;
+		else
+			pba = E1000_PBA_48K;
+	} else {
+		if(adapter->rx_buffer_len > E1000_RXBUFFER_8192)
+			pba = E1000_PBA_22K;
+		else
+			pba = E1000_PBA_30K;
+		adapter->tx_fifo_head = 0;
+		adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
+		adapter->tx_fifo_size =
+			(E1000_PBA_40K - pba) << E1000_TX_FIFO_SIZE_SHIFT;
+		atomic_set(&adapter->tx_fifo_stall, 0);
+	}
+	E1000_WRITE_REG(&adapter->hw, PBA, pba);
 
 	adapter->hw.fc = adapter->hw.original_fc;
 	e1000_reset_hw(&adapter->hw);
@@ -389,9 +423,9 @@
 	netdev->change_mtu = &e1000_change_mtu;
 	netdev->do_ioctl = &e1000_ioctl;
 	netdev->tx_timeout = &e1000_tx_timeout;
-	netdev->watchdog_timeo = HZ;
+	netdev->watchdog_timeo = 5 * HZ;
 #ifdef CONFIG_E1000_NAPI
-	netdev->poll = &e1000_poll;
+	netdev->poll = &e1000_clean;
 	netdev->weight = 64;
 #endif
 	netdev->vlan_rx_register = e1000_vlan_rx_register;
@@ -413,17 +447,18 @@
 
 	if(adapter->hw.mac_type >= e1000_82543) {
 		netdev->features = NETIF_F_SG |
-			           NETIF_F_HW_CSUM |
-		       	           NETIF_F_HW_VLAN_TX |
-		                   NETIF_F_HW_VLAN_RX |
+				   NETIF_F_HW_CSUM |
+				   NETIF_F_HW_VLAN_TX |
+				   NETIF_F_HW_VLAN_RX |
 				   NETIF_F_HW_VLAN_FILTER;
 	} else {
 		netdev->features = NETIF_F_SG;
 	}
 
-	if(adapter->hw.mac_type >= e1000_82544)
+	if((adapter->hw.mac_type >= e1000_82544) &&
+	   (adapter->hw.mac_type != e1000_82547))
 		netdev->features |= NETIF_F_TSO;
- 
+
 	if(pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
@@ -446,13 +481,9 @@
 
 	e1000_get_bus_info(&adapter->hw);
 
-	if((adapter->hw.mac_type == e1000_82544) &&
-	   (adapter->hw.bus_type == e1000_bus_type_pcix))
-
-		adapter->max_data_per_txd = 4096;
-	else
-		adapter->max_data_per_txd = MAX_JUMBO_FRAME_SIZE;
-
+	init_timer(&adapter->tx_fifo_stall_timer);
+	adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
+	adapter->tx_fifo_stall_timer.data = (unsigned long) adapter;
 
 	init_timer(&adapter->watchdog_timer);
 	adapter->watchdog_timer.function = &e1000_watchdog;
@@ -482,11 +513,12 @@
 	 * enable the ACPI Magic Packet filter
 	 */
 
-	e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG, &eeprom_data);
+	e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG,1, &eeprom_data);
 	if((adapter->hw.mac_type >= e1000_82544) &&
 	   (eeprom_data & E1000_EEPROM_APME))
 		adapter->wol |= E1000_WUFC_MAG;
 
+
 	/* reset the hardware with the new settings */
 
 	e1000_reset(adapter);
@@ -533,6 +565,7 @@
 
 	e1000_phy_hw_reset(&adapter->hw);
 
+
 	iounmap(adapter->hw.hw_addr);
 	pci_release_regions(pdev);
 
@@ -568,7 +601,7 @@
 
 	adapter->rx_buffer_len = E1000_RXBUFFER_2048;
 	hw->max_frame_size = netdev->mtu +
-	                         ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
+			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
 	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
 
 	/* identify the MAC */
@@ -578,6 +611,10 @@
 		return -1;
 	}
 
+	/* initialize eeprom parameters */
+
+	e1000_init_eeprom_params(hw);
+
 	/* flow control settings */
 
 	hw->fc_high_water = E1000_FC_HIGH_THRESH;
@@ -585,6 +622,9 @@
 	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
 	hw->fc_send_xon = 1;
 
+	if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547))
+		hw->phy_init_script = 1;
+
 	/* Media type - copper or fiber */
 
 	if(hw->mac_type >= e1000_82543) {
@@ -782,7 +822,7 @@
 
 	tctl &= ~E1000_TCTL_CT;
 	tctl |= E1000_TCTL_EN | E1000_TCTL_PSP |
-	       (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
+		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
 
 	E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
 
@@ -852,8 +892,8 @@
 	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
 
 	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
-	        E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
-	        (adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
+		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
+		(adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
 
 	if(adapter->hw.tbi_compatibility_on == 1)
 		rctl |= E1000_RCTL_SBP;
@@ -907,12 +947,9 @@
 
 	if(adapter->hw.mac_type >= e1000_82540) {
 		E1000_WRITE_REG(&adapter->hw, RADV, adapter->rx_abs_int_delay);
-
-		/* Set the interrupt throttling rate.  Value is calculated
-		 * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) */
-#define MAX_INTS_PER_SEC        8000
-#define DEFAULT_ITR             1000000000/(MAX_INTS_PER_SEC * 256)
-		E1000_WRITE_REG(&adapter->hw, ITR, DEFAULT_ITR);
+		if(adapter->itr > 1)
+			E1000_WRITE_REG(&adapter->hw, ITR,
+				1000000000 / (adapter->itr * 256));
 	}
 
 	/* Setup the Base and Length of the Rx Descriptor Ring */
@@ -1184,9 +1221,9 @@
 	if(hw->mac_type == e1000_82542_rev2_0)
 		e1000_enter_82542_rst(adapter);
 
-	/* load the first 15 multicast address into the exact filters 1-15
+	/* load the first 14 multicast address into the exact filters 1-14
 	 * RAR 0 is used for the station MAC adddress
-	 * if there are not 15 addresses, go ahead and clear the filters
+	 * if there are not 14 addresses, go ahead and clear the filters
 	 */
 	mc_ptr = netdev->mc_list;
 
@@ -1216,6 +1253,40 @@
 		e1000_leave_82542_rst(adapter);
 }
 
+static void
+e1000_tx_flush(struct e1000_adapter *adapter)
+{
+	uint32_t ctrl, tctl, txcw, icr;
+
+	e1000_irq_disable(adapter);
+
+	if(adapter->hw.mac_type < e1000_82543) {
+		/* Transmit Unit Reset */
+		tctl = E1000_READ_REG(&adapter->hw, TCTL);
+		E1000_WRITE_REG(&adapter->hw, TCTL, tctl | E1000_TCTL_RST);
+		E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
+		e1000_clean_tx_ring(adapter);
+		e1000_configure_tx(adapter);
+	} else {
+		txcw = E1000_READ_REG(&adapter->hw, TXCW);
+		E1000_WRITE_REG(&adapter->hw, TXCW, txcw & ~E1000_TXCW_ANE);
+
+		ctrl = E1000_READ_REG(&adapter->hw, CTRL);
+		E1000_WRITE_REG(&adapter->hw, CTRL, ctrl | E1000_CTRL_SLU |
+				E1000_CTRL_ILOS);
+
+		mdelay(10);
+
+		e1000_clean_tx_irq(adapter);
+		E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
+		E1000_WRITE_REG(&adapter->hw, TXCW, txcw);
+
+		/* clear the link status change interrupts this caused */
+		icr = E1000_READ_REG(&adapter->hw, ICR);
+	}
+
+	e1000_irq_enable(adapter);
+}
 
 /* need to wait a few seconds after link up to get diagnostic information from the phy */
 
@@ -1227,6 +1298,48 @@
 }
 
 /**
+ * e1000_82547_tx_fifo_stall - Timer Call-back
+ * @data: pointer to adapter cast into an unsigned long
+ **/
+
+static void
+e1000_82547_tx_fifo_stall(unsigned long data)
+{
+	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
+	struct net_device *netdev = adapter->netdev;
+	uint32_t tctl;
+
+	if(atomic_read(&adapter->tx_fifo_stall)) {
+		if((E1000_READ_REG(&adapter->hw, TDT) ==
+		    E1000_READ_REG(&adapter->hw, TDH)) &&
+		   (E1000_READ_REG(&adapter->hw, TDFT) ==
+		    E1000_READ_REG(&adapter->hw, TDFH)) &&
+		   (E1000_READ_REG(&adapter->hw, TDFTS) ==
+		    E1000_READ_REG(&adapter->hw, TDFHS))) {
+			tctl = E1000_READ_REG(&adapter->hw, TCTL);
+			E1000_WRITE_REG(&adapter->hw, TCTL,
+					tctl & ~E1000_TCTL_EN);
+			E1000_WRITE_REG(&adapter->hw, TDFT,
+					adapter->tx_head_addr);
+			E1000_WRITE_REG(&adapter->hw, TDFH,
+					adapter->tx_head_addr);
+			E1000_WRITE_REG(&adapter->hw, TDFTS,
+					adapter->tx_head_addr);
+			E1000_WRITE_REG(&adapter->hw, TDFHS,
+					adapter->tx_head_addr);
+			E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
+			E1000_WRITE_FLUSH(&adapter->hw);
+
+			adapter->tx_fifo_head = 0;
+			atomic_set(&adapter->tx_fifo_stall, 0);
+			netif_wake_queue(netdev);
+		} else {
+			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
+		}
+	}
+}
+
+/**
  * e1000_watchdog - Timer Call-back
  * @data: pointer to netdev cast into an unsigned long
  **/
@@ -1256,6 +1369,7 @@
 			netif_carrier_on(netdev);
 			netif_wake_queue(netdev);
 			mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
+			adapter->smartspeed = 0;
 		}
 	} else {
 		if(netif_carrier_ok(netdev)) {
@@ -1268,11 +1382,34 @@
 			netif_stop_queue(netdev);
 			mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
 		}
+
+		e1000_smartspeed(adapter);
 	}
 
 	e1000_update_stats(adapter);
 	e1000_update_adaptive(&adapter->hw);
 
+	if(!netif_carrier_ok(netdev)) {
+		if(E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
+			unsigned long flags;
+			spin_lock_irqsave(&netdev->xmit_lock, flags);
+			e1000_tx_flush(adapter);
+			spin_unlock_irqrestore(&netdev->xmit_lock, flags);
+		}
+	}
+
+	/* Dynamic mode for Interrupt Throttle Rate (ITR) */
+	if(adapter->hw.mac_type >= e1000_82540 && adapter->itr == 1) {
+		/* Symmetric Tx/Rx gets a reduced ITR=2000; Total
+		 * asymmetrical Tx or Rx gets ITR=8000; everyone
+		 * else is between 2000-8000. */
+		uint32_t goc = (adapter->gotcl + adapter->gorcl) / 10000;
+		uint32_t dif = (adapter->gotcl > adapter->gorcl ? 
+			adapter->gotcl - adapter->gorcl :
+			adapter->gorcl - adapter->gotcl) / 10000;
+		uint32_t itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
+		E1000_WRITE_REG(&adapter->hw, ITR, 1000000000 / (itr * 256));
+	}
 
 	/* Cause software interrupt to ensure rx ring is cleaned */
 	E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0);
@@ -1301,7 +1438,7 @@
 	int i;
 	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
 	uint16_t ipcse, tucse, mss;
-	
+
 	if(skb_shinfo(skb)->tso_size) {
 		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
 		mss = skb_shinfo(skb)->tso_size;
@@ -1321,7 +1458,7 @@
 
 		i = adapter->tx_ring.next_to_use;
 		context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i);
-		
+
 		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
 		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
 		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
@@ -1335,12 +1472,12 @@
 			E1000_TXD_CMD_IP | E1000_TXD_CMD_TCP |
 			(skb->len - (hdr_len)));
 
-		i = (i + 1) % adapter->tx_ring.count;
+		if(++i == adapter->tx_ring.count) i = 0;
 		adapter->tx_ring.next_to_use = i;
 
 		return TRUE;
 	}
-	
+
 	return FALSE;
 }
 
@@ -1365,7 +1502,7 @@
 		context_desc->cmd_and_length =
 			cpu_to_le32(adapter->txd_cmd | E1000_TXD_CMD_DEXT);
 
-		i = (i + 1) % adapter->tx_ring.count;
+		if(++i == adapter->tx_ring.count) i = 0;
 		adapter->tx_ring.next_to_use = i;
 
 		return TRUE;
@@ -1374,24 +1511,24 @@
 	return FALSE;
 }
 
+#define E1000_MAX_TXD_PWR	12
+#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
+
 static inline int
 e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb)
 {
 	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
-	int len, offset, size, count, i;
+	int len = skb->len, offset = 0, size, count = 0, i;
+
 	int tso = skb_shinfo(skb)->tso_size;
 	int nr_frags = skb_shinfo(skb)->nr_frags;
-
 	int f;
-	len = skb->len - skb->data_len;
-	i = (tx_ring->next_to_use + tx_ring->count - 1) % tx_ring->count;
-	count = 0;
+	len -= skb->data_len;
 
-	offset = 0;
+	i = tx_ring->next_to_use;
 
 	while(len) {
-		i = (i + 1) % tx_ring->count;
-		size = min(len, adapter->max_data_per_txd);
+		size = min(len, E1000_MAX_DATA_PER_TXD);
 		/* Workaround for premature desc write-backs
 		 * in TSO mode.  Append 4-byte sentinel desc */
 		if(tso && !nr_frags && size == len && size > 4)
@@ -1407,6 +1544,7 @@
 		len -= size;
 		offset += size;
 		count++;
+		if(++i == tx_ring->count) i = 0;
 	}
 
 	for(f = 0; f < nr_frags; f++) {
@@ -1417,8 +1555,7 @@
 		offset = 0;
 
 		while(len) {
-			i = (i + 1) % tx_ring->count;
-			size = min(len, adapter->max_data_per_txd);
+			size = min(len, E1000_MAX_DATA_PER_TXD);
 			/* Workaround for premature desc write-backs
 			 * in TSO mode.  Append 4-byte sentinel desc */
 			if(tso && f == (nr_frags-1) && size == len && size > 4)
@@ -1435,8 +1572,10 @@
 			len -= size;
 			offset += size;
 			count++;
+			if(++i == tx_ring->count) i = 0;
 		}
 	}
+	if(--i < 0) i = tx_ring->count - 1;
 	tx_ring->buffer_info[i].skb = skb;
 
 	return count;
@@ -1477,7 +1616,7 @@
 		tx_desc->lower.data =
 			cpu_to_le32(txd_lower | tx_ring->buffer_info[i].length);
 		tx_desc->upper.data = cpu_to_le32(txd_upper);
-		i = (i + 1) % tx_ring->count;
+		if(++i == tx_ring->count) i = 0;
 	}
 
 	tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP);
@@ -1492,34 +1631,74 @@
 	E1000_WRITE_REG(&adapter->hw, TDT, i);
 }
 
-#define TXD_USE_COUNT(S, X) (((S) / (X)) + (((S) % (X)) ? 1 : 0))
+/**
+ * 82547 workaround to avoid controller hang in half-duplex environment.
+ * The workaround is to avoid queuing a large packet that would span
+ * the internal Tx FIFO ring boundary by notifying the stack to resend
+ * the packet at a later time.  This gives the Tx FIFO an opportunity to
+ * flush all packets.  When that occurs, we reset the Tx FIFO pointers
+ * to the beginning of the Tx FIFO.
+ **/
+
+#define E1000_FIFO_HDR			0x10
+#define E1000_82547_PAD_LEN		0x3E0
+
+static inline int
+e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb)
+{
+	uint32_t fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
+	uint32_t skb_fifo_len = skb->len + E1000_FIFO_HDR;
+
+	E1000_ROUNDUP(skb_fifo_len, E1000_FIFO_HDR);
+
+	if(adapter->link_duplex != HALF_DUPLEX)
+		goto no_fifo_stall_required;
+
+	if(atomic_read(&adapter->tx_fifo_stall))
+		return 1;
+
+	if(skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
+		atomic_set(&adapter->tx_fifo_stall, 1);
+		return 1;
+	}
+
+no_fifo_stall_required:
+	adapter->tx_fifo_head += skb_fifo_len;
+	if(adapter->tx_fifo_head >= adapter->tx_fifo_size)
+		adapter->tx_fifo_head -= adapter->tx_fifo_size;
+	return 0;
+}
+
+/* Tx Descriptors needed, worst case */
+#define TXD_USE_COUNT(S) (((S) >> E1000_MAX_TXD_PWR) + \
+			 (((S) & (E1000_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
+#define DESC_NEEDED TXD_USE_COUNT(MAX_JUMBO_FRAME_SIZE) + \
+	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1
 
 static int
 e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev->priv;
-	int tx_flags = 0, count;
-	int f;
+	int tx_flags = 0;
 
-	count = TXD_USE_COUNT(skb->len - skb->data_len,
-	                      adapter->max_data_per_txd);
-
-	if(count == 0) {
+	if(skb->len <= 0) {
 		dev_kfree_skb_any(skb);
 		return 0;
 	}
 
-	for(f = 0; f < skb_shinfo(skb)->nr_frags; f++)
-		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
-		                       adapter->max_data_per_txd);
-	if((skb_shinfo(skb)->tso_size) || (skb->ip_summed == CHECKSUM_HW))
-		count++;
-
-	if(E1000_DESC_UNUSED(&adapter->tx_ring) < count) {
+	if(E1000_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED) {
 		netif_stop_queue(netdev);
 		return 1;
 	}
 
+	if(adapter->hw.mac_type == e1000_82547) {
+		if(e1000_82547_fifo_workaround(adapter, skb)) {
+			netif_stop_queue(netdev);
+			mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
+			return 1;
+		}
+	}
+
 	if(adapter->vlgrp && vlan_tx_tag_present(skb)) {
 		tx_flags |= E1000_TX_FLAGS_VLAN;
 		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
@@ -1530,9 +1709,7 @@
 	else if(e1000_tx_csum(adapter, skb))
 		tx_flags |= E1000_TX_FLAGS_CSUM;
 
-	count = e1000_tx_map(adapter, skb);
-
-	e1000_tx_queue(adapter, count, tx_flags);
+	e1000_tx_queue(adapter, e1000_tx_map(adapter, skb), tx_flags);
 
 	netdev->trans_start = jiffies;
 
@@ -1653,7 +1830,8 @@
 
 	adapter->stats.crcerrs += E1000_READ_REG(hw, CRCERRS);
 	adapter->stats.gprc += E1000_READ_REG(hw, GPRC);
-	adapter->stats.gorcl += E1000_READ_REG(hw, GORCL);
+	adapter->gorcl = E1000_READ_REG(hw, GORCL);
+	adapter->stats.gorcl += adapter->gorcl;
 	adapter->stats.gorch += E1000_READ_REG(hw, GORCH);
 	adapter->stats.bprc += E1000_READ_REG(hw, BPRC);
 	adapter->stats.mprc += E1000_READ_REG(hw, MPRC);
@@ -1684,7 +1862,8 @@
 	adapter->stats.xofftxc += E1000_READ_REG(hw, XOFFTXC);
 	adapter->stats.fcruc += E1000_READ_REG(hw, FCRUC);
 	adapter->stats.gptc += E1000_READ_REG(hw, GPTC);
-	adapter->stats.gotcl += E1000_READ_REG(hw, GOTCL);
+	adapter->gotcl = E1000_READ_REG(hw, GOTCL);
+	adapter->stats.gotcl += adapter->gotcl;
 	adapter->stats.gotch += E1000_READ_REG(hw, GOTCH);
 	adapter->stats.rnbc += E1000_READ_REG(hw, RNBC);
 	adapter->stats.ruc += E1000_READ_REG(hw, RUC);
@@ -1807,60 +1986,57 @@
 {
 	struct net_device *netdev = data;
 	struct e1000_adapter *adapter = netdev->priv;
-	
-#ifdef CONFIG_E1000_NAPI
-	if (netif_rx_schedule_prep(netdev)) {
-		/* Disable interrupts and enable polling */
-		atomic_inc(&adapter->irq_sem);
-		E1000_WRITE_REG(&adapter->hw, IMC, ~0);
-		E1000_WRITE_FLUSH(&adapter->hw);
-		__netif_rx_schedule(netdev);
-	}
-#else
-	uint32_t icr;
-	int i = E1000_MAX_INTR;
-
-	while(i && (icr = E1000_READ_REG(&adapter->hw, ICR))) {
-
-		if(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
-			adapter->hw.get_link_status = 1;
-			mod_timer(&adapter->watchdog_timer, jiffies);
-		}
+	uint32_t icr = E1000_READ_REG(&adapter->hw, ICR);
+#ifndef CONFIG_E1000_NAPI
+	int i;
+#endif
 
-		e1000_clean_rx_irq(adapter);
-		e1000_clean_tx_irq(adapter);
-		i--;
+	if(!icr)
+		return;  /* Not our interrupt */
 
+	if(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+		adapter->hw.get_link_status = 1;
+		mod_timer(&adapter->watchdog_timer, jiffies);
 	}
+
+#ifdef CONFIG_E1000_NAPI
+	/* Don't disable interrupts - rely on h/w interrupt
+	 * moderation to keep interrupts low.  netif_rx_schedule
+	 * is NOP if already polling. */
+	netif_rx_schedule(netdev);
+#else
+	for(i = 0; i < E1000_MAX_INTR; i++)
+		if(!e1000_clean_rx_irq(adapter) &&
+		   !e1000_clean_tx_irq(adapter))
+			break;
 #endif
 }
 
 #ifdef CONFIG_E1000_NAPI
+/**
+ * e1000_clean - NAPI Rx polling callback
+ * @adapter: board private structure
+ **/
+
 static int
-e1000_process_intr(struct net_device *netdev)
+e1000_clean(struct net_device *netdev, int *budget)
 {
 	struct e1000_adapter *adapter = netdev->priv;
-	uint32_t icr;
-	int i = E1000_MAX_INTR;
-	int hasReceived = 0;
-
-	while(i && (icr = E1000_READ_REG(&adapter->hw, ICR))) {
-		if (icr & E1000_ICR_RXT0)
-			hasReceived = 1;
- 
-		if (!(icr & ~(E1000_ICR_RXT0)))
+	int work_to_do = min(*budget, netdev->quota);
+	int work_done = 0;
+	
+	while(work_done < work_to_do)
+		if(!e1000_clean_rx_irq(adapter, &work_done, work_to_do) &&
+		   !e1000_clean_tx_irq(adapter))
 			break;
-    
-		if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
-			adapter->hw.get_link_status = 1;
-			mod_timer(&adapter->watchdog_timer, jiffies);
-		}
- 
-		e1000_clean_tx_irq(adapter);
-		i--;
-	}
 
-	return hasReceived;
+	*budget -= work_done;
+	netdev->quota -= work_done;
+	
+	if(work_done < work_to_do)
+		netif_rx_complete(netdev);
+
+	return (work_done >= work_to_do);
 }
 #endif
 
@@ -1869,20 +2045,22 @@
  * @adapter: board private structure
  **/
 
-static void
+static boolean_t
 e1000_clean_tx_irq(struct e1000_adapter *adapter)
 {
 	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_tx_desc *tx_desc;
-	int i;
+	int i, cleaned = FALSE;
 
 	i = tx_ring->next_to_clean;
 	tx_desc = E1000_TX_DESC(*tx_ring, i);
 
 	while(tx_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
 
+		cleaned = TRUE;
+
 		if(tx_ring->buffer_info[i].dma) {
 
 			pci_unmap_page(pdev,
@@ -1900,158 +2078,34 @@
 			tx_ring->buffer_info[i].skb = NULL;
 		}
 
+		tx_desc->buffer_addr = 0;
+		tx_desc->lower.data = 0;
 		tx_desc->upper.data = 0;
 
-		i = (i + 1) % tx_ring->count;
+		if(++i == tx_ring->count) i = 0;
 		tx_desc = E1000_TX_DESC(*tx_ring, i);
 	}
 
 	tx_ring->next_to_clean = i;
 
-	if(netif_queue_stopped(netdev) && netif_carrier_ok(netdev) &&
-	   (E1000_DESC_UNUSED(tx_ring) > E1000_TX_QUEUE_WAKE)) {
-
+	if(cleaned && netif_queue_stopped(netdev) && netif_carrier_ok(netdev))
 		netif_wake_queue(netdev);
-	}
-}
-
-#ifdef CONFIG_E1000_NAPI
-static int
-e1000_poll(struct net_device *netdev, int *budget)
-{
-	struct e1000_adapter *adapter = netdev->priv;
-	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
-	struct pci_dev *pdev = adapter->pdev;
-	struct e1000_rx_desc *rx_desc;
-	struct sk_buff *skb;
-	unsigned long flags;
-	uint32_t length;
-	uint8_t last_byte;
-	int i;
-	int received = 0;
-	int rx_work_limit = *budget;
-
-	if(rx_work_limit > netdev->quota)
-		rx_work_limit = netdev->quota;
-
-	e1000_process_intr(netdev);
-
-	i = rx_ring->next_to_clean;
-	rx_desc = E1000_RX_DESC(*rx_ring, i);
-
-	while(rx_desc->status & E1000_RXD_STAT_DD) {
-		if(--rx_work_limit < 0)
-			goto not_done;
-
-		pci_unmap_single(pdev,
-		                 rx_ring->buffer_info[i].dma,
-		                 rx_ring->buffer_info[i].length,
-		                 PCI_DMA_FROMDEVICE);
-
-		skb = rx_ring->buffer_info[i].skb;
-		length = le16_to_cpu(rx_desc->length);
-
-		if(!(rx_desc->status & E1000_RXD_STAT_EOP)) {
-
-			/* All receives must fit into a single buffer */
-
-			E1000_DBG("Receive packet consumed multiple buffers\n");
-
-			dev_kfree_skb_irq(skb);
-			rx_desc->status = 0;
-			rx_ring->buffer_info[i].skb = NULL;
-
-			i = (i + 1) % rx_ring->count;
-
-			rx_desc = E1000_RX_DESC(*rx_ring, i);
-			continue;
-		}
-
-		if(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
-
-			last_byte = *(skb->data + length - 1);
-
-			if(TBI_ACCEPT(&adapter->hw, rx_desc->status,
-			              rx_desc->errors, length, last_byte)) {
-
-				spin_lock_irqsave(&adapter->stats_lock, flags);
-
-				e1000_tbi_adjust_stats(&adapter->hw,
-				                       &adapter->stats,
-				                       length, skb->data);
-
-				spin_unlock_irqrestore(&adapter->stats_lock,
-				                       flags);
-				length--;
-			} else {
-
-				dev_kfree_skb_irq(skb);
-				rx_desc->status = 0;
-				rx_ring->buffer_info[i].skb = NULL;
-
-				i = (i + 1) % rx_ring->count;
 
-				rx_desc = E1000_RX_DESC(*rx_ring, i);
-				continue;
-			}
-		}
-
-		/* Good Receive */
-		skb_put(skb, length - ETHERNET_FCS_SIZE);
-
-		/* Receive Checksum Offload */
-		e1000_rx_checksum(adapter, rx_desc, skb);
-
-		skb->protocol = eth_type_trans(skb, netdev);
-		if(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP)) {
-			vlan_hwaccel_rx(skb, adapter->vlgrp,
-				(rx_desc->special & E1000_RXD_SPC_VLAN_MASK));
-		} else {
-			netif_receive_skb(skb);
-		}
-		netdev->last_rx = jiffies;
-
-		rx_desc->status = 0;
-		rx_ring->buffer_info[i].skb = NULL;
-
-		i = (i + 1) % rx_ring->count;
-
-		rx_desc = E1000_RX_DESC(*rx_ring, i);
-		received++;
-	}
-
-	if(!received)
-		received = 1;
-
-	e1000_alloc_rx_buffers(adapter);
-	
-	rx_ring->next_to_clean = i;
-	netdev->quota -= received;
-	*budget -= received;
-
-	netif_rx_complete(netdev);
-
-	e1000_irq_enable(adapter);
-	return 0;
-
-not_done:
-
-	e1000_alloc_rx_buffers(adapter);
-	
-	rx_ring->next_to_clean = i;
-	netdev->quota -= received;
-	*budget -= received;
-
-	return 1;
+	return cleaned;
 }
-#else
+
 /**
  * e1000_clean_rx_irq - Send received data up the network stack,
  * @adapter: board private structure
  **/
 
-static void
+static boolean_t
+#ifdef CONFIG_E1000_NAPI
+e1000_clean_rx_irq(struct e1000_adapter *adapter, int *work_done,
+                   int work_to_do)
+#else
 e1000_clean_rx_irq(struct e1000_adapter *adapter)
+#endif
 {
 	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
 	struct net_device *netdev = adapter->netdev;
@@ -2061,13 +2115,22 @@
 	unsigned long flags;
 	uint32_t length;
 	uint8_t last_byte;
-	int i;
+	int i, cleaned = FALSE;
 
 	i = rx_ring->next_to_clean;
 	rx_desc = E1000_RX_DESC(*rx_ring, i);
 
 	while(rx_desc->status & E1000_RXD_STAT_DD) {
 
+#ifdef CONFIG_E1000_NAPI
+		if(*work_done >= work_to_do)
+			break;
+
+		(*work_done)++;
+#endif
+
+		cleaned = TRUE;
+
 		pci_unmap_single(pdev,
 		                 rx_ring->buffer_info[i].dma,
 		                 rx_ring->buffer_info[i].length,
@@ -2086,7 +2149,7 @@
 			rx_desc->status = 0;
 			rx_ring->buffer_info[i].skb = NULL;
 
-			i = (i + 1) % rx_ring->count;
+			if(++i == rx_ring->count) i = 0;
 
 			rx_desc = E1000_RX_DESC(*rx_ring, i);
 			continue;
@@ -2114,7 +2177,7 @@
 				rx_desc->status = 0;
 				rx_ring->buffer_info[i].skb = NULL;
 
-				i = (i + 1) % rx_ring->count;
+				if(++i == rx_ring->count) i = 0;
 
 				rx_desc = E1000_RX_DESC(*rx_ring, i);
 				continue;
@@ -2128,18 +2191,28 @@
 		e1000_rx_checksum(adapter, rx_desc, skb);
 
 		skb->protocol = eth_type_trans(skb, netdev);
+#ifdef CONFIG_E1000_NAPI
+		if(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP)) {
+			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+				(rx_desc->special & E1000_RXD_SPC_VLAN_MASK));
+		} else {
+			netif_receive_skb(skb);
+		}
+#else /* CONFIG_E1000_NAPI */
 		if(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP)) {
 			vlan_hwaccel_rx(skb, adapter->vlgrp,
 				(rx_desc->special & E1000_RXD_SPC_VLAN_MASK));
 		} else {
 			netif_rx(skb);
 		}
+#endif /* CONFIG_E1000_NAPI */
+
 		netdev->last_rx = jiffies;
 
 		rx_desc->status = 0;
 		rx_ring->buffer_info[i].skb = NULL;
 
-		i = (i + 1) % rx_ring->count;
+		if(++i == rx_ring->count) i = 0;
 
 		rx_desc = E1000_RX_DESC(*rx_ring, i);
 	}
@@ -2147,8 +2220,9 @@
 	rx_ring->next_to_clean = i;
 
 	e1000_alloc_rx_buffers(adapter);
+
+	return cleaned;
 }
-#endif
 
 /**
  * e1000_alloc_rx_buffers - Replace used receive buffers
@@ -2163,11 +2237,9 @@
 	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_rx_desc *rx_desc;
 	struct sk_buff *skb;
-	int reserve_len;
+	int reserve_len = 2;
 	int i;
 
-	reserve_len = 2;
-
 	i = rx_ring->next_to_use;
 
 	while(!rx_ring->buffer_info[i].skb) {
@@ -2198,7 +2270,7 @@
 
 		rx_desc->buffer_addr = cpu_to_le64(rx_ring->buffer_info[i].dma);
 
-		if(!(i % E1000_RX_BUFFER_WRITE)) {
+		if((i & ~(E1000_RX_BUFFER_WRITE - 1)) == i) {
 			/* Force memory writes to complete before letting h/w
 			 * know there are new descriptors to fetch.  (Only
 			 * applicable for weak-ordered memory model archs,
@@ -2208,13 +2280,68 @@
 			E1000_WRITE_REG(&adapter->hw, RDT, i);
 		}
 
-		i = (i + 1) % rx_ring->count;
+		if(++i == rx_ring->count) i = 0;
 	}
 
 	rx_ring->next_to_use = i;
 }
 
 /**
+ * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
+ * @adapter:
+ **/
+
+static void
+e1000_smartspeed(struct e1000_adapter *adapter)
+{
+	uint16_t phy_status;
+	uint16_t phy_ctrl;
+
+	if((adapter->hw.phy_type != e1000_phy_igp) || !adapter->hw.autoneg ||
+	   !(adapter->hw.autoneg_advertised & ADVERTISE_1000_FULL))
+		return;
+
+	if(adapter->smartspeed == 0) {
+		/* If Master/Slave config fault is asserted twice,
+		 * we assume back-to-back */
+		e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
+		if(!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
+		e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
+		if(!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
+		e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
+		if(phy_ctrl & CR_1000T_MS_ENABLE) {
+			phy_ctrl &= ~CR_1000T_MS_ENABLE;
+			e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL,
+					    phy_ctrl);
+			adapter->smartspeed++;
+			if(!e1000_phy_setup_autoneg(&adapter->hw) &&
+			   !e1000_read_phy_reg(&adapter->hw, PHY_CTRL,
+				   	       &phy_ctrl)) {
+				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
+					     MII_CR_RESTART_AUTO_NEG);
+				e1000_write_phy_reg(&adapter->hw, PHY_CTRL,
+						    phy_ctrl);
+			}
+		}
+		return;
+	} else if(adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
+		/* If still no link, perhaps using 2/3 pair cable */
+		e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
+		phy_ctrl |= CR_1000T_MS_ENABLE;
+		e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_ctrl);
+		if(!e1000_phy_setup_autoneg(&adapter->hw) &&
+		   !e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_ctrl)) {
+			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
+				     MII_CR_RESTART_AUTO_NEG);
+			e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_ctrl);
+		}
+	}
+	/* Restart process after E1000_SMARTSPEED_MAX iterations */
+	if(adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
+		adapter->smartspeed = 0;
+}
+
+/**
  * e1000_ioctl -
  * @netdev:
  * @ifreq:
@@ -2225,6 +2352,10 @@
 e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 {
 	switch (cmd) {
+	case SIOCGMIIPHY:
+	case SIOCGMIIREG:
+	case SIOCSMIIREG:
+		return e1000_mii_ioctl(netdev, ifr, cmd);
 	case SIOCETHTOOL:
 		return e1000_ethtool_ioctl(netdev, ifr);
 	default:
@@ -2233,6 +2364,86 @@
 }
 
 /**
+ * e1000_mii_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ **/
+
+static int
+e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	struct e1000_adapter *adapter = netdev->priv;
+	struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
+	int retval;
+	uint16_t mii_reg;
+	uint16_t spddplx;
+
+	if(adapter->hw.media_type == e1000_media_type_fiber)
+		return -EOPNOTSUPP;
+
+	switch (cmd) {
+	case SIOCGMIIPHY:
+		data->phy_id = adapter->hw.phy_addr;
+		break;
+	case SIOCGMIIREG:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		if (e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+				   &data->val_out))
+			return -EIO;
+		break;
+	case SIOCSMIIREG:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		if (data->reg_num & ~(0x1F))
+			return -EFAULT;
+		mii_reg = data->val_in;
+		if (e1000_write_phy_reg(&adapter->hw, data->reg_num,
+					data->val_in))
+			return -EIO;
+		if (adapter->hw.phy_type == e1000_phy_m88) {
+			switch (data->reg_num) {
+			case PHY_CTRL:
+				if(data->val_in & MII_CR_AUTO_NEG_EN) {
+					adapter->hw.autoneg = 1;
+					adapter->hw.autoneg_advertised = 0x2F;
+				} else {
+					if (data->val_in & 0x40)
+						spddplx = SPEED_1000;
+					else if (data->val_in & 0x2000)
+						spddplx = SPEED_100;
+					else
+						spddplx = SPEED_10;
+					spddplx += (data->val_in & 0x100)
+						   ? FULL_DUPLEX :
+						   HALF_DUPLEX;
+					retval = e1000_set_spd_dplx(adapter,
+								    spddplx);
+					if(retval)
+						return retval;
+				}
+				if(netif_running(adapter->netdev)) {
+					e1000_down(adapter);
+					e1000_up(adapter);
+				} else
+					e1000_reset(adapter);
+				break;
+			case M88E1000_PHY_SPEC_CTRL:
+			case M88E1000_EXT_PHY_SPEC_CTRL:
+				if (e1000_phy_reset(&adapter->hw))
+					return -EIO;
+				break;
+			}
+		}
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+	return E1000_SUCCESS;
+}
+
+/**
  * e1000_rx_checksum - Receive Checksum Offload for 82543
  * @adapter: board private structure
  * @rx_desc: receive descriptor
@@ -2402,6 +2613,35 @@
 	}
 }
 
+int
+e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx)
+{
+	adapter->hw.autoneg = 0;
+
+	switch(spddplx) {
+	case SPEED_10 + DUPLEX_HALF:
+		adapter->hw.forced_speed_duplex = e1000_10_half;
+		break;
+	case SPEED_10 + DUPLEX_FULL:
+		adapter->hw.forced_speed_duplex = e1000_10_full;
+		break;
+	case SPEED_100 + DUPLEX_HALF:
+		adapter->hw.forced_speed_duplex = e1000_100_half;
+		break;
+	case SPEED_100 + DUPLEX_FULL:
+		adapter->hw.forced_speed_duplex = e1000_100_full;
+		break;
+	case SPEED_1000 + DUPLEX_FULL:
+		adapter->hw.autoneg = 1;
+		adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
+		break;
+	case SPEED_1000 + DUPLEX_HALF: /* not supported */
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static int
 e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
 {
@@ -2419,6 +2659,7 @@
 	return NOTIFY_DONE;
 }
 
+
 static int
 e1000_suspend(struct pci_dev *pdev, uint32_t state)
 {
@@ -2483,7 +2724,8 @@
 		if(manc & E1000_MANC_SMBUS_EN) {
 			manc |= E1000_MANC_ARP_EN;
 			E1000_WRITE_REG(&adapter->hw, MANC, manc);
-			state = 0;
+			pci_enable_wake(pdev, 3, 1);
+			pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */
 		}
 	}
 
diff -Nru a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h
--- a/drivers/net/e1000/e1000_osdep.h	Fri Feb  7 00:20:34 2003
+++ b/drivers/net/e1000/e1000_osdep.h	Mon Mar 17 14:23:15 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -77,24 +77,22 @@
 
 
 #define E1000_WRITE_REG(a, reg, value) ( \
-    ((a)->mac_type >= e1000_82543) ? \
-        (writel((value), ((a)->hw_addr + E1000_##reg))) : \
-        (writel((value), ((a)->hw_addr + E1000_82542_##reg))))
+    writel((value), ((a)->hw_addr + \
+        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg))))
 
 #define E1000_READ_REG(a, reg) ( \
-    ((a)->mac_type >= e1000_82543) ? \
-        readl((a)->hw_addr + E1000_##reg) : \
-        readl((a)->hw_addr + E1000_82542_##reg))
+    readl((a)->hw_addr + \
+        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg)))
 
 #define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \
-    ((a)->mac_type >= e1000_82543) ? \
-        writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2))) : \
-        writel((value), ((a)->hw_addr + E1000_82542_##reg + ((offset) << 2))))
+    writel((value), ((a)->hw_addr + \
+        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
+        ((offset) << 2))))
 
 #define E1000_READ_REG_ARRAY(a, reg, offset) ( \
-    ((a)->mac_type >= e1000_82543) ? \
-        readl((a)->hw_addr + E1000_##reg + ((offset) << 2)) : \
-        readl((a)->hw_addr + E1000_82542_##reg + ((offset) << 2)))
+    readl((a)->hw_addr + \
+        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
+        ((offset) << 2)))
 
 #define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS)
 
diff -Nru a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
--- a/drivers/net/e1000/e1000_param.c	Fri Jan  3 12:34:57 2003
+++ b/drivers/net/e1000/e1000_param.c	Sat Mar 22 08:30:55 2003
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   
-  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
+  Copyright(c) 1999 - 2003 Intel Corporation. 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 
@@ -75,7 +75,7 @@
  * Valid Range: 80-256 for 82542 and 82543 gigabit ethernet controllers
  * Valid Range: 80-4096 for 82544
  *
- * Default Value: 80
+ * Default Value: 256
  */
 
 E1000_PARAM(RxDescriptors, "Number of receive descriptors");
@@ -169,7 +169,7 @@
  *
  * Valid Range: 0-65535
  *
- * Default Value: 0/128
+ * Default Value: 0
  */
 
 E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
@@ -183,6 +183,15 @@
 
 E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
 
+/* Interrupt Throttle Rate (interrupts/sec)
+ *
+ * Valid Range: 100-100000 (0=off, 1=dynamic)
+ *
+ * Default Value: 1
+ */
+
+E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
+
 #define AUTONEG_ADV_DEFAULT  0x2F
 #define AUTONEG_ADV_MASK     0x2F
 #define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
@@ -192,7 +201,7 @@
 #define MIN_TXD                       80
 #define MAX_82544_TXD               4096
 
-#define DEFAULT_RXD                   80
+#define DEFAULT_RXD                  256
 #define MAX_RXD                      256
 #define MIN_RXD                       80
 #define MAX_82544_RXD               4096
@@ -213,6 +222,10 @@
 #define MAX_TXABSDELAY            0xFFFF
 #define MIN_TXABSDELAY                 0
 
+#define DEFAULT_ITR                    1
+#define MAX_ITR                   100000
+#define MIN_ITR                      100
+
 struct e1000_option {
 	enum { enable_option, range_option, list_option } type;
 	char *name;
@@ -309,7 +322,7 @@
 			.name = "Transmit Descriptors",
 			.err  = "using default of " __MODULE_STRING(DEFAULT_TXD),
 			.def  = DEFAULT_TXD,
-			.arg  = { .r = { .min = MIN_TXD }}
+			.arg  = { .r { .min = MIN_TXD }}
 		};
 		struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
 		e1000_mac_type mac_type = adapter->hw.mac_type;
@@ -362,7 +375,8 @@
 			.name = "Flow Control",
 			.err  = "reading default settings from EEPROM",
 			.def  = e1000_fc_default,
-			.arg  = { .l = { .nr = ARRAY_SIZE(fc_list), .p = fc_list }}
+			.arg  = { .l = { .nr = ARRAY_SIZE(fc_list),
+					 .p = fc_list }}
 		};
 
 		int fc = FlowControl[bd];
@@ -370,58 +384,78 @@
 		adapter->hw.fc = adapter->hw.original_fc = fc;
 	}
 	{ /* Transmit Interrupt Delay */
-		char *tidv = "using default of " __MODULE_STRING(DEFAULT_TIDV);
 		struct e1000_option opt = {
 			.type = range_option,
 			.name = "Transmit Interrupt Delay",
-			.arg  = { .r = { .min = MIN_TXDELAY, .max = MAX_TXDELAY }}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_TIDV),
+			.def  = DEFAULT_TIDV,
+			.arg  = { .r = { .min = MIN_TXDELAY,
+					 .max = MAX_TXDELAY }}
 		};
-		opt.def = DEFAULT_TIDV;
-		opt.err = tidv;
 
 		adapter->tx_int_delay = TxIntDelay[bd];
 		e1000_validate_option(&adapter->tx_int_delay, &opt);
 	}
 	{ /* Transmit Absolute Interrupt Delay */
-		char *tadv = "using default of " __MODULE_STRING(DEFAULT_TADV);
 		struct e1000_option opt = {
 			.type = range_option,
 			.name = "Transmit Absolute Interrupt Delay",
-			.arg  = { .r = { .min = MIN_TXABSDELAY, .max = MAX_TXABSDELAY }}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_TADV),
+			.def  = DEFAULT_TADV,
+			.arg  = { .r = { .min = MIN_TXABSDELAY,
+					 .max = MAX_TXABSDELAY }}
 		};
-		opt.def = DEFAULT_TADV;
-		opt.err = tadv;
 
 		adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
 		e1000_validate_option(&adapter->tx_abs_int_delay, &opt);
 	}
 	{ /* Receive Interrupt Delay */
-		char *rdtr = "using default of " __MODULE_STRING(DEFAULT_RDTR);
 		struct e1000_option opt = {
 			.type = range_option,
 			.name = "Receive Interrupt Delay",
-			.arg  = { .r = { .min = MIN_RXDELAY, .max = MAX_RXDELAY }}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_RDTR),
+			.def  = DEFAULT_RDTR,
+			.arg  = { .r = { .min = MIN_RXDELAY,
+					 .max = MAX_RXDELAY }}
 		};
-		opt.def = DEFAULT_RDTR;
-		opt.err = rdtr;
 
 		adapter->rx_int_delay = RxIntDelay[bd];
 		e1000_validate_option(&adapter->rx_int_delay, &opt);
 	}
 	{ /* Receive Absolute Interrupt Delay */
-		char *radv = "using default of " __MODULE_STRING(DEFAULT_RADV);
 		struct e1000_option opt = {
 			.type = range_option,
 			.name = "Receive Absolute Interrupt Delay",
-			.arg  = { .r = { .min = MIN_RXABSDELAY, .max = MAX_RXABSDELAY }}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_RADV),
+			.def  = DEFAULT_RADV,
+			.arg  = { .r = { .min = MIN_RXABSDELAY,
+					 .max = MAX_RXABSDELAY }}
 		};
-		opt.def = DEFAULT_RADV;
-		opt.err = radv;
 
 		adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
 		e1000_validate_option(&adapter->rx_abs_int_delay, &opt);
 	}
-	
+	{ /* Interrupt Throttling Rate */
+		struct e1000_option opt = {
+			.type = range_option,
+			.name = "Interrupt Throttling Rate (ints/sec)",
+			.err  = "using default of " __MODULE_STRING(DEFAULT_ITR),
+			.def  = DEFAULT_ITR,
+			.arg  = { .r = { .min = MIN_ITR,
+					 .max = MAX_ITR }}
+		};
+
+		adapter->itr = InterruptThrottleRate[bd];
+		if(adapter->itr == 0) {
+			printk(KERN_INFO "%s turned off\n", opt.name);
+		} else if(adapter->itr == 1 || adapter->itr == -1) {
+			/* Dynamic mode */
+			adapter->itr = 1;
+		} else {
+			e1000_validate_option(&adapter->itr, &opt);
+		}
+	}
+
 	switch(adapter->hw.media_type) {
 	case e1000_media_type_fiber:
 		e1000_check_fiber_options(adapter);
@@ -486,7 +520,8 @@
 			.name = "Speed",
 			.err  = "parameter ignored",
 			.def  = 0,
-			.arg  = { .l = { .nr = ARRAY_SIZE(speed_list), .p = speed_list }}
+			.arg  = { .l = { .nr = ARRAY_SIZE(speed_list),
+					 .p = speed_list }}
 		};
 
 		speed = Speed[bd];
@@ -502,7 +537,8 @@
 			.name = "Duplex",
 			.err  = "parameter ignored",
 			.def  = 0,
-			.arg  = { .l = { .nr = ARRAY_SIZE(dplx_list), .p = dplx_list }}
+			.arg  = { .l = { .nr = ARRAY_SIZE(dplx_list),
+					 .p = dplx_list }}
 		};
 
 		dplx = Duplex[bd];
@@ -554,7 +590,8 @@
 			.name = "AutoNeg",
 			.err  = "parameter ignored",
 			.def  = AUTONEG_ADV_DEFAULT,
-			.arg  = { .l = { .nr = ARRAY_SIZE(an_list), .p = an_list }}
+			.arg  = { .l = { .nr = ARRAY_SIZE(an_list),
+					 .p = an_list }}
 		};
 
 		int an = AutoNeg[bd];
diff -Nru a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
--- a/drivers/net/irda/ali-ircc.c	Fri Jan  3 12:53:07 2003
+++ b/drivers/net/irda/ali-ircc.c	Sun Feb 16 16:17:15 2003
@@ -248,7 +248,6 @@
 	struct ali_ircc_cb *self;
 	struct pm_dev *pmdev;
 	int dongle_id;
-	int ret;
 	int err;
 			
 	IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__);	
diff -Nru a/drivers/net/macmace.c b/drivers/net/macmace.c
--- a/drivers/net/macmace.c	Thu Nov  7 15:09:29 2002
+++ b/drivers/net/macmace.c	Wed Feb  5 08:52:02 2003
@@ -331,8 +331,8 @@
 		return -ENOMEM;
 	}
 
-	mp->rx_ring_phys = (unsigned char *) virt_to_bus(mp->rx_ring);
-	mp->tx_ring_phys = (unsigned char *) virt_to_bus(mp->tx_ring);
+	mp->rx_ring_phys = (unsigned char *) virt_to_bus((void *)mp->rx_ring);
+	mp->tx_ring_phys = (unsigned char *) virt_to_bus((void *)mp->tx_ring);
 
 	/* We want the Rx buffer to be uncached and the Tx buffer to be writethrough */
 
diff -Nru a/drivers/net/ne2k_cbus.c b/drivers/net/ne2k_cbus.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/ne2k_cbus.c	Fri Mar 14 19:37:35 2003
@@ -0,0 +1,879 @@
+/* ne.c: A general non-shared-memory NS8390 ethernet driver for linux. */
+/*
+    Written 1992-94 by Donald Becker.
+
+    Copyright 1993 United States Government as represented by the
+    Director, National Security Agency.
+
+    This software may be used and distributed according to the terms
+    of the GNU General Public License, incorporated herein by reference.
+
+    The author may be reached as becker@scyld.com, or C/O
+    Scyld Computing Corporation, 410 Severn Ave., Suite 210, Annapolis MD 21403
+
+    This driver should work with many programmed-I/O 8390-based ethernet
+    boards.  Currently it supports the NE1000, NE2000, many clones,
+    and some Cabletron products.
+
+    Changelog:
+
+    Paul Gortmaker	: use ENISR_RDC to monitor Tx PIO uploads, made
+			  sanity checks and bad clone support optional.
+    Paul Gortmaker	: new reset code, reset card after probe at boot.
+    Paul Gortmaker	: multiple card support for module users.
+    Paul Gortmaker	: Support for PCI ne2k clones, similar to lance.c
+    Paul Gortmaker	: Allow users with bad cards to avoid full probe.
+    Paul Gortmaker	: PCI probe changes, more PCI cards supported.
+    rjohnson@analogic.com : Changed init order so an interrupt will only
+    occur after memory is allocated for dev->priv. Deallocated memory
+    last in cleanup_modue()
+    Richard Guenther    : Added support for ISAPnP cards
+    Paul Gortmaker	: Discontinued PCI support - use ne2k-pci.c instead.
+    Osamu Tomita	: Separate driver for NEC PC-9800.
+
+*/
+
+/* Routines for the NatSemi-based designs (NE[12]000). */
+
+static const char version1[] =
+"ne.c:v1.10 9/23/94 Donald Becker (becker@scyld.com)\n";
+static const char version2[] =
+"Last modified Nov 1, 2000 by Paul Gortmaker\n";
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/isapnp.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+
+#include "8390.h"
+
+/* Some defines that people can play with if so inclined. */
+
+/* Do we support clones that don't adhere to 14,15 of the SAprom ? */
+#define SUPPORT_NE_BAD_CLONES
+
+/* Do we perform extra sanity checks on stuff ? */
+/* #define NE_SANITY_CHECK */
+
+/* Do we implement the read before write bugfix ? */
+/* #define NE_RW_BUGFIX */
+
+/* Do we have a non std. amount of memory? (in units of 256 byte pages) */
+/* #define PACKETBUF_MEMSIZE	0x40 */
+
+#ifdef SUPPORT_NE_BAD_CLONES
+/* A list of bad clones that we none-the-less recognize. */
+static struct { const char *name8, *name16; unsigned char SAprefix[4];}
+bad_clone_list[] __initdata = {
+    {"LA/T-98?", "LA/T-98", {0x00, 0xa0, 0xb0}},	/* I/O Data */
+    {"EGY-98?", "EGY-98", {0x00, 0x40, 0x26}},		/* Melco EGY98 */
+    {"ICM?", "ICM-27xx-ET", {0x00, 0x80, 0xc8}},	/* ICM IF-27xx-ET */
+    {"CNET-98/EL?", "CNET(98)E/L", {0x00, 0x80, 0x4C}},	/* Contec CNET-98/EL */
+    {0,}
+};
+#endif
+
+/* ---- No user-serviceable parts below ---- */
+
+#define NE_BASE	 (dev->base_addr)
+#define NE_CMD	 	EI_SHIFT(0x00)
+#define NE_DATAPORT	EI_SHIFT(0x10)	/* NatSemi-defined port window offset. */
+#define NE_RESET	EI_SHIFT(0x1f) /* Issue a read to reset, a write to clear. */
+#define NE_IO_EXTENT	0x20
+
+#define NE1SM_START_PG	0x20	/* First page of TX buffer */
+#define NE1SM_STOP_PG 	0x40	/* Last page +1 of RX ring */
+#define NESM_START_PG	0x40	/* First page of TX buffer */
+#define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */
+
+#include "ne2k_cbus.h"
+
+int ne_probe(struct net_device *dev);
+static int ne_probe1(struct net_device *dev, int ioaddr);
+static int ne_open(struct net_device *dev);
+static int ne_close(struct net_device *dev);
+
+static void ne_reset_8390(struct net_device *dev);
+static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
+			  int ring_page);
+static void ne_block_input(struct net_device *dev, int count,
+			  struct sk_buff *skb, int ring_offset);
+static void ne_block_output(struct net_device *dev, const int count,
+		const unsigned char *buf, const int start_page);
+
+
+/*  Probe for various non-shared-memory ethercards.
+
+   NEx000-clone boards have a Station Address PROM (SAPROM) in the packet
+   buffer memory space.  NE2000 clones have 0x57,0x57 in bytes 0x0e,0x0f of
+   the SAPROM, while other supposed NE2000 clones must be detected by their
+   SA prefix.
+
+   Reading the SAPROM from a word-wide card with the 8390 set in byte-wide
+   mode results in doubled values, which can be detected and compensated for.
+
+   The probe is also responsible for initializing the card and filling
+   in the 'dev' and 'ei_status' structures.
+
+   We use the minimum memory size for some ethercard product lines, iff we can't
+   distinguish models.  You can increase the packet buffer size by setting
+   PACKETBUF_MEMSIZE.  Reported Cabletron packet buffer locations are:
+	E1010   starts at 0x100 and ends at 0x2000.
+	E1010-x starts at 0x100 and ends at 0x8000. ("-x" means "more memory")
+	E2010	 starts at 0x100 and ends at 0x4000.
+	E2010-x starts at 0x100 and ends at 0xffff.  */
+
+int __init ne_probe(struct net_device *dev)
+{
+	unsigned int base_addr = dev->base_addr;
+
+	SET_MODULE_OWNER(dev);
+
+	if (ei_debug > 2)
+		printk(KERN_DEBUG "ne_probe(): entered.\n");
+
+	/* If CONFIG_NET_CBUS,
+	   we need dev->priv->reg_offset BEFORE to probe */
+	if (ne2k_cbus_init(dev) != 0)
+		return -ENOMEM;
+
+	/* First check any supplied i/o locations. User knows best. <cough> */
+	if (base_addr > 0) {
+		int result;
+		const struct ne2k_cbus_hwinfo *hw = ne2k_cbus_get_hwinfo((int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK));
+
+		if (ei_debug > 2)
+			printk(KERN_DEBUG "ne_probe(): call ne_probe_cbus(base_addr=0x%x)\n", base_addr);
+
+		result = ne_probe_cbus(dev, hw, base_addr);
+		if (result != 0)
+			ne2k_cbus_destroy(dev);
+
+		return result;
+	}
+
+	if (ei_debug > 2)
+		printk(KERN_DEBUG "ne_probe(): base_addr is not specified.\n");
+
+#ifndef MODULE
+	/* Last resort. The semi-risky C-Bus auto-probe. */
+	if (ei_debug > 2)
+		printk(KERN_DEBUG "ne_probe(): auto-probe start.\n");
+
+	{
+		const struct ne2k_cbus_hwinfo *hw = ne2k_cbus_get_hwinfo((int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK));
+
+		if (hw && hw->hwtype) {
+			const unsigned short *plist;
+			for (plist = hw->portlist; *plist; plist++)
+				if (ne_probe_cbus(dev, hw, *plist) == 0)
+					return 0;
+		} else {
+			for (hw = &ne2k_cbus_hwinfo_list[0]; hw->hwtype; hw++) {
+				const unsigned short *plist;
+				for (plist = hw->portlist; *plist; plist++)
+					if (ne_probe_cbus(dev, hw, *plist) == 0)
+						return 0;
+			}
+		}
+	}
+#endif
+
+	ne2k_cbus_destroy(dev);
+
+	return -ENODEV;
+}
+
+static int __init ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr)
+{
+	if (ei_debug > 2)
+		printk(KERN_DEBUG "ne_probe_cbus(): entered. (called from %p)\n",
+		       __builtin_return_address(0));
+
+	if (hw && hw->hwtype) {
+		ne2k_cbus_set_hwtype(dev, hw, ioaddr);
+		return ne_probe1(dev, ioaddr);
+	} else {
+		/* auto detect */
+
+		printk(KERN_DEBUG "ne_probe_cbus(): try to determine hardware types.\n");
+		for (hw = &ne2k_cbus_hwinfo_list[0]; hw->hwtype; hw++) {
+			ne2k_cbus_set_hwtype(dev, hw, ioaddr);
+			if (ne_probe1(dev, ioaddr) == 0)
+				return 0;
+		}
+	}
+	return -ENODEV;
+}
+
+static int __init ne_probe1(struct net_device *dev, int ioaddr)
+{
+	int i;
+	unsigned char SA_prom[32];
+	int wordlength = 2;
+	const char *name = NULL;
+	int start_page, stop_page;
+	int neX000, bad_card;
+	int reg0, ret;
+	static unsigned version_printed;
+	const struct ne2k_cbus_region *rlist;
+	const struct ne2k_cbus_hwinfo *hw = ne2k_cbus_get_hwinfo((int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK));
+	struct ei_device *ei_local = (struct ei_device *)(dev->priv);
+
+#ifdef CONFIG_NE2K_CBUS_CNET98EL
+	if (hw->hwtype == NE2K_CBUS_HARDWARE_TYPE_CNET98EL) {
+		outb_p(0, CONFIG_NE2K_CBUS_CNET98EL_IO_BASE);
+		/* udelay(5000);	*/
+		outb_p(1, CONFIG_NE2K_CBUS_CNET98EL_IO_BASE);
+		/* udelay(5000);	*/
+		outb_p((ioaddr & 0xf000) >> 8 | 0x08 | 0x01, CONFIG_NE2K_CBUS_CNET98EL_IO_BASE + 2);
+		/* udelay(5000); */
+	}
+#endif
+
+	for (rlist = hw->regionlist; rlist->range; rlist++)
+		if (!request_region(ioaddr + rlist->start,
+					rlist->range, dev->name)) {
+			ret = -EBUSY;
+			goto err_out;
+		}
+
+	reg0 = inb_p(ioaddr + EI_SHIFT(0));
+	if (reg0 == 0xFF) {
+		ret = -ENODEV;
+		goto err_out;
+	}
+
+	/* Do a preliminary verification that we have a 8390. */
+#ifdef CONFIG_NE2K_CBUS_CNET98EL
+	if (hw->hwtype != NE2K_CBUS_HARDWARE_TYPE_CNET98EL)
+#endif
+	{
+		int regd;
+		outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
+		regd = inb_p(ioaddr + EI_SHIFT(0x0d));
+		outb_p(0xff, ioaddr + EI_SHIFT(0x0d));
+		outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
+		inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
+		if (inb_p(ioaddr + EN0_COUNTER0) != 0) {
+			outb_p(reg0, ioaddr);
+			outb_p(regd, ioaddr + EI_SHIFT(0x0d));	/* Restore the old values. */
+			ret = -ENODEV;
+			goto err_out;
+		}
+	}
+
+	if (ei_debug  &&  version_printed++ == 0)
+		printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2);
+
+	printk(KERN_INFO "NE*000 ethercard probe at %#3x:", ioaddr);
+
+	/* A user with a poor card that fails to ack the reset, or that
+	   does not have a valid 0x57,0x57 signature can still use this
+	   without having to recompile. Specifying an i/o address along
+	   with an otherwise unused dev->mem_end value of "0xBAD" will
+	   cause the driver to skip these parts of the probe. */
+
+	bad_card = ((dev->base_addr != 0) && (dev->mem_end == 0xbad));
+
+	/* Reset card. Who knows what dain-bramaged state it was left in. */
+
+	{
+		unsigned long reset_start_time = jiffies;
+
+		/* derived from CNET98EL-patch for bad clones */
+		outb_p(E8390_NODMA | E8390_STOP, ioaddr + E8390_CMD);
+
+		/* DON'T change these to inb_p/outb_p or reset will fail on clones. */
+		outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET);
+
+		while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0)
+		if (jiffies - reset_start_time > 2*HZ/100) {
+			if (bad_card) {
+				printk(" (warning: no reset ack)");
+				break;
+			} else {
+				printk(" not found (no reset ack).\n");
+				ret = -ENODEV;
+				goto err_out;
+			}
+		}
+
+		outb_p(0xff, ioaddr + EN0_ISR);		/* Ack all intr. */
+	}
+
+#ifdef CONFIG_NE2K_CBUS_CNET98EL
+	if (hw->hwtype == NE2K_CBUS_HARDWARE_TYPE_CNET98EL) {
+		static const char pat[32] ="AbcdeFghijKlmnoPqrstUvwxyZ789012";
+		char buf[32];
+		int maxwait = 200;
+
+		if (ei_debug > 2)
+			printk(" [CNET98EL-specific initialize...");
+		outb_p(E8390_NODMA | E8390_STOP, ioaddr + E8390_CMD); /* 0x20|0x1 */
+		i = inb(ioaddr);
+		if ((i & ~0x2) != (0x20 | 0x01))
+			return -ENODEV;
+		if ((inb(ioaddr + 0x7) & 0x80) != 0x80)
+			return -ENODEV;
+		outb_p(E8390_RXOFF, ioaddr + EN0_RXCR); /* out(ioaddr+0xc, 0x20) */
+		/* outb_p(ENDCFG_WTS|ENDCFG_FT1|ENDCFG_LS, ioaddr+EN0_DCFG); */
+		outb_p(ENDCFG_WTS | 0x48, ioaddr + EN0_DCFG); /* 0x49 */
+		outb_p(CNET98EL_START_PG, ioaddr + EN0_STARTPG);
+		outb_p(CNET98EL_STOP_PG, ioaddr + EN0_STOPPG);
+		if (ei_debug > 2)
+			printk("memory check");
+		for (i = 0; i < 65536; i += 1024) {
+			if (ei_debug > 2)
+				printk(" %04x", i);
+			ne2k_cbus_writemem(dev, ioaddr, i, pat, 32);
+			while (((inb(ioaddr + EN0_ISR) & ENISR_RDC) != ENISR_RDC) && --maxwait)
+				;
+			ne2k_cbus_readmem(dev, ioaddr, i, buf, 32);
+			if (memcmp(pat, buf, 32)) {
+				if (ei_debug > 2)
+					printk(" failed.");
+				break;
+			}
+		}
+		if (i != 16384) {
+			if (ei_debug > 2)
+				printk("] ");
+			printk("memory failure at %x\n", i);
+			return -ENODEV;
+		}
+		if (ei_debug > 2)
+			printk(" good...");
+		if (!dev->irq) {
+			if (ei_debug > 2)
+				printk("] ");
+			printk("IRQ must be specified for C-NET(98)E/L. probe failed.\n");
+			return -ENODEV;
+		}
+		outb((dev->irq > 5) ? (dev->irq & 4):(dev->irq >> 1), ioaddr + (0x2 | 0x400));
+		outb(0x7e, ioaddr + (0x4 | 0x400));
+		ne2k_cbus_readmem(dev, ioaddr, 16384, SA_prom, 32);
+		outb(0xff, ioaddr + EN0_ISR);
+		if (ei_debug > 2)
+			printk("done]");
+	} else
+#endif /* CONFIG_NE2K_CBUS_CNET98EL */
+	/* Read the 16 bytes of station address PROM.
+	   We must first initialize registers, similar to NS8390_init(eifdev, 0).
+	   We can't reliably read the SAPROM address without this.
+	   (I learned the hard way!). */
+	{
+		struct {unsigned char value; unsigned short offset;} program_seq[] = 
+		{
+			{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
+			/* NEC PC-9800: some board can only handle word-wide access? */
+			{0x48 | ENDCFG_WTS,	EN0_DCFG},	/* Set word-wide (0x48) access. */
+			{16384 / 256, EN0_STARTPG},
+			{32768 / 256, EN0_STOPPG},
+			{0x00,	EN0_RCNTLO},	/* Clear the count regs. */
+			{0x00,	EN0_RCNTHI},
+			{0x00,	EN0_IMR},	/* Mask completion irq. */
+			{0xFF,	EN0_ISR},
+			{E8390_RXOFF, EN0_RXCR},	/* 0x20  Set to monitor */
+			{E8390_TXOFF, EN0_TXCR},	/* 0x02  and loopback mode. */
+			{32,	EN0_RCNTLO},
+			{0x00,	EN0_RCNTHI},
+			{0x00,	EN0_RSARLO},	/* DMA starting at 0x0000. */
+			{0x00,	EN0_RSARHI},
+			{E8390_RREAD+E8390_START, E8390_CMD},
+		};
+
+		for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
+			outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
+		insw(ioaddr + NE_DATAPORT, SA_prom, 32 >> 1);
+
+	}
+
+	if (wordlength == 2)
+	{
+		for (i = 0; i < 16; i++)
+			SA_prom[i] = SA_prom[i+i];
+		start_page = NESM_START_PG;
+		stop_page = NESM_STOP_PG;
+#ifdef CONFIG_NE2K_CBUS_CNET98EL
+		if (hw->hwtype == NE2K_CBUS_HARDWARE_TYPE_CNET98EL) {
+			start_page = CNET98EL_START_PG;
+			stop_page = CNET98EL_STOP_PG;
+		}
+#endif
+	} else {
+		start_page = NE1SM_START_PG;
+		stop_page = NE1SM_STOP_PG;
+	}
+
+	neX000 = (SA_prom[14] == 0x57  &&  SA_prom[15] == 0x57);
+	if (neX000) {
+		name = "C-Bus-NE2K-compat";
+	}
+	else
+	{
+#ifdef SUPPORT_NE_BAD_CLONES
+		/* Ack!  Well, there might be a *bad* NE*000 clone there.
+		   Check for total bogus addresses. */
+		for (i = 0; bad_clone_list[i].name8; i++)
+		{
+			if (SA_prom[0] == bad_clone_list[i].SAprefix[0] &&
+				SA_prom[1] == bad_clone_list[i].SAprefix[1] &&
+				SA_prom[2] == bad_clone_list[i].SAprefix[2])
+			{
+				if (wordlength == 2)
+				{
+					name = bad_clone_list[i].name16;
+				} else {
+					name = bad_clone_list[i].name8;
+				}
+				break;
+			}
+		}
+		if (bad_clone_list[i].name8 == NULL)
+		{
+			printk(" not found (invalid signature %2.2x %2.2x).\n",
+				SA_prom[14], SA_prom[15]);
+			ret = -ENXIO;
+			goto err_out;
+		}
+#else
+		printk(" not found.\n");
+		ret = -ENXIO;
+		goto err_out;
+#endif
+	}
+
+	if (dev->irq < 2)
+	{
+		unsigned long cookie = probe_irq_on();
+		outb_p(0x50, ioaddr + EN0_IMR);	/* Enable one interrupt. */
+		outb_p(0x00, ioaddr + EN0_RCNTLO);
+		outb_p(0x00, ioaddr + EN0_RCNTHI);
+		outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */
+		mdelay(10);		/* wait 10ms for interrupt to propagate */
+		outb_p(0x00, ioaddr + EN0_IMR); 		/* Mask it again. */
+		dev->irq = probe_irq_off(cookie);
+		if (ei_debug > 2)
+			printk(" autoirq is %d\n", dev->irq);
+	} else if (dev->irq == 7)
+		/* Fixup for users that don't know that IRQ 7 is really IRQ 11,
+		   or don't know which one to set. */
+		dev->irq = 11;
+
+	if (! dev->irq) {
+		printk(" failed to detect IRQ line.\n");
+		ret = -EAGAIN;
+		goto err_out;
+	}
+
+	/* Allocate dev->priv and fill in 8390 specific dev fields. */
+	if (ethdev_init(dev))
+	{
+        	printk (" unable to get memory for dev->priv.\n");
+        	ret = -ENOMEM;
+		goto err_out;
+	}
+
+	/* Snarf the interrupt now.  There's no point in waiting since we cannot
+	   share and the board will usually be enabled. */
+	ret = request_irq(dev->irq, ei_interrupt, 0, name, dev);
+	if (ret) {
+		printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret);
+		goto err_out_kfree;
+	}
+
+	dev->base_addr = ioaddr;
+
+	for(i = 0; i < ETHER_ADDR_LEN; i++) {
+		printk(" %2.2x", SA_prom[i]);
+		dev->dev_addr[i] = SA_prom[i];
+	}
+
+	printk("\n%s: %s found at %#x, hardware type %d(%s), using IRQ %d.\n",
+		   dev->name, name, ioaddr, hw->hwtype, hw->hwident, dev->irq);
+
+	ei_status.name = name;
+	ei_status.tx_start_page = start_page;
+	ei_status.stop_page = stop_page;
+	ei_status.word16 = (wordlength == 2);
+
+	ei_status.rx_start_page = start_page + TX_PAGES;
+#ifdef PACKETBUF_MEMSIZE
+	 /* Allow the packet buffer size to be overridden by know-it-alls. */
+	ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
+#endif
+
+	ei_status.reset_8390 = &ne_reset_8390;
+	ei_status.block_input = &ne_block_input;
+	ei_status.block_output = &ne_block_output;
+	ei_status.get_8390_hdr = &ne_get_8390_hdr;
+	ei_status.priv = 0;
+	dev->open = &ne_open;
+	dev->stop = &ne_close;
+	NS8390_init(dev, 0);
+	return 0;
+
+err_out_kfree:
+	ne2k_cbus_destroy(dev);
+err_out:
+	while (rlist > hw->regionlist) {
+		rlist --;
+		release_region(ioaddr + rlist->start, rlist->range);
+	}
+	return ret;
+}
+
+static int ne_open(struct net_device *dev)
+{
+	ei_open(dev);
+	return 0;
+}
+
+static int ne_close(struct net_device *dev)
+{
+	if (ei_debug > 1)
+		printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
+	ei_close(dev);
+	return 0;
+}
+
+/* Hard reset the card.  This used to pause for the same period that a
+   8390 reset command required, but that shouldn't be necessary. */
+
+static void ne_reset_8390(struct net_device *dev)
+{
+	unsigned long reset_start_time = jiffies;
+	struct ei_device *ei_local = (struct ei_device *)(dev->priv);
+
+	if (ei_debug > 1)
+		printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies);
+
+	/* derived from CNET98EL-patch for bad clones... */
+	outb_p(E8390_NODMA | E8390_STOP, NE_BASE + E8390_CMD);  /* 0x20 | 0x1 */
+
+	/* DON'T change these to inb_p/outb_p or reset will fail on clones. */
+	outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
+
+	ei_status.txing = 0;
+	ei_status.dmaing = 0;
+
+	/* This check _should_not_ be necessary, omit eventually. */
+	while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0)
+		if (jiffies - reset_start_time > 2*HZ/100) {
+			printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name);
+			break;
+		}
+	outb_p(ENISR_RESET, NE_BASE + EN0_ISR);	/* Ack intr. */
+}
+
+/* Grab the 8390 specific header. Similar to the block_input routine, but
+   we don't need to be concerned with ring wrap as the header will be at
+   the start of a page, so we optimize accordingly. */
+
+static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
+{
+	int nic_base = dev->base_addr;
+	struct ei_device *ei_local = (struct ei_device *)(dev->priv);
+
+	/* This *shouldn't* happen. If it does, it's the last thing you'll see */
+
+	if (ei_status.dmaing)
+	{
+		printk(KERN_EMERG "%s: DMAing conflict in ne_get_8390_hdr "
+			"[DMAstat:%d][irqlock:%d].\n",
+			dev->name, ei_status.dmaing, ei_status.irqlock);
+		return;
+	}
+
+	ei_status.dmaing |= 0x01;
+	outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+	outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
+	outb_p(0, nic_base + EN0_RCNTHI);
+	outb_p(0, nic_base + EN0_RSARLO);		/* On page boundary */
+	outb_p(ring_page, nic_base + EN0_RSARHI);
+	outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+	if (ei_status.word16)
+		insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
+	else
+		insb(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
+
+	outb_p(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
+	ei_status.dmaing &= ~0x01;
+
+	le16_to_cpus(&hdr->count);
+}
+
+/* Block input and output, similar to the Crynwr packet driver.  If you
+   are porting to a new ethercard, look at the packet driver source for hints.
+   The NEx000 doesn't share the on-board packet memory -- you have to put
+   the packet out through the "remote DMA" dataport using outb. */
+
+static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
+{
+#ifdef NE_SANITY_CHECK
+	int xfer_count = count;
+#endif
+	int nic_base = dev->base_addr;
+	char *buf = skb->data;
+	struct ei_device *ei_local = (struct ei_device *)(dev->priv);
+
+	/* This *shouldn't* happen. If it does, it's the last thing you'll see */
+	if (ei_status.dmaing)
+	{
+		printk(KERN_EMERG "%s: DMAing conflict in ne_block_input "
+			"[DMAstat:%d][irqlock:%d].\n",
+			dev->name, ei_status.dmaing, ei_status.irqlock);
+		return;
+	}
+	ei_status.dmaing |= 0x01;
+
+	/* round up count to a word (derived from ICM-patch) */
+	count = (count + 1) & ~1;
+
+	outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+	outb_p(count & 0xff, nic_base + EN0_RCNTLO);
+	outb_p(count >> 8, nic_base + EN0_RCNTHI);
+	outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
+	outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
+	outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+	if (ei_status.word16)
+	{
+		insw(NE_BASE + NE_DATAPORT,buf,count>>1);
+		if (count & 0x01)
+		{
+			buf[count-1] = inb(NE_BASE + NE_DATAPORT);
+#ifdef NE_SANITY_CHECK
+			xfer_count++;
+#endif
+		}
+	} else {
+		insb(NE_BASE + NE_DATAPORT, buf, count);
+	}
+
+#ifdef NE_SANITY_CHECK
+	/* This was for the ALPHA version only, but enough people have
+	   been encountering problems so it is still here.  If you see
+	   this message you either 1) have a slightly incompatible clone
+	   or 2) have noise/speed problems with your bus. */
+
+	if (ei_debug > 1)
+	{
+		/* DMA termination address check... */
+		int addr, tries = 20;
+		do {
+			/* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
+			   -- it's broken for Rx on some cards! */
+			int high = inb_p(nic_base + EN0_RSARHI);
+			int low = inb_p(nic_base + EN0_RSARLO);
+			addr = (high << 8) + low;
+			if (((ring_offset + xfer_count) & 0xff) == low)
+				break;
+		} while (--tries > 0);
+	 	if (tries <= 0)
+			printk(KERN_WARNING "%s: RX transfer address mismatch,"
+				"%#4.4x (expected) vs. %#4.4x (actual).\n",
+				dev->name, ring_offset + xfer_count, addr);
+	}
+#endif
+	outb_p(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
+	ei_status.dmaing &= ~0x01;
+}
+
+static void ne_block_output(struct net_device *dev, int count,
+		const unsigned char *buf, const int start_page)
+{
+	int nic_base = NE_BASE;
+	unsigned long dma_start;
+#ifdef NE_SANITY_CHECK
+	int retries = 0;
+#endif
+	struct ei_device *ei_local = (struct ei_device *)(dev->priv);
+
+	/* Round the count up for word writes.  Do we need to do this?
+	   What effect will an odd byte count have on the 8390?
+	   I should check someday. */
+
+	if (ei_status.word16 && (count & 0x01))
+		count++;
+
+	/* This *shouldn't* happen. If it does, it's the last thing you'll see */
+	if (ei_status.dmaing)
+	{
+		printk(KERN_EMERG "%s: DMAing conflict in ne_block_output."
+			"[DMAstat:%d][irqlock:%d]\n",
+			dev->name, ei_status.dmaing, ei_status.irqlock);
+		return;
+	}
+	ei_status.dmaing |= 0x01;
+	/* We should already be in page 0, but to be safe... */
+	outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
+
+#ifdef NE_SANITY_CHECK
+retry:
+#endif
+
+#ifdef NE8390_RW_BUGFIX
+	/* Handle the read-before-write bug the same way as the
+	   Crynwr packet driver -- the NatSemi method doesn't work.
+	   Actually this doesn't always work either, but if you have
+	   problems with your NEx000 this is better than nothing! */
+
+	outb_p(0x42, nic_base + EN0_RCNTLO);
+	outb_p(0x00,   nic_base + EN0_RCNTHI);
+	outb_p(0x42, nic_base + EN0_RSARLO);
+	outb_p(0x00, nic_base + EN0_RSARHI);
+	outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+	/* Make certain that the dummy read has occurred. */
+	udelay(6);
+#endif
+
+	outb_p(ENISR_RDC, nic_base + EN0_ISR);
+
+	/* Now the normal output. */
+	outb_p(count & 0xff, nic_base + EN0_RCNTLO);
+	outb_p(count >> 8,   nic_base + EN0_RCNTHI);
+	outb_p(0x00, nic_base + EN0_RSARLO);
+	outb_p(start_page, nic_base + EN0_RSARHI);
+
+	outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
+	if (ei_status.word16) {
+		outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
+	} else {
+		outsb(NE_BASE + NE_DATAPORT, buf, count);
+	}
+
+	dma_start = jiffies;
+
+#ifdef NE_SANITY_CHECK
+	/* This was for the ALPHA version only, but enough people have
+	   been encountering problems so it is still here. */
+
+	if (ei_debug > 1)
+	{
+		/* DMA termination address check... */
+		int addr, tries = 20;
+		do {
+			int high = inb_p(nic_base + EN0_RSARHI);
+			int low = inb_p(nic_base + EN0_RSARLO);
+			addr = (high << 8) + low;
+			if ((start_page << 8) + count == addr)
+				break;
+		} while (--tries > 0);
+
+		if (tries <= 0)
+		{
+			printk(KERN_WARNING "%s: Tx packet transfer address mismatch,"
+				"%#4.4x (expected) vs. %#4.4x (actual).\n",
+				dev->name, (start_page << 8) + count, addr);
+			if (retries++ == 0)
+				goto retry;
+		}
+	}
+#endif
+
+	while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
+		if (jiffies - dma_start > 2*HZ/100) {		/* 20ms */
+			printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);
+			ne_reset_8390(dev);
+			NS8390_init(dev,1);
+			break;
+		}
+
+	outb_p(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
+	ei_status.dmaing &= ~0x01;
+	return;
+}
+
+
+#ifdef MODULE
+#define MAX_NE_CARDS	4	/* Max number of NE cards per module */
+static struct net_device dev_ne[MAX_NE_CARDS];
+static int io[MAX_NE_CARDS];
+static int irq[MAX_NE_CARDS];
+static int bad[MAX_NE_CARDS];	/* 0xbad = bad sig or no reset ack */
+static int hwtype[MAX_NE_CARDS] = { 0, }; /* board type */
+
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM(hwtype, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM_DESC(io, "I/O base address(es),required");
+MODULE_PARM_DESC(irq, "IRQ number(s)");
+MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures");
+MODULE_PARM_DESC(hwtype, "Board type of PC-9800 C-Bus NIC");
+MODULE_DESCRIPTION("NE1000/NE2000 PC-9800 C-bus Ethernet driver");
+MODULE_LICENSE("GPL");
+
+/* This is set up so that no ISA autoprobe takes place. We can't guarantee
+that the ne2k probe is the last 8390 based probe to take place (as it
+is at boot) and so the probe will get confused by any other 8390 cards.
+ISA device autoprobes on a running machine are not recommended anyway. */
+
+int init_module(void)
+{
+	int this_dev, found = 0;
+
+	for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+		struct net_device *dev = &dev_ne[this_dev];
+		dev->irq = irq[this_dev];
+		dev->mem_end = bad[this_dev];
+		dev->base_addr = io[this_dev];
+		dev->mem_start = hwtype[this_dev];
+		dev->init = ne_probe;
+		if (register_netdev(dev) == 0) {
+			found++;
+			continue;
+		}
+		if (found != 0) { 	/* Got at least one. */
+			return 0;
+		}
+		if (io[this_dev] != 0)
+			printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]);
+		else
+			printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for C-Bus cards.\n");
+		return -ENXIO;
+	}
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	int this_dev;
+
+	for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+		struct net_device *dev = &dev_ne[this_dev];
+		if (dev->priv != NULL) {
+			const struct ne2k_cbus_region *rlist;
+			const struct ne2k_cbus_hwinfo *hw = ne2k_cbus_get_hwinfo((int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK));
+
+			free_irq(dev->irq, dev);
+			for (rlist = hw->regionlist; rlist->range; rlist++) {
+				release_region(dev->base_addr + rlist->start,
+						rlist->range);
+			}
+			unregister_netdev(dev);
+			ne2k_cbus_destroy(dev);
+		}
+	}
+}
+#endif /* MODULE */
+
+
+/*
+ * Local variables:
+ *  compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c ne.c"
+ *  version-control: t
+ *  kept-new-versions: 5
+ * End:
+ */
diff -Nru a/drivers/net/ne2k_cbus.h b/drivers/net/ne2k_cbus.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/ne2k_cbus.h	Sat Dec 14 17:56:15 2002
@@ -0,0 +1,481 @@
+/* ne2k_cbus.h: 
+   vender-specific information definition for NEC PC-9800
+   C-bus Ethernet Cards
+   Used in ne.c 
+
+   (C)1998,1999 KITAGWA Takurou & Linux/98 project
+*/
+
+#include <linux/config.h>
+
+#undef NE_RESET
+#define NE_RESET EI_SHIFT(0x11) /* Issue a read to reset, a write to clear. */
+
+#ifdef CONFIG_NE2K_CBUS_CNET98EL
+#ifndef CONFIG_NE2K_CBUS_CNET98EL_IO_BASE
+#warning CONFIG_NE2K_CBUS_CNET98EL_IO_BASE is not defined(config error?)
+#warning use 0xaaed as default
+#define CONFIG_NE2K_CBUS_CNET98EL_IO_BASE 0xaaed /* or 0x55ed */
+#endif
+#define CNET98EL_START_PG 0x00
+#define CNET98EL_STOP_PG 0x40
+#endif
+
+/* Hardware type definition (derived from *BSD) */
+#define NE2K_CBUS_HARDWARE_TYPE_MASK 0xff
+
+/* 0: reserved for auto-detect */
+/* 1: (not tested)
+   Allied Telesis CentreCom LA-98-T */
+#define NE2K_CBUS_HARDWARE_TYPE_ATLA98 1
+/* 2: (not tested)
+   ELECOM Laneed
+   LD-BDN[123]A
+   PLANET SMART COM 98 EN-2298-C
+   MACNICA ME98 */
+#define NE2K_CBUS_HARDWARE_TYPE_BDN 2
+/* 3:
+   Melco EGY-98
+   Contec C-NET(98)E*A/L*A,C-NET(98)P */
+#define NE2K_CBUS_HARDWARE_TYPE_EGY98 3
+/* 4:
+   Melco LGY-98,IND-SP,IND-SS
+   MACNICA NE2098 */
+#define NE2K_CBUS_HARDWARE_TYPE_LGY98 4
+/* 5:
+   ICM DT-ET-25,DT-ET-T5,IF-2766ET,IF-2771ET
+   PLANET SMART COM 98 EN-2298-T,EN-2298P-T
+   D-Link DE-298PT,DE-298PCAT
+   ELECOM Laneed LD-98P */
+#define NE2K_CBUS_HARDWARE_TYPE_ICM 5
+/* 6: (reserved for SIC-98, which is not supported in this driver.) */
+/* 7: (unused in *BSD?)
+   <Original NE2000 compatible>
+   <for PCI/PCMCIA cards>
+*/
+#define NE2K_CBUS_HARDWARE_TYPE_NE2K 7
+/* 8:
+   NEC PC-9801-108 */
+#define NE2K_CBUS_HARDWARE_TYPE_NEC108 8
+/* 9:
+   I-O DATA LA-98,LA/T-98 */
+#define NE2K_CBUS_HARDWARE_TYPE_IOLA98 9
+/* 10: (reserved for C-NET(98), which is not supported in this driver.) */
+/* 11:
+   Contec C-NET(98)E,L */
+#define NE2K_CBUS_HARDWARE_TYPE_CNET98EL 11
+
+#define NE2K_CBUS_HARDWARE_TYPE_MAX 11
+
+/* HARDWARE TYPE ID 12-31: reserved */
+
+struct ne2k_cbus_offsetinfo {
+	unsigned short skip;
+	unsigned short offset8; /* +0x8 - +0xf */
+	unsigned short offset10; /* +0x10 */
+	unsigned short offset1f; /* +0x1f */
+};
+
+struct ne2k_cbus_region {
+	unsigned short start;
+	short range;
+};
+
+struct ne2k_cbus_hwinfo {
+	const unsigned short hwtype;
+	const unsigned char *hwident;
+#ifndef MODULE
+	const unsigned short *portlist;
+#endif
+	const struct ne2k_cbus_offsetinfo *offsetinfo;
+	const struct ne2k_cbus_region *regionlist;
+};
+
+#ifdef CONFIG_NE2K_CBUS_ATLA98
+#ifndef MODULE
+static unsigned short atla98_portlist[] __initdata = {
+	0xd0,
+	0
+};
+#endif
+#define atla98_offsetinfo ne2k_offsetinfo
+#define atla98_regionlist ne2k_regionlist
+#endif /* CONFIG_NE2K_CBUS_ATLA98 */
+
+#ifdef CONFIG_NE2K_CBUS_BDN
+#ifndef MODULE
+static unsigned short bdn_portlist[] __initdata = {
+	0xd0,
+	0
+};
+#endif
+static struct ne2k_cbus_offsetinfo bdn_offsetinfo __initdata = {
+#if 0
+	/* comes from FreeBSD(98) ed98.h */
+	0x1000, 0x8000, 0x100, 0xc200 /* ??? */
+#else
+	/* comes from NetBSD/pc98 if_ne_isa.c */
+	0x1000, 0x8000, 0x100, 0x7f00 /* ??? */
+#endif
+};
+static struct ne2k_cbus_region bdn_regionlist[] __initdata = {
+	{0x0, 1}, {0x1000, 1}, {0x2000, 1}, {0x3000,1},
+	{0x4000, 1}, {0x5000, 1}, {0x6000, 1}, {0x7000, 1},
+	{0x8000, 1}, {0x9000, 1}, {0xa000, 1}, {0xb000, 1},
+	{0xc000, 1}, {0xd000, 1}, {0xe000, 1}, {0xf000, 1},
+	{0x100, 1}, {0x7f00, 1},
+	{0x0, 0}
+};
+#endif /* CONFIG_NE2K_CBUS_BDN */
+
+#ifdef CONFIG_NE2K_CBUS_EGY98
+#ifndef MODULE
+static unsigned short egy98_portlist[] __initdata = {
+	0xd0,
+	0
+};
+#endif
+static struct ne2k_cbus_offsetinfo egy98_offsetinfo __initdata = {
+	0x02, 0x100, 0x200, 0x300
+};
+static struct ne2k_cbus_region egy98_regionlist[] __initdata = {
+	{0x0, 1}, {0x2, 1}, {0x4, 1}, {0x6, 1},
+	{0x8, 1}, {0xa, 1}, {0xc, 1}, {0xe, 1},
+	{0x100, 1}, {0x102, 1}, {0x104, 1}, {0x106, 1},
+	{0x108, 1}, {0x10a, 1}, {0x10c, 1}, {0x10e, 1},
+	{0x200, 1}, {0x300, 1},
+	{0x0, 0}
+};
+#endif /* CONFIG_NE2K_CBUS_EGY98 */
+
+#ifdef CONFIG_NE2K_CBUS_LGY98
+#ifndef MODULE
+static unsigned short lgy98_portlist[] __initdata = {
+	0xd0, 0x10d0, 0x20d0, 0x30d0, 0x40d0, 0x50d0, 0x60d0, 0x70d0,
+	0
+};
+#endif
+static struct ne2k_cbus_offsetinfo lgy98_offsetinfo __initdata = {
+	0x01, 0x08, 0x200, 0x300
+};
+static struct ne2k_cbus_region lgy98_regionlist[] __initdata = {
+	{0x0, 16}, {0x200, 1}, {0x300, 1},
+	{0x0, 0}
+};
+#endif /* CONFIG_NE2K_CBUS_LGY98 */
+
+#ifdef CONFIG_NE2K_CBUS_ICM
+#ifndef MODULE
+static unsigned short icm_portlist[] __initdata = {
+	/* ICM */
+	0x56d0,
+	/* LD-98PT */
+	0x46d0, 0x66d0, 0x76d0, 0x86d0, 0x96d0, 0xa6d0, 0xb6d0, 0xc6d0,
+	0
+};
+#endif
+static struct ne2k_cbus_offsetinfo icm_offsetinfo __initdata = {
+	0x01, 0x08, 0x100, 0x10f
+};
+static struct ne2k_cbus_region icm_regionlist[] __initdata = {
+	{0x0, 16}, {0x100, 16},
+	{0x0, 0}
+};
+#endif /* CONFIG_NE2K_CBUS_ICM */
+
+#if defined(CONFIG_NE2K_CBUS_NE2K) && !defined(MODULE)
+static unsigned short ne2k_portlist[] __initdata = {
+	0xd0, 0x300, 0x280, 0x320, 0x340, 0x360, 0x380,
+	0
+};
+#endif
+#if defined(CONFIG_NE2K_CBUS_NE2K) || defined(CONFIG_NE2K_CBUS_ATLA98)
+static struct ne2k_cbus_offsetinfo ne2k_offsetinfo __initdata = {
+	0x01, 0x08, 0x10, 0x1f
+};
+static struct ne2k_cbus_region ne2k_regionlist[] __initdata = {
+	{0x0, 32},
+	{0x0, 0}
+};
+#endif
+
+#ifdef CONFIG_NE2K_CBUS_NEC108
+#ifndef MODULE
+static unsigned short nec108_portlist[] __initdata = {
+	0x770, 0x2770, 0x4770, 0x6770,
+	0
+};
+#endif
+static struct ne2k_cbus_offsetinfo nec108_offsetinfo __initdata = {
+	0x02, 0x1000, 0x888, 0x88a
+};
+static struct ne2k_cbus_region nec108_regionlist[] __initdata = {
+	{0x0, 1}, {0x2, 1}, {0x4, 1}, {0x6, 1},
+	{0x8, 1}, {0xa, 1}, {0xc, 1}, {0xe, 1},
+	{0x1000, 1}, {0x1002, 1}, {0x1004, 1}, {0x1006, 1},
+	{0x1008, 1}, {0x100a, 1}, {0x100c, 1}, {0x100e, 1},
+	{0x888, 1}, {0x88a, 1}, {0x88c, 1}, {0x88e, 1},
+	{0x0, 0}
+};
+#endif
+
+#ifdef CONFIG_NE2K_CBUS_IOLA98
+#ifndef MODULE
+static unsigned short iola98_portlist[] __initdata = {
+	0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
+	0
+};
+#endif
+static struct ne2k_cbus_offsetinfo iola98_offsetinfo __initdata = {
+	0x1000, 0x8000, 0x100, 0xf100
+};
+static struct ne2k_cbus_region iola98_regionlist[] __initdata = {
+	{0x0, 1}, {0x1000, 1}, {0x2000, 1}, {0x3000, 1},
+	{0x4000, 1}, {0x5000, 1}, {0x6000, 1}, {0x7000, 1},
+	{0x8000, 1}, {0x9000, 1}, {0xa000, 1}, {0xb000, 1},
+	{0xc000, 1}, {0xd000, 1}, {0xe000, 1}, {0xf000, 1},
+	{0x100, 1}, {0xf100, 1},
+	{0x0,0}
+};
+#endif /* CONFIG_NE2K_CBUS_IOLA98 */
+
+#ifdef CONFIG_NE2K_CBUS_CNET98EL
+#ifndef MODULE
+static unsigned short cnet98el_portlist[] __initdata = {
+	0x3d0, 0x13d0, 0x23d0, 0x33d0, 0x43d0, 0x53d0, 0x60d0, 0x70d0,
+	0
+};
+#endif
+static struct ne2k_cbus_offsetinfo cnet98el_offsetinfo __initdata = {
+	0x01, 0x08, 0x40e, 0x400
+};
+static struct ne2k_cbus_region cnet98el_regionlist[] __initdata = {
+	{0x0, 16}, {0x400, 16},
+	{0x0, 0}
+};
+#endif
+
+
+/* port information table (for ne.c initialize/probe process) */
+
+static struct ne2k_cbus_hwinfo ne2k_cbus_hwinfo_list[] __initdata = {
+#ifdef CONFIG_NE2K_CBUS_ATLA98
+/* NOT TESTED */
+	{
+		NE2K_CBUS_HARDWARE_TYPE_ATLA98,
+		"LA-98-T",
+#ifndef MODULE
+		atla98_portlist,
+#endif
+		&atla98_offsetinfo, atla98_regionlist
+	},
+#endif
+#ifdef CONFIG_NE2K_CBUS_BDN
+/* NOT TESTED */
+	{
+		NE2K_CBUS_HARDWARE_TYPE_BDN,
+		"LD-BDN[123]A",
+#ifndef MODULE
+		bdn_portlist,
+#endif
+		&bdn_offsetinfo, bdn_regionlist
+	},
+#endif
+#ifdef CONFIG_NE2K_CBUS_ICM
+	{
+		NE2K_CBUS_HARDWARE_TYPE_ICM,
+		"IF-27xxET",
+#ifndef MODULE
+		icm_portlist,
+#endif
+		&icm_offsetinfo, icm_regionlist
+	},
+#endif
+#ifdef CONFIG_NE2K_CBUS_NE2K
+	{
+		NE2K_CBUS_HARDWARE_TYPE_NE2K,
+		"NE2000 compat.",
+#ifndef MODULE
+		ne2k_portlist,
+#endif
+		&ne2k_offsetinfo, ne2k_regionlist
+	},
+#endif
+#ifdef CONFIG_NE2K_CBUS_NEC108
+	{
+		NE2K_CBUS_HARDWARE_TYPE_NEC108,
+		"PC-9801-108",
+#ifndef MODULE
+		nec108_portlist,
+#endif
+		&nec108_offsetinfo, nec108_regionlist
+	},
+#endif
+#ifdef CONFIG_NE2K_CBUS_IOLA98
+	{
+		NE2K_CBUS_HARDWARE_TYPE_IOLA98,
+		"LA-98",
+#ifndef MODULE
+		iola98_portlist,
+#endif
+		&iola98_offsetinfo, iola98_regionlist
+	},
+#endif
+#ifdef CONFIG_NE2K_CBUS_CNET98EL
+	{
+		NE2K_CBUS_HARDWARE_TYPE_CNET98EL,
+		"C-NET(98)E/L",
+#ifndef MODULE
+		cnet98el_portlist,
+#endif
+		&cnet98el_offsetinfo, cnet98el_regionlist
+	},
+#endif
+/* NOTE: LGY98 must be probed before EGY98, or system stalled!? */
+#ifdef CONFIG_NE2K_CBUS_LGY98
+	{
+		NE2K_CBUS_HARDWARE_TYPE_LGY98,
+		"LGY-98",
+#ifndef MODULE
+		lgy98_portlist,
+#endif
+		&lgy98_offsetinfo, lgy98_regionlist
+	},
+#endif
+#ifdef CONFIG_NE2K_CBUS_EGY98
+	{
+		NE2K_CBUS_HARDWARE_TYPE_EGY98,
+		"EGY-98",
+#ifndef MODULE
+		egy98_portlist,
+#endif
+		&egy98_offsetinfo, egy98_regionlist
+	},
+#endif
+	{
+		0,
+		"unsupported hardware",
+#ifndef MODULE
+		NULL,
+#endif
+		NULL, NULL
+	}
+};
+
+static int __init ne2k_cbus_init(struct net_device *dev)
+{
+	struct ei_device *ei_local;
+	if (dev->priv == NULL) {
+		ei_local = kmalloc(sizeof(struct ei_device), GFP_KERNEL);
+		if (ei_local == NULL)
+			return -ENOMEM;
+		memset(ei_local, 0, sizeof(struct ei_device));
+		ei_local->reg_offset = kmalloc(sizeof(typeof(*ei_local->reg_offset))*18, GFP_KERNEL);
+		if (ei_local->reg_offset == NULL) {
+			kfree(ei_local);
+			return -ENOMEM;
+		}
+		spin_lock_init(&ei_local->page_lock);
+		dev->priv = ei_local;
+	}
+	return 0;
+}
+
+static void ne2k_cbus_destroy(struct net_device *dev)
+{
+	struct ei_device *ei_local = (struct ei_device *)(dev->priv);
+	if (ei_local != NULL) {
+		if (ei_local->reg_offset)
+			kfree(ei_local->reg_offset);
+		kfree(dev->priv);
+		dev->priv = NULL;
+	}
+}
+
+static const struct ne2k_cbus_hwinfo * __init ne2k_cbus_get_hwinfo(int hwtype)
+{
+	const struct ne2k_cbus_hwinfo *hw;
+
+	for (hw = &ne2k_cbus_hwinfo_list[0]; hw->hwtype; hw++) {
+		if (hw->hwtype == hwtype) break;
+	}
+	return hw;
+}
+
+static void __init ne2k_cbus_set_hwtype(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr)
+{
+	struct ei_device *ei_local = (struct ei_device *)(dev->priv);
+	int i;
+	int hwtype_old = dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK;
+
+	if (!ei_local)
+		panic("Gieee! ei_local == NULL!! (from %p)",
+		       __builtin_return_address(0));
+
+	dev->mem_start &= ~NE2K_CBUS_HARDWARE_TYPE_MASK;
+	dev->mem_start |= hw->hwtype & NE2K_CBUS_HARDWARE_TYPE_MASK;
+
+	if (ei_debug > 2) {
+		printk(KERN_DEBUG "hwtype changed: %d -> %d\n",hwtype_old,(int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK));
+	}
+
+	if (hw->offsetinfo) {
+		for (i = 0; i < 8; i++) {
+			ei_local->reg_offset[i] = hw->offsetinfo->skip * i;
+		}
+		for (i = 8; i < 16; i++) {
+			ei_local->reg_offset[i] =
+				hw->offsetinfo->skip*(i-8) + hw->offsetinfo->offset8;
+		}
+#ifdef CONFIG_NE2K_CBUS_NEC108
+		if (hw->hwtype == NE2K_CBUS_HARDWARE_TYPE_NEC108) {
+			int adj = (ioaddr & 0xf000) /2;
+			ei_local->reg_offset[16] = 
+				(hw->offsetinfo->offset10 | adj) - ioaddr;
+			ei_local->reg_offset[17] = 
+				(hw->offsetinfo->offset1f | adj) - ioaddr;
+		} else {
+#endif /* CONFIG_NE2K_CBUS_NEC108 */
+			ei_local->reg_offset[16] = hw->offsetinfo->offset10;
+			ei_local->reg_offset[17] = hw->offsetinfo->offset1f;
+#ifdef CONFIG_NE2K_CBUS_NEC108
+		}
+#endif
+	} else {
+		/* make dummmy offset list */
+		for (i = 0; i < 16; i++) {
+			ei_local->reg_offset[i] = i;
+		}
+		ei_local->reg_offset[16] = 0x10;
+		ei_local->reg_offset[17] = 0x1f;
+	}
+}
+
+#if defined(CONFIG_NE2K_CBUS_ICM) || defined(CONFIG_NE2K_CBUS_CNET98EL)
+static void __init ne2k_cbus_readmem(struct net_device *dev, int ioaddr, unsigned short memaddr, char *buf, unsigned short len)
+{
+	struct ei_device *ei_local = (struct ei_device *)(dev->priv);
+	outb_p(E8390_NODMA | E8390_START, ioaddr+E8390_CMD);
+	outb_p(len & 0xff, ioaddr+EN0_RCNTLO);
+	outb_p(len >> 8, ioaddr+EN0_RCNTHI);
+	outb_p(memaddr & 0xff, ioaddr+EN0_RSARLO);
+	outb_p(memaddr >> 8, ioaddr+EN0_RSARHI);
+	outb_p(E8390_RREAD | E8390_START, ioaddr+E8390_CMD);
+	insw(ioaddr+NE_DATAPORT, buf, len >> 1);
+}
+static void __init ne2k_cbus_writemem(struct net_device *dev, int ioaddr, unsigned short memaddr, const char *buf, unsigned short len)
+{
+	struct ei_device *ei_local = (struct ei_device *)(dev->priv);
+	outb_p(E8390_NODMA | E8390_START, ioaddr+E8390_CMD);
+	outb_p(ENISR_RDC, ioaddr+EN0_ISR);
+	outb_p(len & 0xff, ioaddr+EN0_RCNTLO);
+	outb_p(len >> 8, ioaddr+EN0_RCNTHI);
+	outb_p(memaddr & 0xff, ioaddr+EN0_RSARLO);
+	outb_p(memaddr >> 8, ioaddr+EN0_RSARHI);
+	outb_p(E8390_RWRITE | E8390_START, ioaddr+E8390_CMD);
+	outsw(ioaddr+NE_DATAPORT, buf, len >> 1);
+}
+#endif
+
+static int ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr);
+/* End of ne2k_cbus.h */
diff -Nru a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
--- a/drivers/net/pcmcia/pcnet_cs.c	Mon Nov 25 15:13:23 2002
+++ b/drivers/net/pcmcia/pcnet_cs.c	Wed Mar 19 02:23:25 2003
@@ -1617,6 +1617,15 @@
 
 /*====================================================================*/
 
+static struct pcmcia_driver pcnet_driver = {
+	.drv		= {
+		.name	= "pcnet_cs",
+	},
+	.attach		= pcnet_attach,
+	.detach		= pcnet_detach,
+	.owner		= THIS_MODULE,
+};
+
 static int __init init_pcnet_cs(void)
 {
     servinfo_t serv;
@@ -1627,14 +1636,14 @@
 	       "does not match!\n");
 	return -EINVAL;
     }
-    register_pccard_driver(&dev_info, &pcnet_attach, &pcnet_detach);
+    pcmcia_register_driver(&pcnet_driver);
     return 0;
 }
 
 static void __exit exit_pcnet_cs(void)
 {
     DEBUG(0, "pcnet_cs: unloading\n");
-    unregister_pccard_driver(&dev_info);
+    pcmcia_unregister_driver(&pcnet_driver);
     while (dev_list != NULL)
 	pcnet_detach(dev_list);
 }
diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
--- a/drivers/net/ppp_generic.c	Tue Jan 21 09:23:39 2003
+++ b/drivers/net/ppp_generic.c	Wed Mar 19 21:17:02 2003
@@ -2214,6 +2214,11 @@
  * and for initialization.
  */
 
+static void ppp_device_destructor(struct net_device *dev)
+{
+	kfree(dev);
+}
+
 /*
  * Create a new ppp interface unit.  Fails if it can't allocate memory
  * or if there is already a unit with the requested number.
@@ -2262,7 +2267,7 @@
 	dev->init = ppp_net_init;
 	sprintf(dev->name, "ppp%d", unit);
 	dev->priv = ppp;
-	dev->features |= NETIF_F_DYNALLOC;
+	dev->destructor = ppp_device_destructor;
 
 	rtnl_lock();
 	ret = register_netdevice(dev);
diff -Nru a/drivers/net/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c
--- a/drivers/net/sk98lin/skvpd.c	Tue Feb 25 10:47:24 2003
+++ b/drivers/net/sk98lin/skvpd.c	Thu Mar 20 10:48:07 2003
@@ -121,7 +121,7 @@
  ******************************************************************************/
 
 /*
-	Please refer skvpd.txt for infomation how to include this module
+	Please refer skvpd.txt for information how to include this module
  */
 static const char SysKonnectFileId[] =
 	"@(#)$Id: skvpd.c,v 1.26 2000/06/13 08:00:01 mkarl Exp $ (C) SK" ;
diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c
--- a/drivers/net/tg3.c	Wed Feb 26 08:24:20 2003
+++ b/drivers/net/tg3.c	Thu Mar 20 21:01:20 2003
@@ -55,8 +55,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.4c"
-#define DRV_MODULE_RELDATE	"Feb 18, 2003"
+#define DRV_MODULE_VERSION	"1.5"
+#define DRV_MODULE_RELDATE	"March 21, 2003"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -6581,11 +6581,11 @@
 
 	tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
 
+	ret = 0;
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701)
-		return 0;
+		goto out;
 
-	ret = 0;
 	while (1) {
 		u32 *p, i;
 
diff -Nru a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
--- a/drivers/net/tulip/winbond-840.c	Mon Feb 24 10:34:39 2003
+++ b/drivers/net/tulip/winbond-840.c	Thu Mar 20 10:48:31 2003
@@ -17,7 +17,7 @@
 	Support and updates available at
 	http://www.scyld.com/network/drivers.html
 
-	Do not remove the copyright infomation.
+	Do not remove the copyright information.
 	Do not change the version information unless an improvement has been made.
 	Merely removing my name, as Compex has done in the past, does not count
 	as an improvement.
diff -Nru a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
--- a/drivers/net/wan/cosa.c	Mon Jan 13 17:11:59 2003
+++ b/drivers/net/wan/cosa.c	Sat Mar 22 07:38:04 2003
@@ -390,7 +390,7 @@
 		unregister_chrdev(cosa_major, "cosa");
 		return -ENODEV;
 	}
-	devfs_mk_dir (NULL, "cosa", NULL);
+	devfs_mk_dir("cosa");
 	for (i=0; i<nr_cards; i++) {
 		char name[16];
 		sprintf(name, "cosa/%d", i);
diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c	Sun Mar  2 18:12:49 2003
+++ b/drivers/net/wireless/airo.c	Fri Mar 21 14:14:01 2003
@@ -5894,6 +5894,7 @@
 #endif /* WIRELESS_EXT */
 
 #ifdef CISCO_EXT
+#define RIDS_SIZE	2048
 /*
  * This just translates from driver IOCTL codes to the command codes to
  * feed to the radio's host interface. Things can be added/deleted
@@ -5902,11 +5903,15 @@
  */
 static int readrids(struct net_device *dev, aironet_ioctl *comp) {
 	unsigned short ridcode;
-	unsigned char iobuf[2048];
+	unsigned char *iobuf;
 	struct airo_info *ai = dev->priv;
+	int ret = 0;
 
 	if (ai->flags & FLAG_FLASHING)
 		return -EIO;
+	iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL);
+	if (!iobuf)
+		return -ENOMEM;
 
 	switch(comp->command)
 	{
@@ -5919,13 +5924,17 @@
 	case AIROGEHTENC:   ridcode = RID_ETHERENCAP;   break;
 	case AIROGWEPKTMP:  ridcode = RID_WEP_TEMP;
 		/* Only super-user can read WEP keys */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
+		if (!capable(CAP_NET_ADMIN)) {
+			ret = -EPERM;
+			goto rr_free;
+		}
 		break;
 	case AIROGWEPKNV:   ridcode = RID_WEP_PERM;
 		/* Only super-user can read WEP keys */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
+		if (!capable(CAP_NET_ADMIN)) {
+			ret = -EPERM;
+			goto rr_free;
+		}
 		break;
 	case AIROGSTAT:     ridcode = RID_STATUS;       break;
 	case AIROGSTATSD32: ridcode = RID_STATSDELTA;   break;
@@ -5933,23 +5942,25 @@
 	case AIROGMICSTATS:
 		if (copy_to_user(comp->data, &ai->micstats,
 				 min((int)comp->len,(int)sizeof(ai->micstats))))
-			return -EFAULT;
-		return 0;
+			ret = -EFAULT;
+		goto rr_free;
 	default:
-		return -EINVAL;
-		break;
+		ret = -EINVAL;
+		goto rr_free;
 	}
 
-	PC4500_readrid(ai,ridcode,iobuf,sizeof(iobuf));
+	PC4500_readrid(ai,ridcode,iobuf,RIDS_SIZE);
 	/* get the count of bytes in the rid  docs say 1st 2 bytes is it.
 	 * then return it to the user
 	 * 9/22/2000 Honor user given length
 	 */
 
 	if (copy_to_user(comp->data, iobuf,
-			 min((int)comp->len, (int)sizeof(iobuf))))
-		return -EFAULT;
-	return 0;
+			 min((int)comp->len, (int)RIDS_SIZE)))
+		ret = -EFAULT;
+rr_free:
+	kfree(iobuf);
+	return ret;
 }
 
 /*
@@ -5961,7 +5972,8 @@
 	int  ridcode, enabled;
 	Resp      rsp;
 	static int (* writer)(struct airo_info *, u16 rid, const void *, int);
-	unsigned char iobuf[2048];
+	unsigned char *iobuf;
+	int ret = 0;
 
 	/* Only super-user can write RIDs */
 	if (!capable(CAP_NET_ADMIN))
@@ -5970,6 +5982,10 @@
 	if (ai->flags & FLAG_FLASHING)
 		return -EIO;
 
+	iobuf = kmalloc(RIDS_SIZE, GFP_KERNEL);
+	if (!iobuf)
+		return -ENOMEM;
+
 	ridcode = 0;
 	writer = do_writerid;
 
@@ -5991,8 +6007,8 @@
 		 */
 	case AIROPMACON:
 		if (enable_MAC(ai, &rsp) != 0)
-			return -EIO;
-		return 0;
+			ret = -EIO;
+		goto wr_free;
 
 		/*
 		 * Evidently this code in the airo driver does not get a symbol
@@ -6000,32 +6016,38 @@
 		 */
 	case AIROPMACOFF:
 		disable_MAC(ai);
-		return 0;
+		goto wr_free;
 
 		/* This command merely clears the counts does not actually store any data
 		 * only reads rid. But as it changes the cards state, I put it in the
 		 * writerid routines.
 		 */
 	case AIROPSTCLR:
-		PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,sizeof(iobuf));
+		PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDS_SIZE);
 
 		enabled = ai->micstats.enabled;
 		memset(&ai->micstats,0,sizeof(ai->micstats));
 		ai->micstats.enabled = enabled;
 
 		if (copy_to_user(comp->data, iobuf,
-				 min((int)comp->len, (int)sizeof(iobuf))))
-			return -EFAULT;
-		return 0;
+				 min((int)comp->len, (int)RIDS_SIZE)))
+			ret = -EFAULT;
+		goto wr_free;
 
 	default:
-		return -EOPNOTSUPP;	/* Blarg! */
+		ret = -EOPNOTSUPP;	/* Blarg! */
+		goto wr_free;
+	}
+
+	if (comp->len > RIDS_SIZE) {
+		ret = -EINVAL;
+		goto wr_free;
 	}
-	if(comp->len > sizeof(iobuf))
-		return -EINVAL;
 
-	if (copy_from_user(iobuf,comp->data,comp->len))
-		return -EFAULT;
+	if (copy_from_user(iobuf,comp->data,comp->len)) {
+		ret = -EFAULT;
+		goto wr_free;
+	}
 
 	if (comp->command == AIROPCFG) {
 		ConfigRid *cfg = (ConfigRid *)iobuf;
@@ -6040,8 +6062,10 @@
 	}
 
 	if((*writer)(ai, ridcode, iobuf,comp->len))
-		return -EIO;
-	return 0;
+		ret = -EIO;
+wr_free:
+	kfree(iobuf);
+	return ret;
 }
 
 /*****************************************************************************
diff -Nru a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
--- a/drivers/net/wireless/airo_cs.c	Sun Feb  2 13:40:35 2003
+++ b/drivers/net/wireless/airo_cs.c	Sun Mar 23 03:28:12 2003
@@ -626,26 +626,25 @@
 	return 0;
 } /* airo_event */
 
-/*====================================================================*/
+static struct pcmcia_driver airo_driver = {
+	.owner		= THIS_MODULE,
+	.drv		= {
+		.name	= "airo_cs",
+	},
+	.attach		= airo_attach,
+	.detach		= airo_detach,
+};
 
 static int airo_cs_init(void)
 {
-	servinfo_t serv;
-	DEBUG(0, "%s\n", version);
-	CardServices(GetCardServicesInfo, &serv);
-	if (serv.Revision != CS_RELEASE_CODE) {
-		printk(KERN_NOTICE "airo_cs: Card Services release "
-		       "does not match!\n");
-		return -1;
-	}
-	register_pcmcia_driver(&dev_info, &airo_attach, &airo_detach);
-	return 0;
+	return pcmcia_register_driver(&airo_driver);
 }
 
 static void airo_cs_cleanup(void)
 {
-	DEBUG(0, "airo_cs: unloading\n");
-	unregister_pcmcia_driver(&dev_info);
+	pcmcia_unregister_driver(&airo_driver);
+
+	/* XXX: this really needs to move into generic code.. */
 	while (dev_list != NULL) {
 		if (dev_list->state & DEV_CONFIG)
 			airo_release((u_long)dev_list);
diff -Nru a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
--- a/drivers/net/wireless/ray_cs.c	Tue Feb 18 17:22:50 2003
+++ b/drivers/net/wireless/ray_cs.c	Sun Mar 23 03:27:36 2003
@@ -2962,12 +2962,21 @@
 }
 #endif
 
+static struct pcmcia_driver ray_driver = {
+	.owner		= THIS_MODULE,
+	.drv		= {
+		.name	= "ray_cs",
+	},
+	.attach		= ray_attach,
+	.detach		= ray_detach,
+};
+
 static int __init init_ray_cs(void)
 {
     int rc;
     
     DEBUG(1, "%s\n", rcsid);
-    rc = register_pcmcia_driver(&dev_info, &ray_attach, &ray_detach);
+    rc = pcmcia_register_driver(&ray_driver);
     DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",rc);
 
 #ifdef CONFIG_PROC_FS
@@ -2993,7 +3002,7 @@
     remove_proc_entry("ray_cs", proc_root_driver);
 #endif
 
-    unregister_pcmcia_driver(&dev_info);
+    pcmcia_unregister_driver(&ray_driver);
     while (dev_list != NULL)
         ray_detach(dev_list);
 
diff -Nru a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
--- a/drivers/oprofile/buffer_sync.c	Sun Mar  2 22:46:44 2003
+++ b/drivers/oprofile/buffer_sync.c	Mon Mar 17 21:33:18 2003
@@ -82,9 +82,16 @@
  
 int sync_start(void)
 {
-	int err = profile_event_register(EXIT_TASK, &exit_task_nb);
+	int err;
+
+	init_timer(&sync_timer);
+	sync_timer.function = timer_ping;
+	sync_timer.expires = jiffies + DEFAULT_EXPIRE;
+	add_timer(&sync_timer);
+
+	err = profile_event_register(EXIT_TASK, &exit_task_nb);
 	if (err)
-		goto out;
+		goto out1;
 	err = profile_event_register(EXIT_MMAP, &exit_mmap_nb);
 	if (err)
 		goto out2;
@@ -92,16 +99,14 @@
 	if (err)
 		goto out3;
 
-	init_timer(&sync_timer);
-	sync_timer.function = timer_ping;
-	sync_timer.expires = jiffies + DEFAULT_EXPIRE;
-	add_timer(&sync_timer);
 out:
 	return err;
 out3:
 	profile_event_unregister(EXIT_MMAP, &exit_mmap_nb);
 out2:
 	profile_event_unregister(EXIT_TASK, &exit_task_nb);
+out1:
+	del_timer_sync(&sync_timer);
 	goto out;
 }
 
diff -Nru a/drivers/parport/init.c b/drivers/parport/init.c
--- a/drivers/parport/init.c	Tue Jun 25 13:50:37 2002
+++ b/drivers/parport/init.c	Thu Mar  6 15:08:36 2003
@@ -227,17 +227,3 @@
 EXPORT_SYMBOL(parport_find_device);
 EXPORT_SYMBOL(parport_find_class);
 #endif
-
-void inc_parport_count(void)
-{
-#ifdef MODULE
-	MOD_INC_USE_COUNT;
-#endif
-}
-
-void dec_parport_count(void)
-{
-#ifdef MODULE
-	MOD_DEC_USE_COUNT;
-#endif
-}
diff -Nru a/drivers/parport/parport_amiga.c b/drivers/parport/parport_amiga.c
--- a/drivers/parport/parport_amiga.c	Mon Nov 18 07:04:59 2002
+++ b/drivers/parport/parport_amiga.c	Thu Mar  6 15:08:46 2003
@@ -195,51 +195,40 @@
 	mb();
 }
 
-static void amiga_inc_use_count(void)
-{
-	MOD_INC_USE_COUNT;
-}
-
-static void amiga_dec_use_count(void)
-{
-	MOD_DEC_USE_COUNT;
-}
-
 static struct parport_operations pp_amiga_ops = {
-	amiga_write_data,
-	amiga_read_data,
+	.write_data	= amiga_write_data,
+	.read_data	= amiga_read_data,
 
-	amiga_write_control,
-	amiga_read_control,
-	amiga_frob_control,
+	.write_control	= amiga_write_control,
+	.read_control	= amiga_read_control,
+	.frob_control	= amiga_frob_control,
 
-	amiga_read_status,
+	.read_status	= amiga_read_status,
 
-	amiga_enable_irq,
-	amiga_disable_irq,
+	.enable_irq	= amiga_enable_irq,
+	.disable_irq	= amiga_disable_irq,
 
-	amiga_data_forward,
-	amiga_data_reverse,
+	.data_forward	= amiga_data_forward,
+	.data_reverse	= amiga_data_reverse,
 
-	amiga_init_state,
-	amiga_save_state,
-	amiga_restore_state,
+	.init_state	= amiga_init_state,
+	.save_state	= amiga_save_state,
+	.restore_state	= amiga_restore_state,
 
-	amiga_inc_use_count,
-	amiga_dec_use_count,
+	.epp_write_data	= parport_ieee1284_epp_write_data,
+	.epp_read_data	= parport_ieee1284_epp_read_data,
+	.epp_write_addr	= parport_ieee1284_epp_write_addr,
+	.epp_read_addr	= parport_ieee1284_epp_read_addr,
 
-	parport_ieee1284_epp_write_data,
-	parport_ieee1284_epp_read_data,
-	parport_ieee1284_epp_write_addr,
-	parport_ieee1284_epp_read_addr,
+	.ecp_write_data	= parport_ieee1284_ecp_write_data,
+	.ecp_read_data	= parport_ieee1284_ecp_read_data,
+	.ecp_write_addr	= parport_ieee1284_ecp_write_addr,
 
-	parport_ieee1284_ecp_write_data,
-	parport_ieee1284_ecp_read_data,
-	parport_ieee1284_ecp_write_addr,
+	.compat_write_data	= parport_ieee1284_write_compat,
+	.nibble_read_data	= parport_ieee1284_read_nibble,
+	.byte_read_data		= parport_ieee1284_read_byte,
 
-	parport_ieee1284_write_compat,
-	parport_ieee1284_read_nibble,
-	parport_ieee1284_read_byte,
+	.owner		= THIS_MODULE,
 };
 
 /* ----------- Initialisation code --------------------------------- */
diff -Nru a/drivers/parport/parport_arc.c b/drivers/parport/parport_arc.c
--- a/drivers/parport/parport_arc.c	Mon Feb  4 23:37:25 2002
+++ b/drivers/parport/parport_arc.c	Thu Mar  6 15:08:51 2003
@@ -65,56 +65,41 @@
 	return data_copy;
 }
 
-static void arc_inc_use_count(void)
-{
-#ifdef MODULE
-	MOD_INC_USE_COUNT;
-#endif
-}
-
-static void arc_dec_use_count(void)
-{
-#ifdef MODULE
-	MOD_DEC_USE_COUNT;
-#endif
-}
-
 static struct parport_operations parport_arc_ops = 
 {
-	arc_write_data,
-	arc_read_data,
-
-	arc_write_control,
-	arc_read_control,
-	arc_frob_control,
+	.write_data	= arc_write_data,
+	.read_data	= arc_read_data,
 
-	arc_read_status,
+	.write_control	= arc_write_control,
+	.read_control	= arc_read_control,
+	.frob_control	= arc_frob_control,
 
-	arc_enable_irq,
-	arc_disable_irq,
+	.read_status	= arc_read_status,
 
-	arc_data_forward,
-	arc_data_reverse,
+	.enable_irq	= arc_enable_irq,
+	.disable_irq	= arc_disable_irq,
 
-	arc_init_state,
-	arc_save_state,
-	arc_restore_state,
+	.data_forward	= arc_data_forward,
+	.data_reverse	= arc_data_reverse,
 
-	arc_inc_use_count,
-	arc_dec_use_count,
+	.init_state	= arc_init_state,
+	.save_state	= arc_save_state,
+	.restore_state	= arc_restore_state,
 
-	parport_ieee1284_epp_write_data,
-	parport_ieee1284_epp_read_data,
-	parport_ieee1284_epp_write_addr,
-	parport_ieee1284_epp_read_addr,
+	.epp_write_data	= parport_ieee1284_epp_write_data,
+	.epp_read_data	= parport_ieee1284_epp_read_data,
+	.epp_write_addr	= parport_ieee1284_epp_write_addr,
+	.epp_read_addr	= parport_ieee1284_epp_read_addr,
 
-	parport_ieee1284_ecp_write_data,
-	parport_ieee1284_ecp_read_data,
-	parport_ieee1284_ecp_write_addr,
+	.ecp_write_data	= parport_ieee1284_ecp_write_data,
+	.ecp_read_data	= parport_ieee1284_ecp_read_data,
+	.ecp_write_addr	= parport_ieee1284_ecp_write_addr,
 	
-	parport_ieee1284_write_compat,
-	parport_ieee1284_read_nibble,
-	parport_ieee1284_read_byte,
+	.compat_write_data	= parport_ieee1284_write_compat,
+	.nibble_read_data	= parport_ieee1284_read_nibble,
+	.byte_read_data		= parport_ieee1284_read_byte,
+
+	.owner		= THIS_MODULE,
 };
 
 /* --- Initialisation code -------------------------------- */
@@ -123,18 +108,24 @@
 {
 	/* Archimedes hardware provides only one port, at a fixed address */
 	struct parport *p;
+	struct resource res;
+	char *fake_name = "parport probe");
 
-	if (check_region(PORT_BASE, 1))
+	res = request_region(PORT_BASE, 1, fake_name);
+	if (res == NULL)
 		return 0;
 
 	p = parport_register_port (PORT_BASE, IRQ_PRINTERACK,
 				   PARPORT_DMA_NONE, &parport_arc_ops);
 
-	if (!p)
+	if (!p) {
+		release_region(PORT_BASE, 1);
 		return 0;
+	}
 
 	p->modes = PARPORT_MODE_ARCSPP;
 	p->size = 1;
+	rename_region(res, p->name);
 
 	printk(KERN_INFO "%s: Archimedes on-board port, using irq %d\n",
 	       p->irq);
diff -Nru a/drivers/parport/parport_atari.c b/drivers/parport/parport_atari.c
--- a/drivers/parport/parport_atari.c	Mon Nov 18 09:39:30 2002
+++ b/drivers/parport/parport_atari.c	Thu Mar  6 15:08:56 2003
@@ -147,53 +147,40 @@
 #endif
 }
 
-static void
-parport_atari_inc_use_count(void)
-{
-	MOD_INC_USE_COUNT;
-}
-
-static void
-parport_atari_dec_use_count(void)
-{
-	MOD_DEC_USE_COUNT;
-}
-
 static struct parport_operations parport_atari_ops = {
-	parport_atari_write_data,
-	parport_atari_read_data,
+	.write_data	= parport_atari_write_data,
+	.read_data	= parport_atari_read_data,
 
-	parport_atari_write_control,
-	parport_atari_read_control,
-	parport_atari_frob_control,
+	.write_control	= parport_atari_write_control,
+	.read_control	= parport_atari_read_control,
+	.frob_control	= parport_atari_frob_control,
 
-	parport_atari_read_status,
+	.read_status	= parport_atari_read_status,
 
-	parport_atari_enable_irq,
-	parport_atari_disable_irq,
+	.enable_irq	= parport_atari_enable_irq,
+	.disable_irq	= parport_atari_disable_irq,
 
-	parport_atari_data_forward,
-	parport_atari_data_reverse,
+	.data_forward	= parport_atari_data_forward,
+	.data_reverse	= parport_atari_data_reverse,
 
-	parport_atari_init_state,
-	parport_atari_save_state,
-	parport_atari_restore_state,
+	.init_state	= parport_atari_init_state,
+	.save_state	= parport_atari_save_state,
+	.restore_state	= parport_atari_restore_state,
 
-	parport_atari_inc_use_count,
-	parport_atari_dec_use_count,
+	.epp_write_data	= parport_ieee1284_epp_write_data,
+	.epp_read_data	= parport_ieee1284_epp_read_data,
+	.epp_write_addr	= parport_ieee1284_epp_write_addr,
+	.epp_read_addr	= parport_ieee1284_epp_read_addr,
 
-	parport_ieee1284_epp_write_data,
-	parport_ieee1284_epp_read_data,
-	parport_ieee1284_epp_write_addr,
-	parport_ieee1284_epp_read_addr,
+	.ecp_write_data	= parport_ieee1284_ecp_write_data,
+	.ecp_read_data	= parport_ieee1284_ecp_read_data,
+	.ecp_write_addr	= parport_ieee1284_ecp_write_addr,
 
-	parport_ieee1284_ecp_write_data,
-	parport_ieee1284_ecp_read_data,
-	parport_ieee1284_ecp_write_addr,
+	.compat_write_data	= parport_ieee1284_write_compat,
+	.nibble_read_data	= parport_ieee1284_read_nibble,
+	.byte_read_data		= parport_ieee1284_read_byte,
 
-	parport_ieee1284_write_compat,
-	parport_ieee1284_read_nibble,
-	parport_ieee1284_read_byte,
+	.owner		= THIS_MODULE,
 };
 
 
diff -Nru a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c
--- a/drivers/parport/parport_gsc.c	Sun Jan  5 03:19:41 2003
+++ b/drivers/parport/parport_gsc.c	Thu Mar  6 15:09:01 2003
@@ -190,17 +190,6 @@
 	parport_writeb (s->u.pc.ctr, CONTROL (p));
 }
 
-void parport_gsc_inc_use_count(void)
-{
-	MOD_INC_USE_COUNT;
-}
-
-void parport_gsc_dec_use_count(void)
-{
-	MOD_DEC_USE_COUNT;
-}
-
-
 struct parport_operations parport_gsc_ops = 
 {
 	.write_data	= parport_gsc_write_data,
@@ -222,9 +211,6 @@
 	.save_state	= parport_gsc_save_state,
 	.restore_state	= parport_gsc_restore_state,
 
-	.inc_use_count	= parport_gsc_inc_use_count,
-	.dec_use_count	= parport_gsc_dec_use_count,
-
 	.epp_write_data	= parport_ieee1284_epp_write_data,
 	.epp_read_data	= parport_ieee1284_epp_read_data,
 	.epp_write_addr	= parport_ieee1284_epp_write_addr,
@@ -237,6 +223,8 @@
 	.compat_write_data 	= parport_ieee1284_write_compat,
 	.nibble_read_data	= parport_ieee1284_read_nibble,
 	.byte_read_data		= parport_ieee1284_read_byte,
+
+	.owner		= THIS_MODULE,
 };
 
 /* --- Mode detection ------------------------------------- */
diff -Nru a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c
--- a/drivers/parport/parport_mfc3.c	Mon Nov 18 07:05:07 2002
+++ b/drivers/parport/parport_mfc3.c	Thu Mar  6 15:09:05 2003
@@ -281,51 +281,40 @@
 	pia(p)->cra |= PIA_DDR;
 }
 
-static void mfc3_inc_use_count(void)
-{
-	MOD_INC_USE_COUNT;
-}
-
-static void mfc3_dec_use_count(void)
-{
-	MOD_DEC_USE_COUNT;
-}
-
 static struct parport_operations pp_mfc3_ops = {
-	mfc3_write_data,
-	mfc3_read_data,
+	.write_data	= mfc3_write_data,
+	.read_data	= mfc3_read_data,
 
-	mfc3_write_control,
-	mfc3_read_control,
-	mfc3_frob_control,
+	.write_control	= mfc3_write_control,
+	.read_control	= mfc3_read_control,
+	.frob_control	= mfc3_frob_control,
 
-	mfc3_read_status,
+	.read_status	= mfc3_read_status,
 
-	mfc3_enable_irq,
-	mfc3_disable_irq,
+	.enable_irq	= mfc3_enable_irq,
+	.disable_irq	= mfc3_disable_irq,
 
-	mfc3_data_forward, 
-	mfc3_data_reverse, 
+	.data_forward	= mfc3_data_forward, 
+	.data_reverse	= mfc3_data_reverse, 
 
-	mfc3_init_state,
-	mfc3_save_state,
-	mfc3_restore_state,
+	.init_state	= mfc3_init_state,
+	.save_state	= mfc3_save_state,
+	.restore_state	= mfc3_restore_state,
 
-	mfc3_inc_use_count,
-	mfc3_dec_use_count,
+	.epp_write_data	= parport_ieee1284_epp_write_data,
+	.epp_read_data	= parport_ieee1284_epp_read_data,
+	.epp_write_addr	= parport_ieee1284_epp_write_addr,
+	.epp_read_addr	= parport_ieee1284_epp_read_addr,
 
-	parport_ieee1284_epp_write_data,
-	parport_ieee1284_epp_read_data,
-	parport_ieee1284_epp_write_addr,
-	parport_ieee1284_epp_read_addr,
+	.ecp_write_data	= parport_ieee1284_ecp_write_data,
+	.ecp_read_data	= parport_ieee1284_ecp_read_data,
+	.ecp_write_addr	= parport_ieee1284_ecp_write_addr,
 
-	parport_ieee1284_ecp_write_data,
-	parport_ieee1284_ecp_read_data,
-	parport_ieee1284_ecp_write_addr,
+	.compat_write_data	= parport_ieee1284_write_compat,
+	.nibble_read_data	= parport_ieee1284_read_nibble,
+	.byte_read_data		= parport_ieee1284_read_byte,
 
-	parport_ieee1284_write_compat,
-	parport_ieee1284_read_nibble,
-	parport_ieee1284_read_byte,
+	.owner		= THIS_MODULE,
 };
 
 /* ----------- Initialisation code --------------------------------- */
diff -Nru a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
--- a/drivers/parport/parport_pc.c	Tue Feb 25 09:44:59 2003
+++ b/drivers/parport/parport_pc.c	Sun Mar 23 14:28:44 2003
@@ -147,7 +147,7 @@
 	if (mode >= 2 && !(priv->ctr & 0x20)) {
 		/* This mode resets the FIFO, so we may
 		 * have to wait for it to drain first. */
-		long expire = jiffies + p->physport->cad->timeout;
+		unsigned long expire = jiffies + p->physport->cad->timeout;
 		int counter;
 		switch (mode) {
 		case ECR_PPF: /* Parallel Port FIFO mode */
@@ -596,7 +596,7 @@
 	int ret = 0;
 	const unsigned char *bufp = buf;
 	size_t left = length;
-	long expire = jiffies + port->physport->cad->timeout;
+	unsigned long expire = jiffies + port->physport->cad->timeout;
 	const int fifo = FIFO (port);
 	int poll_for = 8; /* 80 usecs */
 	const struct parport_pc_private *priv = port->physport->private_data;
@@ -724,7 +724,7 @@
 	parport_pc_data_forward (port); /* Must be in PS2 mode */
 
 	while (left) {
-		long expire = jiffies + port->physport->cad->timeout;
+		unsigned long expire = jiffies + port->physport->cad->timeout;
 
 		size_t count = left;
 
@@ -816,7 +816,7 @@
 {
 	size_t written;
 	int r;
-	long int expire;
+	unsigned long expire;
 	const struct parport_pc_private *priv = port->physport->private_data;
 
 	/* Special case: a timeout of zero means we cannot call schedule().
@@ -893,7 +893,7 @@
 {
 	size_t written;
 	int r;
-	long int expire;
+	unsigned long expire;
 	const struct parport_pc_private *priv = port->physport->private_data;
 
 	/* Special case: a timeout of zero means we cannot call schedule().
@@ -1111,7 +1111,7 @@
 	/* Do the transfer. */
 	while (left > fifofull) {
 		int ret;
-		long int expire = jiffies + port->cad->timeout;
+		unsigned long expire = jiffies + port->cad->timeout;
 		unsigned char ecrval = inb (ECONTROL (port));
 
 		if (need_resched() && time_before (jiffies, expire))
@@ -1232,57 +1232,41 @@
  *	******************************************
  */
 
-
-void parport_pc_inc_use_count(void)
-{
-#ifdef MODULE
-	MOD_INC_USE_COUNT;
-#endif
-}
-
-void parport_pc_dec_use_count(void)
-{
-#ifdef MODULE
-	MOD_DEC_USE_COUNT;
-#endif
-}
-
 struct parport_operations parport_pc_ops = 
 {
-	parport_pc_write_data,
-	parport_pc_read_data,
+	.write_data	= parport_pc_write_data,
+	.read_data	= parport_pc_read_data,
 
-	parport_pc_write_control,
-	parport_pc_read_control,
-	parport_pc_frob_control,
+	.write_control	= parport_pc_write_control,
+	.read_control	= parport_pc_read_control,
+	.frob_control	= parport_pc_frob_control,
 
-	parport_pc_read_status,
+	.read_status	= parport_pc_read_status,
 
-	parport_pc_enable_irq,
-	parport_pc_disable_irq,
+	.enable_irq	= parport_pc_enable_irq,
+	.disable_irq	= parport_pc_disable_irq,
 
-	parport_pc_data_forward,
-	parport_pc_data_reverse,
+	.data_forward	= parport_pc_data_forward,
+	.data_reverse	= parport_pc_data_reverse,
 
-	parport_pc_init_state,
-	parport_pc_save_state,
-	parport_pc_restore_state,
+	.init_state	= parport_pc_init_state,
+	.save_state	= parport_pc_save_state,
+	.restore_state	= parport_pc_restore_state,
 
-	parport_pc_inc_use_count,
-	parport_pc_dec_use_count,
+	.epp_write_data	= parport_ieee1284_epp_write_data,
+	.epp_read_data	= parport_ieee1284_epp_read_data,
+	.epp_write_addr	= parport_ieee1284_epp_write_addr,
+	.epp_read_addr	= parport_ieee1284_epp_read_addr,
 
-	parport_ieee1284_epp_write_data,
-	parport_ieee1284_epp_read_data,
-	parport_ieee1284_epp_write_addr,
-	parport_ieee1284_epp_read_addr,
+	.ecp_write_data	= parport_ieee1284_ecp_write_data,
+	.ecp_read_data	= parport_ieee1284_ecp_read_data,
+	.ecp_write_addr	= parport_ieee1284_ecp_write_addr,
 
-	parport_ieee1284_ecp_write_data,
-	parport_ieee1284_ecp_read_data,
-	parport_ieee1284_ecp_write_addr,
+	.compat_write_data	= parport_ieee1284_write_compat,
+	.nibble_read_data	= parport_ieee1284_read_nibble,
+	.byte_read_data		= parport_ieee1284_read_byte,
 
-	parport_ieee1284_write_compat,
-	parport_ieee1284_read_nibble,
-	parport_ieee1284_read_byte,
+	.owner		= THIS_MODULE,
 };
 
 #ifdef CONFIG_PARPORT_PC_SUPERIO
@@ -2212,16 +2196,32 @@
 	struct parport tmp;
 	struct parport *p = &tmp;
 	int probedirq = PARPORT_IRQ_NONE;
-	if (check_region(base, 3)) return NULL;
+	struct resource *base_res;
+	struct resource	*ECR_res = NULL;
+	struct resource	*EPP_res = NULL;
+	char *fake_name = "parport probe";
+
+	/*
+	 * Chicken and Egg problem.  request_region() wants the name of
+	 * the owner, but this instance will not know that name until
+	 * after the parport_register_port() call.  Give request_region()
+	 * a fake name until after parport_register_port(), then use
+	 * rename_region() to set correct name.
+	 */
+	base_res = request_region(base, 3, fake_name);
+	if (base_res == NULL)
+		return NULL;
 	priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL);
 	if (!priv) {
 		printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base);
+		release_region(base, 3);
 		return NULL;
 	}
 	ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);
 	if (!ops) {
 		printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n",
 			base);
+		release_region(base, 3);
 		kfree (priv);
 		return NULL;
 	}
@@ -2242,32 +2242,39 @@
 	p->private_data = priv;
 	p->physport = p;
 
-	if (base_hi && !check_region(base_hi,3))
-		parport_ECR_present(p);
+	if (base_hi) {
+		ECR_res = request_region(base_hi, 3, fake_name);
+		if (ECR_res)
+			parport_ECR_present(p);
+	}
 
 	if (base != 0x3bc) {
-		if (!check_region(base+0x3, 5)) {
+		EPP_res = request_region(base+0x3, 5, fake_name);
+		if (EPP_res)
 			if (!parport_EPP_supported(p))
 				parport_ECPEPP_supported(p);
-		}
 	}
-	if (!parport_SPP_supported (p)) {
+	if (!parport_SPP_supported (p))
 		/* No port. */
-		kfree (priv);
-		kfree (ops);
-		return NULL;
-	}
+		goto errout;
 	if (priv->ecr)
 		parport_ECPPS2_supported(p);
 	else
 		parport_PS2_supported (p);
 
 	if (!(p = parport_register_port(base, PARPORT_IRQ_NONE,
-					PARPORT_DMA_NONE, ops))) {
-		kfree (priv);
-		kfree (ops);
-		return NULL;
-	}
+					PARPORT_DMA_NONE, ops)))
+		goto errout;
+
+	/*
+	 * Now the real name is known... Replace the fake name
+	 * in the resources with the correct one.
+	 */
+	rename_region(base_res, p->name);
+	if (ECR_res)
+		rename_region(ECR_res, p->name);
+	if (EPP_res)
+		rename_region(EPP_res, p->name);
 
 	p->base_hi = base_hi;
 	p->modes = tmp.modes;
@@ -2343,11 +2350,11 @@
 		printk(KERN_INFO "%s: irq %d detected\n", p->name, probedirq);
 	parport_proc_register(p);
 
-	request_region (p->base, 3, p->name);
-	if (p->size > 3)
-		request_region (p->base + 3, p->size - 3, p->name);
-	if (p->modes & PARPORT_MODE_ECP)
-		request_region (p->base_hi, 3, p->name);
+	/* If No ECP release the ports grabbed above. */
+	if (ECR_res && (p->modes & PARPORT_MODE_ECP) == 0) {
+		release_region(base_hi, 3);
+		ECR_res = NULL;
+	}
 
 	if (p->irq != PARPORT_IRQ_NONE) {
 		if (request_irq (p->irq, parport_pc_interrupt,
@@ -2401,6 +2408,17 @@
 	parport_announce_port (p);
 
 	return p;
+
+errout:
+	release_region(p->base, 3);
+	if (ECR_res)
+		release_region(base_hi, 3);
+	if (EPP_res)
+		release_region(base+0x3, 5);
+
+	kfree (priv);
+	kfree (ops);
+	return NULL;
 }
 
 void parport_pc_unregister_port (struct parport *p)
@@ -2437,9 +2455,11 @@
 					 int autodma)
 {
 	short inta_addr[6] = { 0x2A0, 0x2C0, 0x220, 0x240, 0x1E0 };
+	struct resource *base_res;
 	u32 ite8872set;
 	u32 ite8872_lpt, ite8872_lpthi;
 	u8 ite8872_irq, type;
+	char *fake_name = "parport probe";
 	int irq;
 	int i;
 
@@ -2447,7 +2467,8 @@
 	
 	// make sure which one chip
 	for(i = 0; i < 5; i++) {
-		if (check_region (inta_addr[i], 0x8) >= 0) {
+		base_res = request_region(inta_addr[i], 0x8, fake_name);
+		if (base_res) {
 			int test;
 			pci_write_config_dword (pdev, 0x60,
 						0xe7000000 | inta_addr[i]);
@@ -2455,6 +2476,7 @@
 						0x00000000 | inta_addr[i]);
 			test = inb (inta_addr[i]);
 			if (test != 0xff) break;
+			release_region(inta_addr[i], 0x8);
 		}
 	}
 	if(i >= 5) {
@@ -2515,6 +2537,10 @@
 	if (autoirq != PARPORT_IRQ_AUTO)
 		irq = PARPORT_IRQ_NONE;
 
+	/*
+	 * Release the resource so that parport_pc_probe_port can get it.
+	 */
+	release_resource(base_res);
 	if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi,
 				   irq, PARPORT_DMA_NONE, NULL)) {
 		printk (KERN_INFO
diff -Nru a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c
--- a/drivers/parport/parport_sunbpp.c	Thu May 23 09:07:44 2002
+++ b/drivers/parport/parport_sunbpp.c	Thu Mar  6 15:08:12 2003
@@ -249,56 +249,41 @@
 	parport_sunbpp_write_control(p, s->u.pc.ctr);
 }
 
-static void parport_sunbpp_inc_use_count(void)
-{
-#ifdef MODULE
-	MOD_INC_USE_COUNT;
-#endif
-}
-
-static void parport_sunbpp_dec_use_count(void)
-{
-#ifdef MODULE
-	MOD_DEC_USE_COUNT;
-#endif
-}
-
 static struct parport_operations parport_sunbpp_ops = 
 {
-	parport_sunbpp_write_data,
-	parport_sunbpp_read_data,
+	.write_data	= parport_sunbpp_write_data,
+	.read_data	= parport_sunbpp_read_data,
 
-	parport_sunbpp_write_control,
-	parport_sunbpp_read_control,
-	parport_sunbpp_frob_control,
+	.write_control	= parport_sunbpp_write_control,
+	.read_control	= parport_sunbpp_read_control,
+	.frob_control	= parport_sunbpp_frob_control,
 
-	parport_sunbpp_read_status,
+	.read_status	= parport_sunbpp_read_status,
 
-	parport_sunbpp_enable_irq,
-        parport_sunbpp_disable_irq,
+	.enable_irq	= parport_sunbpp_enable_irq,
+	.disable_irq	= parport_sunbpp_disable_irq,
 
-        parport_sunbpp_data_forward,
-        parport_sunbpp_data_reverse,
+	.data_forward	= parport_sunbpp_data_forward,
+	.data_reverse	= parport_sunbpp_data_reverse,
 
-        parport_sunbpp_init_state,
-        parport_sunbpp_save_state,
-        parport_sunbpp_restore_state,
+	.init_state	= parport_sunbpp_init_state,
+	.save_state	= parport_sunbpp_save_state,
+	.restore_state	= parport_sunbpp_restore_state,
 
-        parport_sunbpp_inc_use_count,
-        parport_sunbpp_dec_use_count,
+	.epp_write_data	= parport_ieee1284_epp_write_data,
+	.epp_read_data	= parport_ieee1284_epp_read_data,
+	.epp_write_addr	= parport_ieee1284_epp_write_addr,
+	.epp_read_addr	= parport_ieee1284_epp_read_addr,
 
-        parport_ieee1284_epp_write_data,
-        parport_ieee1284_epp_read_data,
-        parport_ieee1284_epp_write_addr,
-        parport_ieee1284_epp_read_addr,
+	.ecp_write_data	= parport_ieee1284_ecp_write_data,
+	.ecp_read_data	= parport_ieee1284_ecp_read_data,
+	.ecp_write_addr	= parport_ieee1284_ecp_write_addr,
 
-        parport_ieee1284_ecp_write_data,
-        parport_ieee1284_ecp_read_data,
-        parport_ieee1284_ecp_write_addr,
+	.compat_write_data	= parport_ieee1284_write_compat,
+	.nibble_read_data	= parport_ieee1284_read_nibble,
+	.byte_read_data		= parport_ieee1284_read_byte,
 
-        parport_ieee1284_write_compat,
-        parport_ieee1284_read_nibble,
-        parport_ieee1284_read_byte,
+	.owner		= THIS_MODULE,
 };
 
 static int __init init_one_port(struct sbus_dev *sdev)
diff -Nru a/drivers/parport/share.c b/drivers/parport/share.c
--- a/drivers/parport/share.c	Mon Jul 29 09:33:38 2002
+++ b/drivers/parport/share.c	Sun Mar 23 15:49:03 2003
@@ -55,37 +55,44 @@
 static void dead_onearg (struct parport *p){}
 static void dead_initstate (struct pardevice *d, struct parport_state *s) { }
 static void dead_state (struct parport *p, struct parport_state *s) { }
-static void dead_noargs (void) { }
 static size_t dead_write (struct parport *p, const void *b, size_t l, int f)
 { return 0; }
 static size_t dead_read (struct parport *p, void *b, size_t l, int f)
 { return 0; }
 static struct parport_operations dead_ops = {
-	dead_write_lines,	/* data */
-	dead_read_lines,
-	dead_write_lines,	/* control */
-	dead_read_lines,
-	dead_frob_lines,
-	dead_read_lines,	/* status */
-	dead_onearg,		/* enable_irq */
-	dead_onearg,		/* disable_irq */
-	dead_onearg,		/* data_forward */
-	dead_onearg,		/* data_reverse */
-	dead_initstate,		/* init_state */
-	dead_state,
-	dead_state,
-	dead_noargs,		/* xxx_use_count */
-	dead_noargs,
-	dead_write,		/* epp */
-	dead_read,
-	dead_write,
-	dead_read,
-	dead_write,		/* ecp */
-	dead_read,
-	dead_write,
-	dead_write,		/* compat */
-	dead_read,		/* nibble */
-	dead_read		/* byte */
+	.write_data	= dead_write_lines,	/* data */
+	.read_data	= dead_read_lines,
+
+	.write_control	= dead_write_lines,	/* control */
+	.read_control	= dead_read_lines,
+	.frob_control	= dead_frob_lines,
+
+	.read_status	= dead_read_lines,	/* status */
+
+	.enable_irq	= dead_onearg,		/* enable_irq */
+	.disable_irq	= dead_onearg,		/* disable_irq */
+
+	.data_forward	= dead_onearg,		/* data_forward */
+	.data_reverse	= dead_onearg,		/* data_reverse */
+
+	.init_state	= dead_initstate,	/* init_state */
+	.save_state	= dead_state,
+	.restore_state	= dead_state,
+
+	.epp_write_data	= dead_write,		/* epp */
+	.epp_read_data	= dead_read,
+	.epp_write_addr	= dead_write,
+	.epp_read_addr	= dead_read,
+
+	.ecp_write_data	= dead_write,		/* ecp */
+	.ecp_read_data	= dead_read,
+	.ecp_write_addr	= dead_write,
+ 
+	.compat_write_data	= dead_write,	/* compat */
+	.nibble_read_data	= dead_read,	/* nibble */
+	.byte_read_data		= dead_read,	/* byte */
+
+	.owner		= NULL,
 };
 
 /* Call attach(port) for each registered driver. */
@@ -390,25 +397,6 @@
 		return NULL;
 	}
 
-	/* Search for the lowest free parport number. */
-
-	spin_lock_irq (&parportlist_lock);
-	for (portnum = 0; ; portnum++) {
-		struct parport *itr = portlist;
-		while (itr) {
-			if (itr->number == portnum)
-				/* No good, already used. */
-				break;
-			else
-				itr = itr->next;
-		}
-
-		if (itr == NULL)
-			/* Got to the end of the list. */
-			break;
-	}
-	spin_unlock_irq (&parportlist_lock);
-	
 	/* Init our structure */
  	memset(tmp, 0, sizeof(struct parport));
 	tmp->base = base;
@@ -420,7 +408,6 @@
 	tmp->devices = tmp->cad = NULL;
 	tmp->flags = 0;
 	tmp->ops = ops;
-	tmp->portnum = tmp->number = portnum;
 	tmp->physport = tmp;
 	memset (tmp->probe_info, 0, 5 * sizeof (struct parport_device_info));
 	tmp->cad_lock = RW_LOCK_UNLOCKED;
@@ -438,9 +425,32 @@
 		kfree(tmp);
 		return NULL;
 	}
+	/* Search for the lowest free parport number. */
+
+	spin_lock_irq (&parportlist_lock);
+	for (portnum = 0; ; portnum++) {
+		struct parport *itr = portlist;
+		while (itr) {
+			if (itr->number == portnum)
+				/* No good, already used. */
+				break;
+			else
+				itr = itr->next;
+		}
+
+		if (itr == NULL)
+			/* Got to the end of the list. */
+			break;
+	}
+
+	/*
+	 * Now that the portnum is known finish doing the Init.
+	 */
+	tmp->portnum = tmp->number = portnum;
 	sprintf(name, "parport%d", portnum);
 	tmp->name = name;
 
+	
 	/*
 	 * Chain the entry to our list.
 	 *
@@ -448,8 +458,6 @@
 	 * to clear irq on the local CPU. -arca
 	 */
 
-	spin_lock(&parportlist_lock);
-
 	/* We are locked against anyone else performing alterations, but
 	 * because of parport_enumerate people can still _read_ the list
 	 * while we are changing it; so be careful..
@@ -464,7 +472,7 @@
 	portlist_tail = tmp;
 	if (!portlist)
 		portlist = tmp;
-	spin_unlock(&parportlist_lock);
+	spin_unlock_irq(&parportlist_lock);
 
 	for (device = 0; device < 5; device++)
 		/* assume the worst */
@@ -664,8 +672,10 @@
            kmalloc.  To be absolutely safe, we have to require that
            our caller doesn't sleep in between parport_enumerate and
            parport_register_device.. */
-	inc_parport_count();
-	port->ops->inc_use_count();
+	if (!try_module_get(port->ops->owner)) {
+		return NULL;
+	}
+		
 	parport_get_port (port);
 
 	tmp = kmalloc(sizeof(struct pardevice), GFP_KERNEL);
@@ -736,9 +746,9 @@
  out_free_pardevice:
 	kfree (tmp);
  out:
-	dec_parport_count();
-	port->ops->dec_use_count();
 	parport_put_port (port);
+	module_put(port->ops->owner);
+
 	return NULL;
 }
 
@@ -801,8 +811,7 @@
 	kfree(dev->state);
 	kfree(dev);
 
-	dec_parport_count();
-	port->ops->dec_use_count();
+	module_put(port->ops->owner);
 	parport_put_port (port);
 
 	/* Yes, that's right, someone _could_ still have a pointer to
diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c	Sat Feb 15 09:39:25 2003
+++ b/drivers/pci/pci.c	Sat Mar 22 07:22:30 2003
@@ -584,6 +584,9 @@
 }
 
 #ifndef HAVE_ARCH_PCI_MWI
+/* This can be overridden by arch code. */
+u8 pci_cache_line_size = L1_CACHE_BYTES >> 2;
+
 /**
  * pci_generic_prep_mwi - helper function for pci_set_mwi
  * @dev: the PCI device for which MWI is enabled
@@ -597,32 +600,29 @@
 static int
 pci_generic_prep_mwi(struct pci_dev *dev)
 {
-	int rc = 0;
-	u8 cache_size;
+	u8 cacheline_size;
+
+	if (!pci_cache_line_size)
+		return -EINVAL;		/* The system doesn't support MWI. */
+
+	/* Validate current setting: the PCI_CACHE_LINE_SIZE must be
+	   equal to or multiple of the right value. */
+	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cacheline_size);
+	if (cacheline_size >= pci_cache_line_size &&
+	    (cacheline_size % pci_cache_line_size) == 0)
+		return 0;
+
+	/* Write the correct value. */
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size);
+	/* Read it back. */
+	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cacheline_size);
+	if (cacheline_size == pci_cache_line_size)
+		return 0;
 
-	/*
-	 * Looks like this is necessary to deal with on all architectures,
-	 * even this %$#%$# N440BX Intel based thing doesn't get it right.
-	 * Ie. having two NICs in the machine, one will have the cache
-	 * line set at boot time, the other will not.
-	 */
-	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &cache_size);
-	cache_size <<= 2;
-	if (cache_size != SMP_CACHE_BYTES) {
-		printk(KERN_WARNING "PCI: %s PCI cache line size set "
-		       "incorrectly (%i bytes) by BIOS/FW, ",
-		       dev->slot_name, cache_size);
-		if (cache_size > SMP_CACHE_BYTES) {
-			printk("expecting %i\n", SMP_CACHE_BYTES);
-			rc = -EINVAL;
-		} else {
-			printk("correcting to %i\n", SMP_CACHE_BYTES);
-			pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
-					      SMP_CACHE_BYTES >> 2);
-		}
-	}
+	printk(KERN_WARNING "PCI: cache line size of %d is not supported "
+	       "by device %s\n", pci_cache_line_size << 2, dev->slot_name);
 
-	return rc;
+	return -EINVAL;
 }
 #endif /* !HAVE_ARCH_PCI_MWI */
 
diff -Nru a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
--- a/drivers/pci/setup-bus.c	Sun Mar 16 15:28:03 2003
+++ b/drivers/pci/setup-bus.c	Sat Mar 22 07:18:29 2003
@@ -36,6 +36,13 @@
 
 #define ROUND_UP(x, a)		(((x) + (a) - 1) & ~((a) - 1))
 
+/*
+ * FIXME: IO should be max 256 bytes.  However, since we may
+ * have a P2P bridge below a cardbus bridge, we need 4K.
+ */
+#define CARDBUS_IO_SIZE		(4096)
+#define CARDBUS_MEM_SIZE	(32*1024*1024)
+
 static int __devinit
 pbus_assign_resources_sorted(struct pci_bus *bus)
 {
@@ -67,12 +74,67 @@
 	return found_vga;
 }
 
+static void __devinit
+pci_setup_cardbus(struct pci_bus *bus)
+{
+	struct pci_dev *bridge = bus->self;
+	struct pci_bus_region region;
+
+	printk("PCI: Bus %d, cardbus bridge: %s\n",
+		bus->number, bridge->slot_name);
+
+	pcibios_resource_to_bus(bridge, &region, bus->resource[0]);
+	if (bus->resource[0]->flags & IORESOURCE_IO) {
+		/*
+		 * The IO resource is allocated a range twice as large as it
+		 * would normally need.  This allows us to set both IO regs.
+		 */
+		printk("  IO window: %08lx-%08lx\n",
+			region.start, region.end);
+		pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
+					region.start);
+		pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
+					region.end);
+	}
+
+	pcibios_resource_to_bus(bridge, &region, bus->resource[1]);
+	if (bus->resource[1]->flags & IORESOURCE_IO) {
+		printk("  IO window: %08lx-%08lx\n",
+			region.start, region.end);
+		pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
+					region.start);
+		pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
+					region.end);
+	}
+
+	pcibios_resource_to_bus(bridge, &region, bus->resource[2]);
+	if (bus->resource[2]->flags & IORESOURCE_MEM) {
+		printk("  PREFETCH window: %08lx-%08lx\n",
+			region.start, region.end);
+		pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
+					region.start);
+		pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
+					region.end);
+	}
+
+	pcibios_resource_to_bus(bridge, &region, bus->resource[3]);
+	if (bus->resource[3]->flags & IORESOURCE_MEM) {
+		printk("  MEM window: %08lx-%08lx\n",
+			region.start, region.end);
+		pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
+					region.start);
+		pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
+					region.end);
+	}
+}
+
 /* Initialize bridges with base/limit values we have collected.
    PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998)
    requires that if there is no I/O ports or memory behind the
    bridge, corresponding range must be turned off by writing base
    value greater than limit to the bridge's base/limit registers.  */
-static void __devinit pci_setup_bridge(struct pci_bus *bus)
+static void __devinit
+pci_setup_bridge(struct pci_bus *bus)
 {
 	struct pci_dev *bridge = bus->self;
 	struct pci_bus_region region;
@@ -154,9 +216,6 @@
 	struct pci_dev *bridge = bus->self;
 	struct resource *b_res;
 
-	if (!bridge || (bridge->class >> 8) != PCI_CLASS_BRIDGE_PCI)
-		return;
-
 	b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
 	b_res[1].flags |= IORESOURCE_MEM;
 
@@ -184,6 +243,26 @@
 		b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
 }
 
+/* Helper function for sizing routines: find first available
+   bus resource of a given type. Note: we intentionally skip
+   the bus resources which have already been assigned (that is,
+   have non-NULL parent resource). */
+static struct resource * __devinit
+find_free_bus_resource(struct pci_bus *bus, unsigned long type)
+{
+	int i;
+	struct resource *r;
+	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
+				  IORESOURCE_PREFETCH;
+
+	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
+		r = bus->resource[i];
+		if (r && (r->flags & type_mask) == type && !r->parent)
+			return r;
+	}
+	return NULL;
+}
+
 /* Sizing the IO windows of the PCI-PCI bridge is trivial,
    since these windows have 4K granularity and the IO ranges
    of non-bridge PCI devices are limited to 256 bytes.
@@ -192,15 +271,15 @@
 pbus_size_io(struct pci_bus *bus)
 {
 	struct pci_dev *dev;
-	struct resource *b_res = bus->resource[0];
+	struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
 	unsigned long size = 0, size1 = 0;
 
-	if (!(b_res->flags & IORESOURCE_IO))
-		return;
+	if (!b_res)
+ 		return;
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		int i;
-		
+
 		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 			struct resource *r = &dev->resource[i];
 			unsigned long r_size;
@@ -215,9 +294,6 @@
 			else
 				size1 += r_size;
 		}
-		/* ??? Reserve some resources for CardBus. */
-		if ((dev->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS)
-			size1 += 4*1024;
 	}
 /* To be fixed in 2.5: we should have sort of HAVE_ISA
    flag in the struct pci_bus. */
@@ -236,15 +312,17 @@
 
 /* Calculate the size of the bus and minimal alignment which
    guarantees that all child resources fit in this size. */
-static void __devinit
+static int __devinit
 pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
 {
 	struct pci_dev *dev;
 	unsigned long min_align, align, size;
 	unsigned long aligns[12];	/* Alignments from 1Mb to 2Gb */
 	int order, max_order;
-	struct resource *b_res = (type & IORESOURCE_PREFETCH) ?
-				 bus->resource[2] : bus->resource[1];
+	struct resource *b_res = find_free_bus_resource(bus, type);
+
+	if (!b_res)
+		return 0;
 
 	memset(aligns, 0, sizeof(aligns));
 	max_order = 0;
@@ -280,11 +358,6 @@
 			if (order > max_order)
 				max_order = order;
 		}
-		/* ??? Reserve some resources for CardBus. */
-		if ((dev->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
-			size += 1UL << 24;		/* 16 Mb */
-			aligns[24 - 20] += 1UL << 24;
-		}
 	}
 
 	align = 0;
@@ -301,38 +374,111 @@
 	size = ROUND_UP(size, min_align);
 	if (!size) {
 		b_res->flags = 0;
-		return;
+		return 1;
 	}
 	b_res->start = min_align;
 	b_res->end = size + min_align - 1;
+	return 1;
+}
+
+static void __devinit
+pci_bus_size_cardbus(struct pci_bus *bus)
+{
+	struct pci_dev *bridge = bus->self;
+	struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
+	u16 ctrl;
+
+	/*
+	 * Reserve some resources for CardBus.  We reserve
+	 * a fixed amount of bus space for CardBus bridges.
+	 */
+	b_res[0].start = CARDBUS_IO_SIZE;
+	b_res[0].end = b_res[0].start + CARDBUS_IO_SIZE - 1;
+	b_res[0].flags |= IORESOURCE_IO;
+
+	b_res[1].start = CARDBUS_IO_SIZE;
+	b_res[1].end = b_res[1].start + CARDBUS_IO_SIZE - 1;
+	b_res[1].flags |= IORESOURCE_IO;
+
+	/*
+	 * Check whether prefetchable memory is supported
+	 * by this bridge.
+	 */
+	pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
+	if (!(ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0)) {
+		ctrl |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
+		pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl);
+		pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl);
+	}
+
+	/*
+	 * If we have prefetchable memory support, allocate
+	 * two regions.  Otherwise, allocate one region of
+	 * twice the size.
+	 */
+	if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) {
+		b_res[2].start = CARDBUS_MEM_SIZE;
+		b_res[2].end = b_res[2].start + CARDBUS_MEM_SIZE - 1;
+		b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
+
+		b_res[3].start = CARDBUS_MEM_SIZE;
+		b_res[3].end = b_res[3].start + CARDBUS_MEM_SIZE - 1;
+		b_res[3].flags |= IORESOURCE_MEM;
+	} else {
+		b_res[3].start = CARDBUS_MEM_SIZE * 2;
+		b_res[3].end = b_res[3].start + CARDBUS_MEM_SIZE * 2 - 1;
+		b_res[3].flags |= IORESOURCE_MEM;
+	}
 }
 
 void __devinit
 pci_bus_size_bridges(struct pci_bus *bus)
 {
-	struct pci_bus *b;
-	unsigned long mask, type;
+	struct pci_dev *dev;
+	unsigned long mask, prefmask;
 
-	list_for_each_entry(b, &bus->children, node) {
-		pci_bus_size_bridges(b);
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		struct pci_bus *b = dev->subordinate;
+		if (!b)
+			continue;
+
+		switch (dev->class >> 8) {
+		case PCI_CLASS_BRIDGE_CARDBUS:
+			pci_bus_size_cardbus(b);
+			break;
+
+		case PCI_CLASS_BRIDGE_PCI:
+		default:
+			pci_bus_size_bridges(b);
+			break;
+		}
 	}
 
 	/* The root bus? */
 	if (!bus->self)
 		return;
 
-	pci_bridge_check_ranges(bus);
-
-	pbus_size_io(bus);
-
-	mask = type = IORESOURCE_MEM;
-	/* If the bridge supports prefetchable range, size it separately. */
-	if (bus->resource[2] &&
-	    bus->resource[2]->flags & IORESOURCE_PREFETCH) {
-		pbus_size_mem(bus, IORESOURCE_PREFETCH, IORESOURCE_PREFETCH);
-		mask |= IORESOURCE_PREFETCH;	/* Size non-prefetch only. */
+	switch (bus->self->class >> 8) {
+	case PCI_CLASS_BRIDGE_CARDBUS:
+		/* don't size cardbuses yet. */
+		break;
+
+	case PCI_CLASS_BRIDGE_PCI:
+		pci_bridge_check_ranges(bus);
+	default:
+		pbus_size_io(bus);
+		/* If the bridge supports prefetchable range, size it
+		   separately. If it doesn't, or its prefetchable window
+		   has already been allocated by arch code, try
+		   non-prefetchable range for both types of PCI memory
+		   resources. */
+		mask = IORESOURCE_MEM;
+		prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+		if (pbus_size_mem(bus, prefmask, prefmask))
+			mask = prefmask; /* Success, size non-prefetch only. */
+		pbus_size_mem(bus, mask, IORESOURCE_MEM);
+		break;
 	}
-	pbus_size_mem(bus, mask, type);
 }
 EXPORT_SYMBOL(pci_bus_size_bridges);
 
@@ -351,9 +497,24 @@
 	}
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		b = dev->subordinate;
-		if (b) {
-			pci_bus_assign_resources(b);
+		if (!b)
+			continue;
+
+		pci_bus_assign_resources(b);
+
+		switch (dev->class >> 8) {
+		case PCI_CLASS_BRIDGE_PCI:
 			pci_setup_bridge(b);
+			break;
+
+		case PCI_CLASS_BRIDGE_CARDBUS:
+			pci_setup_cardbus(b);
+			break;
+
+		default:
+			printk(KERN_INFO "PCI: not setting up bridge %s "
+			       "for bus %d\n", dev->slot_name, b->number);
+			break;
 		}
 	}
 }
diff -Nru a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
--- a/drivers/pci/setup-res.c	Sun Mar 16 14:16:33 2003
+++ b/drivers/pci/setup-res.c	Sun Mar 23 14:25:41 2003
@@ -59,9 +59,8 @@
 		reg = dev->rom_base_reg;
 	} else {
 		/* Hmm, non-standard resource. */
-		printk("PCI: trying to set non-standard region %s/%d\n",
-		       dev->slot_name, resno);
-		return;
+		BUG();
+		return;		/* kill uninitialised var warning */
 	}
 
 	pci_write_config_dword(dev, reg, new);
@@ -141,7 +140,7 @@
 	if (ret) {
 		printk(KERN_ERR "PCI: Failed to allocate resource %d(%lx-%lx) for %s\n",
 		       resno, res->start, res->end, dev->slot_name);
-	} else {
+	} else if (resno < PCI_BRIDGE_RESOURCES) {
 		pci_update_resource(dev, res, resno);
 	}
 
diff -Nru a/drivers/pcmcia/bulkmem.c b/drivers/pcmcia/bulkmem.c
--- a/drivers/pcmcia/bulkmem.c	Sun Oct 13 17:23:15 2002
+++ b/drivers/pcmcia/bulkmem.c	Thu Mar 13 16:52:15 2003
@@ -31,8 +31,6 @@
     
 ======================================================================*/
 
-#define __NO_VERSION__
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
diff -Nru a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
--- a/drivers/pcmcia/cardbus.c	Sat Mar  1 10:23:13 2003
+++ b/drivers/pcmcia/cardbus.c	Thu Mar 13 16:52:15 2003
@@ -46,8 +46,6 @@
  */
 
 
-#define __NO_VERSION__
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
diff -Nru a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
--- a/drivers/pcmcia/cistpl.c	Sun Feb 23 02:23:58 2003
+++ b/drivers/pcmcia/cistpl.c	Thu Mar 13 16:52:15 2003
@@ -31,8 +31,6 @@
     
 ======================================================================*/
 
-#define __NO_VERSION__
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
diff -Nru a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
--- a/drivers/pcmcia/cs.c	Sun Feb 23 04:12:23 2003
+++ b/drivers/pcmcia/cs.c	Thu Mar 13 17:11:43 2003
@@ -895,6 +895,10 @@
 	c = &s->config[reg->Function];
     } else
 	c = CONFIG(handle);
+
+    if (c == NULL)
+	return CS_NO_CARD;
+
     if (!(c->state & CONFIG_LOCKED))
 	return CS_CONFIGURATION_LOCKED;
 
diff -Nru a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
--- a/drivers/pcmcia/ds.c	Sun Nov 17 23:09:46 2002
+++ b/drivers/pcmcia/ds.c	Sat Mar 22 07:54:06 2003
@@ -77,16 +77,8 @@
 
 /*====================================================================*/
 
-typedef struct driver_info_t {
-    dev_info_t		dev_info;
-    int			use_count, status;
-    dev_link_t		*(*attach)(void);
-    void		(*detach)(dev_link_t *);
-    struct driver_info_t *next;
-} driver_info_t;
-
 typedef struct socket_bind_t {
-    driver_info_t	*driver;
+    struct pcmcia_driver	*driver;
     u_char		function;
     dev_link_t		*instance;
     struct socket_bind_t *next;
@@ -124,9 +116,6 @@
 /* Device driver ID passed to Card Services */
 static dev_info_t dev_info = "Driver Services";
 
-/* Linked list of all registered device drivers */
-static driver_info_t *root_driver = NULL;
-
 static int sockets = 0, major_dev = -1;
 static socket_info_t *socket_table = NULL;
 
@@ -143,35 +132,66 @@
     pcmcia_report_error(handle, &err);
 }
 
-/*======================================================================
+/*======================================================================*/
+
+static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info);
+
+/**
+ * pcmcia_register_driver - register a PCMCIA driver with the bus core
+ *
+ * Registers a PCMCIA driver with the PCMCIA bus core.
+ */
+int pcmcia_register_driver(struct pcmcia_driver *driver)
+{
+	if (!driver)
+		return -EINVAL;
+
+ 	driver->use_count = 0;
+ 	driver->status = init_status;
+	driver->drv.bus = &pcmcia_bus_type;
+
+	return driver_register(&driver->drv);
+}
+EXPORT_SYMBOL(pcmcia_register_driver);
+
+/**
+ * pcmcia_unregister_driver - unregister a PCMCIA driver with the bus core
+ */
+void pcmcia_unregister_driver(struct pcmcia_driver *driver)
+{
+	socket_bind_t *b;
+	int i;
+
+	if (driver->use_count > 0) {
+		/* Blank out any left-over device instances */
+		driver->attach = NULL; driver->detach = NULL;
+		for (i = 0; i < sockets; i++)
+			for (b = socket_table[i].bind; b; b = b->next)
+				if (b->driver == driver) 
+					b->instance = NULL;
+ 	}
+
+	driver_unregister(&driver->drv);
+}
+EXPORT_SYMBOL(pcmcia_unregister_driver);
 
-    Register_pccard_driver() and unregister_pccard_driver() are used
-    tell Driver Services that a PC Card client driver is available to
-    be bound to sockets.
-    
-======================================================================*/
 
 int register_pccard_driver(dev_info_t *dev_info,
 			   dev_link_t *(*attach)(void),
 			   void (*detach)(dev_link_t *))
 {
-    driver_info_t *driver;
+    struct pcmcia_driver *driver;
     socket_bind_t *b;
     int i;
 
     DEBUG(0, "ds: register_pccard_driver('%s')\n", (char *)dev_info);
-    for (driver = root_driver; driver; driver = driver->next)
-	if (strncmp((char *)dev_info, (char *)driver->dev_info,
-		    DEV_NAME_LEN) == 0)
-	    break;
+    driver = get_pcmcia_driver(dev_info);
     if (!driver) {
-	driver = kmalloc(sizeof(driver_info_t), GFP_KERNEL);
+	driver = kmalloc(sizeof(struct pcmcia_driver), GFP_KERNEL);
 	if (!driver) return -ENOMEM;
-	strncpy(driver->dev_info, (char *)dev_info, DEV_NAME_LEN);
-	driver->use_count = 0;
-	driver->status = init_status;
-	driver->next = root_driver;
-	root_driver = driver;
+	memset(driver, 0, sizeof(struct pcmcia_driver));
+	driver->drv.name = (char *)dev_info;
+	pcmcia_register_driver(driver);
     }
 
     driver->attach = attach;
@@ -185,7 +205,7 @@
 	    b->instance = driver->attach();
 	    if (b->instance == NULL)
 		printk(KERN_NOTICE "ds: unable to create instance "
-		       "of '%s'!\n", driver->dev_info);
+		       "of '%s'!\n", driver->drv.name);
 	}
     
     return 0;
@@ -195,44 +215,45 @@
 
 int unregister_pccard_driver(dev_info_t *dev_info)
 {
-    driver_info_t *target, **d = &root_driver;
-    socket_bind_t *b;
-    int i;
-    
+    struct pcmcia_driver *driver;
+
     DEBUG(0, "ds: unregister_pccard_driver('%s')\n",
 	  (char *)dev_info);
-    while ((*d) && (strncmp((*d)->dev_info, (char *)dev_info,
-			    DEV_NAME_LEN) != 0))
-	d = &(*d)->next;
-    if (*d == NULL)
+
+    driver = get_pcmcia_driver(dev_info);
+    if (!driver)
 	return -ENODEV;
     
-    target = *d;
-    if (target->use_count == 0) {
-	*d = target->next;
-	kfree(target);
-    } else {
-	/* Blank out any left-over device instances */
-	target->attach = NULL; target->detach = NULL;
-	for (i = 0; i < sockets; i++)
-	    for (b = socket_table[i].bind; b; b = b->next)
-		if (b->driver == target) b->instance = NULL;
-    }
+    pcmcia_unregister_driver(driver);
+    kfree(driver);
     return 0;
 } /* unregister_pccard_driver */
 
 /*====================================================================*/
 
 #ifdef CONFIG_PROC_FS
+static int proc_read_drivers_callback(struct device_driver *driver, void *d)
+{
+	char **p = d;
+	struct pcmcia_driver *p_dev = container_of(driver, 
+						   struct pcmcia_driver, drv);
+
+	*p += sprintf(*p, "%-24.24s %d %d\n", driver->name, p_dev->status,
+		     p_dev->use_count);
+	d = (void *) p;
+
+	return 0;
+}
+
 static int proc_read_drivers(char *buf, char **start, off_t pos,
 			     int count, int *eof, void *data)
 {
-    driver_info_t *d;
-    char *p = buf;
-    for (d = root_driver; d; d = d->next)
-	p += sprintf(p, "%-24.24s %d %d\n", d->dev_info,
-		     d->status, d->use_count);
-    return (p - buf);
+	char *p = buf;
+
+	bus_for_each_drv(&pcmcia_bus_type, NULL, 
+			 (void *) &p, proc_read_drivers_callback);
+
+	return (p - buf);
 }
 #endif
 
@@ -376,7 +397,7 @@
 
 static int bind_request(int i, bind_info_t *bind_info)
 {
-    struct driver_info_t *driver;
+    struct pcmcia_driver *driver;
     socket_bind_t *b;
     bind_req_t bind_req;
     socket_info_t *s = &socket_table[i];
@@ -384,18 +405,13 @@
 
     DEBUG(2, "bind_request(%d, '%s')\n", i,
 	  (char *)bind_info->dev_info);
-    for (driver = root_driver; driver; driver = driver->next)
-	if (strcmp((char *)driver->dev_info,
-		   (char *)bind_info->dev_info) == 0)
-	    break;
+    driver = get_pcmcia_driver(&bind_info->dev_info);
     if (driver == NULL) {
-	driver = kmalloc(sizeof(driver_info_t), GFP_KERNEL);
+	driver = kmalloc(sizeof(struct pcmcia_driver), GFP_KERNEL);
 	if (!driver) return -ENOMEM;
-	strncpy(driver->dev_info, bind_info->dev_info, DEV_NAME_LEN);
-	driver->use_count = 0;
-	driver->next = root_driver;
-	driver->attach = NULL; driver->detach = NULL;
-	root_driver = driver;
+	memset(driver, 0, sizeof(struct pcmcia_driver));
+	driver->drv.name = bind_info->dev_info;
+	pcmcia_register_driver(driver);
     }
 
     for (b = s->bind; b; b = b->next)
@@ -409,7 +425,7 @@
 
     bind_req.Socket = i;
     bind_req.Function = bind_info->function;
-    bind_req.dev_info = &driver->dev_info;
+    bind_req.dev_info = (dev_info_t *) driver->drv.name;
     ret = pcmcia_bind_device(&bind_req);
     if (ret != CS_SUCCESS) {
 	cs_error(NULL, BindDevice, ret);
@@ -490,7 +506,7 @@
 #endif
 
     for (b = s->bind; b; b = b->next)
-	if ((strcmp((char *)b->driver->dev_info,
+	if ((strcmp((char *)b->driver->drv.name,
 		    (char *)bind_info->dev_info) == 0) &&
 	    (b->function == bind_info->function))
 	    break;
@@ -524,7 +540,7 @@
     DEBUG(2, "unbind_request(%d, '%s')\n", i,
 	  (char *)bind_info->dev_info);
     for (b = &s->bind; *b; b = &(*b)->next)
-	if ((strcmp((char *)(*b)->driver->dev_info,
+	if ((strcmp((char *)(*b)->driver->drv.name,
 		    (char *)bind_info->dev_info) == 0) &&
 	    ((*b)->function == bind_info->function))
 	    break;
@@ -536,14 +552,6 @@
     if (c->driver->detach) {
 	if (c->instance)
 	    c->driver->detach(c->instance);
-    } else {
-	if (c->driver->use_count == 0) {
-	    driver_info_t **d;
-	    for (d = &root_driver; *d; d = &((*d)->next))
-		if (c->driver == *d) break;
-	    *d = (*d)->next;
-	    kfree(c->driver);
-	}
     }
     *b = c->next;
     kfree(c);
@@ -881,7 +889,18 @@
 
 /*====================================================================*/
 
-int __init init_pcmcia_ds(void)
+struct bus_type pcmcia_bus_type = {
+	.name = "pcmcia",
+};
+EXPORT_SYMBOL(pcmcia_bus_type);
+
+static int __init init_pcmcia_bus(void)
+{
+	bus_register(&pcmcia_bus_type);
+	return 0;
+}
+
+static int __init init_pcmcia_ds(void)
 {
     client_reg_t client_reg;
     servinfo_t serv;
@@ -967,11 +986,8 @@
     return 0;
 }
 
-late_initcall(init_pcmcia_ds);
 
-#ifdef MODULE
-
-void __exit cleanup_module(void)
+static void __exit exit_pcmcia_ds(void)
 {
     int i;
 #ifdef CONFIG_PROC_FS
@@ -984,6 +1000,57 @@
 	pcmcia_deregister_client(socket_table[i].handle);
     sockets = 0;
     kfree(socket_table);
+    bus_unregister(&pcmcia_bus_type);
 }
 
+#ifdef MODULE
+
+/* init_pcmcia_bus must be done early, init_pcmcia_ds late. If we load this 
+ * as a module, we can only specify one initcall, though... 
+ */
+static int __init init_pcmcia_module(void) {
+	init_pcmcia_bus();
+	return init_pcmcia_ds();
+}
+module_init(init_pcmcia_module);
+
+#else /* !MODULE */
+subsys_initcall(init_pcmcia_bus);
+late_initcall(init_pcmcia_ds);
 #endif
+
+module_exit(exit_pcmcia_ds);
+
+
+/* helpers for backwards-compatible functions */
+
+/* backwards-compatible accessing of driver --- by name! */
+
+struct cmp_data {
+	void *dev_info;
+	struct pcmcia_driver *drv;
+};
+
+static int cmp_drv_callback(struct device_driver *drv, void *data)
+{
+	struct cmp_data *cmp = data;
+	if (strncmp((char *)cmp->dev_info, (char *)drv->name,
+		    DEV_NAME_LEN) == 0) {
+		cmp->drv = container_of(drv, struct pcmcia_driver, drv);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)
+{
+	int ret;
+	struct cmp_data cmp = {
+		.dev_info = dev_info,
+	};
+	
+	ret = bus_for_each_drv(&pcmcia_bus_type, NULL, &cmp, cmp_drv_callback);
+	if (ret)
+		return cmp.drv;
+	return NULL;
+}
diff -Nru a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
--- a/drivers/pcmcia/i82365.c	Tue Mar  4 22:35:34 2003
+++ b/drivers/pcmcia/i82365.c	Sat Mar 22 06:24:36 2003
@@ -1608,9 +1608,11 @@
 	return -1;
     }
     DEBUG(0, "%s\n", version);
+    if (driver_register(&i82365_driver))
+	return -1;
+
     printk(KERN_INFO "Intel PCIC probe: ");
     sockets = 0;
-    driver_register(&i82365_driver);
 
 #ifdef CONFIG_ISA
     isa_probe();
diff -Nru a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
--- a/drivers/pcmcia/rsrc_mgr.c	Fri Nov 15 14:35:45 2002
+++ b/drivers/pcmcia/rsrc_mgr.c	Thu Mar 13 16:52:15 2003
@@ -31,8 +31,6 @@
     
 ======================================================================*/
 
-#define __NO_VERSION__
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
diff -Nru a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
--- a/drivers/pcmcia/tcic.c	Tue Mar  4 22:35:34 2003
+++ b/drivers/pcmcia/tcic.c	Sat Mar 22 06:26:14 2003
@@ -408,7 +408,8 @@
 	return -1;
     }
 
-    driver_register(&tcic_driver);
+    if (driver_register(&tcic_driver))
+	return -1;
     
     printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
     sock = 0;
diff -Nru a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
--- a/drivers/pnp/isapnp/core.c	Sun Mar  9 15:37:55 2003
+++ b/drivers/pnp/isapnp/core.c	Tue Mar 18 09:02:48 2003
@@ -72,8 +72,13 @@
 MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
 MODULE_LICENSE("GPL");
 
+#ifdef CONFIG_X86_PC9800
+#define _PIDXR		0x259
+#define _PNPWRP		0xa59
+#else
 #define _PIDXR		0x279
 #define _PNPWRP		0xa79
+#endif
 
 /* short tags */
 #define _STAG_PNPVERNO		0x01
diff -Nru a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
--- a/drivers/pnp/pnpbios/core.c	Wed Feb 19 09:54:46 2003
+++ b/drivers/pnp/pnpbios/core.c	Thu Mar 20 10:13:07 2003
@@ -322,7 +322,7 @@
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
-	if ( !boot & pnpbios_dont_use_current_config )
+	if ( !boot && pnpbios_dont_use_current_config )
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0,
 			       nodenum, sizeof(char), data, 65536);
@@ -350,7 +350,7 @@
 	u16 status;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
-	if ( !boot & pnpbios_dont_use_current_config )
+	if ( !boot && pnpbios_dont_use_current_config )
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	status = call_pnp_bios(PNP_SET_SYS_DEV_NODE, nodenum, 0, PNP_TS1, boot ? 2 : 1, PNP_DS, 0, 0,
 			       data, 65536, 0, 0);
@@ -969,7 +969,7 @@
 
 	spin_lock_init(&pnp_bios_lock);
 
-	if(pnpbios_disabled) {
+	if(pnpbios_disabled || (dmi_broken & BROKEN_PNP_BIOS)) {
 		printk(KERN_INFO "PnPBIOS: Disabled\n");
 		return -ENODEV;
 	}
diff -Nru a/drivers/pnp/pnpbios/proc.c b/drivers/pnp/pnpbios/proc.c
--- a/drivers/pnp/pnpbios/proc.c	Thu Oct 17 13:28:27 2002
+++ b/drivers/pnp/pnpbios/proc.c	Thu Mar 13 16:52:26 2003
@@ -19,7 +19,6 @@
  */
 
 //#include <pcmcia/config.h>
-#define __NO_VERSION__
 //#include <pcmcia/k_compat.h>
 
 #include <linux/module.h>
diff -Nru a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
--- a/drivers/s390/block/dasd.c	Mon Feb 24 12:31:17 2003
+++ b/drivers/s390/block/dasd.c	Sat Mar 22 09:04:07 2003
@@ -174,11 +174,11 @@
 static inline int
 dasd_state_new_to_known(dasd_device_t *device)
 {
-	char buffer[10];
 	dasd_devmap_t *devmap;
 	umode_t devfs_perm;
 	devfs_handle_t dir;
 	int major, minor;
+	char buf[20];
 
 	/* Increase reference count of bdev. */
 	if (bdget(MKDEV(device->gdp->major, device->gdp->first_minor)) == NULL)
@@ -193,14 +193,15 @@
 	minor = devmap->devindex % DASD_PER_MAJOR;
 
 	/* Add a proc directory and the dasd device entry to devfs. */
- 	sprintf(buffer, "dasd/%04x", device->devno);
- 	dir = devfs_mk_dir(NULL, buffer, NULL);
+ 	dir = devfs_mk_dir("dasd/%04x", device->devno);
 	device->gdp->de = dir;
 	if (device->ro_flag)
 		devfs_perm = S_IFBLK | S_IRUSR;
 	else
 		devfs_perm = S_IFBLK | S_IRUSR | S_IWUSR;
-	device->devfs_entry = devfs_register(dir, "device", DEVFS_FL_DEFAULT,
+
+	snprintf(buf, sizeof(buf), "dasd/%04x/device", device->devno);
+	device->devfs_entry = devfs_register(NULL, buf, 0,
 					     major, minor << DASD_PARTN_BITS,
 					     devfs_perm,
 					     &dasd_device_operations, NULL);
@@ -2077,7 +2078,7 @@
 
 	DBF_EVENT(DBF_EMERG, "%s", "debug area created");
 
-	if (devfs_mk_dir(NULL, "dasd", NULL)) {
+	if (devfs_mk_dir("dasd")) {
 		DBF_EVENT(DBF_ALERT, "%s", "no devfs");
 		rc = -ENOSYS;
 		goto failed;
diff -Nru a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
--- a/drivers/s390/block/xpram.c	Sat Mar  8 14:50:22 2003
+++ b/drivers/s390/block/xpram.c	Sat Mar 22 07:38:05 2003
@@ -434,7 +434,7 @@
 	if (rc < 0)
 		goto out;
 
-	devfs_mk_dir(NULL, "slram", NULL);
+	devfs_mk_dir("slram");
 
 	/*
 	 * Assign the other needed values: make request function, sizes and
diff -Nru a/drivers/s390/char/tubfs.c b/drivers/s390/char/tubfs.c
--- a/drivers/s390/char/tubfs.c	Sun Nov 17 23:10:35 2002
+++ b/drivers/s390/char/tubfs.c	Sat Mar 22 09:04:07 2003
@@ -73,9 +73,8 @@
 		return -1;
 	}
 #ifdef CONFIG_DEVFS_FS
-	fs3270_devfs_dir = devfs_mk_dir(NULL, "3270", NULL);
-	fs3270_devfs_tub = 
-		devfs_register(fs3270_devfs_dir, "tub", DEVFS_FL_DEFAULT,
+	fs3270_devfs_dir = devfs_mk_dir("3270");
+	fs3270_devfs_tub = devfs_register(NULL, "3270/tub", 0,
 			       IBM_FS3270_MAJOR, 0,
 			       S_IFCHR | S_IRUGO | S_IWUGO, 
 			       &fs3270_fops, NULL);
diff -Nru a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
--- a/drivers/sbus/char/bpp.c	Sun Jan  5 22:09:38 2003
+++ b/drivers/sbus/char/bpp.c	Sat Mar 22 07:38:04 2003
@@ -1049,7 +1049,7 @@
 		instances[idx].opened = 0;
 		probeLptPort(idx);
 	}
-	devfs_mk_dir (NULL, "bpp", NULL);
+	devfs_mk_dir("bpp");
 	for (idx = 0; idx < BPP_NO; idx++) {
 		char name[16];
 		sprintf(name, "bpp/%d", idx);
diff -Nru a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
--- a/drivers/sbus/char/vfc_dev.c	Mon Dec  2 17:15:05 2002
+++ b/drivers/sbus/char/vfc_dev.c	Sat Mar 22 07:38:05 2003
@@ -681,7 +681,7 @@
 		kfree(vfc_dev_lst);
 		return -EIO;
 	}
-	devfs_mk_dir (NULL, "vfc", NULL);
+	devfs_mk_dir("vfc");
 	instance = 0;
 	for_all_sbusdev(sdev, sbus) {
 		if (strcmp(sdev->prom_name, "vfc") == 0) {
diff -Nru a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
--- a/drivers/scsi/3w-xxxx.c	Tue Feb 18 10:25:13 2003
+++ b/drivers/scsi/3w-xxxx.c	Sun Mar 23 07:52:56 2003
@@ -6,7 +6,7 @@
    		     Arnaldo Carvalho de Melo <acme@conectiva.com.br>
                      Brad Strand <linux@3ware.com>
 
-   Copyright (C) 1999-2002 3ware Inc.
+   Copyright (C) 1999-2003 3ware Inc.
 
    Kernel compatiblity By: 	Andre Hedrick <andre@suse.com>
    Non-Copyright (C) 2000	Andre Hedrick <andre@suse.com>
@@ -164,6 +164,11 @@
                  Add support for mode sense opcode.
                  Add support for cache mode page.
                  Add support for synchronize cache opcode.
+   1.02.00.032 - Fix small multicard rollcall bug.
+                 Make driver stay loaded with no units for hot add/swap.
+                 Add support for "twe" character device for ioctls.
+                 Clean up request_id queueing code.
+                 Fix tw_scsi_queue() spinlocks.
 */
 
 #include <linux/module.h>
@@ -203,6 +208,9 @@
 
 #include "3w-xxxx.h"
 
+static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+static int tw_chrdev_open(struct inode *inode, struct file *file);
+static int tw_chrdev_release(struct inode *inode, struct file *file);
 static int tw_copy_info(TW_Info *info, char *fmt, ...);
 static void tw_copy_mem_info(TW_Info *info, char *data, int len);
 static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
@@ -216,10 +224,19 @@
 	tw_halt, NULL, 0
 };
 
+/* File operations struct for character device */
+static struct file_operations tw_fops = {
+	owner: THIS_MODULE,
+	ioctl: tw_chrdev_ioctl,
+	open: tw_chrdev_open,
+	release: tw_chrdev_release
+};
+
 /* Globals */
-char *tw_driver_version="1.02.00.031";
+char *tw_driver_version="1.02.00.032";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
+static int twe_major = -1;
 
 /* Functions */
 
@@ -599,6 +616,192 @@
 	return 0;
 } /* End tw_check_errors() */
 
+/* This function handles ioctl for the character device */
+static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int error, request_id;
+	dma_addr_t dma_handle;
+	unsigned short tw_aen_code;
+	unsigned long before;
+	unsigned long flags;
+	unsigned int data_buffer_length = 0;
+	unsigned long data_buffer_length_adjusted = 0;
+	unsigned long *cpu_addr;
+	TW_New_Ioctl *tw_ioctl;
+	TW_Passthru *passthru;
+	TW_Device_Extension *tw_dev = tw_device_extension_list[minor(inode->i_rdev)];
+	int retval = -EFAULT;
+
+	dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n");
+
+	/* Only let one of these through at a time */
+	if (down_interruptible(&tw_dev->ioctl_sem))
+		return -EINTR;
+
+	/* First copy down the buffer length */
+	error = copy_from_user(&data_buffer_length, (void *)arg, sizeof(unsigned int));
+	if (error)
+		goto out;
+
+	/* Check size */
+	if (data_buffer_length > TW_MAX_SECTORS * 512) {
+		retval = -EINVAL;
+		goto out;
+	}
+
+	/* Hardware can only do multiple of 512 byte transfers */
+	data_buffer_length_adjusted = (data_buffer_length + 511) & ~511;
+	
+	/* Now allocate ioctl buf memory */
+	cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle);
+	if (cpu_addr == NULL) {
+		retval = -ENOMEM;
+		goto out;
+	}
+
+	tw_ioctl = (TW_New_Ioctl *)cpu_addr;
+
+	/* Now copy down the entire ioctl */
+	error = copy_from_user(tw_ioctl, (void *)arg, data_buffer_length + sizeof(TW_New_Ioctl) - 1);
+	if (error)
+		goto out2;
+
+	passthru = (TW_Passthru *)&tw_ioctl->firmware_command;
+
+	/* See which ioctl we are doing */
+	switch (cmd) {
+		case TW_OP_NOP:
+			dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_OP_NOP.\n");
+			break;
+		case TW_OP_AEN_LISTEN:
+			dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_AEN_LISTEN.\n");
+			memset(tw_ioctl->data_buffer, 0, tw_ioctl->data_buffer_length);
+
+			spin_lock_irqsave(&tw_dev->host->host_lock, flags);
+			if (tw_dev->aen_head == tw_dev->aen_tail) {
+				tw_aen_code = TW_AEN_QUEUE_EMPTY;
+			} else {
+				tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
+				if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
+					tw_dev->aen_head = TW_Q_START;
+				} else {
+					tw_dev->aen_head = tw_dev->aen_head + 1;
+				}
+			}
+			spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
+			memcpy(tw_ioctl->data_buffer, &tw_aen_code, sizeof(tw_aen_code));
+			break;
+		case TW_CMD_PACKET_WITH_DATA:
+			dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");
+			spin_lock_irqsave(&tw_dev->tw_lock, flags);
+
+			tw_state_request_start(tw_dev, &request_id);
+
+			/* Flag internal command */
+			tw_dev->srb[request_id] = 0;
+
+			/* Flag chrdev ioctl */
+			tw_dev->chrdev_request_id = request_id;
+
+			tw_ioctl->firmware_command.request_id = request_id;
+
+			/* Load the sg list */
+			switch (tw_ioctl->firmware_command.byte0.sgl_offset) {
+			case 2:
+				tw_ioctl->firmware_command.byte8.param.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
+				tw_ioctl->firmware_command.byte8.param.sgl[0].length = data_buffer_length_adjusted;
+				break;
+			case 3:
+				tw_ioctl->firmware_command.byte8.io.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
+				tw_ioctl->firmware_command.byte8.io.sgl[0].length = data_buffer_length_adjusted;
+				break;
+			case 5:
+				passthru->sg_list[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
+				passthru->sg_list[0].length = data_buffer_length_adjusted;
+				break;
+			}
+
+			memcpy(tw_dev->command_packet_virtual_address[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command));
+
+			/* Now post the command packet to the controller */
+			tw_post_command_packet(tw_dev, request_id);
+			spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
+
+			/* Now wait for the command to complete */
+			before = jiffies;
+
+			while (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) 
+			{
+				/* FIXME: race condition on the wait*/
+				interruptible_sleep_on_timeout(&tw_dev->ioctl_wqueue, 1);
+				if (time_after(jiffies, before + HZ *TW_IOCTL_CHRDEV_TIMEOUT)) {
+					/* Now we need to reset the board */
+					printk(KERN_WARNING "3w-xxxx: scsi%d: Character ioctl (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, cmd);
+					spin_lock_irqsave(&tw_dev->tw_lock, flags);
+					tw_dev->state[request_id] = TW_S_COMPLETED;
+					tw_state_request_finish(tw_dev, request_id);
+					tw_dev->posted_request_count--;
+					if (tw_reset_device_extension(tw_dev)) {
+						printk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no);
+					}
+					spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
+					if (signal_pending(current))
+						retval = -EINTR;
+					else
+						retval = -EIO;
+					goto out2;
+				}
+			}
+
+			/* Now copy in the command packet response */
+			memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
+
+			/* Now complete the io */
+			spin_lock_irqsave(&tw_dev->tw_lock, flags);
+			tw_dev->posted_request_count--;
+			tw_dev->state[request_id] = TW_S_COMPLETED;
+			tw_state_request_finish(tw_dev, request_id);
+			spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
+			break;
+		default:
+			retval = -ENOTTY;
+			goto out2;
+	}
+
+	/* Now copy the response to userspace */
+	error = copy_to_user((void *)arg, tw_ioctl, sizeof(TW_New_Ioctl) + tw_ioctl->data_buffer_length - 1);
+	if (error == 0)
+		retval = 0;
+out2:
+	/* Now free ioctl buf memory */
+	pci_free_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);
+out:
+	up(&tw_dev->ioctl_sem);
+	return retval;
+} /* End tw_chrdev_ioctl() */
+
+/* This function handles open for the character device */
+static int tw_chrdev_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor_number;
+
+	dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
+
+	minor_number = minor(inode->i_rdev);
+	if (minor_number >= tw_device_extension_count)
+		return -ENODEV;
+
+	return 0;
+} /* End tw_chrdev_open() */
+
+/* This function handles close for the character device */
+static int tw_chrdev_release(struct inode *inode, struct file *file)
+{
+	dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_release()\n");
+
+	return 0;
+} /* End tw_chrdev_release() */
+
 /* This function will clear all interrupts on the controller */
 void tw_clear_all_interrupts(TW_Device_Extension *tw_dev)
 {
@@ -833,6 +1036,8 @@
 				continue;
 			}
 			memset(tw_dev, 0, sizeof(TW_Device_Extension));
+			
+			init_MUTEX(&tw_dev->ioctl_sem);
 
 			/* Save pci_dev struct to device extension */
 			tw_dev->tw_pci_dev = tw_pci_dev;
@@ -867,7 +1072,9 @@
 
 			/* Disable interrupts on the card */
 			tw_disable_interrupts(tw_dev);
-			
+
+			tries = 0;
+
 			while (tries < TW_MAX_RESET_TRIES) {
 				/* Do soft reset */
 				tw_soft_reset(tw_dev);
@@ -897,8 +1104,8 @@
 				continue;
 			}
 
-			/* Make sure that io region isn't already taken */
-			if (check_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE)) {
+			/* Reserve the io address space */
+			if (!request_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE, TW_DEVICE_NAME)) {
 				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't get io range 0x%lx-0x%lx for card %d.\n", 
 				       (tw_dev->tw_pci_dev->resource[0].start), 
 				       (tw_dev->tw_pci_dev->resource[0].start) + 
@@ -907,16 +1114,10 @@
 				kfree(tw_dev);
 				continue;
 			}
-    
-			/* Reserve the io address space */
-			request_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE, TW_DEVICE_NAME);
+
 			error = tw_initialize_units(tw_dev);
 			if (error) {
 				printk(KERN_WARNING "3w-xxxx: No valid units for for card %d.\n", j);
-				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
-				tw_free_device_extension(tw_dev);
-				kfree(tw_dev);
-				continue;
 			}
 
 			error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
@@ -935,7 +1136,7 @@
 			if (tw_dev->num_units > 0) {
 				/* Use SHT cmd_per_lun here */
 				tw_dev->free_head = TW_Q_START;
-				tw_dev->free_tail = TW_Q_LENGTH - 1;
+				tw_dev->free_tail = TW_Q_START;
 				tw_dev->free_wrap = TW_Q_LENGTH - 1;
 			}
 
@@ -992,13 +1193,7 @@
 			/* Tell the firmware we support shutdown notification*/
 			error = tw_setfeature(tw_dev2, 2, 1, &c);
 			if (error) {
-				printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Error setting features for card %d.\n", j);
-				scsi_unregister(host);
-				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
-				tw_free_device_extension(tw_dev);
-				kfree(tw_dev);
-				numcards--;
-				continue;
+				printk(KERN_WARNING "3w-xxxx: Unable to set features for card %d, old firmware or card.\n", j);
 			}
 
 			/* Now setup the interrupt handler */
@@ -1023,10 +1218,14 @@
 		}
 	}
 
-	if (numcards == 0) 
-		printk(KERN_WARNING "3w-xxxx: No cards with valid units found.\n");
-	else
-	  register_reboot_notifier(&tw_notifier);
+	if (numcards == 0) {
+		printk(KERN_WARNING "3w-xxxx: No cards found.\n");
+	} else {
+		register_reboot_notifier(&tw_notifier);
+		if ((twe_major = register_chrdev (0, "twe", &tw_fops)) < 0) {
+			printk(KERN_WARNING "3w-xxxx: Unable to register \"twe\" character device, error = %d.\n", twe_major);
+		}
+	}
 
 	return numcards;
 } /* End tw_findcards() */
@@ -1153,6 +1352,8 @@
 	tw_dev->pending_head = TW_Q_START;
 	tw_dev->pending_tail = TW_Q_START;
 	spin_lock_init(&tw_dev->tw_lock);
+	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
+	init_waitqueue_head(&tw_dev->ioctl_wqueue);
 
 	return 0;
 } /* End tw_initialize_device_extension() */
@@ -1395,9 +1596,14 @@
 				/* Check for internal command completion */
 				if (tw_dev->srb[request_id] == 0) {
 					dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
-					retval = tw_aen_complete(tw_dev, request_id);
-					if (retval) {
-						printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
+					/* Check for chrdev ioctl completion */
+					if (request_id != tw_dev->chrdev_request_id) {
+						retval = tw_aen_complete(tw_dev, request_id);
+						if (retval) {
+							printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
+						}
+					} else {
+						tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
 					}
 				} else {
 				switch (tw_dev->srb[request_id]->cmnd[0]) {
@@ -1409,6 +1615,10 @@
 					case WRITE_6:
 						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10/WRITE_6\n");
 						break;
+					case TEST_UNIT_READY:
+						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TEST_UNIT_READY\n");
+						error = tw_scsiop_test_unit_ready_complete(tw_dev, request_id);
+						break;
 					case INQUIRY:
 						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
 						error = tw_scsiop_inquiry_complete(tw_dev, request_id);
@@ -2070,12 +2280,13 @@
 		tw_dev->state[i] = TW_S_INITIAL;
 	}
 	tw_dev->free_head = TW_Q_START;
-	tw_dev->free_tail = TW_Q_LENGTH - 1;
+	tw_dev->free_tail = TW_Q_START;
 	tw_dev->posted_request_count = 0;
 	tw_dev->pending_request_count = 0;
 	tw_dev->pending_head = TW_Q_START;
 	tw_dev->pending_tail = TW_Q_START;
 	tw_dev->reset_print = 0;
+	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
 
 	return 0;
 } /* End tw_reset_device_extension() */
@@ -2357,7 +2568,6 @@
 	unsigned char *command = SCpnt->cmnd;
 	int request_id = 0;
 	int error = 0;
-	unsigned long flags = 0;
 	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
 
 	if (tw_dev == NULL) {
@@ -2367,14 +2577,14 @@
 		return 0;
 	}
 
-	spin_lock_irqsave(&tw_dev->tw_lock, flags);
+	spin_lock(&tw_dev->tw_lock);
 	dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue()\n");
 
 	/* Skip scsi command if it isn't for us */
-	if ((tw_dev->is_unit_present[SCpnt->device->id] == FALSE) || (SCpnt->device->lun != 0)) {
+	if ((SCpnt->device->channel != 0) || (SCpnt->device->lun != 0)) {
 		SCpnt->result = (DID_BAD_TARGET << 16);
 		done(SCpnt);
-		spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
+		spin_unlock(&tw_dev->tw_lock);
 		return 0;
 	}
 	
@@ -2387,6 +2597,9 @@
 	/* Save the scsi command for use by the ISR */
 	tw_dev->srb[request_id] = SCpnt;
 
+	/* Initialize phase to zero */
+	SCpnt->SCp.phase = 0;
+
 	switch (*command) {
 		case READ_10:
 		case READ_6:
@@ -2436,7 +2649,7 @@
 		SCpnt->result = (DID_ERROR << 16);
 		done(SCpnt);
 	}
-	spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
+	spin_unlock(&tw_dev->tw_lock);
 
 	return 0;
 } /* End tw_scsi_queue() */
@@ -2460,6 +2673,12 @@
 	/* Free up the IRQ */
 	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
 
+	/* Unregister character device */
+	if (twe_major >= 0) {
+		unregister_chrdev(twe_major, "twe");
+		twe_major = -1;
+	}
+
 	/* Free up device extension resources */
 	tw_free_device_extension(tw_dev);
 
@@ -2533,7 +2752,6 @@
 {
 	unsigned char *is_unit_present;
 	unsigned char *request_buffer;
-	int i;
 	TW_Param *param;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
@@ -2545,12 +2763,12 @@
 	}
 	request_buffer = tw_dev->srb[request_id]->request_buffer;
 	memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
-	request_buffer[0] = TYPE_DISK;									 /* Peripheral device type */
-	request_buffer[1] = 0;													 /* Device type modifier */
-	request_buffer[2] = 0;													 /* No ansi/iso compliance */
-	request_buffer[4] = 31;													/* Additional length */
+	request_buffer[0] = TYPE_DISK; /* Peripheral device type */
+	request_buffer[1] = 0;	       /* Device type modifier */
+	request_buffer[2] = 0;	       /* No ansi/iso compliance */
+	request_buffer[4] = 31;	       /* Additional length */
 	memcpy(&request_buffer[8], "3ware   ", 8);	 /* Vendor ID */
-	memcpy(&request_buffer[16], "3w-xxxx         ", 16); /* Product ID */
+	sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
 	memcpy(&request_buffer[32], tw_driver_version, 3);
 
 	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
@@ -2560,15 +2778,12 @@
 	}
 	is_unit_present = &(param->data[0]);
 
-	for (i=0 ; i<TW_MAX_UNITS; i++) {
-		if (is_unit_present[i] == 0) {
-			tw_dev->is_unit_present[i] = FALSE;
-		} else {
-		  if (is_unit_present[i] & TW_UNIT_ONLINE) {
-			tw_dev->is_unit_present[i] = TRUE;
-			dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete: Unit %d found.\n", i);
-		  }
-		}
+	if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
+		tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = TRUE;
+	} else {
+		tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = FALSE;
+		tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
+		return TW_ISR_DONT_RESULT;
 	}
 
 	return 0;
@@ -2946,17 +3161,88 @@
 /* This function will handle test unit ready scsi command */
 int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
 {
+	TW_Param *param;
+	TW_Command *command_packet;
+	unsigned long command_que_value;
+	u32 command_que_addr;
+	unsigned long param_value;
+
 	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
 
-	/* Tell the scsi layer were done */
-	tw_dev->state[request_id] = TW_S_COMPLETED;
-	tw_state_request_finish(tw_dev, request_id);
-	tw_dev->srb[request_id]->result = (DID_OK << 16);
-	tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+	/* Initialize command packet */
+	command_que_addr = tw_dev->registers.command_que_addr;
+	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+	if (command_packet == NULL) {
+		printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet virtual address.\n");
+		return 1;
+	}
+	memset(command_packet, 0, sizeof(TW_Sector));
+	command_packet->byte0.opcode = TW_OP_GET_PARAM;
+	command_packet->byte0.sgl_offset = 2;
+	command_packet->size = 4;
+	command_packet->request_id = request_id;
+	command_packet->byte3.unit = 0;
+	command_packet->byte3.host_id = 0;
+	command_packet->status = 0;
+	command_packet->flags = 0;
+	command_packet->byte6.parameter_count = 1;
+
+	/* Now setup the param */
+	if (tw_dev->alignment_virtual_address[request_id] == NULL) {
+		printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment virtual address.\n");
+		return 1;
+	}
+	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+	memset(param, 0, sizeof(TW_Sector));
+	param->table_id = 3;	 /* unit summary table */
+	param->parameter_id = 3; /* unitsstatus parameter */
+	param->parameter_size_bytes = TW_MAX_UNITS;
+	param_value = tw_dev->alignment_physical_address[request_id];
+	if (param_value == 0) {
+		printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment physical address.\n");
+		return 1;
+	}
+
+	command_packet->byte8.param.sgl[0].address = param_value;
+	command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
+	command_que_value = tw_dev->command_packet_physical_address[request_id];
+	if (command_que_value == 0) {
+		printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet physical address.\n");
+		return 1;
+	}
+
+	/* Now try to post the command packet */
+	tw_post_command_packet(tw_dev, request_id);
 
 	return 0;
 } /* End tw_scsiop_test_unit_ready() */
 
+/* This function is called by the isr to complete a testunitready command */
+int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id)
+{
+	unsigned char *is_unit_present;
+	TW_Param *param;
+
+	dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete()\n");
+
+	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+	if (param == NULL) {
+		printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete(): Bad alignment virtual address.\n");
+		return 1;
+	}
+	is_unit_present = &(param->data[0]);
+
+	if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
+		tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = TRUE;
+	} else {
+		tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = FALSE;
+		tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
+		return TW_ISR_DONT_RESULT;
+	}
+
+	return 0;
+} /* End tw_scsiop_test_unit_ready_complete() */
+
 /* Set a value in the features table */
 int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
                   unsigned char *val)
@@ -3091,17 +3377,13 @@
 {
 	dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish()\n");
   
-	do {    
-		if (tw_dev->free_tail == tw_dev->free_wrap) {
-			tw_dev->free_tail = TW_Q_START;
-		} else {
-			tw_dev->free_tail = tw_dev->free_tail + 1;
-		}
-	} while ((tw_dev->state[tw_dev->free_queue[tw_dev->free_tail]] != TW_S_COMPLETED));
-
 	tw_dev->free_queue[tw_dev->free_tail] = request_id;
-
 	tw_dev->state[request_id] = TW_S_FINISHED;
+	if (tw_dev->free_tail == tw_dev->free_wrap)
+		tw_dev->free_tail = TW_Q_START;
+	else
+		tw_dev->free_tail++;
+
 	dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish(): Freeing request_id %d\n", request_id);
 
 	return 0;
@@ -3115,20 +3397,16 @@
 	dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start()\n");
 	
 	/* Obtain next free request_id */
-	do {
-		if (tw_dev->free_head == tw_dev->free_wrap) {
-			tw_dev->free_head = TW_Q_START;
-		} else {
-			tw_dev->free_head = tw_dev->free_head + 1;
-		}
-	} while (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] & TW_START_MASK);
-
 	id = tw_dev->free_queue[tw_dev->free_head];
+	if (tw_dev->free_head == tw_dev->free_wrap)
+		tw_dev->free_head = TW_Q_START;
+	else
+		tw_dev->free_head++;
 
-	dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start(): id = %d.\n", id);
 	*request_id = id;
 	tw_dev->state[id] = TW_S_STARTED;
 
+	dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start(): id = %d.\n", id);
 	return 0;
 } /* End tw_state_request_start() */
 
diff -Nru a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
--- a/drivers/scsi/3w-xxxx.h	Tue Feb 18 10:25:13 2003
+++ b/drivers/scsi/3w-xxxx.h	Sat Mar 22 12:19:28 2003
@@ -6,7 +6,7 @@
    		     Arnaldo Carvalho de Melo <acme@conectiva.com.br>
                      Brad Strand <linux@3ware.com>
 
-   Copyright (C) 1999-2002 3ware Inc.
+   Copyright (C) 1999-2003 3ware Inc.
 
    Kernel compatiblity By:	Andre Hedrick <andre@suse.com>
    Non-Copyright (C) 2000	Andre Hedrick <andre@suse.com>
@@ -113,11 +113,11 @@
   {0x84, 0x0b, 0x47, 0x00}, // Data CRC error               SCSI parity error
   {0xd0, 0x0b, 0x00, 0x00}, // Device busy                  Aborted command
   {0xd1, 0x0b, 0x00, 0x00}, // Device busy                  Aborted command
+  {0x37, 0x02, 0x04, 0x00}, // Unit offline                 Not ready
 
   /* Codes for older firmware */
                             // 3ware Error                  SCSI Error
   {0x09, 0x0b, 0x00, 0x00}, // Unrecovered disk error       Aborted command
-  {0x37, 0x0b, 0x04, 0x00}, // Unit offline                 Logical unit not ready
   {0x51, 0x0b, 0x00, 0x00}  // Unspecified                  Aborted command
 };
 
@@ -219,18 +219,23 @@
 #define TW_MAX_PCI_BUSES		      255
 #define TW_MAX_RESET_TRIES		      3
 #define TW_UNIT_INFORMATION_TABLE_BASE	      0x300
-#define TW_MAX_CMDS_PER_LUN		      255
+#define TW_MAX_CMDS_PER_LUN		      254 /* 254 for io, 1 for
+                                                     chrdev ioctl, one for
+                                                     internal aen post */
 #define TW_BLOCK_SIZE			      0x200 /* 512-byte blocks */
 #define TW_IOCTL                              0x80
 #define TW_UNIT_ONLINE                        1
 #define TW_IN_INTR                            1
 #define TW_IN_IOCTL                           2
+#define TW_IN_CHRDEV_IOCTL                    3
 #define TW_MAX_SECTORS                        256
 #define TW_AEN_WAIT_TIME                      1000
 #define TW_IOCTL_WAIT_TIME                    (1 * HZ) /* 1 second */
 #define TW_ISR_DONT_COMPLETE                  2
 #define TW_ISR_DONT_RESULT                    3
 #define TW_IOCTL_TIMEOUT                      25 /* 25 seconds */
+#define TW_IOCTL_CHRDEV_TIMEOUT               25 /* 25 seconds */
+#define TW_IOCTL_CHRDEV_FREE                  -1
 
 /* Macros */
 #define TW_STATUS_ERRORS(x) \
@@ -246,6 +251,8 @@
 #define dprintk(msg...) do { } while(0)
 #endif
 
+#pragma pack(1)
+
 /* Scatter Gather List Entry */
 typedef struct TAG_TW_SG_Entry {
 	u32 address;
@@ -295,6 +302,8 @@
 	} byte8;
 } TW_Command;
 
+#pragma pack()
+
 typedef struct TAG_TW_Ioctl {
 	unsigned char opcode;
 	unsigned short table_id;
@@ -304,6 +313,16 @@
 	unsigned char data[1];
 } TW_Ioctl;
 
+#pragma pack(1)
+
+/* Structure for new chardev ioctls */
+typedef struct TAG_TW_New_Ioctl {
+	unsigned int data_buffer_length;
+	unsigned char padding [508];
+	TW_Command firmware_command;
+	char data_buffer[1];
+} TW_New_Ioctl;
+
 /* GetParam descriptor */
 typedef struct {
 	unsigned short	table_id;
@@ -406,6 +425,7 @@
 	u32			aen_count;
 	struct Scsi_Host	*host;
 	spinlock_t		tw_lock;
+	struct semaphore	ioctl_sem;
 	int		        ioctl_size[TW_Q_LENGTH];
 	unsigned short		aen_queue[TW_Q_LENGTH];
 	unsigned char		aen_head;
@@ -414,8 +434,12 @@
 	unsigned long		*ioctl_data[TW_Q_LENGTH];
 	int			reset_print;
 	char                    online;
+	volatile int		chrdev_request_id;
+	wait_queue_head_t	ioctl_wqueue;
 } TW_Device_Extension;
 
+#pragma pack()
+
 /* Function prototypes */
 int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id);
 int tw_aen_drain_queue(TW_Device_Extension *tw_dev);
@@ -463,6 +487,7 @@
 int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id);
+int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id);
 int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size, 
 		  unsigned char *val);
 int tw_setup_irq(TW_Device_Extension *tw_dev);
@@ -483,9 +508,10 @@
 	.eh_abort_handler	= tw_scsi_eh_abort,	\
 	.eh_host_reset_handler	= tw_scsi_eh_reset,	\
 	.bios_param	= tw_scsi_biosparam,		\
-	.can_queue	= TW_Q_LENGTH-1,		\
+	.can_queue	= TW_Q_LENGTH-2,		\
 	.this_id	= -1,				\
 	.sg_tablesize	= TW_MAX_SGL_LENGTH,		\
+	.max_sectors    = TW_MAX_SECTORS,		\
 	.cmd_per_lun	= TW_MAX_CMDS_PER_LUN,		\
 	.present	= 0,				\
 	.unchecked_isa_dma	= 0,			\
diff -Nru a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c
--- a/drivers/scsi/53c7xx.c	Tue Feb 18 10:44:43 2003
+++ b/drivers/scsi/53c7xx.c	Thu Feb 13 08:12:27 2003
@@ -1463,9 +1463,9 @@
     patch_abs_32 (hostdata->script, 0, test_src, 
 	virt_to_bus(&hostdata->test_source));
     patch_abs_32 (hostdata->script, 0, saved_dsa,
-	virt_to_bus(&hostdata->saved2_dsa));
+	virt_to_bus((void *)&hostdata->saved2_dsa));
     patch_abs_32 (hostdata->script, 0, emulfly,
-	virt_to_bus(&hostdata->emulated_intfly));
+	virt_to_bus((void *)&hostdata->emulated_intfly));
 
     patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect, 
 	(unsigned char)(Ent_dsa_code_check_reselect - Ent_dsa_zero));
@@ -1759,7 +1759,7 @@
 static void 
 NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) {
     Scsi_Cmnd *c = cmd->cmd;
-    struct Scsi_Host *host = c->host;
+    struct Scsi_Host *host = c->device->host;
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
     	host->hostdata[0];
     int i;
@@ -1784,18 +1784,18 @@
      */
 
     patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-    	dsa_temp_lun, c->lun);
+    	dsa_temp_lun, c->device->lun);
     patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
 	dsa_temp_addr_next, virt_to_bus(&cmd->dsa_next_addr));
     patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
     	dsa_temp_next, virt_to_bus(cmd->dsa) + Ent_dsa_zero -
 	Ent_dsa_code_template + A_dsa_next);
     patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32), 
-    	dsa_temp_sync, virt_to_bus((void *)hostdata->sync[c->target].script));
+    	dsa_temp_sync, virt_to_bus((void *)hostdata->sync[c->device->id].script));
     patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32), 
-    	dsa_sscf_710, virt_to_bus((void *)&hostdata->sync[c->target].sscf_710));
+    	dsa_sscf_710, virt_to_bus((void *)&hostdata->sync[c->device->id].sscf_710));
     patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
-    	    dsa_temp_target, 1 << c->target);
+    	    dsa_temp_target, 1 << c->device->id);
     /* XXX - new pointer stuff */
     patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
     	dsa_temp_addr_saved_pointer, virt_to_bus(&cmd->saved_data_pointer));
@@ -1856,7 +1856,7 @@
 static void 
 abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
     Scsi_Cmnd *c = cmd->cmd;
-    struct Scsi_Host *host = c->host;
+    struct Scsi_Host *host = c->device->host;
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
     	host->hostdata[0];
     unsigned long flags;
@@ -1940,7 +1940,7 @@
 	    host->host_no, c->pid);
     else if (linux_search) {
 	*linux_prev = linux_search->next;
-	--hostdata->busy[c->target][c->lun];
+	--hostdata->busy[c->device->id][c->device->lun];
     }
 
     /* Return the NCR command structure to the free list */
@@ -2287,9 +2287,9 @@
 	    hostdata->dsp_changed = 1;
 	    if (cmd && (cmd->flags & CMD_FLAG_SDTR)) {
 		printk ("scsi%d : target %d rejected SDTR\n", host->host_no, 
-		    c->target);
+		    c->device->id);
 		cmd->flags &= ~CMD_FLAG_SDTR;
-		asynchronous (host, c->target);
+		asynchronous (host, c->device->id);
 		print = 0;
 	    } 
 	    break;
@@ -2311,7 +2311,7 @@
 	if (print) {
 	    printk ("scsi%d : received message", host->host_no);
 	    if (c) 
-	    	printk (" from target %d lun %d ", c->target, c->lun);
+	    	printk (" from target %d lun %d ", c->device->id, c->device->lun);
 	    print_msg ((unsigned char *) hostdata->msg_buf);
 	    printk("\n");
 	}
@@ -2331,7 +2331,7 @@
 
 	if (cmd) {
 	    char buf[80];
-	    sprintf (buf, "scsi%d : target %d %s ", host->host_no, c->target,
+	    sprintf (buf, "scsi%d : target %d %s ", host->host_no, c->device->id,
 		(cmd->flags & CMD_FLAG_SDTR) ? "accepting" : "requesting");
 	    print_synchronous (buf, (unsigned char *) hostdata->msg_buf);
 
@@ -2346,10 +2346,10 @@
 	    if (cmd->flags & CMD_FLAG_SDTR) {
 		cmd->flags &= ~CMD_FLAG_SDTR; 
 		if (hostdata->msg_buf[4]) 
-		    synchronous (host, c->target, (unsigned char *) 
+		    synchronous (host, c->device->id, (unsigned char *) 
 		    	hostdata->msg_buf);
 		else 
-		    asynchronous (host, c->target);
+		    asynchronous (host, c->device->id);
 		hostdata->dsp = hostdata->script + hostdata->E_accept_message /
 		    sizeof(u32);
 		hostdata->dsp_changed = 1;
@@ -2357,11 +2357,11 @@
 	    } else {
 		if (hostdata->options & OPTION_SYNCHRONOUS)  {
 		    cmd->flags |= CMD_FLAG_DID_SDTR;
-		    synchronous (host, c->target, (unsigned char *) 
+		    synchronous (host, c->device->id, (unsigned char *) 
 			hostdata->msg_buf);
 		} else {
 		    hostdata->msg_buf[4] = 0;		/* 0 offset = async */
-		    asynchronous (host, c->target);
+		    asynchronous (host, c->device->id);
 		}
 		patch_dsa_32 (cmd->dsa, dsa_msgout_other, 0, 5);
 		patch_dsa_32 (cmd->dsa, dsa_msgout_other, 1, (u32) 
@@ -2545,9 +2545,9 @@
 		    host->host_no, NCR53c7x0_read8(SXFER_REG));
 	    if (c) {
 		print_insn (host, (u32 *) 
-		    hostdata->sync[c->target].script, "", 1);
+		    hostdata->sync[c->device->id].script, "", 1);
 		print_insn (host, (u32 *) 
-		    hostdata->sync[c->target].script + 2, "", 1);
+		    hostdata->sync[c->device->id].script + 2, "", 1);
 	    }
 	}
     	return SPECIFIC_INT_RESTART;
@@ -2658,7 +2658,7 @@
 	if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
 	    if (c)
 		printk("scsi%d : target %d lun %d disconnecting\n", 
-		    host->host_no, c->target, c->lun);
+		    host->host_no, c->device->id, c->device->lun);
 	    else
 		printk("scsi%d : unknown target disconnecting\n",
 		    host->host_no);
@@ -2680,9 +2680,9 @@
 #endif
 	    if (c) {
 		print_insn (host, (u32 *) 
-		    hostdata->sync[c->target].script, "", 1);
+		    hostdata->sync[c->device->id].script, "", 1);
 		print_insn (host, (u32 *) 
-		    hostdata->sync[c->target].script + 2, "", 1);
+		    hostdata->sync[c->device->id].script + 2, "", 1);
 	    }
 	}
 	return SPECIFIC_INT_RESTART;
@@ -2734,8 +2734,8 @@
 	    if ((hostdata->chip / 100) == 8) {
 		scntl3 = NCR53c7x0_read8 (SCNTL3_REG_800);
 		if (c) {
-		  if (sxfer != hostdata->sync[c->target].sxfer_sanity ||
-		    scntl3 != hostdata->sync[c->target].scntl3_sanity) {
+		  if (sxfer != hostdata->sync[c->device->id].sxfer_sanity ||
+		    scntl3 != hostdata->sync[c->device->id].scntl3_sanity) {
 		   	printk ("scsi%d :  sync sanity check failed sxfer=0x%x, scntl3=0x%x",
 			    host->host_no, sxfer, scntl3);
 			NCR53c7x0_write8 (SXFER_REG, sxfer);
@@ -2746,12 +2746,12 @@
 		    host->host_no, (int) sxfer, (int) scntl3);
 	    } else {
 		if (c) {
-		  if (sxfer != hostdata->sync[c->target].sxfer_sanity) {
+		  if (sxfer != hostdata->sync[c->device->id].sxfer_sanity) {
 		   	printk ("scsi%d :  sync sanity check failed sxfer=0x%x",
 			    host->host_no, sxfer);
 			NCR53c7x0_write8 (SXFER_REG, sxfer);
 			NCR53c7x0_write8 (SBCL_REG,
-				hostdata->sync[c->target].sscf_710);
+				hostdata->sync[c->device->id].sscf_710);
 		    }
 		} else 
     	    	  printk ("scsi%d : unknown command sxfer=0x%x\n",
@@ -2807,9 +2807,9 @@
 			(DCMD_REG)) == hostdata->script + 
 		    	Ent_select_check_dsa / sizeof(u32) ?
 		    "selection" : "reselection";
-		if (c && sdid != c->target) {
+		if (c && sdid != c->device->id) {
 		    printk ("scsi%d : SDID target %d != DSA target %d at %s\n",
-			host->host_no, sdid, c->target, where);
+			host->host_no, sdid, c->device->id, where);
 		    print_lots(host);
 		    dump_events (host, 20);
 		    return SPECIFIC_INT_PANIC;
@@ -2855,7 +2855,7 @@
 		if (event->event == EVENT_RESELECT)
 		    event->lun = hostdata->reselected_identify & 0xf;
 		else if (c)
-		    event->lun = c->lun;
+		    event->lun = c->device->lun;
 		else
 		    event->lun = 255;
 		do_gettimeofday(&(event->time));
@@ -3049,7 +3049,7 @@
 
 static struct NCR53c7x0_cmd *
 allocate_cmd (Scsi_Cmnd *cmd) {
-    struct Scsi_Host *host = cmd->host;
+    struct Scsi_Host *host = cmd->device->host;
     struct NCR53c7x0_hostdata *hostdata = 
 	(struct NCR53c7x0_hostdata *) host->hostdata[0];
     u32 real;			/* Real address */
@@ -3061,8 +3061,8 @@
 	printk ("scsi%d : num_cmds = %d, can_queue = %d\n"
 		"         target = %d, lun = %d, %s\n",
 	    host->host_no, hostdata->num_cmds, host->can_queue,
-	    cmd->target, cmd->lun, (hostdata->cmd_allocated[cmd->target] &
-		(1 << cmd->lun)) ? "already allocated" : "not allocated");
+	    cmd->device->id, cmd->device->lun, (hostdata->cmd_allocated[cmd->device->id] &
+		(1 << cmd->device->lun)) ? "already allocated" : "not allocated");
 
 /*
  * If we have not yet reserved commands for this I_T_L nexus, and
@@ -3070,11 +3070,11 @@
  * being allocated under 1.3.x, or being outside of scan_scsis in
  * 1.2.x), do so now.
  */
-    if (!(hostdata->cmd_allocated[cmd->target] & (1 << cmd->lun)) &&
+    if (!(hostdata->cmd_allocated[cmd->device->id] & (1 << cmd->device->lun)) &&
 				cmd->device && cmd->device->has_cmdblocks) {
       if ((hostdata->extra_allocate + hostdata->num_cmds) < host->can_queue)
           hostdata->extra_allocate += host->cmd_per_lun;
-      hostdata->cmd_allocated[cmd->target] |= (1 << cmd->lun);
+      hostdata->cmd_allocated[cmd->device->id] |= (1 << cmd->device->lun);
     }
 
     for (; hostdata->extra_allocate > 0 ; --hostdata->extra_allocate, 
@@ -3130,7 +3130,7 @@
     local_irq_restore(flags);
     if (!tmp)
 	printk ("scsi%d : can't allocate command for target %d lun %d\n",
-	    host->host_no, cmd->target, cmd->lun);
+	    host->host_no, cmd->device->id, cmd->device->lun);
     return tmp;
 }
 
@@ -3150,7 +3150,7 @@
 static struct NCR53c7x0_cmd *
 create_cmd (Scsi_Cmnd *cmd) {
     NCR53c7x0_local_declare();
-    struct Scsi_Host *host = cmd->host;
+    struct Scsi_Host *host = cmd->device->host;
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
         host->hostdata[0];	
     struct NCR53c7x0_cmd *tmp; 	/* NCR53c7x0_cmd structure for this command */
@@ -3166,7 +3166,7 @@
 #endif
     unsigned long flags;
     u32 exp_select_indirect;	/* Used in sanity check */
-    NCR53c7x0_local_setup(cmd->host);
+    NCR53c7x0_local_setup(cmd->device->host);
 
     if (!(tmp = allocate_cmd (cmd)))
 	return NULL;
@@ -3322,45 +3322,45 @@
 
     if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS) {
 
-	exp_select_indirect = ((1 << cmd->target) << 16) |
-			(hostdata->sync[cmd->target].sxfer_sanity << 8);
+	exp_select_indirect = ((1 << cmd->device->id) << 16) |
+			(hostdata->sync[cmd->device->id].sxfer_sanity << 8);
 
-	if (hostdata->sync[cmd->target].select_indirect != 
+	if (hostdata->sync[cmd->device->id].select_indirect !=
 				exp_select_indirect) {
 	    printk ("scsi%d :  sanity check failed select_indirect=0x%x\n",
-		host->host_no, hostdata->sync[cmd->target].select_indirect);
+		host->host_no, hostdata->sync[cmd->device->id].select_indirect);
 	    FATAL(host);
 
 	}
     }
 
     patch_dsa_32(tmp->dsa, dsa_select, 0,
-		hostdata->sync[cmd->target].select_indirect);
+		hostdata->sync[cmd->device->id].select_indirect);
 
     /*
      * Right now, we'll do the WIDE and SYNCHRONOUS negotiations on
      * different commands; although it should be trivial to do them
      * both at the same time.
      */
-    if (hostdata->initiate_wdtr & (1 << cmd->target)) {
+    if (hostdata->initiate_wdtr & (1 << cmd->device->id)) {
 	memcpy ((void *) (tmp->select + 1), (void *) wdtr_message,
 	    sizeof(wdtr_message));
     	patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(wdtr_message));
 	local_irq_save(flags);
-	hostdata->initiate_wdtr &= ~(1 << cmd->target);
+	hostdata->initiate_wdtr &= ~(1 << cmd->device->id);
 	local_irq_restore(flags);
-    } else if (hostdata->initiate_sdtr & (1 << cmd->target)) {
+    } else if (hostdata->initiate_sdtr & (1 << cmd->device->id)) {
 	memcpy ((void *) (tmp->select + 1), (void *) sdtr_message, 
 	    sizeof(sdtr_message));
     	patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(sdtr_message));
 	tmp->flags |= CMD_FLAG_SDTR;
 	local_irq_save(flags);
-	hostdata->initiate_sdtr &= ~(1 << cmd->target);
+	hostdata->initiate_sdtr &= ~(1 << cmd->device->id);
 	local_irq_restore(flags);
     
     }
 #if 1
-    else if (!(hostdata->talked_to & (1 << cmd->target)) && 
+    else if (!(hostdata->talked_to & (1 << cmd->device->id)) &&
 		!(hostdata->options & OPTION_NO_ASYNC)) {
 
 	memcpy ((void *) (tmp->select + 1), (void *) async_message, 
@@ -3372,9 +3372,9 @@
     else 
     	patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1);
 
-    hostdata->talked_to |= (1 << cmd->target);
+    hostdata->talked_to |= (1 << cmd->device->id);
     tmp->select[0] = (hostdata->options & OPTION_DISCONNECT) ? 
-	IDENTIFY (1, cmd->lun) : IDENTIFY (0, cmd->lun);
+	IDENTIFY (1, cmd->device->lun) : IDENTIFY (0, cmd->device->lun);
     patch_dsa_32(tmp->dsa, dsa_msgout, 1, virt_to_bus(tmp->select));
     patch_dsa_32(tmp->dsa, dsa_cmdout, 0, cmd->cmd_len);
     patch_dsa_32(tmp->dsa, dsa_cmdout, 1, virt_to_bus(tmp->cmnd));
@@ -3591,7 +3591,7 @@
 
 int
 NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
-    struct Scsi_Host *host = cmd->host;
+    struct Scsi_Host *host = cmd->device->host;
     struct NCR53c7x0_hostdata *hostdata = 
 	(struct NCR53c7x0_hostdata *) host->hostdata[0];
     unsigned long flags;
@@ -3604,9 +3604,9 @@
 
 #ifdef VALID_IDS
     /* Ignore commands on invalid IDs */
-    if (!hostdata->valid_ids[cmd->target]) {
+    if (!hostdata->valid_ids[cmd->device->id]) {
         printk("scsi%d : ignoring target %d lun %d\n", host->host_no,
-            cmd->target, cmd->lun);
+            cmd->device->id, cmd->device->lun);
         cmd->result = (DID_BAD_TARGET << 16);
         done(cmd);
         return 0;
@@ -3616,16 +3616,16 @@
     local_irq_save(flags);
     if ((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY)) 
 	|| ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
-	    !(hostdata->debug_lun_limit[cmd->target] & (1 << cmd->lun))) 
+	    !(hostdata->debug_lun_limit[cmd->device->id] & (1 << cmd->device->lun)))
 #ifdef LINUX_1_2
-	|| cmd->target > 7
+	|| cmd->device->id > 7
 #else
-	|| cmd->target > host->max_id
+	|| cmd->device->id > host->max_id
 #endif
-	|| cmd->target == host->this_id
+	|| cmd->device->id == host->this_id
 	|| hostdata->state == STATE_DISABLED) {
 	printk("scsi%d : disabled or bad target %d lun %d\n", host->host_no,
-	    cmd->target, cmd->lun);
+	    cmd->device->id, cmd->device->lun);
 	cmd->result = (DID_BAD_TARGET << 16);
 	done(cmd);
 	local_irq_restore(flags);
@@ -3738,7 +3738,7 @@
 	--i, ncrcurrent += 2 /* JUMP instructions are two words */);
 
     if (i > 0) {
-	++hostdata->busy[tmp->target][tmp->lun];
+	++hostdata->busy[tmp->device->id][tmp->device->lun];
 	cmd->next = hostdata->running_list;
 	hostdata->running_list = cmd;
 
@@ -3799,7 +3799,7 @@
     /* FIXME : in the future, this needs to accommodate SCSI-II tagged
        queuing, and we may be able to play with fairness here a bit.
      */
-    return hostdata->busy[cmd->target][cmd->lun];
+    return hostdata->busy[cmd->device->id][cmd->device->lun];
 }
 
 /*
@@ -3873,7 +3873,7 @@
 			    if (tmp->host_scribble) {
 				if (hostdata->options & OPTION_DEBUG_QUEUES) 
 				    printk ("scsi%d : moving command for target %d lun %d to start list\n",
-					host->host_no, tmp->target, tmp->lun);
+					host->host_no, tmp->device->id, tmp->device->lun);
 		
 
 			    	to_schedule_list (host, hostdata, 
@@ -3937,7 +3937,7 @@
 	    printk ("scsi%d : Selection Timeout\n", host->host_no);
     	    if (cmd) {
     	    	printk("scsi%d : target %d, lun %d, command ",
-    	    	    host->host_no, cmd->cmd->target, cmd->cmd->lun);
+		    host->host_no, cmd->cmd->device->id, cmd->cmd->device->lun);
     	    	print_command (cmd->cmd->cmnd);
 		printk("scsi%d : dsp = 0x%x (virt 0x%p)\n", host->host_no,
 		    NCR53c7x0_read32(DSP_REG),
@@ -3975,7 +3975,7 @@
 	fatal = 1;
 	if (cmd) {
 	    printk("scsi%d : target %d lun %d unexpected disconnect\n",
-		host->host_no, cmd->cmd->target, cmd->cmd->lun);
+		host->host_no, cmd->cmd->device->id, cmd->cmd->device->lun);
 	    print_lots (host);
 	    abnormal_finished(cmd, DID_ERROR << 16);
 	} else 
@@ -3991,7 +3991,7 @@
 	fatal = 1;
 	if (cmd && cmd->cmd) {
 	    printk("scsi%d : target %d lun %d parity error.\n",
-		host->host_no, cmd->cmd->target, cmd->cmd->lun);
+		host->host_no, cmd->cmd->device->id, cmd->cmd->device->lun);
 	    abnormal_finished (cmd, DID_PARITY << 16); 
 	} else
 	    printk("scsi%d : parity error\n", host->host_no);
@@ -4199,7 +4199,7 @@
 	if (cmd_prev_ptr)
 	    *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next;
 
-	--hostdata->busy[tmp->target][tmp->lun];
+	--hostdata->busy[tmp->device->id][tmp->device->lun];
 	cmd->next = hostdata->free;
 	hostdata->free = cmd;
 
@@ -4207,7 +4207,7 @@
 
 	if (hostdata->options & OPTION_DEBUG_INTR) {
 	    printk ("scsi%d : command complete : pid %lu, id %d,lun %d result 0x%x ", 
-		  host->host_no, tmp->pid, tmp->target, tmp->lun, tmp->result);
+		  host->host_no, tmp->pid, tmp->device->id, tmp->device->lun, tmp->result);
 	    print_command (tmp->cmnd);
 	}
 
@@ -4292,8 +4292,8 @@
 	if (hostdata->options & OPTION_DEBUG_INTR) {
 	    if (cmd) {
 		printk("scsi%d : interrupt for pid %lu, id %d, lun %d ", 
-		    host->host_no, cmd->cmd->pid, (int) cmd->cmd->target,
-		    (int) cmd->cmd->lun);
+		    host->host_no, cmd->cmd->pid, (int) cmd->cmd->device->id,
+		    (int) cmd->cmd->device->lun);
 		print_command (cmd->cmd->cmnd);
 	    } else {
 		printk("scsi%d : no active command\n", host->host_no);
@@ -4671,7 +4671,7 @@
 	    hostdata->dsp = dsp + 2 /* two _words_ */;
 	    hostdata->dsp_changed = 1;
 	    printk ("scsi%d : target %d ignored SDTR and went into COMMAND OUT\n", 
-		host->host_no, cmd->cmd->target);
+		host->host_no, cmd->cmd->device->id);
 	    cmd->flags &= ~CMD_FLAG_SDTR;
 	    action = ACTION_CONTINUE;
 	    break;
@@ -5136,7 +5136,7 @@
 int 
 NCR53c7xx_abort (Scsi_Cmnd *cmd) {
     NCR53c7x0_local_declare();
-    struct Scsi_Host *host = cmd->host;
+    struct Scsi_Host *host = cmd->device->host;
     struct NCR53c7x0_hostdata *hostdata = host ? (struct NCR53c7x0_hostdata *) 
 	host->hostdata[0] : NULL;
     unsigned long flags;
@@ -5242,7 +5242,7 @@
 	    return SCSI_ABORT_NOT_RUNNING;
 	} else {
 	    printk ("scsi%d : DANGER : command running, can not abort.\n",
-		cmd->host->host_no);
+		cmd->device->host->host_no);
 	    local_irq_restore(flags);
 	    return SCSI_ABORT_BUSY;
 	}
@@ -5273,7 +5273,7 @@
  * command was ever counted as BUSY, so if we end up here we can
  * decrement the busy count if and only if it is necessary.
  */
-        --hostdata->busy[cmd->target][cmd->lun];
+        --hostdata->busy[cmd->device->id][cmd->device->lun];
     }
     local_irq_restore(flags);
     cmd->scsi_done(cmd);
@@ -5318,7 +5318,7 @@
      * each command.  
      */
     Scsi_Cmnd *nuke_list = NULL;
-    struct Scsi_Host *host = cmd->host;
+    struct Scsi_Host *host = cmd->device->host;
     struct NCR53c7x0_hostdata *hostdata = 
     	(struct NCR53c7x0_hostdata *) host->hostdata[0];
 
@@ -5388,7 +5388,7 @@
 static int 
 insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
     struct NCR53c7x0_hostdata *hostdata = 
-	(struct NCR53c7x0_hostdata *) cmd->host->hostdata[0];
+	(struct NCR53c7x0_hostdata *) cmd->device->host->hostdata[0];
     struct NCR53c7x0_cmd *ncmd = 
 	(struct NCR53c7x0_cmd *) cmd->host_scribble;
     int offset = 0, buffers;
@@ -5418,7 +5418,7 @@
     	    	     --buffers, offset += segment->length, ++segment)
 #if 0
 		    printk("scsi%d: comparing 0x%p to 0x%p\n", 
-			cmd->host->host_no, saved, page_address(segment->page+segment->offset);
+			cmd->device->host->host_no, saved, page_address(segment->page+segment->offset);
 #else
 		    ;
 #endif
@@ -5456,7 +5456,7 @@
     int offset, i;
     char *where;
     u32 *ptr;
-    NCR53c7x0_local_setup (cmd->host);
+    NCR53c7x0_local_setup (cmd->device->host);
 
     if (check_address ((unsigned long) ncmd,sizeof (struct NCR53c7x0_cmd)) == 0)
     {
@@ -5484,15 +5484,15 @@
 
 	if (offset != -1) 
 	    printk ("scsi%d : %s data pointer at offset %d\n",
-		cmd->host->host_no, where, offset);
+		cmd->device->host->host_no, where, offset);
 	else {
 	    int size;
 	    printk ("scsi%d : can't determine %s data pointer offset\n",
-		cmd->host->host_no, where);
+		cmd->device->host->host_no, where);
 	    if (ncmd) {
-		size = print_insn (cmd->host, 
+		size = print_insn (cmd->device->host,
 		    bus_to_virt(ncmd->saved_data_pointer), "", 1);
-		print_insn (cmd->host, 
+		print_insn (cmd->device->host,
 		    bus_to_virt(ncmd->saved_data_pointer) + size * sizeof(u32),
 		    "", 1);
 	    }
@@ -5549,7 +5549,7 @@
     /* XXX Maybe we should access cmd->host_scribble->result here. RGH */
     if (cmd) {
 	printk("               result = 0x%x, target = %d, lun = %d, cmd = ",
-	    cmd->result, cmd->target, cmd->lun);
+	    cmd->result, cmd->device->id, cmd->device->lun);
 	print_command(cmd->cmnd);
     } else
 	printk("\n");
@@ -5558,11 +5558,11 @@
     if (cmd) { 
 	printk("scsi%d target %d : sxfer_sanity = 0x%x, scntl3_sanity = 0x%x\n"
 	       "                   script : ",
-	    host->host_no, cmd->target,
-	    hostdata->sync[cmd->target].sxfer_sanity,
-	    hostdata->sync[cmd->target].scntl3_sanity);
-	for (i = 0; i < (sizeof(hostdata->sync[cmd->target].script) / 4); ++i)
-	    printk ("0x%x ", hostdata->sync[cmd->target].script[i]);
+	    host->host_no, cmd->device->id,
+	    hostdata->sync[cmd->device->id].sxfer_sanity,
+	    hostdata->sync[cmd->device->id].scntl3_sanity);
+	for (i = 0; i < (sizeof(hostdata->sync[cmd->device->id].script) / 4); ++i)
+	    printk ("0x%x ", hostdata->sync[cmd->device->id].script[i]);
 	printk ("\n");
     	print_progress (cmd);
     }
@@ -5604,7 +5604,7 @@
 		    -> dsa, "");
 	} else 
 	    printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n",
-		host->host_no, cmd->pid, cmd->target, cmd->lun);
+		host->host_no, cmd->pid, cmd->device->id, cmd->device->lun);
 	local_irq_restore(flags);
     }
 
diff -Nru a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
--- a/drivers/scsi/NCR53C9x.c	Mon Feb 24 10:09:58 2003
+++ b/drivers/scsi/NCR53C9x.c	Fri Feb 14 05:25:53 2003
@@ -1099,7 +1099,7 @@
 		 * disconnect.
 		 */
 		ESPMISC(("esp: Selecting device for first time. target=%d "
-			 "lun=%d\n", target, SCptr->lun));
+			 "lun=%d\n", target, SCptr->device->lun));
 		if(!SDptr->borken && !esp_dev->disconnect)
 			esp_dev->disconnect = 1;
 
@@ -1173,7 +1173,7 @@
 		if(((SDptr->scsi_level < 3) && (SDptr->type != TYPE_TAPE)) ||
 		   toshiba_cdrom_hwbug_wkaround || SDptr->borken) {
 			ESPMISC((KERN_INFO "esp%d: Disabling DISCONNECT for target %d "
-				 "lun %d\n", esp->esp_id, SCptr->target, SCptr->lun));
+				 "lun %d\n", esp->esp_id, SCptr->device->id, SCptr->device->lun));
 			esp_dev->disconnect = 0;
 			*cmdp++ = IDENTIFY(0, lun);
 		} else {
@@ -1255,8 +1255,8 @@
 		esp->dma_led_on(esp);
 
 	/* We use the scratch area. */
-	ESPQUEUE(("esp_queue: target=%d lun=%d ", SCpnt->target, SCpnt->lun));
-	ESPDISC(("N<%02x,%02x>", SCpnt->target, SCpnt->lun));
+	ESPQUEUE(("esp_queue: target=%d lun=%d ", SCpnt->device->id, SCpnt->lun));
+	ESPDISC(("N<%02x,%02x>", SCpnt->device->id, SCpnt->lun));
 
 	esp_get_dmabufs(esp, SCpnt);
 	esp_save_pointers(esp, SCpnt); /* FIXME for tag queueing */
@@ -2235,7 +2235,7 @@
 			 * state.
 			 */
 			ESPMISC(("esp: Status <%d> for target %d lun %d\n",
-				 SCptr->SCp.Status, SCptr->target, SCptr->lun));
+				 SCptr->SCp.Status, SCptr->device->id, SCptr->device->lun));
 
 			/* But don't do this when spinning up a disk at
 			 * boot time while we poll for completion as it
@@ -2246,14 +2246,14 @@
 			if(esp_should_clear_sync(SCptr) != 0)
 				esp_dev->sync = 0;
 		}
-		ESPDISC(("F<%02x,%02x>", SCptr->target, SCptr->lun));
+		ESPDISC(("F<%02x,%02x>", SCptr->device->id, SCptr->device->lun));
 		esp_done(esp, ((SCptr->SCp.Status & 0xff) |
 			       ((SCptr->SCp.Message & 0xff)<<8) |
 			       (DID_OK << 16)));
 	} else if(esp->prevmsgin == DISCONNECT) {
 		/* Normal disconnect. */
 		esp_cmd(esp, eregs, ESP_CMD_ESEL);
-		ESPDISC(("D<%02x,%02x>", SCptr->target, SCptr->lun));
+		ESPDISC(("D<%02x,%02x>", SCptr->device->id, SCptr->device->lun));
 		append_SC(&esp->disconnected_SC, SCptr);
 		esp->current_SC = NULL;
 		if(esp->issue_SC)
@@ -2811,7 +2811,7 @@
 			/* Else, there really isn't anyone there. */
 			ESPMISC(("esp: selection failure, maybe nobody there?\n"));
 			ESPMISC(("esp: target %d lun %d\n",
-				 SCptr->target, SCptr->lun));
+				 SCptr->device->id, SCptr->device->lun));
 			esp_done(esp, (DID_BAD_TARGET << 16));
 		}
 		return do_intr_end;
@@ -3084,7 +3084,7 @@
 			ESPSDTR(("soff=%2x stp=%2x cfg3=%2x\n",
 				esp_dev->sync_max_offset,
 				esp_dev->sync_min_period,
-				esp->config3[SCptr->target]));
+				esp->config3[SCptr->device->id]));
 
 			esp->snip = 0;
 		} else if(esp_dev->sync_max_offset) {
diff -Nru a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
--- a/drivers/scsi/a2091.c	Wed Nov 20 03:36:29 2002
+++ b/drivers/scsi/a2091.c	Thu Feb 13 08:14:20 2003
@@ -52,7 +52,7 @@
 {
     unsigned short cntr = CNTR_PDMD | CNTR_INTEN;
     unsigned long addr = virt_to_bus(cmd->SCp.ptr);
-    struct Scsi_Host *instance = cmd->host;
+    struct Scsi_Host *instance = cmd->device->host;
 
     /* don't allow DMA if the physical address is bad */
     if (addr & A2091_XFER_MASK ||
@@ -102,12 +102,12 @@
 	cntr |= CNTR_DDIR;
 
     /* remember direction */
-    HDATA(cmd->host)->dma_dir = dir_in;
+    HDATA(cmd->device->host)->dma_dir = dir_in;
 
-    DMA(cmd->host)->CNTR = cntr;
+    DMA(cmd->device->host)->CNTR = cntr;
 
     /* setup DMA *physical* address */
-    DMA(cmd->host)->ACR = addr;
+    DMA(cmd->device->host)->ACR = addr;
 
     if (dir_in){
 	/* invalidate any cache */
@@ -117,7 +117,7 @@
 	cache_push (addr, cmd->SCp.this_residual);
       }
     /* start DMA */
-    DMA(cmd->host)->ST_DMA = 1;
+    DMA(cmd->device->host)->ST_DMA = 1;
 
     /* return success */
     return 0;
diff -Nru a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c
--- a/drivers/scsi/a3000.c	Wed Nov 20 03:36:29 2002
+++ b/drivers/scsi/a3000.c	Thu Feb 27 07:08:11 2003
@@ -225,7 +225,7 @@
 
 #include "scsi_module.c"
 
-int __exit a3000_release(struct Scsi_Host *instance)
+int a3000_release(struct Scsi_Host *instance)
 {
     wd33c93_release();
     DMA(instance)->CNTR = 0;
diff -Nru a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
--- a/drivers/scsi/advansys.c	Wed Feb 12 13:59:26 2003
+++ b/drivers/scsi/advansys.c	Thu Mar  6 14:05:42 2003
@@ -7099,7 +7099,7 @@
          * then return the number of underrun bytes.
          */
         if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
-            qdonep->remain_bytes <= scp->request_bufflen != 0) {
+            qdonep->remain_bytes <= scp->request_bufflen) {
             ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
             (unsigned) qdonep->remain_bytes);
             scp->resid = qdonep->remain_bytes;
diff -Nru a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
--- a/drivers/scsi/aha152x.c	Wed Feb 26 19:02:59 2003
+++ b/drivers/scsi/aha152x.c	Thu Mar 13 16:54:01 2003
@@ -2651,7 +2651,7 @@
 
 static void datai_run(struct Scsi_Host *shpnt)
 {
-	unsigned int the_time;
+	unsigned long the_time;
 	int fifodata, data_count;
 
 	/*
@@ -2793,7 +2793,7 @@
 
 static void datao_run(struct Scsi_Host *shpnt)
 {
-	unsigned int the_time;
+	unsigned long the_time;
 	int data_count;
 
 	/* until phase changes or all data sent */
diff -Nru a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
--- a/drivers/scsi/aha1542.c	Tue Feb 25 11:50:51 2003
+++ b/drivers/scsi/aha1542.c	Thu Mar  6 14:15:12 2003
@@ -1020,7 +1020,7 @@
 
 static int __init do_setup(char *str)
 {
-	int ints[4];
+	int ints[5];
 
 	int count=setup_idx;
 
diff -Nru a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c
--- a/drivers/scsi/amiga7xx.c	Wed Nov 20 03:36:29 2002
+++ b/drivers/scsi/amiga7xx.c	Sun Feb  9 07:21:12 2003
@@ -86,7 +86,7 @@
 #ifdef CONFIG_WARPENGINE_SCSI
     	    case ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx:
 		if (request_mem_region(address+0x40000, 0x1000, "ncr53c710")) {
-		    address = (unsigned long)ioremap(address, size);
+		    address = (unsigned long)z_ioremap(address, size);
 		    options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 |
 			      OPTION_INTFLY | OPTION_SYNCHRONOUS |
 			      OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT;
@@ -102,7 +102,7 @@
 	    case ZORRO_PROD_CBM_A4091_1:
 	    case ZORRO_PROD_CBM_A4091_2:
 		if (request_mem_region(address+0x800000, 0x1000, "ncr53c710")) {
-		    address = (unsigned long)ioremap(address, size);
+		    address = (unsigned long)z_ioremap(address, size);
 		    options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 |
 			      OPTION_INTFLY | OPTION_SYNCHRONOUS |
 			      OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT;
diff -Nru a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
--- a/drivers/scsi/atari_NCR5380.c	Wed Feb 26 19:03:01 2003
+++ b/drivers/scsi/atari_NCR5380.c	Thu Feb 13 07:42:37 2003
@@ -266,7 +266,7 @@
 #define	NEXTADDR(cmd)	((Scsi_Cmnd **)&((cmd)->host_scribble))
 
 #define	HOSTNO		instance->host_no
-#define	H_NO(cmd)	(cmd)->host->host_no
+#define	H_NO(cmd)	(cmd)->device->host->host_no
 
 #ifdef SUPPORT_TAGS
 
@@ -350,17 +350,17 @@
 
 static int is_lun_busy( Scsi_Cmnd *cmd, int should_be_tagged )
 {
-    SETUP_HOSTDATA(cmd->host);
+    SETUP_HOSTDATA(cmd->device->host);
 
-    if (hostdata->busy[cmd->target] & (1 << cmd->lun))
+    if (hostdata->busy[cmd->device->id] & (1 << cmd->device->lun))
 	return( 1 );
     if (!should_be_tagged ||
 	!setup_use_tagged_queuing || !cmd->device->tagged_supported)
 	return( 0 );
-    if (TagAlloc[cmd->target][cmd->lun].nr_allocated >=
-	TagAlloc[cmd->target][cmd->lun].queue_size ) {
+    if (TagAlloc[cmd->device->id][cmd->device->lun].nr_allocated >=
+	TagAlloc[cmd->device->id][cmd->device->lun].queue_size ) {
 	TAG_PRINTK( "scsi%d: target %d lun %d: no free tags\n",
-		    H_NO(cmd), cmd->target, cmd->lun );
+		    H_NO(cmd), cmd->device->id, cmd->device->lun );
 	return( 1 );
     }
     return( 0 );
@@ -374,7 +374,7 @@
 
 static void cmd_get_tag( Scsi_Cmnd *cmd, int should_be_tagged )
 {
-    SETUP_HOSTDATA(cmd->host);
+    SETUP_HOSTDATA(cmd->device->host);
 
     /* If we or the target don't support tagged queuing, allocate the LUN for
      * an untagged command.
@@ -382,19 +382,19 @@
     if (!should_be_tagged ||
 	!setup_use_tagged_queuing || !cmd->device->tagged_supported) {
 	cmd->tag = TAG_NONE;
-	hostdata->busy[cmd->target] |= (1 << cmd->lun);
+	hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
 	TAG_PRINTK( "scsi%d: target %d lun %d now allocated by untagged "
-		    "command\n", H_NO(cmd), cmd->target, cmd->lun );
+		    "command\n", H_NO(cmd), cmd->device->id, cmd->device->lun );
     }
     else {
-	TAG_ALLOC *ta = &TagAlloc[cmd->target][cmd->lun];
+	TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
 
 	cmd->tag = find_first_zero_bit( ta->allocated, MAX_TAGS );
 	set_bit( cmd->tag, ta->allocated );
 	ta->nr_allocated++;
 	TAG_PRINTK( "scsi%d: using tag %d for target %d lun %d "
 		    "(now %d tags in use)\n",
-		    H_NO(cmd), cmd->tag, cmd->target, cmd->lun,
+		    H_NO(cmd), cmd->tag, cmd->device->id, cmd->device->lun,
 		    ta->nr_allocated );
     }
 }
@@ -406,23 +406,23 @@
 
 static void cmd_free_tag( Scsi_Cmnd *cmd )
 {
-    SETUP_HOSTDATA(cmd->host);
+    SETUP_HOSTDATA(cmd->device->host);
 
     if (cmd->tag == TAG_NONE) {
-	hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+	hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 	TAG_PRINTK( "scsi%d: target %d lun %d untagged cmd finished\n",
-		    H_NO(cmd), cmd->target, cmd->lun );
+		    H_NO(cmd), cmd->device->id, cmd->device->lun );
     }
     else if (cmd->tag >= MAX_TAGS) {
 	printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n",
 		H_NO(cmd), cmd->tag );
     }
     else {
-	TAG_ALLOC *ta = &TagAlloc[cmd->target][cmd->lun];
+	TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
 	clear_bit( cmd->tag, ta->allocated );
 	ta->nr_allocated--;
 	TAG_PRINTK( "scsi%d: freed tag %d for target %d lun %d\n",
-		    H_NO(cmd), cmd->tag, cmd->target, cmd->lun );
+		    H_NO(cmd), cmd->tag, cmd->device->id, cmd->device->lun );
     }
 }
 
@@ -811,7 +811,7 @@
     int i, s;
     unsigned char *command;
     SPRINTF("scsi%d: destination target %d, lun %d\n",
-	    H_NO(cmd), cmd->target, cmd->lun);
+	    H_NO(cmd), cmd->device->id, cmd->device->lun);
     SPRINTF("        command = ");
     command = cmd->cmnd;
     SPRINTF("%2d (0x%02x)", command[0], command[0]);
@@ -834,7 +834,7 @@
  * 
  */
 
-static void __init NCR5380_init (struct Scsi_Host *instance, int flags)
+static int NCR5380_init (struct Scsi_Host *instance, int flags)
 {
     int i;
     SETUP_HOSTDATA(instance);
@@ -878,6 +878,8 @@
     NCR5380_write(MODE_REG, MR_BASE);
     NCR5380_write(TARGET_COMMAND_REG, 0);
     NCR5380_write(SELECT_ENABLE_REG, 0);
+
+    return 0;
 }
 
 /* 
@@ -898,13 +900,10 @@
  *
  */
 
-/* Only make static if a wrapper function is used */
-#ifndef NCR5380_queue_command
 static
-#endif
 int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
-    SETUP_HOSTDATA(cmd->host);
+    SETUP_HOSTDATA(cmd->device->host);
     Scsi_Cmnd *tmp;
     int oldto;
     unsigned long flags;
@@ -938,15 +937,15 @@
 	    case WRITE:
 	    case WRITE_6:
 	    case WRITE_10:
-		hostdata->time_write[cmd->target] -= (jiffies - hostdata->timebase);
-		hostdata->bytes_write[cmd->target] += cmd->request_bufflen;
+		hostdata->time_write[cmd->device->id] -= (jiffies - hostdata->timebase);
+		hostdata->bytes_write[cmd->device->id] += cmd->request_bufflen;
 		hostdata->pendingw++;
 		break;
 	    case READ:
 	    case READ_6:
 	    case READ_10:
-		hostdata->time_read[cmd->target] -= (jiffies - hostdata->timebase);
-		hostdata->bytes_read[cmd->target] += cmd->request_bufflen;
+		hostdata->time_read[cmd->device->id] -= (jiffies - hostdata->timebase);
+		hostdata->bytes_read[cmd->device->id] += cmd->request_bufflen;
 		hostdata->pendingr++;
 		break;
 	}
@@ -1014,7 +1013,7 @@
     if (in_interrupt() || ((flags >> 8) & 7) >= 6)
 	queue_main();
     else
-	NCR5380_main();
+	NCR5380_main(NULL);
     return 0;
 }
 
@@ -1030,7 +1029,7 @@
  *  reenable them.  This prevents reentrancy and kernel stack overflow.
  */ 	
     
-static void NCR5380_main (void)
+static void NCR5380_main (void *bl)
 {
     Scsi_Cmnd *tmp, *prev;
     struct Scsi_Host *instance = first_instance;
@@ -1087,8 +1086,8 @@
 #if (NDEBUG & NDEBUG_LISTS)
 		if (prev != tmp)
 		    printk("MAIN tmp=%p   target=%d   busy=%d lun=%d\n",
-			   tmp, tmp->target, hostdata->busy[tmp->target],
-			   tmp->lun);
+			   tmp, tmp->device->id, hostdata->busy[tmp->device->id],
+			   tmp->device->lun);
 #endif
 		/*  When we find one, remove it from the issue queue. */
 		/* ++guenther: possible race with Falcon locking */
@@ -1096,7 +1095,7 @@
 #ifdef SUPPORT_TAGS
 		    !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE)
 #else
-		    !(hostdata->busy[tmp->target] & (1 << tmp->lun))
+		    !(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))
 #endif
 		    ) {
 		    /* ++guenther: just to be sure, this must be atomic */
@@ -1122,7 +1121,7 @@
 		     */
 		    MAIN_PRINTK("scsi%d: main(): command for target %d "
 				"lun %d removed from issue_queue\n",
-				HOSTNO, tmp->target, tmp->lun);
+				HOSTNO, tmp->device->id, tmp->device->lun);
 		    /* 
 		     * REQUEST SENSE commands are issued without tagged
 		     * queueing, even on SCSI-II devices because the 
@@ -1356,15 +1355,15 @@
 	    case WRITE:
 	    case WRITE_6:
 	    case WRITE_10:
-		hostdata->time_write[cmd->target] += (jiffies - hostdata->timebase);
-		/*hostdata->bytes_write[cmd->target] += cmd->request_bufflen;*/
+		hostdata->time_write[cmd->device->id] += (jiffies - hostdata->timebase);
+		/*hostdata->bytes_write[cmd->device->id] += cmd->request_bufflen;*/
 		hostdata->pendingw--;
 		break;
 	    case READ:
 	    case READ_6:
 	    case READ_10:
-		hostdata->time_read[cmd->target] += (jiffies - hostdata->timebase);
-		/*hostdata->bytes_read[cmd->target] += cmd->request_bufflen;*/
+		hostdata->time_read[cmd->device->id] += (jiffies - hostdata->timebase);
+		/*hostdata->bytes_read[cmd->device->id] += cmd->request_bufflen;*/
 		hostdata->pendingr--;
 		break;
 	}
@@ -1525,7 +1524,7 @@
      * the host and target ID's on the SCSI bus.
      */
 
-    NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->target)));
+    NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id)));
 
     /* 
      * Raise ATN while SEL is true before BSY goes false from arbitration,
@@ -1578,7 +1577,7 @@
 
     udelay(1);
 
-    SEL_PRINTK("scsi%d: selecting target %d\n", HOSTNO, cmd->target);
+    SEL_PRINTK("scsi%d: selecting target %d\n", HOSTNO, cmd->device->id);
 
     /* 
      * The SCSI specification calls for a 250 ms timeout for the actual 
@@ -1629,7 +1628,7 @@
 
     if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	if (hostdata->targets_present & (1 << cmd->target)) {
+	if (hostdata->targets_present & (1 << cmd->device->id)) {
 	    printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO);
 	    if (hostdata->restart_select)
 		printk(KERN_NOTICE "\trestart select\n");
@@ -1651,7 +1650,7 @@
 	return 0;
     } 
 
-    hostdata->targets_present |= (1 << cmd->target);
+    hostdata->targets_present |= (1 << cmd->device->id);
 
     /*
      * Since we followed the SCSI spec, and raised ATN while SEL 
@@ -1672,8 +1671,8 @@
     while (!(NCR5380_read(STATUS_REG) & SR_REQ));
 
     SEL_PRINTK("scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
-	       HOSTNO, cmd->target);
-    tmp[0] = IDENTIFY(1, cmd->lun);
+	       HOSTNO, cmd->device->id);
+    tmp[0] = IDENTIFY(1, cmd->device->lun);
 
 #ifdef SUPPORT_TAGS
     if (cmd->tag != TAG_NONE) {
@@ -1695,7 +1694,7 @@
     /* XXX need to handle errors here */
     hostdata->connected = cmd;
 #ifndef SUPPORT_TAGS
-    hostdata->busy[cmd->target] |= (1 << cmd->lun);
+    hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
 #endif    
 
     initialize_SCp(cmd);
@@ -2085,7 +2084,7 @@
 			 * polled-IO. */ 
 			printk(KERN_NOTICE "scsi%d: switching target %d "
 			       "lun %d to slow handshake\n", HOSTNO,
-			       cmd->target, cmd->lun);
+			       cmd->device->id, cmd->device->lun);
 			cmd->device->borken = 1;
 			NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
 			    ICR_ASSERT_ATN);
@@ -2137,7 +2136,7 @@
 		    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		    
 		    LNK_PRINTK("scsi%d: target %d lun %d linked command "
-			       "complete.\n", HOSTNO, cmd->target, cmd->lun);
+			       "complete.\n", HOSTNO, cmd->device->id, cmd->device->lun);
 
 		    /* Enable reselect interrupts */
 		    NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
@@ -2150,7 +2149,7 @@
 		    if (!cmd->next_link) {
 			 printk(KERN_NOTICE "scsi%d: target %d lun %d "
 				"linked command complete, no next_link\n",
-				HOSTNO, cmd->target, cmd->lun);
+				HOSTNO, cmd->device->id, cmd->device->lun);
 			    sink = 1;
 			    do_abort (instance);
 			    return;
@@ -2163,7 +2162,7 @@
 		    cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); 
 		    LNK_PRINTK("scsi%d: target %d lun %d linked request "
 			       "done, calling scsi_done().\n",
-			       HOSTNO, cmd->target, cmd->lun);
+			       HOSTNO, cmd->device->id, cmd->device->lun);
 #ifdef NCR5380_STATS
 		    collect_stats(hostdata, cmd);
 #endif
@@ -2179,7 +2178,7 @@
 		    falcon_dont_release++;
 		    hostdata->connected = NULL;
 		    QU_PRINTK("scsi%d: command for target %d, lun %d "
-			      "completed\n", HOSTNO, cmd->target, cmd->lun);
+			      "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
 #ifdef SUPPORT_TAGS
 		    cmd_free_tag( cmd );
 		    if (status_byte(cmd->SCp.Status) == QUEUE_FULL) {
@@ -2191,16 +2190,16 @@
 			 */
 			/* ++Andreas: the mid level code knows about
 			   QUEUE_FULL now. */
-			TAG_ALLOC *ta = &TagAlloc[cmd->target][cmd->lun];
+			TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
 			TAG_PRINTK("scsi%d: target %d lun %d returned "
 				   "QUEUE_FULL after %d commands\n",
-				   HOSTNO, cmd->target, cmd->lun,
+				   HOSTNO, cmd->device->id, cmd->device->lun,
 				   ta->nr_allocated);
 			if (ta->queue_size > ta->nr_allocated)
 			    ta->nr_allocated = ta->queue_size;
 		    }
 #else
-		    hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+		    hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 		    /* Enable reselect interrupts */
 		    NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
@@ -2296,12 +2295,12 @@
 			 * the command is treated as untagged further on.
 			 */
 			cmd->device->tagged_supported = 0;
-			hostdata->busy[cmd->target] |= (1 << cmd->lun);
+			hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
 			cmd->tag = TAG_NONE;
 			TAG_PRINTK("scsi%d: target %d lun %d rejected "
 				   "QUEUE_TAG message; tagged queuing "
 				   "disabled\n",
-				   HOSTNO, cmd->target, cmd->lun);
+				   HOSTNO, cmd->device->id, cmd->device->lun);
 			break;
 		    }
 		    break;
@@ -2318,7 +2317,7 @@
 		    QU_PRINTK("scsi%d: command for target %d lun %d was "
 			      "moved from connected to the "
 			      "disconnected_queue\n", HOSTNO, 
-			      cmd->target, cmd->lun);
+			      cmd->device->id, cmd->device->lun);
 		    /* 
 		     * Restore phase bits to 0 so an interrupted selection, 
 		     * arbitration can resume.
@@ -2417,13 +2416,13 @@
 		    } else if (tmp != EXTENDED_MESSAGE)
 			printk(KERN_DEBUG "scsi%d: rejecting unknown "
 			       "message %02x from target %d, lun %d\n",
-			       HOSTNO, tmp, cmd->target, cmd->lun);
+			       HOSTNO, tmp, cmd->device->id, cmd->device->lun);
 		    else
 			printk(KERN_DEBUG "scsi%d: rejecting unknown "
 			       "extended message "
 			       "code %02x, length %d from target %d, lun %d\n",
 			       HOSTNO, extended_msg[1], extended_msg[0],
-			       cmd->target, cmd->lun);
+			       cmd->device->id, cmd->device->lun);
    
 
 		    msgout = MESSAGE_REJECT;
@@ -2441,7 +2440,7 @@
 #ifdef SUPPORT_TAGS
 		    cmd_free_tag( cmd );
 #else
-		    hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+		    hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 		    hostdata->connected = NULL;
 		    cmd->result = DID_ERROR << 16;
@@ -2577,7 +2576,7 @@
 
     for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; 
 	 tmp; prev = tmp, tmp = NEXT(tmp) ) {
-	if ((target_mask == (1 << tmp->target)) && (lun == tmp->lun)
+	if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun)
 #ifdef SUPPORT_TAGS
 	    && (tag == tmp->tag) 
 #endif
@@ -2620,7 +2619,7 @@
 
     hostdata->connected = tmp;
     RSL_PRINTK("scsi%d: nexus established, target = %d, lun = %d, tag = %d\n",
-	       HOSTNO, tmp->target, tmp->lun, tmp->tag);
+	       HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag);
     falcon_dont_release--;
 }
 
@@ -2642,12 +2641,10 @@
  * 	 called where the loop started in NCR5380_main().
  */
 
-#ifndef NCR5380_abort
 static
-#endif
 int NCR5380_abort (Scsi_Cmnd *cmd)
 {
-    struct Scsi_Host *instance = cmd->host;
+    struct Scsi_Host *instance = cmd->device->host;
     SETUP_HOSTDATA(instance);
     Scsi_Cmnd *tmp, **prev;
     unsigned long flags;
@@ -2701,7 +2698,7 @@
 #ifdef SUPPORT_TAGS
 	  cmd_free_tag( cmd );
 #else
-	  hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+	  hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 	  local_irq_restore(flags);
 	  cmd->scsi_done(cmd);
@@ -2808,7 +2805,7 @@
 #ifdef SUPPORT_TAGS
 		    cmd_free_tag( tmp );
 #else
-		    hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+		    hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 		    local_irq_restore(flags);
 		    tmp->scsi_done(tmp);
@@ -2842,7 +2839,7 @@
 
 
 /* 
- * Function : int NCR5380_reset (Scsi_Cmnd *cmd, unsigned int reset_flags)
+ * Function : int NCR5380_reset (Scsi_Cmnd *cmd)
  * 
  * Purpose : reset the SCSI bus.
  *
@@ -2850,9 +2847,9 @@
  *
  */ 
 
-static int NCR5380_reset( Scsi_Cmnd *cmd, unsigned int reset_flags)
+static int NCR5380_bus_reset( Scsi_Cmnd *cmd)
 {
-    SETUP_HOSTDATA(cmd->host);
+    SETUP_HOSTDATA(cmd->device->host);
     int           i;
     unsigned long flags;
 #if 1
@@ -2863,7 +2860,7 @@
 	printk(KERN_ERR "scsi%d: !!BINGO!! Falcon has no lock in NCR5380_reset\n",
 	       H_NO(cmd) );
 
-    NCR5380_print_status (cmd->host);
+    NCR5380_print_status (cmd->device->host);
 
     /* get in phase */
     NCR5380_write( TARGET_COMMAND_REG,
diff -Nru a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
--- a/drivers/scsi/atari_scsi.c	Thu Nov  7 15:12:28 2002
+++ b/drivers/scsi/atari_scsi.c	Thu Feb 13 07:37:43 2003
@@ -819,11 +819,11 @@
 #endif
 }
 
-int atari_scsi_reset( Scsi_Cmnd *cmd, unsigned int reset_flags)
+int atari_scsi_bus_reset(Scsi_Cmnd *cmd)
 {
 	int		rv;
 	struct NCR5380_hostdata *hostdata =
-		(struct NCR5380_hostdata *)cmd->host->hostdata;
+		(struct NCR5380_hostdata *)cmd->device->host->hostdata;
 
 	/* For doing the reset, SCSI interrupts must be disabled first,
 	 * since the 5380 raises its IRQ line while _RST is active and we
@@ -845,7 +845,7 @@
 #endif /* REAL_DMA */
 	}
 
-	rv = NCR5380_reset(cmd, reset_flags);
+	rv = NCR5380_bus_reset(cmd);
 
 	/* Re-enable ints */
 	if (IS_A_TT()) {
@@ -1146,8 +1146,8 @@
 	.release		= atari_scsi_release,
 	.info			= atari_scsi_info,
 	.queuecommand		= atari_scsi_queue_command,
-	.abort			= atari_scsi_abort,
-	.reset			= atari_scsi_reset,
+	.eh_abort_handler	= atari_scsi_abort,
+	.eh_bus_reset_handler	= atari_scsi_bus_reset,
 	.can_queue		= 0, /* initialized at run-time */
 	.this_id		= 0, /* initialized at run-time */
 	.sg_tablesize		= 0, /* initialized at run-time */
diff -Nru a/drivers/scsi/atari_scsi.h b/drivers/scsi/atari_scsi.h
--- a/drivers/scsi/atari_scsi.h	Fri Dec 20 06:28:58 2002
+++ b/drivers/scsi/atari_scsi.h	Sun Feb  9 11:14:51 2003
@@ -18,10 +18,8 @@
 /* (I_HAVE_OVERRUNS stuff removed) */
 
 #ifndef ASM
-int atari_scsi_abort (Scsi_Cmnd *);
 int atari_scsi_detect (Scsi_Host_Template *);
 const char *atari_scsi_info (struct Scsi_Host *);
-int atari_scsi_queue_command (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 int atari_scsi_reset (Scsi_Cmnd *, unsigned int);
 int atari_scsi_proc_info (char *, char **, off_t, int, int, int);
 #ifdef MODULE
diff -Nru a/drivers/scsi/blz1230.c b/drivers/scsi/blz1230.c
--- a/drivers/scsi/blz1230.c	Mon Nov 18 09:39:38 2002
+++ b/drivers/scsi/blz1230.c	Wed Feb  5 09:05:18 2003
@@ -167,8 +167,8 @@
 		esp->eregs = eregs;
 
 		/* Set the command buffer */
-		esp->esp_command = (volatile unsigned char*) cmd_buffer;
-		esp->esp_command_dvma = virt_to_bus(cmd_buffer);
+		esp->esp_command = cmd_buffer;
+		esp->esp_command_dvma = virt_to_bus((void *)cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
 		esp->slot = board+REAL_BLZ1230_ESP_ADDR;
diff -Nru a/drivers/scsi/blz2060.c b/drivers/scsi/blz2060.c
--- a/drivers/scsi/blz2060.c	Mon Nov 18 09:39:45 2002
+++ b/drivers/scsi/blz2060.c	Wed Feb  5 09:04:51 2003
@@ -142,8 +142,8 @@
 		esp->eregs = (struct ESP_regs *)(address + BLZ2060_ESP_ADDR);
 		
 		/* Set the command buffer */
-		esp->esp_command = (volatile unsigned char*) cmd_buffer;
-		esp->esp_command_dvma = virt_to_bus(cmd_buffer);
+		esp->esp_command = cmd_buffer;
+		esp->esp_command_dvma = virt_to_bus((void *)cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
 		request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ,
diff -Nru a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c
--- a/drivers/scsi/cpqfcTSinit.c	Tue Feb 25 10:47:18 2003
+++ b/drivers/scsi/cpqfcTSinit.c	Thu Mar 13 16:43:25 2003
@@ -686,7 +686,7 @@
 	if( (vendor_cmd->rw_flag == VENDOR_READ_OPCODE) &&
 	     vendor_cmd->len )
         if(  copy_to_user( vendor_cmd->bufp, buf, vendor_cmd->len))
-		return( -EFAULT);
+		result = -EFAULT;
 
         if( buf) 
 	  kfree( buf);
diff -Nru a/drivers/scsi/cyberstorm.c b/drivers/scsi/cyberstorm.c
--- a/drivers/scsi/cyberstorm.c	Mon Nov 18 09:39:50 2002
+++ b/drivers/scsi/cyberstorm.c	Wed Feb  5 09:03:17 2003
@@ -168,8 +168,8 @@
 		esp->eregs = (struct ESP_regs *)(address + CYBER_ESP_ADDR);
 		
 		/* Set the command buffer */
-		esp->esp_command = (volatile unsigned char*) cmd_buffer;
-		esp->esp_command_dvma = virt_to_bus(cmd_buffer);
+		esp->esp_command = cmd_buffer;
+		esp->esp_command_dvma = virt_to_bus((void *)cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
 		request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ,
diff -Nru a/drivers/scsi/cyberstormII.c b/drivers/scsi/cyberstormII.c
--- a/drivers/scsi/cyberstormII.c	Mon Nov 18 09:39:58 2002
+++ b/drivers/scsi/cyberstormII.c	Wed Feb  5 09:03:44 2003
@@ -149,8 +149,8 @@
 		esp->eregs = eregs;
 		
 		/* Set the command buffer */
-		esp->esp_command = (volatile unsigned char*) cmd_buffer;
-		esp->esp_command_dvma = virt_to_bus(cmd_buffer);
+		esp->esp_command = cmd_buffer;
+		esp->esp_command_dvma = virt_to_bus((void *)cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
 		request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ,
diff -Nru a/drivers/scsi/fastlane.c b/drivers/scsi/fastlane.c
--- a/drivers/scsi/fastlane.c	Mon Nov 18 14:36:44 2002
+++ b/drivers/scsi/fastlane.c	Wed Feb  5 09:05:42 2003
@@ -191,8 +191,8 @@
 		esp->edev = (void *) address;
 		
 		/* Set the command buffer */
-		esp->esp_command = (volatile unsigned char*) cmd_buffer;
-		esp->esp_command_dvma = virt_to_bus(cmd_buffer);
+		esp->esp_command = cmd_buffer;
+		esp->esp_command_dvma = virt_to_bus((void *)cmd_buffer);
 
 		esp->irq = IRQ_AMIGA_PORTS;
 		esp->slot = board+FASTLANE_ESP_ADDR;
diff -Nru a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
--- a/drivers/scsi/gdth.c	Mon Feb 24 09:56:33 2003
+++ b/drivers/scsi/gdth.c	Thu Mar  6 15:11:01 2003
@@ -4,7 +4,7 @@
  * Intel Corporation:  Storage RAID Controllers                         *
  *                                                                      *
  * gdth.c                                                               *
- * Copyright (C) 1995-02 ICP vortex, an Intel company,  Achim Leubner   *
+ * Copyright (C) 1995-03 ICP vortex, an Intel company,  Achim Leubner   *
  * <achim.leubner@intel.com>                                            *
  *                                                                      *
  * Additions/Fixes: Boji Tony Kannanthanam                              *
@@ -24,11 +24,17 @@
  * 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.20, ..., 2.4.18                   *
+ * Tested with Linux 1.2.13, ..., 2.2.20, ..., 2.4.20                   *
  *                                                                      *
  * $Log: gdth.c,v $
- * Revision 1.61  2002/10/03 09:35:22  boji
- * Fixed SCREENSERVICE initialisation in SMP cases.
+ * Revision 1.62  2003/02/27 15:01:59  achim
+ * Dynamic DMA mapping implemented
+ * New (character device) IOCTL interface added
+ * Other controller related changes made
+ *
+ * Revision 1.61  2002/11/08 13:09:52  boji
+ * Added support for XSCALE based RAID Controllers
+ * Fixed SCREENSERVICE initialization in SMP cases
  * Added checks for gdth_polling before GDTH_HA_LOCK
  *
  * Revision 1.60  2002/02/05 09:35:22  achim
@@ -216,7 +222,7 @@
  *
  * Revision 1.9  1997/09/04 10:07:25  achim
  * IO-mapping with virt_to_bus(), gdth_readb(), gdth_writeb(), ...
- * register_reboot_notifier() to get a notify on shutdown used
+ * register_reboot_notifier() to get a notify on shutown used
  *
  * Revision 1.8  1997/04/02 12:14:30  achim
  * Version 1.00 (see gdth.h), tested with kernel 2.0.29
@@ -248,7 +254,7 @@
  * Initial revision
  *
  ************************************************************************/
-#ident "$Id: gdth.c,v 1.60 2002/02/05 09:35:22 achim Exp $" 
+#ident "$Id: gdth.c,v 1.62 2003/02/27 15:01:59 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
@@ -300,18 +306,21 @@
  */
 
 /* The meaning of the Scsi_Pointer members in this driver is as follows:
- * ptr:                         Chaining
- * this_residual:               Command priority
- * buffer:                      Unused
- * buffers_residual:            Timeout value
- * Status:                      Command status (gdth_do_cmd())
- * Message:                     Additional info (gdth_do_cmd())
- * have_data_in:                Flag for gdth_wait_completion()
- * sent_command:                Opcode special command
- * phase:                       Service/parameter/return code special command
+ * ptr:                     Chaining
+ * this_residual:           Command priority
+ * buffer:                  phys. DMA sense buffer 
+ * dma_handle:              phys. DMA buffer (kernel >= 2.4.0)
+ * buffers_residual:        Timeout value
+ * Status:                  Command status (gdth_do_cmd()), DMA mem. mappings
+ * Message:                 Additional info (gdth_do_cmd()), DMA direction
+ * have_data_in:            Flag for gdth_wait_completion()
+ * sent_command:            Opcode special command
+ * phase:                   Service/parameter/return code special command
  */
 
-#error Please convert me to Documentation/DMA-mapping.txt
+/* default: activate /proc and character device IOCTL interface */
+#define GDTH_IOCTL_PROC
+#define GDTH_IOCTL_CHRDEV
 
 #include <linux/module.h>
 
@@ -324,6 +333,7 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
+#include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/proc_fs.h>
 #include <linux/time.h>
@@ -340,6 +350,7 @@
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/io.h>
+#include <asm/uaccess.h>
 #if LINUX_VERSION_CODE >= 0x020322
 #include <linux/spinlock.h>
 #elif LINUX_VERSION_CODE >= 0x02015F
@@ -353,6 +364,9 @@
 #endif
 #include "scsi.h"
 #include "hosts.h"
+#if LINUX_VERSION_CODE < 0x020503
+#include "sd.h"
+#endif
 
 #include "gdth.h"
 
@@ -378,7 +392,8 @@
                                gdth_evt_str *estr);
 static void gdth_clear_events(void);
 
-static void gdth_copy_internal_data(Scsi_Cmnd *scp,char *buffer,ushort count);
+static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp,
+                                    char *buffer,ushort count);
 static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp);
 static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive);
 
@@ -408,6 +423,13 @@
 
 static const char *gdth_ctr_name(int hanum);
 
+#ifdef GDTH_IOCTL_CHRDEV
+static int gdth_open(struct inode *inode, struct file *filep);
+static int gdth_close(struct inode *inode, struct file *filep);
+static int gdth_ioctl(struct inode *inode, struct file *filep,
+                      unsigned int cmd, unsigned long arg);
+#endif
+
 #if LINUX_VERSION_CODE >= 0x010300
 static void gdth_flush(int hanum);
 #if LINUX_VERSION_CODE >= 0x020100
@@ -604,6 +626,9 @@
 static gdth_evt_str ebuffer[MAX_EVENTS];                /* event buffer */
 static int elastidx;
 static int eoldidx;
+#ifdef GDTH_IOCTL_CHRDEV
+static int major;
+#endif
 
 #define DIN     1                               /* IN data direction */
 #define DOU     2                               /* OUT data direction */
@@ -641,24 +666,35 @@
 #define __init
 #endif
 
-#if LINUX_VERSION_CODE >= 0x02015F
+#if LINUX_VERSION_CODE >= 0x020503
+#define GDTH_INIT_LOCK_HA(ha)           spin_lock_init(&(ha)->smp_lock)
+#define GDTH_LOCK_HA(ha,flags)          spin_lock_irqsave(&(ha)->smp_lock,flags)
+#define GDTH_UNLOCK_HA(ha,flags)        spin_unlock_irqrestore(&(ha)->smp_lock,flags)
+
+#define GDTH_LOCK_SCSI_DONE(dev, flags) spin_lock_irqsave(dev->host_lock,flags)
+#define GDTH_UNLOCK_SCSI_DONE(dev, flags) spin_unlock_irqrestore(dev->host_lock,flags)
+#define GDTH_LOCK_SCSI_DOCMD(dev)       spin_lock_irq(dev->host_lock)
+#define GDTH_UNLOCK_SCSI_DOCMD(dev)     spin_unlock_irq(dev->host_lock)
+
+#elif LINUX_VERSION_CODE >= 0x02015F
 #define GDTH_INIT_LOCK_HA(ha)           spin_lock_init(&(ha)->smp_lock)
 #define GDTH_LOCK_HA(ha,flags)          spin_lock_irqsave(&(ha)->smp_lock,flags)
 #define GDTH_UNLOCK_HA(ha,flags)        spin_unlock_irqrestore(&(ha)->smp_lock,flags)
 
-#define GDTH_LOCK_SCSI_DONE(dev, flags)      spin_lock_irqsave(dev->host_lock,flags)
-#define GDTH_UNLOCK_SCSI_DONE(flags)    spin_unlock_irqrestore(dev->host_lock,flags)
-#define GDTH_LOCK_SCSI_DOCMD(dev)          spin_lock_irq(dev->host_lock)
-#define GDTH_UNLOCK_SCSI_DOCMD(dev)        spin_unlock_irq(dev->host_lock)
+#define GDTH_LOCK_SCSI_DONE(flags)      spin_lock_irqsave(&io_request_lock,flags)
+#define GDTH_UNLOCK_SCSI_DONE(flags)    spin_unlock_irqrestore(&io_request_lock,flags)
+#define GDTH_LOCK_SCSI_DOCMD()          spin_lock_irq(&io_request_lock)
+#define GDTH_UNLOCK_SCSI_DOCMD()        spin_unlock_irq(&io_request_lock)
+
 #else
 #define GDTH_INIT_LOCK_HA(ha)           do {} while (0)
 #define GDTH_LOCK_HA(ha,flags)          do {save_flags(flags); cli();} while (0)
 #define GDTH_UNLOCK_HA(ha,flags)        do {restore_flags(flags);} while (0)
 
-#define GDTH_LOCK_SCSI_DONE(dev, flags)      do {} while (0)
-#define GDTH_UNLOCK_SCSI_DONE(dev, flags)    do {} while (0)
-#define GDTH_LOCK_SCSI_DOCMD(dev)          do {} while (0)
-#define GDTH_UNLOCK_SCSI_DOCMD(dev)        do {} while (0)
+#define GDTH_LOCK_SCSI_DONE(flags)      do {} while (0)
+#define GDTH_UNLOCK_SCSI_DONE(flags)    do {} while (0)
+#define GDTH_LOCK_SCSI_DOCMD()          do {} while (0)
+#define GDTH_UNLOCK_SCSI_DOCMD()        do {} while (0)
 #endif
 
 /* LILO and modprobe/insmod parameters */
@@ -702,10 +738,21 @@
 MODULE_PARM(virt_ctr, "i");
 MODULE_PARM(shared_access, "i");
 MODULE_AUTHOR("Achim Leubner");
+#endif
+#if LINUX_VERSION_CODE >= 0x02040B
 MODULE_LICENSE("GPL");
 #endif
 #endif
 
+#ifdef GDTH_IOCTL_CHRDEV
+/* ioctl interface */
+static struct file_operations gdth_fops = {
+    ioctl:gdth_ioctl,
+    open:gdth_open,
+    release:gdth_close,
+};
+#endif
+
 /* /proc support */
 #if LINUX_VERSION_CODE >= 0x010300
 #include <linux/stat.h> 
@@ -813,6 +860,8 @@
                     PCI_DEVICE_ID_VORTEX_GDTNEWRX);
     gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
                     PCI_DEVICE_ID_INTEL_SRC);
+    gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
+                    PCI_DEVICE_ID_INTEL_SRC_XSCALE);
     return cnt;
 }
 
@@ -820,10 +869,11 @@
 /* Vortex only makes RAID controllers.
  * We do not really want to specify all 550 ids here, so wildcard match.
  */
-static struct pci_device_id gdthtable[] = {
-	{PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID },
-	{PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID }, 
-	{0}
+static struct pci_device_id gdthtable[] __devinitdata = {
+    {PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID},
+    {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID}, 
+    {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC_XSCALE,PCI_ANY_ID,PCI_ANY_ID}, 
+    {0}
 };
 MODULE_DEVICE_TABLE(pci,gdthtable);
 #endif
@@ -1235,6 +1285,9 @@
     ha->stype = (ulong32)pcistr->device_id;
     ha->subdevice_id = pcistr->subdevice_id;
     ha->irq = pcistr->irq;
+#if LINUX_VERSION_CODE >= 0x20400
+    ha->pdev = pcistr->pdev;
+#endif
     
     if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6000B) {  /* GDT6000/B */
         TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
@@ -1511,6 +1564,11 @@
                                    PCI_ROM_ADDRESS, rom_addr);
 #endif
         
+        /* Ensure that it is safe to access the non HW portions of DPMEM.
+         * Aditional check needed for Xscale based RAID controllers */
+        while( ((int)gdth_readb(&((gdt6m_dpram_str *)ha->brd)->i960r.sema0_reg) ) & 3 )
+            gdth_delay(1);
+        
         /* check and reset interface area */
         dp6m_ptr = (gdt6m_dpram_str *)ha->brd;
         gdth_writel(DPMEM_MAGIC, &dp6m_ptr->u);
@@ -1840,7 +1898,7 @@
 
     if (ha->type == GDT_EISA) {
         if (ha->pccb->OpCode == GDT_INIT)               /* store DMA buffer */
-            outl(virt_to_bus(ha->pccb), ha->bmic + MAILBOXREG);
+            outl(ha->ccb_phys, ha->bmic + MAILBOXREG);
         outb(ha->pccb->Service, ha->bmic + LDOORREG);
     } else if (ha->type == GDT_ISA) {
         gdth_writeb(0, &((gdt2_dpram_str *)ha->brd)->io.event);
@@ -1916,7 +1974,7 @@
                 cmd_ptr->u.ioctl.subfunc = p1;
                 cmd_ptr->u.ioctl.channel = p2;
                 cmd_ptr->u.ioctl.param_size = (ushort)p3;
-                cmd_ptr->u.ioctl.p_param = virt_to_bus(ha->pscratch);
+                cmd_ptr->u.ioctl.p_param = ha->scratch_phys;
             } else {
                 cmd_ptr->u.cache.DeviceNo = (ushort)p1;
                 cmd_ptr->u.cache.BlockNo  = p2;
@@ -1965,6 +2023,8 @@
     gdth_raw_iochan_str *iocr;
     gdth_arcdl_str *alst;
     gdth_alist_str *alst2;
+    gdth_oem_str_ioctl *oemstr;
+
 #ifdef GDTH_RTC
     unchar rtc[12];
     ulong flags;
@@ -2233,6 +2293,27 @@
         }
     }
 
+    /* Determine OEM string using IOCTL */
+    oemstr = (gdth_oem_str_ioctl *)ha->pscratch;
+    oemstr->params.ctl_version = 0x01;
+    oemstr->params.buffer_size = sizeof(oemstr->text);
+    if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,
+                          CACHE_READ_OEM_STRING_RECORD,INVALID_CHANNEL,
+                          sizeof(gdth_oem_str_ioctl))) {
+        TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD OK\n"));
+        printk("GDT CTR%d Vendor: %s\n",hanum,oemstr->text.oem_company_name);
+        /* Save the Host Drive inquiry data */
+        strncpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id,7);
+        ha->oem_name[7] = '\0';
+    } else {
+        /* Old method, based on PCI ID */
+        TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD failed\n"));
+        if (ha->oem_id == OEM_ID_INTEL)
+            strcpy(ha->oem_name,"Intel  ");
+        else
+            strcpy(ha->oem_name,"ICP    ");
+    }
+
     /* scanning for host drives */
     for (i = 0; i < cdev_cnt; ++i) 
         gdth_analyse_hdrive(hanum,i);
@@ -2313,8 +2394,13 @@
     GDTH_LOCK_HA(ha, flags);
 
     scp->SCp.this_residual = (int)priority;
+#if LINUX_VERSION_CODE >= 0x02053C
     b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
     t = scp->device->id;
+#else
+    b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
+    t = scp->target;
+#endif
 #if LINUX_VERSION_CODE >= 0x010300
     if (priority >= DEFAULT_PRI) {
         if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
@@ -2357,7 +2443,7 @@
     register gdth_ha_str *ha;
     register Scsi_Cmnd *pscp;
     register Scsi_Cmnd *nscp;
-    unchar b, t, firsttime;
+    unchar b, t, l, firsttime;
     unchar this_cmd, next_cmd;
     ulong flags = 0;
     int cmd_index;
@@ -2365,7 +2451,7 @@
     TRACE(("gdth_next() hanum %d\n",hanum));
     ha = HADATA(gdth_ctr_tab[hanum]);
     if (!gdth_polling) 
-    	GDTH_LOCK_HA(ha, flags);
+        GDTH_LOCK_HA(ha, flags);
 
     ha->cmd_cnt = ha->cmd_offs_dpmem = 0;
     this_cmd = firsttime = TRUE;
@@ -2375,8 +2461,15 @@
     for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) {
         if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr)
             pscp = (Scsi_Cmnd *)pscp->SCp.ptr;
+#if LINUX_VERSION_CODE >= 0x02053C
         b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel;
         t = nscp->device->id;
+        l = nscp->device->lun;
+#else
+        b = virt_ctr ? NUMDATA(nscp->host)->busnum : nscp->channel;
+        t = nscp->target;
+        l = nscp->lun;
+#endif
         if (nscp->SCp.this_residual >= DEFAULT_PRI) {
             if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
                 (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) 
@@ -2404,16 +2497,16 @@
             nscp->SCp.phase = CACHESERVICE;           /* default: cache svc. */ 
             if (nscp->cmnd[0] == TEST_UNIT_READY) {
                 TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n", 
-                        b, t, nscp->lun));
+                        b, t, l));
                 /* TEST_UNIT_READY -> set scan mode */
                 if ((ha->scan_mode & 0x0f) == 0) {
-                    if (b == 0 && t == 0 && nscp->device->lun == 0) {
+                    if (b == 0 && t == 0 && l == 0) {
                         ha->scan_mode |= 1;
                         TRACE2(("Scan mode: 0x%x\n", ha->scan_mode));
                     }
                 } else if ((ha->scan_mode & 0x0f) == 1) {
-                    if (b == 0 && ((t == 0 && nscp->device->lun == 1) ||
-                         (t == 1 && nscp->device->lun == 0))) {
+                    if (b == 0 && ((t == 0 && l == 1) ||
+                         (t == 1 && l == 0))) {
                         nscp->SCp.sent_command = GDT_SCAN_START;
                         nscp->SCp.phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) 
                             | SCSIRAWSERVICE;
@@ -2465,7 +2558,7 @@
                     /* io_request_lock already active ! */
                     nscp->scsi_done(nscp);
                     if (!gdth_polling) 
-                    	GDTH_LOCK_HA(ha,flags);
+                        GDTH_LOCK_HA(ha,flags);
                 }
             }
         } else
@@ -2483,19 +2576,19 @@
                 this_cmd = FALSE;
             else 
                 ha->raw[BUS_L2P(ha,b)].io_cnt[t]++;
-        } else if (t >= MAX_HDRIVES || !ha->hdr[t].present || nscp->device->lun != 0) {
+        } else if (t >= MAX_HDRIVES || !ha->hdr[t].present || l != 0) {
             TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n",
-                    nscp->cmnd[0], b, t, nscp->lun));
+                    nscp->cmnd[0], b, t, l));
             nscp->result = DID_BAD_TARGET << 16;
             if (!nscp->SCp.have_data_in)
                 nscp->SCp.have_data_in++;
             else {
                 if (!gdth_polling) 
-                	GDTH_UNLOCK_HA(ha,flags);
+                    GDTH_UNLOCK_HA(ha,flags);
                 /* io_request_lock already active ! */      
                 nscp->scsi_done(nscp);
                 if (!gdth_polling) 
-                	GDTH_LOCK_HA(ha,flags);
+                    GDTH_LOCK_HA(ha,flags);
             }
         } else {
             switch (nscp->cmnd[0]) {
@@ -2521,20 +2614,20 @@
                     if (!nscp->SCp.have_data_in)
                         nscp->SCp.have_data_in++;
                     else {
-                	if (!gdth_polling) 
-                        	GDTH_UNLOCK_HA(ha,flags);
+                        if (!gdth_polling) 
+                            GDTH_UNLOCK_HA(ha,flags);
                         /* io_request_lock already active ! */      
                         nscp->scsi_done(nscp);
-                	if (!gdth_polling) 
-                        	GDTH_LOCK_HA(ha,flags);
+                        if (!gdth_polling) 
+                            GDTH_LOCK_HA(ha,flags);
                     }
                 } else if (gdth_internal_cache_cmd(hanum,nscp)) {
                     if (!gdth_polling) 
-                    	GDTH_UNLOCK_HA(ha,flags);
+                        GDTH_UNLOCK_HA(ha,flags);
                     /* io_request_lock already active ! */      
                     nscp->scsi_done(nscp);
                     if (!gdth_polling) 
-                    	GDTH_LOCK_HA(ha,flags);
+                        GDTH_LOCK_HA(ha,flags);
                 }
                 break;
 
@@ -2549,12 +2642,12 @@
                     if (!nscp->SCp.have_data_in)
                         nscp->SCp.have_data_in++;
                     else {
-                    	if (!gdth_polling) 
-                        	GDTH_UNLOCK_HA(ha,flags);
+                        if (!gdth_polling) 
+                            GDTH_UNLOCK_HA(ha,flags);
                         /* io_request_lock already active ! */      
                         nscp->scsi_done(nscp);
-                    	if (!gdth_polling) 
-                        	GDTH_LOCK_HA(ha,flags);
+                        if (!gdth_polling) 
+                            GDTH_LOCK_HA(ha,flags);
                     }
                 } else {
                     nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0;
@@ -2589,12 +2682,12 @@
                     if (!nscp->SCp.have_data_in)
                         nscp->SCp.have_data_in++;
                     else {
-                    	if (!gdth_polling) 
-                        	GDTH_UNLOCK_HA(ha,flags);
+                        if (!gdth_polling) 
+                            GDTH_UNLOCK_HA(ha,flags);
                         /* io_request_lock already active ! */      
                         nscp->scsi_done(nscp);
-                    	if (!gdth_polling) 
-                        	GDTH_LOCK_HA(ha,flags);
+                        if (!gdth_polling) 
+                            GDTH_LOCK_HA(ha,flags);
                     }
                 } else if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t)))
                     this_cmd = FALSE;
@@ -2611,11 +2704,11 @@
                     nscp->SCp.have_data_in++;
                 else {
                     if (!gdth_polling) 
-                    	GDTH_UNLOCK_HA(ha,flags);
+                        GDTH_UNLOCK_HA(ha,flags);
                     /* io_request_lock already active ! */  
                     nscp->scsi_done(nscp);
                     if (!gdth_polling) 
-                    	GDTH_LOCK_HA(ha,flags);
+                        GDTH_LOCK_HA(ha,flags);
                 }
                 break;
             }
@@ -2636,7 +2729,7 @@
     }
 
     if (!gdth_polling) 
-    	GDTH_UNLOCK_HA(ha, flags);
+        GDTH_UNLOCK_HA(ha, flags);
 
     if (gdth_polling && ha->cmd_cnt > 0) {
         if (!gdth_wait(hanum,cmd_index,POLL_TIMEOUT))
@@ -2645,27 +2738,54 @@
     }
 }
     
-static void gdth_copy_internal_data(Scsi_Cmnd *scp,char *buffer,ushort count)
+static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp,
+                                    char *buffer,ushort count)
 {
     ushort cpcount,i;
     ushort cpsum,cpnow;
     struct scatterlist *sl;
+    gdth_ha_str *ha;
+    int sgcnt;
+    char *address;
 
     cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen;
+    ha = HADATA(gdth_ctr_tab[hanum]);
+
     if (scp->use_sg) {
         sl = (struct scatterlist *)scp->request_buffer;
-        for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl) {
-            cpnow = (ushort)sl->length;
+#if LINUX_VERSION_CODE >= 0x020400
+        sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,PCI_DMA_FROMDEVICE);
+        for (i=0,cpsum=0; i<sgcnt; ++i,++sl) {
+            cpnow = (ushort)sg_dma_len(sl);
             TRACE(("copy_internal() now %d sum %d count %d %d\n",
                           cpnow,cpsum,cpcount,(ushort)scp->bufflen));
             if (cpsum+cpnow > cpcount) 
                 cpnow = cpcount - cpsum;
             cpsum += cpnow;
-            memcpy((char*)sl->address,buffer,cpnow);
+            address = (char *)phys_to_virt(sg_dma_address(sl));
+            memcpy(address,buffer,cpnow);
+            if (cpsum == cpcount)
+                break;
+            buffer += cpnow;
+        }
+        pci_unmap_sg(ha->pdev,scp->request_buffer,
+                     scp->use_sg,PCI_DMA_FROMDEVICE);
+#else
+        sgcnt = scp->use_sg;
+        for (i=0,cpsum=0; i<sgcnt; ++i,++sl) {
+            cpnow = (ushort)sl->length;
+            TRACE(("copy_internal() now %d sum %d count %d %d\n",
+                          cpnow,cpsum,cpcount,(ushort)scp->bufflen));
+            if (cpsum+cpnow > cpcount) 
+               cpnow = cpcount - cpsum;
+            cpsum += cpnow;
+            address = (char *)sl->address;
+            memcpy(address,buffer,cpnow);
             if (cpsum == cpcount)
                 break;
             buffer += cpnow;
         }
+#endif
     } else {
         TRACE(("copy_internal() count %d\n",cpcount));
         memcpy((char*)scp->request_buffer,buffer,cpcount);
@@ -2682,7 +2802,11 @@
     gdth_modep_data mpd;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
+#if LINUX_VERSION_CODE >= 0x02053C
     t  = scp->device->id;
+#else
+    t  = scp->target;
+#endif
     TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n",
            scp->cmnd[0],t));
 
@@ -2706,13 +2830,10 @@
         inq.version   = 2;
         inq.resp_aenc = 2;
         inq.add_length= 32;
-        if (ha->oem_id == OEM_ID_INTEL)
-            strcpy(inq.vendor,"Intel  ");
-        else 
-            strcpy(inq.vendor,"ICP    ");
+        strcpy(inq.vendor,ha->oem_name);
         sprintf(inq.product,"Host Drive  #%02d",t);
         strcpy(inq.revision,"   ");
-        gdth_copy_internal_data(scp,(char*)&inq,sizeof(gdth_inq_data));
+        gdth_copy_internal_data(hanum,scp,(char*)&inq,sizeof(gdth_inq_data));
         break;
 
       case REQUEST_SENSE:
@@ -2722,7 +2843,7 @@
         sd.key       = NO_SENSE;
         sd.info      = 0;
         sd.add_length= 0;
-        gdth_copy_internal_data(scp,(char*)&sd,sizeof(gdth_sense_data));
+        gdth_copy_internal_data(hanum,scp,(char*)&sd,sizeof(gdth_sense_data));
         break;
 
       case MODE_SENSE:
@@ -2734,14 +2855,14 @@
         mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16;
         mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8;
         mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff);
-        gdth_copy_internal_data(scp,(char*)&mpd,sizeof(gdth_modep_data));
+        gdth_copy_internal_data(hanum,scp,(char*)&mpd,sizeof(gdth_modep_data));
         break;
 
       case READ_CAPACITY:
         TRACE2(("Read capacity hdrive %d\n",t));
         rdc.last_block_no = ntohl(ha->hdr[t].size-1);
         rdc.block_length  = ntohl(SECTOR_SIZE);
-        gdth_copy_internal_data(scp,(char*)&rdc,sizeof(gdth_rdcap_data));
+        gdth_copy_internal_data(hanum,scp,(char*)&rdc,sizeof(gdth_rdcap_data));
         break;
 
       default:
@@ -2766,8 +2887,8 @@
     register gdth_cmd_str *cmdp;
     struct scatterlist *sl;
     ushort i, cnt;
-    ulong32 no;
-    int cmd_index, read_write;
+    ulong32 no, phys_addr;
+    int cmd_index, read_write, sgcnt;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
     cmdp = ha->pccb;
@@ -2789,7 +2910,7 @@
         gdth_set_sema0(hanum);
 
     /* fill command */
-    read_write = FALSE;
+    read_write = 0;
     if (scp->SCp.sent_command != -1) 
         cmdp->OpCode = scp->SCp.sent_command;   /* special cache cmd. */
     else if (scp->cmnd[0] == RESERVE) 
@@ -2803,15 +2924,16 @@
             cmdp->OpCode = GDT_UNMOUNT;
         else
             cmdp->OpCode = GDT_FLUSH;
-    } else if (scp->cmnd[0] == WRITE_6 || scp->cmnd[0] == WRITE_10) {
-        read_write = TRUE;
+    } else if (scp->cmnd[0] == WRITE_6 || scp->cmnd[0] == WRITE_10 ||
+               scp->cmnd[0] == WRITE_12) {
+        read_write = 1;
         if (gdth_write_through || ((ha->hdr[hdrive].rw_attribs & 1) && 
                                    (ha->cache_feat & GDT_WR_THROUGH)))
             cmdp->OpCode = GDT_WRITE_THR;
         else
             cmdp->OpCode = GDT_WRITE;
     } else {
-        read_write = TRUE;
+        read_write = 2;
         cmdp->OpCode = GDT_READ;
     }
     
@@ -2835,10 +2957,22 @@
         if (scp->use_sg) {
             cmdp->u.cache.DestAddr= 0xffffffff;
             sl = (struct scatterlist *)scp->request_buffer;
-            for (i=0; i<scp->use_sg; ++i,++sl) {
+            sgcnt = scp->use_sg;
+#if LINUX_VERSION_CODE >= 0x020400
+            scp->SCp.Status = GDTH_MAP_SG;
+            scp->SCp.Message = (read_write == 1 ? 
+                PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);   
+            sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message);
+            for (i=0; i<sgcnt; ++i,++sl) {
+                cmdp->u.cache.sg_lst[i].sg_ptr = sg_dma_address(sl);
+                cmdp->u.cache.sg_lst[i].sg_len = sg_dma_len(sl);
+            }
+#else
+            for (i=0; i<sgcnt; ++i,++sl) {
                 cmdp->u.cache.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
                 cmdp->u.cache.sg_lst[i].sg_len = (ulong32)sl->length;
             }
+#endif
             cmdp->u.cache.sg_canz = (ulong32)i;
 
 #ifdef GDTH_STATISTICS
@@ -2850,15 +2984,24 @@
             if (i<GDTH_MAXSG)
                 cmdp->u.cache.sg_lst[i].sg_len = 0;
         } else {
+#if LINUX_VERSION_CODE >= 0x020400
+            scp->SCp.Status = GDTH_MAP_SINGLE;
+            scp->SCp.Message = (read_write == 1 ? 
+                PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);   
+            phys_addr = pci_map_single(ha->pdev,scp->request_buffer,
+                                       scp->request_bufflen,scp->SCp.Message);
+            scp->SCp.dma_handle = phys_addr;
+#else
+            phys_addr = virt_to_bus(scp->request_buffer);
+#endif
             if (ha->cache_feat & SCATTER_GATHER) {
                 cmdp->u.cache.DestAddr = 0xffffffff;
                 cmdp->u.cache.sg_canz = 1;
-                cmdp->u.cache.sg_lst[0].sg_ptr = 
-                    virt_to_bus(scp->request_buffer);
+                cmdp->u.cache.sg_lst[0].sg_ptr = phys_addr;
                 cmdp->u.cache.sg_lst[0].sg_len = scp->request_bufflen;
                 cmdp->u.cache.sg_lst[1].sg_len = 0;
             } else {
-                cmdp->u.cache.DestAddr  = virt_to_bus(scp->request_buffer);
+                cmdp->u.cache.DestAddr  = phys_addr;
                 cmdp->u.cache.sg_canz= 0;
             }
         }
@@ -2896,12 +3039,18 @@
     register gdth_cmd_str *cmdp;
     struct scatterlist *sl;
     ushort i;
-    int cmd_index;
+    ulong32 phys_addr, sense_paddr;
+    int cmd_index, sgcnt;
     unchar t,l;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
+#if LINUX_VERSION_CODE >= 0x02053C
     t = scp->device->id;
     l = scp->device->lun;
+#else
+    t = scp->target;
+    l = scp->lun;
+#endif
     cmdp = ha->pccb;
     TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n",
            scp->cmnd[0],b,t,l));
@@ -2931,6 +3080,13 @@
         /* evaluate command size */
         ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst);
     } else {
+#if LINUX_VERSION_CODE >= 0x020400
+        sense_paddr = pci_map_single(ha->pdev,scp->sense_buffer,
+                                     16,PCI_DMA_FROMDEVICE);
+        scp->SCp.buffer = (struct scatterlist *)sense_paddr;
+#else
+        sense_paddr = virt_to_bus(scp->sense_buffer);
+#endif
         cmdp->OpCode           = GDT_WRITE;             /* always */
         cmdp->BoardNode        = LOCALBOARD;
         cmdp->u.raw.reserved   = 0;
@@ -2944,7 +3100,7 @@
         cmdp->u.raw.link_p     = 0;
         cmdp->u.raw.sdlen      = scp->request_bufflen;
         cmdp->u.raw.sense_len  = 16;
-        cmdp->u.raw.sense_data = virt_to_bus(scp->sense_buffer);
+        cmdp->u.raw.sense_data = sense_paddr;
         cmdp->u.raw.direction  = 
             gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN;
         memcpy(cmdp->u.raw.cmd,scp->cmnd,12);
@@ -2952,10 +3108,21 @@
         if (scp->use_sg) {
             cmdp->u.raw.sdata  = 0xffffffff;
             sl = (struct scatterlist *)scp->request_buffer;
-            for (i=0; i<scp->use_sg; ++i,++sl) {
+            sgcnt = scp->use_sg;
+#if LINUX_VERSION_CODE >= 0x020400
+            scp->SCp.Status = GDTH_MAP_SG;
+            scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; 
+            sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message);
+            for (i=0; i<sgcnt; ++i,++sl) {
+                cmdp->u.raw.sg_lst[i].sg_ptr = sg_dma_address(sl);
+                cmdp->u.raw.sg_lst[i].sg_len = sg_dma_len(sl);
+            }
+#else
+            for (i=0; i<sgcnt; ++i,++sl) {
                 cmdp->u.raw.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
                 cmdp->u.raw.sg_lst[i].sg_len = (ulong32)sl->length;
             }
+#endif
             cmdp->u.raw.sg_ranz = (ulong32)i;
 
 #ifdef GDTH_STATISTICS
@@ -2967,14 +3134,23 @@
             if (i<GDTH_MAXSG)
                 cmdp->u.raw.sg_lst[i].sg_len = 0;
         } else {
+#if LINUX_VERSION_CODE >= 0x020400
+            scp->SCp.Status = GDTH_MAP_SINGLE;
+            scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; 
+            phys_addr = pci_map_single(ha->pdev,scp->request_buffer,
+                                       scp->request_bufflen,scp->SCp.Message);
+            scp->SCp.dma_handle = phys_addr;
+#else
+            phys_addr = virt_to_bus(scp->request_buffer);
+#endif
             if (ha->raw_feat & SCATTER_GATHER) {
                 cmdp->u.raw.sdata  = 0xffffffff;
                 cmdp->u.raw.sg_ranz= 1;
-                cmdp->u.raw.sg_lst[0].sg_ptr = virt_to_bus(scp->request_buffer);
+                cmdp->u.raw.sg_lst[0].sg_ptr = phys_addr;
                 cmdp->u.raw.sg_lst[0].sg_len = scp->request_bufflen;
                 cmdp->u.raw.sg_lst[1].sg_len = 0;
             } else {
-                cmdp->u.raw.sdata  = virt_to_bus(scp->request_buffer);
+                cmdp->u.raw.sdata  = phys_addr;
                 cmdp->u.raw.sg_ranz= 0;
             }
         }
@@ -3372,9 +3548,19 @@
     if (rval == 2) {
         gdth_putq(hanum,scp,scp->SCp.this_residual);
     } else if (rval == 1) {
+#if LINUX_VERSION_CODE >= 0x02053C
         GDTH_LOCK_SCSI_DONE(scp->device->host, flags);
         scp->scsi_done(scp);
-        GDTH_UNLOCK_SCSI_DONE(scp->host,flags);
+        GDTH_UNLOCK_SCSI_DONE(scp->device->host, flags);
+#elif LINUX_VERSION_CODE >= 0x020503
+        GDTH_LOCK_SCSI_DONE(scp->host, flags);
+        scp->scsi_done(scp);
+        GDTH_UNLOCK_SCSI_DONE(scp->host, flags);
+#else
+        GDTH_LOCK_SCSI_DONE(flags);
+        scp->scsi_done(scp);
+        GDTH_UNLOCK_SCSI_DONE(flags);
+#endif
     }
     gdth_next(hanum);
 }
@@ -3384,7 +3570,7 @@
     register gdth_ha_str *ha;
     gdth_msg_str *msg;
     gdth_cmd_str *cmdp;
-    unchar b;
+    unchar b, t;
 
     ha   = HADATA(gdth_ctr_tab[hanum]);
     cmdp = ha->pccb;
@@ -3413,7 +3599,7 @@
             cmdp->BoardNode     = LOCALBOARD;
             cmdp->u.screen.reserved  = 0;
             cmdp->u.screen.su.msg.msg_handle= msg->msg_handle;
-            cmdp->u.screen.su.msg.msg_addr  = virt_to_bus(msg);
+            cmdp->u.screen.su.msg.msg_addr  = ha->scratch_phys;
             ha->scratch_busy = TRUE;
             ha->cmd_offs_dpmem = 0;
             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 
@@ -3448,7 +3634,7 @@
             cmdp->BoardNode     = LOCALBOARD;
             cmdp->u.screen.reserved  = 0;
             cmdp->u.screen.su.msg.msg_handle= msg->msg_handle;
-            cmdp->u.screen.su.msg.msg_addr  = virt_to_bus(msg);
+            cmdp->u.screen.su.msg.msg_addr  = ha->scratch_phys;
             ha->scratch_busy = TRUE;
             ha->cmd_offs_dpmem = 0;
             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 
@@ -3461,11 +3647,35 @@
         printk("\n");
 
     } else {
+#if LINUX_VERSION_CODE >= 0x02053C
         b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
+        t = scp->device->id;
+#else
+        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
+        t = scp->target;
+#endif
         if (scp->SCp.sent_command == -1 && b != ha->virt_bus) {
-            ha->raw[BUS_L2P(ha,b)].io_cnt[scp->device->id]--;
+            ha->raw[BUS_L2P(ha,b)].io_cnt[t]--;
         }
         /* cache or raw service */
+        if (ha->status == S_BSY) {
+            TRACE2(("Controller busy -> retry !\n"));
+            if (scp->SCp.sent_command == GDT_MOUNT)
+                scp->SCp.sent_command = GDT_CLUST_INFO;
+            /* retry */
+            return 2;
+        }
+#if LINUX_VERSION_CODE >= 0x020400
+        if (scp->SCp.Status == GDTH_MAP_SG) 
+            pci_unmap_sg(ha->pdev,scp->request_buffer,
+                         scp->use_sg,scp->SCp.Message);
+        else if (scp->SCp.Status == GDTH_MAP_SINGLE) 
+            pci_unmap_single(ha->pdev,scp->SCp.dma_handle,
+                         scp->request_bufflen,scp->SCp.Message);
+        if (scp->SCp.buffer)
+            pci_unmap_single(ha->pdev,(dma_addr_t)scp->SCp.buffer,
+                             16,PCI_DMA_FROMDEVICE);
+#endif
         if (ha->status == S_OK) {
             scp->SCp.Status = S_OK;
             scp->SCp.Message = ha->info;
@@ -3474,12 +3684,12 @@
                         scp->SCp.sent_command));
                 /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */
                 if (scp->SCp.sent_command == GDT_CLUST_INFO) {
-                    ha->hdr[scp->device->id].cluster_type = (unchar)ha->info;
-                    if (!(ha->hdr[scp->device->id].cluster_type & 
+                    ha->hdr[t].cluster_type = (unchar)ha->info;
+                    if (!(ha->hdr[t].cluster_type & 
                         CLUSTER_MOUNTED)) {
                         /* NOT MOUNTED -> MOUNT */
                         scp->SCp.sent_command = GDT_MOUNT;
-                        if (ha->hdr[scp->device->id].cluster_type & 
+                        if (ha->hdr[t].cluster_type & 
                             CLUSTER_RESERVED) {
                             /* cluster drive RESERVED (on the other node) */
                             scp->SCp.phase = -2;      /* reservation conflict */
@@ -3489,11 +3699,11 @@
                     }
                 } else {
                     if (scp->SCp.sent_command == GDT_MOUNT) {
-                        ha->hdr[scp->device->id].cluster_type |= CLUSTER_MOUNTED;
-                        ha->hdr[scp->device->id].media_changed = TRUE;
+                        ha->hdr[t].cluster_type |= CLUSTER_MOUNTED;
+                        ha->hdr[t].media_changed = TRUE;
                     } else if (scp->SCp.sent_command == GDT_UNMOUNT) {
-                        ha->hdr[scp->device->id].cluster_type &= ~CLUSTER_MOUNTED;
-                        ha->hdr[scp->device->id].media_changed = TRUE;
+                        ha->hdr[t].cluster_type &= ~CLUSTER_MOUNTED;
+                        ha->hdr[t].media_changed = TRUE;
                     } 
                     scp->SCp.sent_command = -1;
                 }
@@ -3503,21 +3713,13 @@
             } else {
                 /* RESERVE/RELEASE ? */
                 if (scp->cmnd[0] == RESERVE) {
-                    ha->hdr[scp->device->id].cluster_type |= CLUSTER_RESERVED;
+                    ha->hdr[t].cluster_type |= CLUSTER_RESERVED;
                 } else if (scp->cmnd[0] == RELEASE) {
-                    ha->hdr[scp->device->id].cluster_type &= ~CLUSTER_RESERVED;
+                    ha->hdr[t].cluster_type &= ~CLUSTER_RESERVED;
                 }           
                 scp->result = DID_OK << 16;
                 scp->sense_buffer[0] = 0;
             }
-        } else if (ha->status == S_BSY) {
-            TRACE2(("Controller busy -> retry !\n"));
-            scp->SCp.Status = S_BSY;
-            scp->SCp.Message = ha->info;
-            if (scp->SCp.sent_command == GDT_MOUNT)
-                scp->SCp.sent_command = GDT_CLUST_INFO;
-            /* retry */
-            return 2;
         } else {
             scp->SCp.Status = ha->status;
             scp->SCp.Message = ha->info;
@@ -3538,10 +3740,10 @@
                 scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
             } else if (service == CACHESERVICE) {
                 if (ha->status == S_CACHE_UNKNOWN &&
-                    (ha->hdr[scp->device->id].cluster_type & 
+                    (ha->hdr[t].cluster_type & 
                      CLUSTER_RESERVE_STATE) == CLUSTER_RESERVE_STATE) {
                     /* bus reset -> force GDT_CLUST_INFO */
-                    ha->hdr[scp->device->id].cluster_type &= ~CLUSTER_RESERVED;
+                    ha->hdr[t].cluster_type &= ~CLUSTER_RESERVED;
                 }
                 memset((char*)scp->sense_buffer,0,16);
                 if (ha->status == (ushort)S_CACHE_RESERV) {
@@ -3560,7 +3762,7 @@
                     ha->dvr.eu.sync.service = service;
                     ha->dvr.eu.sync.status  = ha->status;
                     ha->dvr.eu.sync.info    = ha->info;
-                    ha->dvr.eu.sync.hostdrive = scp->device->id;
+                    ha->dvr.eu.sync.hostdrive = t;
                     if (ha->status >= 0x8000)
                         gdth_store_event(ha, ES_SYNC, 0, &ha->dvr);
                     else
@@ -3765,7 +3967,7 @@
             cmdp->BoardNode     = LOCALBOARD;
             cmdp->u.screen.reserved  = 0;
             cmdp->u.screen.su.msg.msg_handle= MSG_INV_HANDLE;
-            cmdp->u.screen.su.msg.msg_addr  = virt_to_bus(msg);
+            cmdp->u.screen.su.msg.msg_addr  = ha->scratch_phys;
             ha->scratch_busy = TRUE;
             ha->cmd_offs_dpmem = 0;
             ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 
@@ -4028,8 +4230,8 @@
             break;
         if (gdth_search_isa(isa_bios)) {        /* controller found */
             shp = scsi_register(shtp,sizeof(gdth_ext_str));
-	    if(shp == NULL)
-		    continue;
+            if (shp == NULL)
+                continue;  
 
             ha = HADATA(shp);
             if (!gdth_init_isa(isa_bios,ha)) {
@@ -4076,11 +4278,15 @@
             NUMDATA(shp)->busnum= 0;
 
             ha->pccb = CMDDATA(shp);
-#if LINUX_VERSION_CODE >= 0x020322
-            ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 
-                                                     GDTH_SCRATCH_ORD);
+            ha->ccb_phys = 0L;
+#if LINUX_VERSION_CODE >= 0x020400
+            ha->pdev = NULL;
+            ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 
+                                                &ha->scratch_phys); 
 #else
             ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
+            if (ha->pscratch)
+                ha->scratch_phys = virt_to_bus(ha->pscratch);
 #endif
             ha->scratch_busy = FALSE;
             ha->req_first = NULL;
@@ -4095,12 +4301,14 @@
                 printk("GDT-ISA: Error during device scan\n");
                 --gdth_ctr_count;
                 --gdth_ctr_vcount;
-                if (ha->pscratch != NULL)
-#if LINUX_VERSION_CODE >= 0x020322
-                    free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD);
+                if (ha->pscratch != NULL) {
+#if LINUX_VERSION_CODE >= 0x020400
+                    pci_free_consistent(ha->pdev, GDTH_SCRATCH, 
+                                        ha->pscratch, ha->scratch_phys);
 #else
                     scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
 #endif
+                }
 #if LINUX_VERSION_CODE >= 0x010346 
                 free_irq(ha->irq,ha);
 #else
@@ -4145,8 +4353,8 @@
             break;
         if (gdth_search_eisa(eisa_slot)) {      /* controller found */
             shp = scsi_register(shtp,sizeof(gdth_ext_str));
-	    if(shp == NULL)
-		    continue;
+            if (shp == NULL)
+                continue;  
 
             ha = HADATA(shp);
             if (!gdth_init_eisa(eisa_slot,ha)) {
@@ -4180,11 +4388,19 @@
                     NUMDATA(shp)->hanum));
 
             ha->pccb = CMDDATA(shp);
-#if LINUX_VERSION_CODE >= 0x020322
-            ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 
-                                                     GDTH_SCRATCH_ORD);
+            ha->ccb_phys = 0L; 
+#if LINUX_VERSION_CODE >= 0x020400
+            ha->pdev = NULL;
+            ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 
+                                                &ha->scratch_phys); 
+            ha->ccb_phys = 
+                pci_map_single(ha->pdev,ha->pccb,
+                               sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
 #else
             ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
+            if (ha->pscratch)
+                ha->scratch_phys = virt_to_bus(ha->pscratch);
+            ha->ccb_phys = virt_to_bus(ha->pccb);
 #endif
             ha->scratch_busy = FALSE;
             ha->req_first = NULL;
@@ -4199,12 +4415,16 @@
                 printk("GDT-EISA: Error during device scan\n");
                 --gdth_ctr_count;
                 --gdth_ctr_vcount;
-                if (ha->pscratch != NULL)
-#if LINUX_VERSION_CODE >= 0x020322
-                    free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD);
+                if (ha->pscratch != NULL) {
+#if LINUX_VERSION_CODE >= 0x020400
+                    pci_free_consistent(ha->pdev, GDTH_SCRATCH, 
+                                        ha->pscratch, ha->scratch_phys);
+                    pci_unmap_single(ha->pdev,ha->ccb_phys,
+                                    sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
 #else
                     scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
 #endif
+                }
 #if LINUX_VERSION_CODE >= 0x010346 
                 free_irq(ha->irq,ha);
 #else
@@ -4252,14 +4472,14 @@
         gdth_pci_str pcistr[MAXHA];
 
         cnt = gdth_search_pci(pcistr);
-	printk("GDT: Found %d PCI Storage RAID Controllers\n",cnt);
+        printk("GDT: Found %d PCI Storage RAID Controllers\n",cnt);
         gdth_sort_pci(pcistr,cnt);
         for (ctr = 0; ctr < cnt; ++ctr) {
             if (gdth_ctr_count >= MAXHA)
                 break;
             shp = scsi_register(shtp,sizeof(gdth_ext_str));
-	    if(shp == NULL)
-		    continue;
+            if (shp == NULL)
+                continue;  
 
             ha = HADATA(shp);
             if (!gdth_init_pci(&pcistr[ctr],ha)) {
@@ -4293,11 +4513,14 @@
             NUMDATA(shp)->busnum= 0;
 
             ha->pccb = CMDDATA(shp);
-#if LINUX_VERSION_CODE >= 0x020322
-            ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 
-                                                     GDTH_SCRATCH_ORD);
+            ha->ccb_phys = 0L;
+#if LINUX_VERSION_CODE >= 0x020400
+            ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 
+                                                &ha->scratch_phys); 
 #else
             ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
+            if (ha->pscratch)
+                ha->scratch_phys = virt_to_bus(ha->pscratch);
 #endif
             ha->scratch_busy = FALSE;
             ha->req_first = NULL;
@@ -4312,12 +4535,14 @@
                 printk("GDT-PCI: Error during device scan\n");
                 --gdth_ctr_count;
                 --gdth_ctr_vcount;
-                if (ha->pscratch != NULL)
-#if LINUX_VERSION_CODE >= 0x020322
-                    free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD);
+                if (ha->pscratch != NULL) {
+#if LINUX_VERSION_CODE >= 0x020400
+                    pci_free_consistent(ha->pdev, GDTH_SCRATCH, 
+                                        ha->pscratch, ha->scratch_phys);
 #else
                     scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
 #endif
+                }
 #if LINUX_VERSION_CODE >= 0x010346 
                 free_irq(ha->irq,ha);
 #else
@@ -4365,6 +4590,9 @@
         gdth_timer.function = gdth_timeout;
         add_timer(&gdth_timer);
 #endif
+#ifdef GDTH_IOCTL_CHRDEV
+        major = register_chrdev(0,"gdth",&gdth_fops);
+#endif
 #if LINUX_VERSION_CODE >= 0x020100
         register_reboot_notifier(&gdth_notifier);
 #endif
@@ -4399,8 +4627,12 @@
             free_dma(shp->dma_channel);
         }
 #endif
-#if LINUX_VERSION_CODE >= 0x020322
-        free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD);
+#if LINUX_VERSION_CODE >= 0x020400
+        pci_free_consistent(ha->pdev, GDTH_SCRATCH, 
+            ha->pscratch, ha->scratch_phys);
+        if (ha->ccb_phys)
+            pci_unmap_single(ha->pdev,ha->ccb_phys,
+                             sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
 #else
         scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
 #endif
@@ -4412,6 +4644,9 @@
 #ifdef GDTH_STATISTICS
             del_timer(&gdth_timer);
 #endif
+#ifdef GDTH_IOCTL_CHRDEV
+            unregister_chrdev(major,"gdth");
+#endif
 #if LINUX_VERSION_CODE >= 0x020100
             unregister_reboot_notifier(&gdth_notifier);
 #endif
@@ -4507,15 +4742,24 @@
     unchar b;
 
     TRACE2(("gdth_eh_bus_reset()\n"));
+#if LINUX_VERSION_CODE >= 0x02053C
     hanum = NUMDATA(scp->device->host)->hanum;
     b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
+#else
+    hanum = NUMDATA(scp->host)->hanum;
+    b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
+#endif
     ha    = HADATA(gdth_ctr_tab[hanum]);
 
     /* clear command tab */
     GDTH_LOCK_HA(ha, flags);
     for (i = 0; i < GDTH_MAXCMDS; ++i) {
         cmnd = ha->cmd_tab[i].cmnd;
+#if LINUX_VERSION_CODE >= 0x02053C
         if (!SPECIAL_SCP(cmnd) && cmnd->device->channel == b)
+#else
+        if (!SPECIAL_SCP(cmnd) && cmnd->channel == b)
+#endif
             ha->cmd_tab[i].cmnd = UNUSED_CMND;
     }
     GDTH_UNLOCK_HA(ha, flags);
@@ -4558,16 +4802,31 @@
 }
 #endif
 
-int gdth_bios_param(struct scsi_device *sdev, struct block_device *bdev,
-		sector_t capacity, int *ip)
+
+#if LINUX_VERSION_CODE >= 0x020503
+int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip)
+#elif LINUX_VERSION_CODE >= 0x010300
+int gdth_bios_param(Disk *disk,kdev_t dev,int *ip)
+#else
+int gdth_bios_param(Disk *disk,int dev,int *ip)
+#endif
 {
     unchar b, t;
     int hanum;
     gdth_ha_str *ha;
+    struct scsi_device *sd;
+    unsigned capacity;
 
-    hanum = NUMDATA(sdev->host)->hanum;
-    b = virt_ctr ? NUMDATA(sdev->host)->busnum : sdev->channel;
-    t = sdev->id;
+#if LINUX_VERSION_CODE >= 0x020503
+    sd = sdev;
+    capacity = cap;
+#else
+    sd = disk->device;
+    capacity = disk->capacity;
+#endif
+    hanum = NUMDATA(sd->host)->hanum;
+    b = virt_ctr ? NUMDATA(sd->host)->busnum : sd->channel;
+    t = sd->id;
     TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", hanum, b, t)); 
     ha = HADATA(gdth_ctr_tab[hanum]);
 
@@ -4592,14 +4851,19 @@
     int hanum;
     int priority;
 
-    TRACE(("gdth_queuecommand() cmd 0x%x id %d lun %d\n",
-           scp->cmnd[0],scp->device->id,scp->lun));
+    TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0]));
     
     scp->scsi_done = (void *)done;
     scp->SCp.have_data_in = 1;
     scp->SCp.phase = -1;
     scp->SCp.sent_command = -1;
+    scp->SCp.Status = GDTH_MAP_NONE;
+    scp->SCp.buffer = (struct scatterlist *)NULL;
+#if LINUX_VERSION_CODE >= 0x02053C
     hanum = NUMDATA(scp->device->host)->hanum;
+#else
+    hanum = NUMDATA(scp->host)->hanum;
+#endif
 #ifdef GDTH_STATISTICS
     ++act_ios;
 #endif
@@ -4615,6 +4879,667 @@
     return 0;
 }
 
+#ifdef GDTH_IOCTL_CHRDEV
+static int gdth_open(struct inode *inode, struct file *filep)
+{
+    TRACE(("gdth_open()\n"));
+    return 0;
+}
+
+static int gdth_close(struct inode *inode, struct file *filep)
+{
+    TRACE(("gdth_close()\n"));
+    return 0;
+}
+
+static int gdth_ioctl(struct inode *inode, struct file *filep,
+                      unsigned int cmd, unsigned long arg)
+{
+    gdth_ha_str *ha; 
+#if LINUX_VERSION_CODE >= 0x020503
+    Scsi_Request *srp;
+    Scsi_Cmnd *scp;
+    Scsi_Device *sdev;
+#elif LINUX_VERSION_CODE >= 0x020322
+    Scsi_Cmnd *scp;
+    Scsi_Device *sdev;
+#else
+    Scsi_Cmnd scp;
+    Scsi_Device sdev;
+#endif
+    ulong flags;
+    char cmnd[MAX_COMMAND_SIZE];   
+    memset(cmnd, 0xff, 12);
+    
+    TRACE(("gdth_ioctl() cmd 0x%x\n", cmd));
+ 
+    switch (cmd) {
+      case GDTIOCTL_CTRCNT:
+      { 
+        int cnt = gdth_ctr_count;
+        put_user(cnt, (int *)arg);
+        break;
+      }
+
+      case GDTIOCTL_DRVERS:
+      { 
+        int ver = (GDTH_VERSION<<8) | GDTH_SUBVERSION;
+        put_user(ver, (int *)arg);
+        break;
+      }
+      
+      case GDTIOCTL_OSVERS:
+      { 
+        gdth_ioctl_osvers osv; 
+
+        osv.version = (unchar)(LINUX_VERSION_CODE >> 16);
+        osv.subversion = (unchar)(LINUX_VERSION_CODE >> 8);
+        osv.revision = (ushort)(LINUX_VERSION_CODE & 0xff);
+        copy_to_user((char *)arg, &osv, sizeof(gdth_ioctl_osvers));
+        break;
+      }
+
+      case GDTIOCTL_CTRTYPE:
+      { 
+        gdth_ioctl_ctrtype ctrt;
+        
+        if (copy_from_user(&ctrt, (char *)arg, sizeof(gdth_ioctl_ctrtype)) ||
+            ctrt.ionode >= gdth_ctr_count)
+            return -EFAULT;
+        ha = HADATA(gdth_ctr_tab[ctrt.ionode]);
+        if (ha->type == GDT_ISA || ha->type == GDT_EISA) {
+            ctrt.type = (unchar)((ha->stype>>20) - 0x10);
+        } else {
+            if (ha->type != GDT_PCIMPR) {
+                ctrt.type = (unchar)((ha->stype<<4) + 6);
+            } else {
+                ctrt.type = 
+                    (ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe);
+                if (ha->stype >= 0x300)
+                    ctrt.ext_type = 0x6000 | ha->subdevice_id;
+                else 
+                    ctrt.ext_type = 0x6000 | ha->stype;
+            }
+            ctrt.device_id = ha->stype;
+            ctrt.sub_device_id = ha->subdevice_id;
+        }
+        ctrt.info = ha->brd_phys;
+        ctrt.oem_id = ha->oem_id;
+        if (copy_to_user((char *)arg, &ctrt, sizeof(gdth_ioctl_ctrtype)))
+            return -EFAULT;
+        break;
+      }
+        
+      case GDTIOCTL_GENERAL:
+      {
+        gdth_ioctl_general gen;
+        char *buf = NULL;
+        ulong32 paddr; 
+        int hanum;
+        
+        if (copy_from_user(&gen, (char *)arg, sizeof(gdth_ioctl_general)) ||
+            gen.ionode >= gdth_ctr_count)
+            return -EFAULT;
+        hanum = gen.ionode; 
+        ha = HADATA(gdth_ctr_tab[hanum]);
+        if (gen.data_len + gen.sense_len != 0) {
+            if (!(buf = gdth_ioctl_alloc(hanum, gen.data_len + gen.sense_len, 
+                                         FALSE, &paddr)))
+                return -EFAULT;
+            if (copy_from_user(buf, (char *)arg + sizeof(gdth_ioctl_general),  
+                               gen.data_len + gen.sense_len)) {
+                gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
+                return -EFAULT;
+            }
+
+            if (gen.command.OpCode == GDT_IOCTL) {
+                gen.command.u.ioctl.p_param = paddr;
+            } else if (gen.command.Service == CACHESERVICE) {
+                if (ha->cache_feat & SCATTER_GATHER) {
+                    gen.command.u.cache.DestAddr = 0xffffffff;
+                    gen.command.u.cache.sg_canz = 1;
+                    gen.command.u.cache.sg_lst[0].sg_ptr = paddr;
+                    gen.command.u.cache.sg_lst[0].sg_len = gen.data_len;
+                    gen.command.u.cache.sg_lst[1].sg_len = 0;
+                } else {
+                    gen.command.u.cache.DestAddr = paddr;
+                    gen.command.u.cache.sg_canz = 0;
+                }
+            } else if (gen.command.Service == SCSIRAWSERVICE) {
+                if (ha->raw_feat & SCATTER_GATHER) {
+                    gen.command.u.raw.sdata = 0xffffffff;
+                    gen.command.u.raw.sg_ranz = 1;
+                    gen.command.u.raw.sg_lst[0].sg_ptr = paddr;
+                    gen.command.u.raw.sg_lst[0].sg_len = gen.data_len;
+                    gen.command.u.raw.sg_lst[1].sg_len = 0;
+                } else {
+                    gen.command.u.raw.sdata = paddr;
+                    gen.command.u.raw.sg_ranz = 0;
+                }
+                gen.command.u.raw.sense_data = paddr + gen.data_len;
+
+            } else {
+                gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
+                return -EFAULT;
+            }
+        }
+
+#if LINUX_VERSION_CODE >= 0x020503
+        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+        srp  = scsi_allocate_request(sdev);
+        if (!srp)
+            return -ENOMEM;
+        srp->sr_cmd_len = 12;
+        srp->sr_use_sg = 0;
+        gdth_do_req(srp, &gen.command, cmnd, gen.timeout);
+        gen.status = srp->sr_command->SCp.Status;
+        gen.info = srp->sr_command->SCp.Message;
+        scsi_release_request(srp);
+        scsi_free_host_dev(sdev);
+#elif LINUX_VERSION_CODE >= 0x020322
+        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+        scp  = scsi_allocate_device(sdev, 1, FALSE);
+        if (!scp)
+            return -ENOMEM;
+        scp->cmd_len = 12;
+        scp->use_sg = 0;
+        gdth_do_cmd(scp, &gen.command, cmnd, gen.timeout);
+        gen.status = scp->SCp.Status;
+        gen.info = scp->SCp.Message;
+        scsi_release_command(scp);
+        scsi_free_host_dev(sdev);
+#else
+        memset(&sdev,0,sizeof(Scsi_Device));
+        memset(&scp, 0,sizeof(Scsi_Cmnd));
+        sdev.host = scp.host = gdth_ctr_tab[hanum];
+        sdev.id = scp.target = sdev.host->this_id;
+        scp.device = &sdev;
+        gdth_do_cmd(&scp, &gen.command, cmnd, gen.timeout);
+        gen.status = scp.SCp.Status;
+        gen.info = scp.SCp.Message;
+#endif
+
+        if (copy_to_user((char *)arg + sizeof(gdth_ioctl_general), buf, 
+                         gen.data_len + gen.sense_len)) {
+            gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
+            return -EFAULT; 
+        } 
+        if (copy_to_user((char *)arg, &gen, 
+            sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) {
+            gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
+            return -EFAULT;
+        }
+        gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
+        break;
+      }
+ 
+      case GDTIOCTL_EVENT:
+      {
+        gdth_ioctl_event evt;
+        gdth_ha_str *ha;
+        ulong flags;
+
+        if (copy_from_user(&evt, (char *)arg, sizeof(gdth_ioctl_event)) ||
+            evt.ionode >= gdth_ctr_count)
+            return -EFAULT;
+        ha = HADATA(gdth_ctr_tab[evt.ionode]);
+
+        if (evt.erase == 0xff) {
+            if (evt.event.event_source == ES_TEST)
+                evt.event.event_data.size=sizeof(evt.event.event_data.eu.test); 
+            else if (evt.event.event_source == ES_DRIVER)
+                evt.event.event_data.size=sizeof(evt.event.event_data.eu.driver); 
+            else if (evt.event.event_source == ES_SYNC)
+                evt.event.event_data.size=sizeof(evt.event.event_data.eu.sync); 
+            else
+                evt.event.event_data.size=sizeof(evt.event.event_data.eu.async);
+            GDTH_LOCK_HA(ha, flags);
+            gdth_store_event(ha, evt.event.event_source, evt.event.event_idx,
+                             &evt.event.event_data);
+            GDTH_UNLOCK_HA(ha, flags);
+        } else if (evt.erase == 0xfe) {
+            gdth_clear_events();
+        } else if (evt.erase == 0) {
+            evt.handle = gdth_read_event(ha, evt.handle, &evt.event);
+        } else {
+            gdth_readapp_event(ha, evt.erase, &evt.event);
+        }     
+        if (copy_to_user((char *)arg, &evt, sizeof(gdth_ioctl_event)))
+            return -EFAULT;
+        break;
+      }
+
+      case GDTIOCTL_LOCKDRV:
+      {
+        gdth_ioctl_lockdrv ldrv;
+        unchar i, j;
+
+        if (copy_from_user(&ldrv, (char *)arg, sizeof(gdth_ioctl_lockdrv)) ||
+            ldrv.ionode >= gdth_ctr_count)
+            return -EFAULT;
+        ha = HADATA(gdth_ctr_tab[ldrv.ionode]);
+ 
+        for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) {
+            j = ldrv.drives[i];
+            if (j >= MAX_HDRIVES || !ha->hdr[j].present)
+                continue;
+            if (ldrv.lock) {
+                GDTH_LOCK_HA(ha, flags);
+                ha->hdr[j].lock = 1;
+                GDTH_UNLOCK_HA(ha, flags);
+                gdth_wait_completion(ldrv.ionode, ha->bus_cnt, j); 
+                gdth_stop_timeout(ldrv.ionode, ha->bus_cnt, j); 
+            } else {
+                GDTH_LOCK_HA(ha, flags);
+                ha->hdr[j].lock = 0;
+                GDTH_UNLOCK_HA(ha, flags);
+                gdth_start_timeout(ldrv.ionode, ha->bus_cnt, j); 
+                gdth_next(ldrv.ionode); 
+            }
+        } 
+        break;
+      }
+
+      case GDTIOCTL_LOCKCHN:
+      {
+        gdth_ioctl_lockchn lchn;
+        unchar i, j;
+
+        if (copy_from_user(&lchn, (char *)arg, sizeof(gdth_ioctl_lockchn)) ||
+            lchn.ionode >= gdth_ctr_count)
+            return -EFAULT;
+        ha = HADATA(gdth_ctr_tab[lchn.ionode]);
+        
+        i = lchn.channel;
+        if (i < ha->bus_cnt) {
+            if (lchn.lock) {
+                GDTH_LOCK_HA(ha, flags);
+                ha->raw[i].lock = 1;
+                GDTH_UNLOCK_HA(ha, flags);
+                for (j = 0; j < ha->tid_cnt; ++j) {
+                    gdth_wait_completion(lchn.ionode, i, j); 
+                    gdth_stop_timeout(lchn.ionode, i, j); 
+                }
+            } else {
+                GDTH_LOCK_HA(ha, flags);
+                ha->raw[i].lock = 0;
+                GDTH_UNLOCK_HA(ha, flags);
+                for (j = 0; j < ha->tid_cnt; ++j) {
+                    gdth_start_timeout(lchn.ionode, i, j); 
+                    gdth_next(lchn.ionode); 
+                }
+            }
+        } 
+        break;
+      }
+
+      case GDTIOCTL_RESCAN:
+      {
+        gdth_ioctl_rescan rsc;
+        gdth_cmd_str cmd;
+        ushort i, status, hdr_cnt;
+        ulong32 info;
+        int hanum, cyls, hds, secs;
+        
+        if (copy_from_user(&rsc, (char *)arg, sizeof(gdth_ioctl_rescan)) ||
+            rsc.ionode >= gdth_ctr_count)
+            return -EFAULT;
+        hanum = rsc.ionode;
+        ha = HADATA(gdth_ctr_tab[hanum]);
+
+#if LINUX_VERSION_CODE >= 0x020503
+        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+        srp  = scsi_allocate_request(sdev);
+        if (!srp)
+            return -ENOMEM;
+        srp->sr_cmd_len = 12;
+        srp->sr_use_sg = 0;
+#elif LINUX_VERSION_CODE >= 0x020322
+        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+        scp  = scsi_allocate_device(sdev, 1, FALSE);
+        if (!scp)
+            return -ENOMEM;
+        scp->cmd_len = 12;
+        scp->use_sg = 0;
+#else
+        memset(&sdev,0,sizeof(Scsi_Device));
+        memset(&scp, 0,sizeof(Scsi_Cmnd));
+        sdev.host = scp.host = gdth_ctr_tab[hanum];
+        sdev.id = scp.target = sdev.host->this_id;
+        scp.device = &sdev;
+#endif
+     
+        if (rsc.flag == 0) {
+            /* old method: re-init. cache service */
+            cmd.Service = CACHESERVICE;
+            cmd.OpCode = GDT_INIT;
+            cmd.u.cache.DeviceNo = LINUX_OS;
+#if LINUX_VERSION_CODE >= 0x020503
+            gdth_do_req(srp, &cmd, cmnd, 30);
+            status = (ushort)srp->sr_command->SCp.Status;
+            info = (ulong32)srp->sr_command->SCp.Message;
+#elif LINUX_VERSION_CODE >= 0x020322
+            gdth_do_cmd(scp, &cmd, cmnd, 30);
+            status = (ushort)scp->SCp.Status;
+            info = (ulong32)scp->SCp.Message;
+#else
+            gdth_do_cmd(&scp, &cmd, cmnd, 30);
+            status = (ushort)scp.SCp.Status;
+            info = (ulong32)scp.SCp.Message;
+#endif
+            i = 0;
+            hdr_cnt = (status == S_OK ? (ushort)info : 0);
+        } else {
+            i = rsc.hdr_no;
+            hdr_cnt = i + 1;
+        }
+        for (; i < hdr_cnt && i < MAX_HDRIVES; ++i) {
+            cmd.Service = CACHESERVICE;
+            cmd.OpCode = GDT_INFO;
+            cmd.u.cache.DeviceNo = i;
+#if LINUX_VERSION_CODE >= 0x020503
+            gdth_do_req(srp, &cmd, cmnd, 30);
+            status = (ushort)srp->sr_command->SCp.Status;
+            info = (ulong32)srp->sr_command->SCp.Message;
+#elif LINUX_VERSION_CODE >= 0x020322
+            gdth_do_cmd(scp, &cmd, cmnd, 30);
+            status = (ushort)scp->SCp.Status;
+            info = (ulong32)scp->SCp.Message;
+#else
+            gdth_do_cmd(&scp, &cmd, cmnd, 30);
+            status = (ushort)scp.SCp.Status;
+            info = (ulong32)scp.SCp.Message;
+#endif
+            GDTH_LOCK_HA(ha, flags);
+            rsc.hdr_list[i].bus = ha->virt_bus;
+            rsc.hdr_list[i].target = i;
+            rsc.hdr_list[i].lun = 0;
+            if (status != S_OK) {
+                ha->hdr[i].present = FALSE;
+            } else {
+                ha->hdr[i].present = TRUE;
+                ha->hdr[i].size = info;
+                /* evaluate mapping */
+                ha->hdr[i].size &= ~SECS32;
+                gdth_eval_mapping(ha->hdr[i].size,&cyls,&hds,&secs); 
+                ha->hdr[i].heads = hds;
+                ha->hdr[i].secs = secs;
+                /* round size */
+                ha->hdr[i].size = cyls * hds * secs;
+            }
+            GDTH_UNLOCK_HA(ha, flags);
+            if (status != S_OK)
+                continue; 
+
+            /* devtype, cluster info, R/W attribs */
+            cmd.Service = CACHESERVICE;
+            cmd.OpCode = GDT_DEVTYPE;
+            cmd.u.cache.DeviceNo = i;
+#if LINUX_VERSION_CODE >= 0x020503
+            gdth_do_req(srp, &cmd, cmnd, 30);
+            status = (ushort)srp->sr_command->SCp.Status;
+            info = (ulong32)srp->sr_command->SCp.Message;
+#elif LINUX_VERSION_CODE >= 0x020322
+            gdth_do_cmd(scp, &cmd, cmnd, 30);
+            status = (ushort)scp->SCp.Status;
+            info = (ulong32)scp->SCp.Message;
+#else
+            gdth_do_cmd(&scp, &cmd, cmnd, 30);
+            status = (ushort)scp.SCp.Status;
+            info = (ulong32)scp.SCp.Message;
+#endif
+            GDTH_LOCK_HA(ha, flags);
+            ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0);
+            GDTH_UNLOCK_HA(ha, flags);
+
+            cmd.Service = CACHESERVICE;
+            cmd.OpCode = GDT_CLUST_INFO;
+            cmd.u.cache.DeviceNo = i;
+#if LINUX_VERSION_CODE >= 0x020503
+            gdth_do_req(srp, &cmd, cmnd, 30);
+            status = (ushort)srp->sr_command->SCp.Status;
+            info = (ulong32)srp->sr_command->SCp.Message;
+#elif LINUX_VERSION_CODE >= 0x020322
+            gdth_do_cmd(scp, &cmd, cmnd, 30);
+            status = (ushort)scp->SCp.Status;
+            info = (ulong32)scp->SCp.Message;
+#else
+            gdth_do_cmd(&scp, &cmd, cmnd, 30);
+            status = (ushort)scp.SCp.Status;
+            info = (ulong32)scp.SCp.Message;
+#endif
+            GDTH_LOCK_HA(ha, flags);
+            ha->hdr[i].cluster_type = 
+                ((status == S_OK && !shared_access) ? (ushort)info : 0);
+            GDTH_UNLOCK_HA(ha, flags);
+            rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
+
+            cmd.Service = CACHESERVICE;
+            cmd.OpCode = GDT_RW_ATTRIBS;
+            cmd.u.cache.DeviceNo = i;
+#if LINUX_VERSION_CODE >= 0x020503
+            gdth_do_req(srp, &cmd, cmnd, 30);
+            status = (ushort)srp->sr_command->SCp.Status;
+            info = (ulong32)srp->sr_command->SCp.Message;
+#elif LINUX_VERSION_CODE >= 0x020322
+            gdth_do_cmd(scp, &cmd, cmnd, 30);
+            status = (ushort)scp->SCp.Status;
+            info = (ulong32)scp->SCp.Message;
+#else
+            gdth_do_cmd(&scp, &cmd, cmnd, 30);
+            status = (ushort)scp.SCp.Status;
+            info = (ulong32)scp.SCp.Message;
+#endif
+            GDTH_LOCK_HA(ha, flags);
+            ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0);
+            GDTH_UNLOCK_HA(ha, flags);
+        }
+#if LINUX_VERSION_CODE >= 0x020503
+        scsi_release_request(srp);
+        scsi_free_host_dev(sdev);
+#elif LINUX_VERSION_CODE >= 0x020322
+        scsi_release_command(scp);
+        scsi_free_host_dev(sdev);
+#endif       
+ 
+        if (copy_to_user((char *)arg, &rsc, sizeof(gdth_ioctl_rescan)))
+            return -EFAULT;
+        break;
+      }
+  
+      case GDTIOCTL_HDRLIST:
+      {
+        gdth_ioctl_rescan rsc;
+        gdth_cmd_str cmd;
+        gdth_ha_str *ha;
+        unchar i;
+        int hanum;
+        
+        if (copy_from_user(&rsc, (char *)arg, sizeof(gdth_ioctl_rescan)) ||
+            rsc.ionode >= gdth_ctr_count)
+            return -EFAULT;
+        hanum = rsc.ionode;
+        ha = HADATA(gdth_ctr_tab[hanum]);
+   
+#if LINUX_VERSION_CODE >= 0x020503
+        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+        srp  = scsi_allocate_request(sdev);
+        if (!srp)
+            return -ENOMEM;
+        srp->sr_cmd_len = 12;
+        srp->sr_use_sg = 0;
+#elif LINUX_VERSION_CODE >= 0x020322
+        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+        scp  = scsi_allocate_device(sdev, 1, FALSE);
+        if (!scp)
+            return -ENOMEM;
+        scp->cmd_len = 12;
+        scp->use_sg = 0;
+#else
+        memset(&sdev,0,sizeof(Scsi_Device));
+        memset(&scp, 0,sizeof(Scsi_Cmnd));
+        sdev.host = scp.host = gdth_ctr_tab[hanum];
+        sdev.id = scp.target = sdev.host->this_id;
+        scp.device = &sdev;
+#endif
+
+        for (i = 0; i < MAX_HDRIVES; ++i) { 
+            if (!ha->hdr[i].present) {
+                rsc.hdr_list[i].bus = 0xff; 
+                continue;
+            } 
+            rsc.hdr_list[i].bus = ha->virt_bus;
+            rsc.hdr_list[i].target = i;
+            rsc.hdr_list[i].lun = 0;
+            rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
+            if (ha->hdr[i].cluster_type & CLUSTER_DRIVE) { 
+                cmd.Service = CACHESERVICE;
+                cmd.OpCode = GDT_CLUST_INFO;
+                cmd.u.cache.DeviceNo = i;
+#if LINUX_VERSION_CODE >= 0x020503
+                gdth_do_req(srp, &cmd, cmnd, 30);
+                if (srp->sr_command->SCp.Status == S_OK)
+                    rsc.hdr_list[i].cluster_type = srp->sr_command->SCp.Message;
+#elif LINUX_VERSION_CODE >= 0x020322
+                gdth_do_cmd(scp, &cmd, cmnd, 30);
+                if (scp->SCp.Status == S_OK)
+                    rsc.hdr_list[i].cluster_type = scp->SCp.Message;
+#else
+                gdth_do_cmd(&scp, &cmd, cmnd, 30);
+                if (scp.SCp.Status == S_OK)
+                    rsc.hdr_list[i].cluster_type = scp.SCp.Message;
+#endif
+            }
+        } 
+#if LINUX_VERSION_CODE >= 0x020503
+        scsi_release_request(srp);
+        scsi_free_host_dev(sdev);
+#elif LINUX_VERSION_CODE >= 0x020322
+        scsi_release_command(scp);
+        scsi_free_host_dev(sdev);
+#endif       
+ 
+        if (copy_to_user((char *)arg, &rsc, sizeof(gdth_ioctl_rescan)))
+            return -EFAULT;
+        break;
+      }
+
+      case GDTIOCTL_RESET_BUS:
+      {
+        gdth_ioctl_reset res;
+        int hanum, rval;
+
+        if (copy_from_user(&res, (char *)arg, sizeof(gdth_ioctl_reset)) ||
+            res.ionode >= gdth_ctr_count)
+            return -EFAULT;
+        hanum = res.ionode; 
+
+        /* Because we need a Scsi_Cmnd struct., we make a scsi_allocate device also for kernels >=2.5.x */        
+#if LINUX_VERSION_CODE >= 0x02053C
+        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+        scp  = scsi_get_command(sdev, GFP_KERNEL);
+        if (!scp)
+            return -ENOMEM;
+        scp->cmd_len = 12;
+        scp->use_sg = 0;
+        scp->device->channel = virt_ctr ? 0 : res.number;
+        rval = gdth_eh_bus_reset(scp);
+        res.status = (rval == SUCCESS ? S_OK : S_GENERR);
+        scsi_put_command(scp);
+        scsi_free_host_dev(sdev);
+#elif LINUX_VERSION_CODE >= 0x020322
+        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+#if LINUX_VERSION_CODE >= 0x020503
+        scp  = scsi_allocate_device(sdev, 1);
+#else
+        scp  = scsi_allocate_device(sdev, 1, FALSE);
+#endif
+        if (!scp)
+            return -ENOMEM;
+        scp->cmd_len = 12;
+        scp->use_sg = 0;
+        scp->channel = virt_ctr ? 0 : res.number;
+        rval = gdth_eh_bus_reset(scp);
+        res.status = (rval == SUCCESS ? S_OK : S_GENERR);
+        scsi_release_command(scp);
+        scsi_free_host_dev(sdev);
+#elif LINUX_VERSION_CODE >= 0x02015F
+        memset(&sdev,0,sizeof(Scsi_Device));
+        memset(&scp, 0,sizeof(Scsi_Cmnd));
+        sdev.host = scp.host = gdth_ctr_tab[hanum];
+        sdev.id = scp.target = sdev.host->this_id;
+        scp.device = &sdev;
+        scp.channel = virt_ctr ? 0 : res.number;
+        rval = gdth_eh_bus_reset(&scp);
+        res.status = (rval == SUCCESS ? S_OK : S_GENERR);
+#else
+        res.status = S_OK;
+#endif
+        if (copy_to_user((char *)arg, &res, sizeof(gdth_ioctl_reset)))
+            return -EFAULT;
+        break;
+      }
+
+      case GDTIOCTL_RESET_DRV:
+      {
+        gdth_ioctl_reset res;
+        gdth_cmd_str cmd;
+        int hanum;
+
+        if (copy_from_user(&res, (char *)arg, sizeof(gdth_ioctl_reset)) ||
+            res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES)
+            return -EFAULT;
+        hanum = res.ionode;
+        ha = HADATA(gdth_ctr_tab[hanum]);
+ 
+        if (!ha->hdr[res.number].present)
+            return 0;
+        cmd.Service = CACHESERVICE;
+        cmd.OpCode = GDT_CLUST_RESET;
+        cmd.u.cache.DeviceNo = res.number;
+#if LINUX_VERSION_CODE >= 0x020503
+        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+        srp  = scsi_allocate_request(sdev);
+        if (!srp)
+            return -ENOMEM;
+        srp->sr_cmd_len = 12;
+        srp->sr_use_sg = 0;
+        gdth_do_req(srp, &cmd, cmnd, 30);
+        res.status = (ushort)srp->sr_command->SCp.Status;
+        scsi_release_request(srp);
+        scsi_free_host_dev(sdev);
+#elif LINUX_VERSION_CODE >= 0x020322
+        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+        scp  = scsi_allocate_device(sdev, 1, FALSE);
+        if (!scp)
+            return -ENOMEM;
+        scp->cmd_len = 12;
+        scp->use_sg = 0;
+        gdth_do_cmd(scp, &cmd, cmnd, 30);
+        res.status = (ushort)scp->SCp.Status;
+        scsi_release_command(scp);
+        scsi_free_host_dev(sdev);
+#else
+        memset(&sdev,0,sizeof(Scsi_Device));
+        memset(&scp, 0,sizeof(Scsi_Cmnd));
+        sdev.host = scp.host = gdth_ctr_tab[hanum];
+        sdev.id = scp.target = sdev.host->this_id;
+        scp.device = &sdev;
+        gdth_do_cmd(&scp, &cmd, cmnd, 30);
+        res.status = (ushort)scp.SCp.Status;
+#endif
+        if (copy_to_user((char *)arg, &res, sizeof(gdth_ioctl_reset)))
+            return -EFAULT;
+        break;
+      }
+
+      default:
+        break; 
+    }
+    return 0;
+}
+#endif
+
 #if LINUX_VERSION_CODE >= 0x010300
 /* flush routine */
 static void gdth_flush(int hanum)
@@ -4622,7 +5547,10 @@
     int             i;
     gdth_ha_str     *ha;
     gdth_cmd_str    gdtcmd;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+    Scsi_Request    *srp;
+    Scsi_Device     *sdev;
+#elif LINUX_VERSION_CODE >= 0x020322
     Scsi_Cmnd       *scp;
     Scsi_Device     *sdev;
 #else
@@ -4635,9 +5563,18 @@
     TRACE2(("gdth_flush() hanum %d\n",hanum));
     ha = HADATA(gdth_ctr_tab[hanum]);
 
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
     sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
-    scp  = scsi_get_command(sdev, GFP_KERNEL);
+    srp  = scsi_allocate_request(sdev);
+    if (!srp)
+        return;
+    srp->sr_cmd_len = 12;
+    srp->sr_use_sg = 0;
+#elif LINUX_VERSION_CODE >= 0x020322
+    sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+    scp  = scsi_allocate_device(sdev, 1, FALSE);
+    if (!scp)
+        return;
     scp->cmd_len = 12;
     scp->use_sg = 0;
 #else
@@ -4657,15 +5594,20 @@
             gdtcmd.u.cache.BlockNo = 1;
             gdtcmd.u.cache.sg_canz = 0;
             TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i));
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+            gdth_do_req(srp, &gdtcmd, cmnd, 30);
+#elif LINUX_VERSION_CODE >= 0x020322
             gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #else
             gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
 #endif
         }
     }
-#if LINUX_VERSION_CODE >= 0x020322
-    scsi_put_command(scp);
+#if LINUX_VERSION_CODE >= 0x020503
+    scsi_release_request(srp);
+    scsi_free_host_dev(sdev);
+#elif LINUX_VERSION_CODE >= 0x020322
+    scsi_release_command(scp);
     scsi_free_host_dev(sdev);
 #endif
 }
@@ -4680,7 +5622,10 @@
     int             hanum;
 #ifndef __alpha__
     gdth_cmd_str    gdtcmd;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+    Scsi_Request    *srp;
+    Scsi_Device     *sdev;
+#elif LINUX_VERSION_CODE >= 0x020322
     Scsi_Cmnd       *scp;
     Scsi_Device     *sdev;
 #else
@@ -4702,6 +5647,7 @@
     }
     halt_called = TRUE;
 #endif
+
     printk("GDT: Flushing all host drives .. ");
     for (hanum = 0; hanum < gdth_ctr_count; ++hanum) {
         gdth_flush(hanum);
@@ -4709,28 +5655,48 @@
 #ifndef __alpha__
         /* controller reset */
         memset(cmnd, 0xff, MAX_COMMAND_SIZE);
-#if LINUX_VERSION_CODE >= 0x020322
+        gdtcmd.BoardNode = LOCALBOARD;
+        gdtcmd.Service = CACHESERVICE;
+        gdtcmd.OpCode = GDT_RESET;
+        TRACE2(("gdth_halt(): reset controller %d\n", hanum));
+#if LINUX_VERSION_CODE >= 0x020503
         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
-        scp  = scsi_get_command(sdev, GFP_KERNEL);
+        srp  = scsi_allocate_request(sdev);
+        if (!srp) {
+#if LINUX_VERSION_CODE >= 0x020100
+            unregister_reboot_notifier(&gdth_notifier);
+            return NOTIFY_OK;
+#else
+            return;
+#endif
+        }
+        srp->sr_cmd_len = 12;
+        srp->sr_use_sg = 0;
+        gdth_do_req(srp, &gdtcmd, cmnd, 10);
+        scsi_release_request(srp);
+        scsi_free_host_dev(sdev);
+#elif LINUX_VERSION_CODE >= 0x020322
+        sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+        scp  = scsi_allocate_device(sdev, 1, FALSE);
+        if (!scp) {
+#if LINUX_VERSION_CODE >= 0x020100
+            unregister_reboot_notifier(&gdth_notifier);
+            return NOTIFY_OK;
+#else
+            return;
+#endif
+        }
         scp->cmd_len = 12;
         scp->use_sg = 0;
+        gdth_do_cmd(scp, &gdtcmd, cmnd, 10);
+        scsi_release_command(scp);
+        scsi_free_host_dev(sdev);
 #else
         memset(&sdev,0,sizeof(Scsi_Device));
         memset(&scp, 0,sizeof(Scsi_Cmnd));
         sdev.host = scp.host = gdth_ctr_tab[hanum];
         sdev.id = scp.target = sdev.host->this_id;
         scp.device = &sdev;
-#endif
-
-        gdtcmd.BoardNode = LOCALBOARD;
-        gdtcmd.Service = CACHESERVICE;
-        gdtcmd.OpCode = GDT_RESET;
-        TRACE2(("gdth_halt(): reset controller %d\n", hanum));
-#if LINUX_VERSION_CODE >= 0x020322
-        gdth_do_cmd(scp, &gdtcmd, cmnd, 10);
-        scsi_put_command(scp);
-        scsi_free_host_dev(sdev);
-#else
         gdth_do_cmd(&scp, &gdtcmd, cmnd, 10);
 #endif
 #endif
diff -Nru a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h
--- a/drivers/scsi/gdth.h	Mon Feb 24 10:17:11 2003
+++ b/drivers/scsi/gdth.h	Thu Mar  6 15:10:14 2003
@@ -10,7 +10,7 @@
  *
  * <achim.leubner@intel.com>
  *
- * $Id: gdth.h,v 1.46 2002/02/05 09:39:53 achim Exp $
+ * $Id: gdth.h,v 1.48 2003/02/27 14:58:22 achim Exp $
  */
 
 #include <linux/version.h>
@@ -29,16 +29,16 @@
 /* defines, macros */
 
 /* driver version */
-#define GDTH_VERSION_STR        "2.05"
+#define GDTH_VERSION_STR        "2.07"
 #define GDTH_VERSION            2
-#define GDTH_SUBVERSION         5
+#define GDTH_SUBVERSION         7
 
 /* protocol version */
 #define PROTOCOL_VERSION        1
 
 /* OEM IDs */
-#define OEM_ID_ICP	0x941c
-#define OEM_ID_INTEL	0x8000
+#define OEM_ID_ICP      0x941c
+#define OEM_ID_INTEL    0x8000
 
 /* controller classes */
 #define GDT_ISA         0x01                    /* ISA controller */
@@ -134,12 +134,17 @@
 
 #ifndef PCI_DEVICE_ID_VORTEX_GDTNEWRX
 /* new GDT Rx Controller */
-#define PCI_DEVICE_ID_VORTEX_GDTNEWRX	0x300
+#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
+#define PCI_DEVICE_ID_INTEL_SRC         0x600
+#endif
+
+#ifndef PCI_DEVICE_ID_INTEL_SRC_XSCALE
+/* Intel Storage RAID Controller */
+#define PCI_DEVICE_ID_INTEL_SRC_XSCALE  0x601
 #endif
 
 /* limits */
@@ -153,8 +158,6 @@
 #define MAXID           127
 #define MAXLUN          8
 #define MAXBUS          6
-#define MAX_HDRIVES     100                     /* max. host drive count */
-#define MAX_LDRIVES     255                     /* max. log. drive count */
 #define MAX_EVENTS      100                     /* event buffer count */
 #define MAX_RES_ARGS    40                      /* device reservation, 
                                                    must be a multiple of 4 */
@@ -254,6 +257,7 @@
 #define CACHE_DRV_INFO  0x07                    /* cache drive info */
 #define BOARD_FEATURES  0x15                    /* controller features */
 #define BOARD_INFO      0x28                    /* controller info */
+#define CACHE_READ_OEM_STRING_RECORD 0x84       /* read OEM string record */ 
 #define HOST_GET        0x10001L                /* get host drive list */
 #define IO_CHANNEL      0x00020000L             /* default IO channel */
 #define INVALID_CHANNEL 0x0000ffffL             /* invalid channel */
@@ -265,7 +269,7 @@
 #define S_CACHE_UNKNOWN 12                      /* cache serv.: drive unknown */
 #define S_RAW_SCSI      12                      /* raw serv.: target error */
 #define S_RAW_ILL       0xff                    /* raw serv.: illegal */
-#define S_CACHE_RESERV	-24			/* cache: reserv. conflict */	
+#define S_CACHE_RESERV  -24                     /* cache: reserv. conflict */   
 
 /* timeout values */
 #define INIT_RETRIES    100000                  /* 100000 * 1ms = 100s */
@@ -292,10 +296,15 @@
 #define MAILBOXREG      0x0c90                  /* mailbox reg. (16 bytes) */
 #define EISAREG         0x0cc0                  /* EISA configuration */
 
+/* DMA memory mappings */
+#define GDTH_MAP_NONE   0
+#define GDTH_MAP_SINGLE 1
+#define GDTH_MAP_SG     2
+#define GDTH_MAP_IOCTL  3 
+
 /* other defines */
 #define LINUX_OS        8                       /* used for cache optim. */
 #define SCATTER_GATHER  1                       /* s/g feature */
-#define GDTH_MAXSG      32                      /* max. s/g elements */
 #define SECS32          0x1f                    /* round capacity */
 #define BIOS_ID_OFFS    0x10                    /* offset contr-ID in ISABIOS */
 #define LOCALBOARD      0                       /* board node always 0 */
@@ -303,10 +312,7 @@
 #define SPEZINDEX       1                       /* cmd index unknown service */
 #define GDT_WR_THROUGH  0x100                   /* WRITE_THROUGH supported */
 
-
-/* typedefs */
-typedef u32     ulong32;
-#define PACKED  __attribute__((packed))
+#include "gdth_ioctl.h"
 
 /* screenservice message */
 typedef struct {                               
@@ -535,6 +541,50 @@
     unchar      ld_error;                       /* error */
 } PACKED gdth_cdrinfo_str;
 
+/* OEM string */
+typedef struct {
+    ulong32     ctl_version;
+    ulong32     file_major_version;
+    ulong32     file_minor_version;
+    ulong32     buffer_size;
+    ulong32     cpy_count;
+    ulong32     ext_error;
+    ulong32     oem_id;
+    ulong32     board_id;
+} PACKED gdth_oem_str_params;
+
+typedef struct {
+    unchar      product_0_1_name[16];
+    unchar      product_4_5_name[16];
+    unchar      product_cluster_name[16];
+    unchar      product_reserved[16];
+    unchar      scsi_cluster_target_vendor_id[16];
+    unchar      cluster_raid_fw_name[16];
+    unchar      oem_brand_name[16];
+    unchar      oem_raid_type[16];
+    unchar      bios_type[13];
+    unchar      bios_title[50];
+    unchar      oem_company_name[37];
+    ulong32     pci_id_1;
+    ulong32     pci_id_2;
+    unchar      validation_status[80];
+    unchar      reserved_1[4];
+    unchar      scsi_host_drive_inquiry_vendor_id[16];
+    unchar      library_file_template[16];
+    unchar      reserved_2[16];
+    unchar      tool_name_1[32];
+    unchar      tool_name_2[32];
+    unchar      tool_name_3[32];
+    unchar      oem_contact_1[84];
+    unchar      oem_contact_2[84];
+    unchar      oem_contact_3[84];
+} PACKED gdth_oem_str;
+
+typedef struct {
+    gdth_oem_str_params params;
+    gdth_oem_str        text;
+} PACKED gdth_oem_str_ioctl;
+
 /* board features */
 typedef struct {
     unchar      chaining;                       /* Chaining supported */
@@ -594,118 +644,6 @@
     gdth_hentry_str entry[MAX_HDRIVES];         /* entries */
 } PACKED gdth_hget_str;    
 
-/* scatter/gather element */
-typedef struct {
-    ulong32     sg_ptr;                         /* address */
-    ulong32     sg_len;                         /* length */
-} PACKED gdth_sg_str;
-
-/* command structure */
-typedef struct {
-    ulong32     BoardNode;                      /* board node (always 0) */
-    ulong32     CommandIndex;                   /* command number */
-    ushort      OpCode;                         /* the command (READ,..) */
-    union {
-        struct {
-            ushort      DeviceNo;               /* number of cache drive */
-            ulong32     BlockNo;                /* block number */
-            ulong32     BlockCnt;               /* block count */
-            ulong32     DestAddr;               /* dest. addr. (if s/g: -1) */
-            ulong32     sg_canz;                /* s/g element count */
-            gdth_sg_str sg_lst[GDTH_MAXSG];     /* s/g list */
-        } PACKED cache;                         /* cache service cmd. str. */
-        struct {
-            ushort      param_size;             /* size of p_param buffer */
-            ulong32     subfunc;                /* IOCTL function */
-            ulong32     channel;                /* device */
-            ulong32     p_param;                /* buffer */
-        } PACKED ioctl;                         /* IOCTL command structure */
-        struct {
-            ushort      reserved;
-            union {
-                struct {
-                    ulong32  msg_handle;        /* message handle */
-                    ulong32  msg_addr;          /* message buffer address */
-                } PACKED msg;
-                unchar       data[12];          /* buffer for rtc data, ... */
-            } su;
-        } PACKED screen;                        /* screen service cmd. str. */
-        struct {
-            ushort      reserved;
-            ulong32     direction;              /* data direction */
-            ulong32     mdisc_time;             /* disc. time (0: no timeout)*/
-            ulong32     mcon_time;              /* connect time(0: no to.) */
-            ulong32     sdata;                  /* dest. addr. (if s/g: -1) */
-            ulong32     sdlen;                  /* data length (bytes) */
-            ulong32     clen;                   /* SCSI cmd. length(6,10,12) */
-            unchar      cmd[12];                /* SCSI command */
-            unchar      target;                 /* target ID */
-            unchar      lun;                    /* LUN */
-            unchar      bus;                    /* SCSI bus number */
-            unchar      priority;               /* only 0 used */
-            ulong32     sense_len;              /* sense data length */
-            ulong32     sense_data;             /* sense data addr. */
-            ulong32     link_p;                 /* linked cmds (not supp.) */
-            ulong32     sg_ranz;                /* s/g element count */
-            gdth_sg_str sg_lst[GDTH_MAXSG];     /* s/g list */
-        } PACKED raw;                           /* raw service cmd. struct. */
-    } u;
-    /* additional variables */
-    unchar      Service;                        /* controller service */
-    ushort      Status;                         /* command result */
-    ulong32     Info;                           /* additional information */
-    Scsi_Cmnd   *RequestBuffer;                 /* request buffer */
-} PACKED gdth_cmd_str;
-
-/* controller event structure */
-#define ES_ASYNC    1
-#define ES_DRIVER   2
-#define ES_TEST     3
-#define ES_SYNC     4
-typedef struct {
-    ushort                  size;               /* size of structure */
-    union {
-        char                stream[16];
-        struct {
-            ushort          ionode;
-            ushort          service;
-            ulong32         index;
-        } PACKED driver;
-        struct {
-            ushort          ionode;
-            ushort          service;
-            ushort          status;
-            ulong32         info;
-            unchar          scsi_coord[3];
-        } PACKED async;
-        struct {
-            ushort          ionode;
-            ushort          service;
-            ushort          status;
-            ulong32         info;
-            ushort          hostdrive;
-            unchar          scsi_coord[3];
-            unchar          sense_key;
-        } PACKED sync;
-        struct {
-            ulong32         l1, l2, l3, l4;
-        } PACKED test;
-    } eu;
-    ulong32                 severity;
-    unchar                  event_string[256];          
-} PACKED gdth_evt_data;
-
-typedef struct {
-    ulong32         first_stamp;
-    ulong32         last_stamp;
-    ushort          same_count;
-    ushort          event_source;
-    ushort          event_idx;
-    unchar          application;
-    unchar          reserved;
-    gdth_evt_data   event_data;
-} PACKED gdth_evt_str;
-
 
 /* DPRAM structures */
 
@@ -889,7 +827,9 @@
     ulong32             brd_phys;               /* slot number/BIOS address */
     gdt6c_plx_regs      *plx;                   /* PLX regs (new PCI contr.) */
     gdth_cmd_str        *pccb;                  /* address command structure */
+    ulong32             ccb_phys;               /* phys. address */
     char                *pscratch;              /* scratch (DMA) buffer */
+    ulong32             scratch_phys;           /* phys. address */
     unchar              scratch_busy;           /* in use? */
     unchar              scan_mode;              /* current scan mode */
     unchar              irq;                    /* IRQ */
@@ -946,6 +886,10 @@
 #if LINUX_VERSION_CODE >= 0x02015F
     spinlock_t          smp_lock;
 #endif
+#if LINUX_VERSION_CODE >= 0x020400
+    struct pci_dev      *pdev;
+#endif
+    char                oem_name[8];
 } gdth_ha_str;
 
 /* structure for scsi_register(), SCSI bus != 0 */
@@ -1032,34 +976,145 @@
 #endif
 const char *gdth_info(struct Scsi_Host *);
 
+#if LINUX_VERSION_CODE >= 0x020501
 int gdth_bios_param(struct scsi_device *,struct block_device *,sector_t,int *);
 int gdth_proc_info(char *,char **,off_t,int,int,int);
 int gdth_eh_abort(Scsi_Cmnd *scp);
 int gdth_eh_device_reset(Scsi_Cmnd *scp);
 int gdth_eh_bus_reset(Scsi_Cmnd *scp);
 int gdth_eh_host_reset(Scsi_Cmnd *scp);
-#define GDTH { .proc_name       = "gdth",                          \
-               .proc_info       = gdth_proc_info,                  \
-               .name            = "GDT SCSI Disk Array Controller",\
-               .detect          = gdth_detect,                     \
-               .release         = gdth_release,                    \
-               .info            = gdth_info,                       \
-               .command         = NULL,                            \
-               .queuecommand    = gdth_queuecommand,               \
-               .eh_abort_handler = gdth_eh_abort,                  \
-               .eh_device_reset_handler = gdth_eh_device_reset,    \
-               .eh_bus_reset_handler = gdth_eh_bus_reset,          \
-               .eh_host_reset_handler = gdth_eh_host_reset,        \
-               .abort           = gdth_abort,                      \
-               .reset           = gdth_reset,                      \
-               .bios_param      = gdth_bios_param,                 \
-               .can_queue       = GDTH_MAXCMDS,                    \
-               .this_id         = -1,                              \
-               .sg_tablesize    = GDTH_MAXSG,                      \
-               .cmd_per_lun     = GDTH_MAXC_P_L,                   \
-               .present         = 0,                               \
-               .unchecked_isa_dma = 1,                             \
-               .use_clustering  = ENABLE_CLUSTERING }
+#define GDTH { .proc_name =      "gdth",                          \
+               .proc_info =      gdth_proc_info,                  \
+               .name =           "GDT SCSI Disk Array Controller",\
+               .detect =         gdth_detect,                     \
+               .release =        gdth_release,                    \
+               .info =           gdth_info,                       \
+               .command =        NULL,                            \
+               .queuecommand =   gdth_queuecommand,               \
+               .eh_abort_handler = gdth_eh_abort,                 \
+               .eh_device_reset_handler = gdth_eh_device_reset,   \
+               .eh_bus_reset_handler = gdth_eh_bus_reset,         \
+               .eh_host_reset_handler = gdth_eh_host_reset,       \
+               .abort =          NULL,                            \
+               .reset =          NULL,                            \
+               .bios_param =     gdth_bios_param,                 \
+               .can_queue =      GDTH_MAXCMDS,                    \
+               .this_id =        -1,                              \
+               .sg_tablesize =   GDTH_MAXSG,                      \
+               .cmd_per_lun =    GDTH_MAXC_P_L,                   \
+               .present =        0,                               \
+               .unchecked_isa_dma = 1,                            \
+               .use_clustering = ENABLE_CLUSTERING}
+
+#elif LINUX_VERSION_CODE >= 0x020322
+int gdth_bios_param(Disk *,kdev_t,int *);
+int gdth_proc_info(char *,char **,off_t,int,int,int);
+int gdth_eh_abort(Scsi_Cmnd *scp);
+int gdth_eh_device_reset(Scsi_Cmnd *scp);
+int gdth_eh_bus_reset(Scsi_Cmnd *scp);
+int gdth_eh_host_reset(Scsi_Cmnd *scp);
+#define GDTH { proc_name:       "gdth",                          \
+               proc_info:       gdth_proc_info,                  \
+               name:            "GDT SCSI Disk Array Controller",\
+               detect:          gdth_detect,                     \
+               release:         gdth_release,                    \
+               info:            gdth_info,                       \
+               command:         NULL,                            \
+               queuecommand:    gdth_queuecommand,               \
+               eh_abort_handler: gdth_eh_abort,                  \
+               eh_device_reset_handler: gdth_eh_device_reset,    \
+               eh_bus_reset_handler: gdth_eh_bus_reset,          \
+               eh_host_reset_handler: gdth_eh_host_reset,        \
+               abort:           gdth_abort,                      \
+               reset:           gdth_reset,                      \
+               bios_param:      gdth_bios_param,                 \
+               can_queue:       GDTH_MAXCMDS,                    \
+               this_id:         -1,                              \
+               sg_tablesize:    GDTH_MAXSG,                      \
+               cmd_per_lun:     GDTH_MAXC_P_L,                   \
+               present:         0,                               \
+               unchecked_isa_dma: 1,                             \
+               use_clustering:  ENABLE_CLUSTERING,               \
+               use_new_eh_code: 1       /* use new error code */ }    
+
+#elif LINUX_VERSION_CODE >= 0x02015F
+int gdth_bios_param(Disk *,kdev_t,int *);
+extern struct proc_dir_entry proc_scsi_gdth;
+int gdth_proc_info(char *,char **,off_t,int,int,int);
+int gdth_eh_abort(Scsi_Cmnd *scp);
+int gdth_eh_device_reset(Scsi_Cmnd *scp);
+int gdth_eh_bus_reset(Scsi_Cmnd *scp);
+int gdth_eh_host_reset(Scsi_Cmnd *scp);
+#define GDTH { proc_dir:        &proc_scsi_gdth,                 \
+               proc_info:       gdth_proc_info,                  \
+               name:            "GDT SCSI Disk Array Controller",\
+               detect:          gdth_detect,                     \
+               release:         gdth_release,                    \
+               info:            gdth_info,                       \
+               command:         NULL,                            \
+               queuecommand:    gdth_queuecommand,               \
+               eh_abort_handler: gdth_eh_abort,                  \
+               eh_device_reset_handler: gdth_eh_device_reset,    \
+               eh_bus_reset_handler: gdth_eh_bus_reset,          \
+               eh_host_reset_handler: gdth_eh_host_reset,        \
+               abort:           gdth_abort,                      \
+               reset:           gdth_reset,                      \
+               bios_param:      gdth_bios_param,                 \
+               can_queue:       GDTH_MAXCMDS,                    \
+               this_id:         -1,                              \
+               sg_tablesize:    GDTH_MAXSG,                      \
+               cmd_per_lun:     GDTH_MAXC_P_L,                   \
+               present:         0,                               \
+               unchecked_isa_dma: 1,                             \
+               use_clustering:  ENABLE_CLUSTERING,               \
+               use_new_eh_code: 1       /* use new error code */ }    
+
+#elif LINUX_VERSION_CODE >= 0x010300
+int gdth_bios_param(Disk *,kdev_t,int *);
+extern struct proc_dir_entry proc_scsi_gdth;
+int gdth_proc_info(char *,char **,off_t,int,int,int);
+#define GDTH { NULL, NULL,                              \
+                   &proc_scsi_gdth,                     \
+                   gdth_proc_info,                      \
+                   "GDT SCSI Disk Array Controller",    \
+                   gdth_detect,                         \
+                   gdth_release,                        \
+                   gdth_info,                           \
+                   NULL,                                \
+                   gdth_queuecommand,                   \
+                   gdth_abort,                          \
+                   gdth_reset,                          \
+                   NULL,                                \
+                   gdth_bios_param,                     \
+                   GDTH_MAXCMDS,                        \
+                   -1,                                  \
+                   GDTH_MAXSG,                          \
+                   GDTH_MAXC_P_L,                       \
+                   0,                                   \
+                   1,                                   \
+                   ENABLE_CLUSTERING}
+
+#else
+int gdth_bios_param(Disk *,int,int *);
+#define GDTH { NULL, NULL,                              \
+                   "GDT SCSI Disk Array Controller",    \
+                   gdth_detect,                         \
+                   gdth_release,                        \
+                   gdth_info,                           \
+                   NULL,                                \
+                   gdth_queuecommand,                   \
+                   gdth_abort,                          \
+                   gdth_reset,                          \
+                   NULL,                                \
+                   gdth_bios_param,                     \
+                   GDTH_MAXCMDS,                        \
+                   -1,                                  \
+                   GDTH_MAXSG,                          \
+                   GDTH_MAXC_P_L,                       \
+                   0,                                   \
+                   1,                                   \
+                   ENABLE_CLUSTERING}
+#endif
 
 #endif
 
diff -Nru a/drivers/scsi/gdth_ioctl.h b/drivers/scsi/gdth_ioctl.h
--- a/drivers/scsi/gdth_ioctl.h	Mon Feb  4 23:44:55 2002
+++ b/drivers/scsi/gdth_ioctl.h	Thu Mar  6 15:10:14 2003
@@ -2,7 +2,7 @@
 #define _GDTH_IOCTL_H
 
 /* gdth_ioctl.h
- * $Id: gdth_ioctl.h,v 1.10 2001/05/22 06:28:59 achim Exp $
+ * $Id: gdth_ioctl.h,v 1.11 2003/02/27 14:59:03 achim Exp $
  */
 
 /* IOCTLs */
@@ -23,8 +23,136 @@
 
 #define GDTIOCTL_MAGIC      0xaffe0004
 #define EVENT_SIZE          294 
-#define MAX_HDRIVES         100                     
+#define GDTH_MAXSG      32                      /* max. s/g elements */
 
+#define MAX_LDRIVES     255                     /* max. log. drive count */
+#ifdef GDTH_IOCTL_PROC
+#define MAX_HDRIVES     100                     /* max. host drive count */
+#else
+#define MAX_HDRIVES     MAX_LDRIVES             /* max. host drive count */
+#endif
+
+/* typedefs */
+#ifdef __KERNEL__
+typedef u32     ulong32;
+#endif
+#define PACKED  __attribute__((packed))
+
+/* scatter/gather element */
+typedef struct {
+    ulong32     sg_ptr;                         /* address */
+    ulong32     sg_len;                         /* length */
+} PACKED gdth_sg_str;
+
+/* command structure */
+typedef struct {
+    ulong32     BoardNode;                      /* board node (always 0) */
+    ulong32     CommandIndex;                   /* command number */
+    ushort      OpCode;                         /* the command (READ,..) */
+    union {
+        struct {
+            ushort      DeviceNo;               /* number of cache drive */
+            ulong32     BlockNo;                /* block number */
+            ulong32     BlockCnt;               /* block count */
+            ulong32     DestAddr;               /* dest. addr. (if s/g: -1) */
+            ulong32     sg_canz;                /* s/g element count */
+            gdth_sg_str sg_lst[GDTH_MAXSG];     /* s/g list */
+        } PACKED cache;                         /* cache service cmd. str. */
+        struct {
+            ushort      param_size;             /* size of p_param buffer */
+            ulong32     subfunc;                /* IOCTL function */
+            ulong32     channel;                /* device */
+            ulong32     p_param;                /* buffer */
+        } PACKED ioctl;                         /* IOCTL command structure */
+        struct {
+            ushort      reserved;
+            union {
+                struct {
+                    ulong32  msg_handle;        /* message handle */
+                    ulong32  msg_addr;          /* message buffer address */
+                } PACKED msg;
+                unchar       data[12];          /* buffer for rtc data, ... */
+            } su;
+        } PACKED screen;                        /* screen service cmd. str. */
+        struct {
+            ushort      reserved;
+            ulong32     direction;              /* data direction */
+            ulong32     mdisc_time;             /* disc. time (0: no timeout)*/
+            ulong32     mcon_time;              /* connect time(0: no to.) */
+            ulong32     sdata;                  /* dest. addr. (if s/g: -1) */
+            ulong32     sdlen;                  /* data length (bytes) */
+            ulong32     clen;                   /* SCSI cmd. length(6,10,12) */
+            unchar      cmd[12];                /* SCSI command */
+            unchar      target;                 /* target ID */
+            unchar      lun;                    /* LUN */
+            unchar      bus;                    /* SCSI bus number */
+            unchar      priority;               /* only 0 used */
+            ulong32     sense_len;              /* sense data length */
+            ulong32     sense_data;             /* sense data addr. */
+            ulong32     link_p;                 /* linked cmds (not supp.) */
+            ulong32     sg_ranz;                /* s/g element count */
+            gdth_sg_str sg_lst[GDTH_MAXSG];     /* s/g list */
+        } PACKED raw;                           /* raw service cmd. struct. */
+    } u;
+    /* additional variables */
+    unchar      Service;                        /* controller service */
+    unchar      reserved;
+    ushort      Status;                         /* command result */
+    ulong32     Info;                           /* additional information */
+    void        *RequestBuffer;                 /* request buffer */
+} PACKED gdth_cmd_str;
+
+/* controller event structure */
+#define ES_ASYNC    1
+#define ES_DRIVER   2
+#define ES_TEST     3
+#define ES_SYNC     4
+typedef struct {
+    ushort                  size;               /* size of structure */
+    union {
+        char                stream[16];
+        struct {
+            ushort          ionode;
+            ushort          service;
+            ulong32         index;
+        } PACKED driver;
+        struct {
+            ushort          ionode;
+            ushort          service;
+            ushort          status;
+            ulong32         info;
+            unchar          scsi_coord[3];
+        } PACKED async;
+        struct {
+            ushort          ionode;
+            ushort          service;
+            ushort          status;
+            ulong32         info;
+            ushort          hostdrive;
+            unchar          scsi_coord[3];
+            unchar          sense_key;
+        } PACKED sync;
+        struct {
+            ulong32         l1, l2, l3, l4;
+        } PACKED test;
+    } eu;
+    ulong32                 severity;
+    unchar                  event_string[256];          
+} PACKED gdth_evt_data;
+
+typedef struct {
+    ulong32         first_stamp;
+    ulong32         last_stamp;
+    ushort          same_count;
+    ushort          event_source;
+    ushort          event_idx;
+    unchar          application;
+    unchar          reserved;
+    gdth_evt_data   event_data;
+} PACKED gdth_evt_str;
+
+
+#ifdef GDTH_IOCTL_PROC
 /* IOCTL structure (write) */
 typedef struct {
     ulong32                 magic;              /* IOCTL magic */
@@ -106,7 +234,82 @@
         } hdr_list[MAX_HDRIVES];                /* index is host drive number */
     } iu;
 } gdth_iord_str;
+#endif
+
+#ifdef GDTH_IOCTL_CHRDEV
+/* GDTIOCTL_GENERAL */
+typedef struct {
+    ushort ionode;                              /* controller number */
+    ushort timeout;                             /* timeout */
+    ulong32 info;                               /* error info */ 
+    ushort status;                              /* status */
+    ulong data_len;                             /* data buffer size */
+    ulong sense_len;	                        /* sense buffer size */
+    gdth_cmd_str command;                       /* command */			
+} gdth_ioctl_general;
+
+/* GDTIOCTL_LOCKDRV */
+typedef struct {
+    ushort ionode;                              /* controller number */
+    unchar lock;                                /* lock/unlock */
+    unchar drive_cnt;                           /* drive count */
+    ushort drives[MAX_HDRIVES];                 /* drives */
+} gdth_ioctl_lockdrv;
+
+/* GDTIOCTL_LOCKCHN */
+typedef struct {
+    ushort ionode;                              /* controller number */
+    unchar lock;                                /* lock/unlock */
+    unchar channel;                             /* channel */
+} gdth_ioctl_lockchn;
+
+/* GDTIOCTL_OSVERS */
+typedef struct {
+    unchar version;                             /* OS version */
+    unchar subversion;                          /* OS subversion */
+    ushort revision;                            /* revision */
+} gdth_ioctl_osvers;
+
+/* GDTIOCTL_CTRTYPE */
+typedef struct {
+    ushort ionode;                              /* controller number */
+    unchar type;                                /* controller type */
+    ushort info;                                /* slot etc. */
+    ushort oem_id;                              /* OEM ID */
+    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 */
+} gdth_ioctl_ctrtype;
+
+/* GDTIOCTL_EVENT */
+typedef struct {
+    ushort ionode;
+    int erase;                                  /* erase event? */
+    int handle;                                 /* event handle */
+    gdth_evt_str event;
+} gdth_ioctl_event;
 
+/* GDTIOCTL_RESCAN/GDTIOCTL_HDRLIST */
+typedef struct {
+    ushort ionode;                              /* controller number */
+    unchar flag;                                /* add/remove */
+    ushort hdr_no;                              /* drive no. */
+    struct {
+        unchar bus;                             /* SCSI bus */
+        unchar target;                          /* target ID */
+        unchar lun;                             /* LUN */
+        unchar cluster_type;                    /* cluster properties */
+    } hdr_list[MAX_HDRIVES];                    /* index is host drive number */
+} gdth_ioctl_rescan;
 
+/* GDTIOCTL_RESET_BUS/GDTIOCTL_RESET_DRV */
+typedef struct {
+    ushort ionode;                              /* controller number */
+    ushort number;                              /* bus/host drive number */
+    ushort status;                              /* status */
+} gdth_ioctl_reset;
 #endif
 
+#endif
diff -Nru a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
--- a/drivers/scsi/gdth_proc.c	Tue Feb  4 08:27:21 2003
+++ b/drivers/scsi/gdth_proc.c	Thu Mar  6 15:10:14 2003
@@ -1,8 +1,7 @@
 /* gdth_proc.c 
- * $Id: gdth_proc.c,v 1.33 2001/08/10 07:54:39 achim Exp $
+ * $Id: gdth_proc.c,v 1.35 2003/02/27 15:00:44 achim Exp $
  */
 
-#include "gdth_ioctl.h"
 #if LINUX_VERSION_CODE >= 0x020407
 #include <linux/completion.h>
 #endif
@@ -33,22 +32,33 @@
 
 static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
 {
-    int             ret_val;
-#if LINUX_VERSION_CODE >= 0x020322
+    int             ret_val = -EINVAL;
+#if LINUX_VERSION_CODE >= 0x020503
+    Scsi_Request    *scp;
+    Scsi_Device     *sdev;
+#elif LINUX_VERSION_CODE >= 0x020322
     Scsi_Cmnd       *scp;
     Scsi_Device     *sdev;
 #else
     Scsi_Cmnd       scp;
     Scsi_Device     sdev;
 #endif
+#ifdef GDTH_IOCTL_PROC
     gdth_iowr_str   *piowr;
-
-    TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum));
     piowr = (gdth_iowr_str *)buffer;
+#endif
+    TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum));
 
-#if LINUX_VERSION_CODE >= 0x020322
-    sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
-    scp  = scsi_get_command(sdev, GFP_KERNEL);
+#if LINUX_VERSION_CODE >= 0x020503
+    sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+    scp  = scsi_allocate_request(sdev);
+    if (!scp)
+        return -ENOMEM;
+    scp->sr_cmd_len = 12;
+    scp->sr_use_sg = 0;
+#elif LINUX_VERSION_CODE >= 0x020322
+    sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+    scp  = scsi_allocate_device(sdev, 1, FALSE);
     if (!scp)
         return -ENOMEM;
     scp->cmd_len = 12;
@@ -56,7 +66,7 @@
 #else
     memset(&sdev,0,sizeof(Scsi_Device));
     memset(&scp, 0,sizeof(Scsi_Cmnd));
-    sdev.host = scp.host = gdth_ctr_vtab[vh];
+    sdev.host = scp.host = gdth_ctr_tab[hanum];
     sdev.id = scp.target = sdev.host->this_id;
     scp.device = &sdev;
 #endif
@@ -66,6 +76,7 @@
             buffer += 5;
             length -= 5;
             ret_val = gdth_set_asc_info( buffer, length, hanum, scp );
+#ifdef GDTH_IOCTL_PROC
         } else if (piowr->magic == GDTIOCTL_MAGIC) {
             ret_val = gdth_set_bin_info( buffer, length, hanum, scp );
         } else {
@@ -75,19 +86,22 @@
                 printk("GDT: Please update your driver.\n");
             else
                 printk("GDT: Please update your tool.\n");
-            ret_val = -EINVAL;
+#endif
         }
-    } else {
-        ret_val = -EINVAL;
     }
-#if LINUX_VERSION_CODE >= 0x020322
-    scsi_put_command(scp);
+#if LINUX_VERSION_CODE >= 0x020503
+    scsi_release_request(scp);
+    scsi_free_host_dev(sdev);
+#elif LINUX_VERSION_CODE >= 0x020322
+    scsi_release_command(scp);
     scsi_free_host_dev(sdev);
 #endif
     return ret_val;
 }
          
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp)
+#elif LINUX_VERSION_CODE >= 0x020322
 static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp)
 #else
 static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
@@ -98,6 +112,7 @@
     gdth_ha_str     *ha;
     gdth_cmd_str    gdtcmd;
     gdth_cpar_str   *pcpar;
+    ulong32         paddr;
 
     char            cmnd[MAX_COMMAND_SIZE];
     memset(cmnd, 0xff, 12);
@@ -133,7 +148,9 @@
                 gdtcmd.OpCode = GDT_FLUSH;
                 gdtcmd.u.cache.DeviceNo = i;
                 gdtcmd.u.cache.BlockNo = 1;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+                gdth_do_req(scp, &gdtcmd, cmnd, 30);
+#elif LINUX_VERSION_CODE >= 0x020322
                 gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #else
                 gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
@@ -178,23 +195,25 @@
     }
 
     if (wb_mode) {
-        if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str), TRUE))
+        if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str), TRUE, &paddr))
             return(-EBUSY);
         pcpar = (gdth_cpar_str *)ha->pscratch;
         memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) );
         gdtcmd.Service = CACHESERVICE;
         gdtcmd.OpCode = GDT_IOCTL;
-        gdtcmd.u.ioctl.p_param = virt_to_bus(pcpar);
+        gdtcmd.u.ioctl.p_param = paddr;
         gdtcmd.u.ioctl.param_size = sizeof(gdth_cpar_str);
         gdtcmd.u.ioctl.subfunc = CACHE_CONFIG;
         gdtcmd.u.ioctl.channel = INVALID_CHANNEL;
         pcpar->write_back = wb_mode==1 ? 0:1;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+        gdth_do_req(scp, &gdtcmd, cmnd, 30);
+#elif LINUX_VERSION_CODE >= 0x020322
         gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #else
         gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
 #endif
-        gdth_ioctl_free(hanum, ha->pscratch);
+        gdth_ioctl_free(hanum, GDTH_SCRATCH, ha->pscratch, paddr);
         printk("Done.\n");
         return(orig_length);
     }
@@ -203,7 +222,10 @@
     return(-EINVAL);
 }
 
-#if LINUX_VERSION_CODE >= 0x020322
+#ifdef GDTH_IOCTL_PROC
+#if LINUX_VERSION_CODE >= 0x020503
+static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Request *scp)
+#elif LINUX_VERSION_CODE >= 0x020322
 static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp)
 #else
 static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
@@ -216,7 +238,7 @@
     gdth_iord_str   *piord;
     gdth_cmd_str    *pcmd;
     gdth_evt_str    *pevt;
-    ulong32         *ppadd, add_size, *ppadd2, add_size2, info;
+    ulong32         *ppadd, add_size, *ppadd2, add_size2, info, paddr;
     ulong           flags;
     gdth_cmd_str    gdtcmd;
     int             drv_cyls, drv_hds, drv_secs;
@@ -273,21 +295,25 @@
             return(-EINVAL);
         }
         if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str)+add_size+add_size2,
-                               TRUE ))
+                               TRUE, &paddr ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
-
         piord->size = sizeof(gdth_iord_str) + add_size + add_size2;
         if (add_size > 0) {
             memcpy(piord->iu.general.data, piowr->iu.general.data, add_size);
-            *ppadd = virt_to_bus(piord->iu.general.data);
+            *ppadd = paddr + GDTOFFSOF(gdth_iord_str, iu.general.data[0]);
         }
         if (add_size2 > 0) {
             memcpy(piord->iu.general.data+add_size, piowr->iu.general.data, add_size2);
-            *ppadd2 = virt_to_bus(piord->iu.general.data+add_size);
+            *ppadd2 = paddr + GDTOFFSOF(gdth_iord_str, iu.general.data[0]) + add_size2;
         }
+        
         /* do IOCTL */
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+        gdth_do_req(scp, pcmd, cmnd, piowr->timeout);
+        piord->status = (scp->sr_command->SCp.Message << 16) |
+            scp->sr_command->SCp.Status;
+#elif LINUX_VERSION_CODE >= 0x020322
         gdth_do_cmd(scp, pcmd, cmnd, piowr->timeout);
         piord->status = (scp->SCp.Message<<16)|scp->SCp.Status;
 #else
@@ -297,7 +323,7 @@
         break;
 
       case GDTIOCTL_DRVERS:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -306,7 +332,7 @@
         break;
 
       case GDTIOCTL_CTRTYPE:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -332,7 +358,7 @@
         break;
 
       case GDTIOCTL_CTRCNT:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -341,7 +367,7 @@
         break;
 
       case GDTIOCTL_OSVERS:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -352,7 +378,7 @@
         break;
 
       case GDTIOCTL_LOCKDRV:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         for (i = 0; i < piowr->iu.lockdrv.drive_cnt; ++i) {
@@ -378,7 +404,7 @@
         break;
 
       case GDTIOCTL_LOCKCHN:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
             return(-EBUSY);
         i = piowr->iu.lockchn.channel;
         if (i < ha->bus_cnt) {
@@ -406,7 +432,7 @@
         break;
 
       case GDTIOCTL_EVENT:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         if (piowr->iu.event.erase == 0xff) {
@@ -439,16 +465,19 @@
         piord->size = sizeof(gdth_iord_str);
         piord->status = S_OK;
         break;
-
+      
       case GDTIOCTL_SCSI:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
+#if LINUX_VERSION_CODE >= 0x020503
+        return(-EINVAL);
+#else
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
         memcpy(cmnd, piowr->iu.scsi.cmd, 12);
 #if LINUX_VERSION_CODE >= 0x020322
-        scp->device->id = piowr->iu.scsi.target;
-        scp->device->channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
+        scp->target = piowr->iu.scsi.target;
+        scp->channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
         scp->cmd_len = piowr->iu.scsi.cmd_len;
         gdth_do_cmd(scp, pcmd, cmnd, piowr->timeout);
         piord->status = (scp->SCp.Message<<16)|scp->SCp.Status;
@@ -459,15 +488,47 @@
         gdth_do_cmd(&scp, pcmd, cmnd, piowr->timeout);
         piord->status = (scp.SCp.Message<<16)|scp.SCp.Status;
 #endif
+#endif
         break;
 
       case GDTIOCTL_RESET_BUS:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
-#if LINUX_VERSION_CODE >= 0x020322
-        scp->device->channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
+#if LINUX_VERSION_CODE >= 0x02053C
+        {
+            Scsi_Device     *sdev;
+            Scsi_Cmnd       *scmnd;
+
+            sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+            scmnd= scsi_get_command(sdev, GFP_KERNEL);
+            if (!scmnd)
+                return(-ENOMEM);
+            scmnd->device->host = scp->sr_host; 
+            scmnd->device->channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
+            piord->status = (ulong32)gdth_eh_bus_reset( scmnd );
+            if (piord->status == SUCCESS)
+                piord->status = S_OK;
+            else
+                piord->status = S_GENERR;
+            scsi_put_command(scmnd);
+            scsi_free_host_dev(sdev);
+        }
+#elif LINUX_VERSION_CODE >= 0x020503
+        {
+            Scsi_Cmnd scmnd;
+             
+            scmnd.host = scp->sr_host; 
+            scmnd.channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
+            piord->status = (ulong32)gdth_eh_bus_reset( &scmnd );
+            if (piord->status == SUCCESS)
+                piord->status = S_OK;
+            else
+                piord->status = S_GENERR;
+        }
+#elif LINUX_VERSION_CODE >= 0x020322
+        scp->channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
         piord->status = (ulong32)gdth_eh_bus_reset( scp );
         if (piord->status == SUCCESS)
             piord->status = S_OK;
@@ -486,7 +547,7 @@
         break;
 
       case GDTIOCTL_HDRLIST:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -501,7 +562,12 @@
                     gdtcmd.Service = CACHESERVICE;
                     gdtcmd.OpCode = GDT_CLUST_INFO;
                     gdtcmd.u.cache.DeviceNo = i;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+                    gdth_do_req(scp, &gdtcmd, cmnd, 30);
+                    if (scp->sr_command->SCp.Status == S_OK)
+                        piord->iu.hdr_list[i].cluster_type = 
+                            (unchar)scp->sr_command->SCp.Message;
+#elif LINUX_VERSION_CODE >= 0x020322
                     gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
                     if (scp->SCp.Status == S_OK)
                         piord->iu.hdr_list[i].cluster_type = 
@@ -520,7 +586,7 @@
         break;
 
       case GDTIOCTL_RESCAN:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -532,7 +598,11 @@
             gdtcmd.Service = CACHESERVICE;
             gdtcmd.OpCode = GDT_INIT;
             gdtcmd.u.cache.DeviceNo = LINUX_OS;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+            gdth_do_req(scp, &gdtcmd, cmnd, 30);
+            status = (ushort)scp->sr_command->SCp.Status; 
+            info = (ulong32)scp->sr_command->SCp.Message;
+#elif LINUX_VERSION_CODE >= 0x020322
             gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
             status = (ushort)scp->SCp.Status; 
             info = (ulong32)scp->SCp.Message;
@@ -557,7 +627,11 @@
             gdtcmd.Service = CACHESERVICE;
             gdtcmd.OpCode = GDT_INFO;
             gdtcmd.u.cache.DeviceNo = k;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+            gdth_do_req(scp, &gdtcmd, cmnd, 30);
+            status = (ushort)scp->sr_command->SCp.Status; 
+            info = (ulong32)scp->sr_command->SCp.Message;
+#elif LINUX_VERSION_CODE >= 0x020322
             gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
             status = (ushort)scp->SCp.Status; 
             info = (ulong32)scp->SCp.Message;
@@ -591,7 +665,11 @@
             gdtcmd.Service = CACHESERVICE;
             gdtcmd.OpCode = GDT_DEVTYPE;
             gdtcmd.u.cache.DeviceNo = k;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+            gdth_do_req(scp, &gdtcmd, cmnd, 30);
+            status = (ushort)scp->sr_command->SCp.Status; 
+            info = (ulong32)scp->sr_command->SCp.Message;
+#elif LINUX_VERSION_CODE >= 0x020322
             gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
             status = (ushort)scp->SCp.Status; 
             info = (ulong32)scp->SCp.Message;
@@ -609,7 +687,11 @@
             gdtcmd.Service = CACHESERVICE;
             gdtcmd.OpCode = GDT_CLUST_INFO;
             gdtcmd.u.cache.DeviceNo = k;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+            gdth_do_req(scp, &gdtcmd, cmnd, 30);
+            status = (ushort)scp->sr_command->SCp.Status; 
+            info = (ulong32)scp->sr_command->SCp.Message;
+#elif LINUX_VERSION_CODE >= 0x020322
             gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
             status = (ushort)scp->SCp.Status; 
             info = (ulong32)scp->SCp.Message;
@@ -628,7 +710,11 @@
             gdtcmd.Service = CACHESERVICE;
             gdtcmd.OpCode = GDT_RW_ATTRIBS;
             gdtcmd.u.cache.DeviceNo = k;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+            gdth_do_req(scp, &gdtcmd, cmnd, 30);
+            status = (ushort)scp->sr_command->SCp.Status; 
+            info = (ulong32)scp->sr_command->SCp.Message;
+#elif LINUX_VERSION_CODE >= 0x020322
             gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
             status = (ushort)scp->SCp.Status; 
             info = (ulong32)scp->SCp.Message;
@@ -646,7 +732,7 @@
         break;
 
       case GDTIOCTL_RESET_DRV:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -656,7 +742,10 @@
             gdtcmd.Service = CACHESERVICE;
             gdtcmd.OpCode = GDT_CLUST_RESET;
             gdtcmd.u.cache.DeviceNo = i;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+            gdth_do_req(scp, &gdtcmd, cmnd, 30);
+            piord->status = (ushort)scp->sr_command->SCp.Status; 
+#elif LINUX_VERSION_CODE >= 0x020322
             gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
             piord->status = (scp->SCp.Message<<16)|scp->SCp.Status;
 #else
@@ -671,6 +760,7 @@
     }
     return length;
 }
+#endif
 
 static int gdth_get_info(char *buffer,char **start,off_t offset,
                          int length,int vh,int hanum,int busnum)
@@ -678,14 +768,16 @@
     int size = 0,len = 0;
     off_t begin = 0,pos = 0;
     gdth_ha_str *ha;
-    gdth_iord_str *piord;
     int id, i, j, k, sec, flag;
     int no_mdrv = 0, drv_no, is_mirr;
-    ulong32 cnt;
+    ulong32 cnt, paddr;
 
     gdth_cmd_str gdtcmd;
     gdth_evt_str estr;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+    Scsi_Request *scp;
+    Scsi_Device *sdev; 
+#elif LINUX_VERSION_CODE >= 0x020322
     Scsi_Cmnd *scp;
     Scsi_Device *sdev;
 #else
@@ -710,9 +802,16 @@
     TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum));
     ha = HADATA(gdth_ctr_tab[hanum]);
 
-#if LINUX_VERSION_CODE >= 0x020322
-    sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
-    scp  = scsi_get_command(sdev, GFP_KERNEL);
+#if LINUX_VERSION_CODE >= 0x020503
+    sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+    scp  = scsi_allocate_request(sdev);
+    if (!scp)
+        return -ENOMEM;
+    scp->sr_cmd_len = 12;
+    scp->sr_use_sg = 0;
+#elif LINUX_VERSION_CODE >= 0x020322
+    sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+    scp  = scsi_allocate_device(sdev, 1, FALSE);
     if (!scp)
         return -ENOMEM;
     scp->cmd_len = 12;
@@ -720,13 +819,15 @@
 #else
     memset(&sdev,0,sizeof(Scsi_Device));
     memset(&scp, 0,sizeof(Scsi_Cmnd));
-    sdev.host = scp.host = gdth_ctr_vtab[vh];
+    sdev.host = scp.host = gdth_ctr_tab[hanum];
     sdev.id = scp.target = sdev.host->this_id;
     scp.device = &sdev;
 #endif
 
+#ifdef GDTH_IOCTL_PROC
     /* ioctl from tool? */
     if (!gdth_ioctl_check_bin(hanum, (ushort)length)) {
+#endif
         /* request is i.e. "cat /proc/scsi/gdth/0" */ 
         /* format: %-15s\t%-10s\t%-15s\t%s */
         /* driver parameters */
@@ -798,7 +899,7 @@
             len += size;  pos = begin + len;
             flag = FALSE;
             
-            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr);
             if (!buf) 
                 goto stop_output;
             for (i = 0; i < ha->bus_cnt; ++i) {
@@ -807,7 +908,7 @@
                 pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4);
                 gdtcmd.Service = CACHESERVICE;
                 gdtcmd.OpCode = GDT_IOCTL;
-                gdtcmd.u.ioctl.p_param = virt_to_bus(pds);
+                gdtcmd.u.ioctl.p_param = paddr + GDTH_SCRATCH/4;
                 gdtcmd.u.ioctl.param_size = 3*GDTH_SCRATCH/4;
                 gdtcmd.u.ioctl.subfunc = DSK_STATISTICS | L_CTRL_PATTERN;
                 gdtcmd.u.ioctl.channel = ha->raw[i].address | INVALID_CHANNEL;
@@ -818,7 +919,10 @@
                     sizeof(pds->list[0]);
                 if (pds->entries > cnt)
                     pds->entries = cnt;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+                gdth_do_req(scp, &gdtcmd, cmnd, 30);
+                if (scp->sr_command->SCp.Status != S_OK) 
+#elif LINUX_VERSION_CODE >= 0x020322
                 gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
                 if (scp->SCp.Status != S_OK) 
 #else
@@ -837,12 +941,15 @@
                     pdi = (gdth_diskinfo_str *)buf;
                     gdtcmd.Service = CACHESERVICE;
                     gdtcmd.OpCode = GDT_IOCTL;
-                    gdtcmd.u.ioctl.p_param = virt_to_bus(pdi);
+                    gdtcmd.u.ioctl.p_param = paddr;
                     gdtcmd.u.ioctl.param_size = sizeof(gdth_diskinfo_str);
                     gdtcmd.u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN;
                     gdtcmd.u.ioctl.channel = 
                         ha->raw[i].address | ha->raw[i].id_list[j];
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+                    gdth_do_req(scp, &gdtcmd, cmnd, 30);
+                    if (scp->sr_command->SCp.Status == S_OK) 
+#elif LINUX_VERSION_CODE >= 0x020322
                     gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
                     if (scp->SCp.Status == S_OK) 
 #else
@@ -892,13 +999,16 @@
                         pdef = (gdth_defcnt_str *)buf;
                         gdtcmd.Service = CACHESERVICE;
                         gdtcmd.OpCode = GDT_IOCTL;
-                        gdtcmd.u.ioctl.p_param = virt_to_bus(pdef);
+                        gdtcmd.u.ioctl.p_param = paddr;
                         gdtcmd.u.ioctl.param_size = sizeof(gdth_defcnt_str);
                         gdtcmd.u.ioctl.subfunc = SCSI_DEF_CNT | L_CTRL_PATTERN;
                         gdtcmd.u.ioctl.channel = 
                             ha->raw[i].address | ha->raw[i].id_list[j];
                         pdef->sddc_type = 0x08;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+                        gdth_do_req(scp, &gdtcmd, cmnd, 30);
+                        if (scp->sr_command->SCp.Status == S_OK) 
+#elif LINUX_VERSION_CODE >= 0x020322
                         gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
                         if (scp->SCp.Status == S_OK) 
 #else
@@ -920,7 +1030,7 @@
                         goto stop_output;
                 }
             }
-            gdth_ioctl_free(hanum, buf);
+            gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr);
 
             if (!flag) {
                 size = sprintf(buffer+len, "\n --\n");
@@ -932,7 +1042,7 @@
             len += size;  pos = begin + len;
             flag = FALSE;
 
-            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr);
             if (!buf) 
                 goto stop_output;
             for (i = 0; i < MAX_LDRIVES; ++i) {
@@ -947,11 +1057,14 @@
                     pcdi = (gdth_cdrinfo_str *)buf;
                     gdtcmd.Service = CACHESERVICE;
                     gdtcmd.OpCode = GDT_IOCTL;
-                    gdtcmd.u.ioctl.p_param = virt_to_bus(pcdi);
+                    gdtcmd.u.ioctl.p_param = paddr;
                     gdtcmd.u.ioctl.param_size = sizeof(gdth_cdrinfo_str);
                     gdtcmd.u.ioctl.subfunc = CACHE_DRV_INFO;
                     gdtcmd.u.ioctl.channel = drv_no;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+                    gdth_do_req(scp, &gdtcmd, cmnd, 30);
+                    if (scp->sr_command->SCp.Status != S_OK) 
+#elif LINUX_VERSION_CODE >= 0x020322
                     gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
                     if (scp->SCp.Status != S_OK)
 #else
@@ -1034,7 +1147,7 @@
                 if (pos > offset + length)
                     goto stop_output;
             }       
-            gdth_ioctl_free(hanum, buf);
+            gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr);
         
             if (!flag) {
                 size = sprintf(buffer+len, "\n --\n");
@@ -1046,7 +1159,7 @@
             len += size;  pos = begin + len;
             flag = FALSE;
 
-            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr);
             if (!buf) 
                 goto stop_output;
             for (i = 0; i < MAX_LDRIVES; ++i) {
@@ -1057,11 +1170,14 @@
                 pai = (gdth_arrayinf_str *)buf;
                 gdtcmd.Service = CACHESERVICE;
                 gdtcmd.OpCode = GDT_IOCTL;
-                gdtcmd.u.ioctl.p_param = virt_to_bus(pai);
+                gdtcmd.u.ioctl.p_param = paddr;
                 gdtcmd.u.ioctl.param_size = sizeof(gdth_arrayinf_str);
                 gdtcmd.u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN;
                 gdtcmd.u.ioctl.channel = i;
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+                gdth_do_req(scp, &gdtcmd, cmnd, 30);
+                if (scp->sr_command->SCp.Status == S_OK) 
+#elif LINUX_VERSION_CODE >= 0x020322
                 gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
                 if (scp->SCp.Status == S_OK) 
 #else
@@ -1112,7 +1228,7 @@
                         goto stop_output;
                 }
             }
-            gdth_ioctl_free(hanum, buf);
+            gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr);
         
             if (!flag) {
                 size = sprintf(buffer+len, "\n --\n");
@@ -1124,7 +1240,7 @@
             len += size;  pos = begin + len;
             flag = FALSE;
 
-            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+            buf = gdth_ioctl_alloc(hanum, sizeof(gdth_hget_str), FALSE, &paddr);
             if (!buf) 
                 goto stop_output;
             for (i = 0; i < MAX_LDRIVES; ++i) {
@@ -1136,13 +1252,16 @@
                 phg = (gdth_hget_str *)buf;
                 gdtcmd.Service = CACHESERVICE;
                 gdtcmd.OpCode = GDT_IOCTL;
-                gdtcmd.u.ioctl.p_param = virt_to_bus(phg);
+                gdtcmd.u.ioctl.p_param = paddr;
                 gdtcmd.u.ioctl.param_size = sizeof(gdth_hget_str);
                 gdtcmd.u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN;
                 gdtcmd.u.ioctl.channel = i;
                 phg->entries = MAX_HDRIVES;
                 phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]); 
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+                gdth_do_req(scp, &gdtcmd, cmnd, 30);
+                if (scp->sr_command->SCp.Status != S_OK) 
+#elif LINUX_VERSION_CODE >= 0x020322
                 gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
                 if (scp->SCp.Status != S_OK) 
 #else
@@ -1164,7 +1283,7 @@
                     }
                 }
             }
-            gdth_ioctl_free(hanum, buf);
+            gdth_ioctl_free(hanum, sizeof(gdth_hget_str), buf, paddr);
 
             for (i = 0; i < MAX_HDRIVES; ++i) {
                 if (!(ha->hdr[i].present))
@@ -1221,20 +1340,27 @@
             if (id == -1)
                 break;
         }
+#ifdef GDTH_IOCTL_PROC
     } else {
+        gdth_iord_str *piord;
+
         /* request from tool (GDTMON,..) */
         piord = (gdth_iord_str *)ha->pscratch;
         if (piord == NULL)
             goto stop_output;
         length = piord->size;
         memcpy(buffer+len, (char *)piord, length);
-        gdth_ioctl_free(hanum, ha->pscratch);
+        gdth_ioctl_free(hanum, GDTH_SCRATCH, ha->pscratch, paddr);
         len = length; 
     }
+#endif
 
 stop_output:
-#if LINUX_VERSION_CODE >= 0x020322
-    scsi_put_command(scp);
+#if LINUX_VERSION_CODE >= 0x020503
+    scsi_release_request(scp);
+    scsi_free_host_dev(sdev);
+#elif LINUX_VERSION_CODE >= 0x020322
+    scsi_release_command(scp);
     scsi_free_host_dev(sdev);
 #endif
     *start = buffer +(offset-begin);
@@ -1246,6 +1372,26 @@
     return(len);
 }
 
+#if LINUX_VERSION_CODE >= 0x020503
+static void gdth_do_req(Scsi_Request *scp, gdth_cmd_str *gdtcmd, 
+                        char *cmnd, int timeout)
+{
+    unsigned bufflen;
+    DECLARE_COMPLETION(wait);
+
+    TRACE2(("gdth_do_req()\n"));
+    if (gdtcmd != NULL) { 
+        bufflen = sizeof(gdth_cmd_str);
+    } else {
+        bufflen = 0;
+    }
+    scp->sr_request->rq_status = RQ_SCSI_BUSY;
+    scp->sr_request->waiting = &wait;
+    scsi_do_req(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
+    wait_for_completion(&wait);
+}
+
+#else
 static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd, 
                         char *cmnd, int timeout)
 {
@@ -1266,8 +1412,8 @@
         scp->SCp.this_residual = DEFAULT_PRI;
         bufflen = 0;
     }
-    scp->request.rq_status = RQ_SCSI_BUSY;
 #if LINUX_VERSION_CODE >= 0x020407
+    scp->request.rq_status = RQ_SCSI_BUSY;
     scp->request.waiting = &wait;
     scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
     wait_for_completion(&wait);
@@ -1283,46 +1429,53 @@
     down(&sem);
 #endif
 }
+#endif
 
 void gdth_scsi_done(Scsi_Cmnd *scp)
 {
     TRACE2(("gdth_scsi_done()\n"));
 
+#if LINUX_VERSION_CODE >= 0x020503
+    scp->request->rq_status = RQ_SCSI_DONE;
+    if (scp->request->waiting != NULL)
+        complete(scp->request->waiting);
+#elif LINUX_VERSION_CODE >= 0x020407
     scp->request.rq_status = RQ_SCSI_DONE;
-
-#if LINUX_VERSION_CODE >= 0x020407
     if (scp->request.waiting != NULL)
         complete(scp->request.waiting);
 #else
+    scp->request.rq_status = RQ_SCSI_DONE;
     if (scp->request.sem != NULL)
         up(scp->request.sem);
 #endif
 }
 
-static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch)
+static char *gdth_ioctl_alloc(int hanum, int size, int scratch, 
+                              ulong32 *paddr)
 {
     gdth_ha_str *ha;
     ulong flags;
     char *ret_val;
 
-    if (size == 0 || size > GDTH_SCRATCH)
-        return FALSE;
+    if (size == 0)
+        return NULL;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
     GDTH_LOCK_HA(ha, flags);
 
-    if (scratch) { 
-        if (!ha->scratch_busy) {
-            ha->scratch_busy = TRUE;
-            ret_val = ha->pscratch;
-        } else
-            ret_val = NULL;
+    if (!ha->scratch_busy && size <= GDTH_SCRATCH) {
+        ha->scratch_busy = TRUE;
+        ret_val = ha->pscratch;
+        *paddr = ha->scratch_phys;
+    } else if (scratch) {
+        ret_val = NULL;
     } else {
-#if LINUX_VERSION_CODE >= 0x020322
-        ret_val = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 
-                                            GDTH_SCRATCH_ORD);
+#if LINUX_VERSION_CODE >= 0x020400
+        ret_val = pci_alloc_consistent(ha->pdev, size, paddr);
 #else
-        ret_val = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
+        ret_val = scsi_init_malloc(size, GFP_ATOMIC | GFP_DMA);
+        if (ret_val)
+            *paddr = virt_to_bus(ret_val);
 #endif
     }
 
@@ -1330,7 +1483,7 @@
     return ret_val;
 }
 
-static void gdth_ioctl_free(int hanum, char *buf)
+static void gdth_ioctl_free(int hanum, int size, char *buf, ulong32 paddr)
 {
     gdth_ha_str *ha;
     ulong flags;
@@ -1341,16 +1494,17 @@
     if (buf == ha->pscratch) {
         ha->scratch_busy = FALSE;
     } else {
-#if LINUX_VERSION_CODE >= 0x020322
-        free_pages((unsigned long)buf, GDTH_SCRATCH_ORD);
+#if LINUX_VERSION_CODE >= 0x020400
+        pci_free_consistent(ha->pdev, size, buf, paddr);
 #else
-        scsi_init_free((void *)buf, GDTH_SCRATCH);
+        scsi_init_free((void *)buf, size);
 #endif
     }
 
     GDTH_UNLOCK_HA(ha, flags);
 }
 
+#ifdef GDTH_IOCTL_PROC
 static int gdth_ioctl_check_bin(int hanum, ushort size)
 {
     gdth_ha_str *ha;
@@ -1368,7 +1522,7 @@
     GDTH_UNLOCK_HA(ha, flags);
     return ret_val;
 }
-
+#endif
 
 static void gdth_wait_completion(int hanum, int busnum, int id)
 {
@@ -1376,23 +1530,39 @@
     ulong flags;
     int i;
     Scsi_Cmnd *scp;
-    unchar b;
+    unchar b, t;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
     GDTH_LOCK_HA(ha, flags);
 
     for (i = 0; i < GDTH_MAXCMDS; ++i) {
         scp = ha->cmd_tab[i].cmnd;
+#if LINUX_VERSION_CODE >= 0x02053C
         b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
-        if (!SPECIAL_SCP(scp) && scp->device->id == (unchar)id && 
+        t = scp->device->id;
+#else
+        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
+        t = scp->target;
+#endif
+        if (!SPECIAL_SCP(scp) && t == (unchar)id && 
             b == (unchar)busnum) {
             scp->SCp.have_data_in = 0;
             GDTH_UNLOCK_HA(ha, flags);
             while (!scp->SCp.have_data_in)
                 barrier();
+#if LINUX_VERSION_CODE >= 0x02053C
+            GDTH_LOCK_SCSI_DONE(scp->device->host, flags);
+            scp->scsi_done(scp);
+            GDTH_UNLOCK_SCSI_DONE(scp->device->host, flags);
+#elif LINUX_VERSION_CODE >= 0x020503
+            GDTH_LOCK_SCSI_DONE(scp->host, flags);
+            scp->scsi_done(scp);
+            GDTH_UNLOCK_SCSI_DONE(scp->host, flags);
+#else
             GDTH_LOCK_SCSI_DONE(flags);
             scp->scsi_done(scp);
             GDTH_UNLOCK_SCSI_DONE(flags);
+#endif
         GDTH_LOCK_HA(ha, flags);
         }
     }
@@ -1404,14 +1574,20 @@
     gdth_ha_str *ha;
     ulong flags;
     Scsi_Cmnd *scp;
-    unchar b;
+    unchar b, t;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
     GDTH_LOCK_HA(ha, flags);
 
     for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
+#if LINUX_VERSION_CODE >= 0x02053C
         b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
-        if (scp->device->id == (unchar)id && b == (unchar)busnum) {
+        t = scp->device->id;
+#else
+        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
+        t = scp->target;
+#endif
+        if (t == (unchar)id && b == (unchar)busnum) {
             TRACE2(("gdth_stop_timeout(): update_timeout()\n"));
             scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);
         }
@@ -1424,14 +1600,20 @@
     gdth_ha_str *ha;
     ulong flags;
     Scsi_Cmnd *scp;
-    unchar b;
+    unchar b, t;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
     GDTH_LOCK_HA(ha, flags);
 
     for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
+#if LINUX_VERSION_CODE >= 0x02053C
         b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
-        if (scp->device->id == (unchar)id && b == (unchar)busnum) {
+        t = scp->device->id;
+#else
+        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
+        t = scp->target;
+#endif
+        if (t == (unchar)id && b == (unchar)busnum) {
             TRACE2(("gdth_start_timeout(): update_timeout()\n"));
             gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual);
         }
@@ -1464,7 +1646,7 @@
             timer_table[SCSI_TIMER].expires = jiffies + timeout;
             timer_active |= 1 << SCSI_TIMER;
         } else {
-            if (time_before(jiffies + timeout, timer_table[SCSI_TIMER].expires))
+            if (jiffies + timeout < timer_table[SCSI_TIMER].expires)
                 timer_table[SCSI_TIMER].expires = jiffies + timeout;
         }
     }
diff -Nru a/drivers/scsi/gdth_proc.h b/drivers/scsi/gdth_proc.h
--- a/drivers/scsi/gdth_proc.h	Mon Feb  4 23:44:55 2002
+++ b/drivers/scsi/gdth_proc.h	Thu Mar  6 15:10:14 2003
@@ -2,26 +2,42 @@
 #define _GDTH_PROC_H
 
 /* gdth_proc.h 
- * $Id: gdth_proc.h,v 1.11 2001/07/25 15:37:40 achim Exp $
+ * $Id: gdth_proc.h,v 1.13 2003/02/27 14:59:25 achim Exp $
  */
 
 static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum);
 static int gdth_get_info(char *buffer,char **start,off_t offset,
                          int length,int vh,int hanum,int busnum);
 
-#if LINUX_VERSION_CODE >= 0x020322
+#if LINUX_VERSION_CODE >= 0x020503
+static void gdth_do_req(Scsi_Request *srp, gdth_cmd_str *cmd, 
+                        char *cmnd, int timeout);
+static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp);
+#ifdef GDTH_IOCTL_PROC
+static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Request *scp);
+#endif
+#elif LINUX_VERSION_CODE >= 0x020322
+static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd, 
+                        char *cmnd, int timeout);
 static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp);
+#ifdef GDTH_IOCTL_PROC
 static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp);
+#endif
 #else 
+static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd, 
+                        char *cmnd, int timeout);
 static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp);
+#ifdef GDTH_IOCTL_PROC
 static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp);
 #endif
-static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd, 
-                        char *cmnd, int timeout);
+#endif
 
-static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch);
-static void gdth_ioctl_free(int hanum, char *buf);
+static char *gdth_ioctl_alloc(int hanum, int size, int scratch,
+                              ulong32 *paddr);  
+static void gdth_ioctl_free(int hanum, int size, char *buf, ulong32 paddr);
+#ifdef GDTH_IOCTL_PROC
 static int gdth_ioctl_check_bin(int hanum, ushort size);
+#endif
 static void gdth_wait_completion(int hanum, int busnum, int id);
 static void gdth_stop_timeout(int hanum, int busnum, int id);
 static void gdth_start_timeout(int hanum, int busnum, int id);
diff -Nru a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
--- a/drivers/scsi/gvp11.c	Wed Nov 20 03:36:29 2002
+++ b/drivers/scsi/gvp11.c	Thu Feb 13 08:15:30 2003
@@ -62,61 +62,62 @@
     static int scsi_alloc_out_of_range = 0;
 
     /* use bounce buffer if the physical address is bad */
-    if (addr & HDATA(cmd->host)->dma_xfer_mask ||
+    if (addr & HDATA(cmd->device->host)->dma_xfer_mask ||
 	(!dir_in && mm_end_of_chunk (addr, cmd->SCp.this_residual)))
     {
-	HDATA(cmd->host)->dma_bounce_len = (cmd->SCp.this_residual + 511)
+	HDATA(cmd->device->host)->dma_bounce_len = (cmd->SCp.this_residual + 511)
 	    & ~0x1ff;
 
  	if( !scsi_alloc_out_of_range ) {
-	    HDATA(cmd->host)->dma_bounce_buffer =
-		kmalloc (HDATA(cmd->host)->dma_bounce_len, GFP_KERNEL);
-	    HDATA(cmd->host)->dma_buffer_pool = BUF_SCSI_ALLOCED;
+	    HDATA(cmd->device->host)->dma_bounce_buffer =
+		kmalloc (HDATA(cmd->device->host)->dma_bounce_len, GFP_KERNEL);
+	    HDATA(cmd->device->host)->dma_buffer_pool = BUF_SCSI_ALLOCED;
 	}
 
-	if ( scsi_alloc_out_of_range || !HDATA(cmd->host)->dma_bounce_buffer) {
-	    HDATA(cmd->host)->dma_bounce_buffer =
-		amiga_chip_alloc(HDATA(cmd->host)->dma_bounce_len,
+	if (scsi_alloc_out_of_range ||
+	    !HDATA(cmd->device->host)->dma_bounce_buffer) {
+	    HDATA(cmd->device->host)->dma_bounce_buffer =
+		amiga_chip_alloc(HDATA(cmd->device->host)->dma_bounce_len,
 				       "GVP II SCSI Bounce Buffer");
 
-	    if(!HDATA(cmd->host)->dma_bounce_buffer)
+	    if(!HDATA(cmd->device->host)->dma_bounce_buffer)
 	    {
-		HDATA(cmd->host)->dma_bounce_len = 0;
+		HDATA(cmd->device->host)->dma_bounce_len = 0;
 		return 1;
 	    }
 
-	    HDATA(cmd->host)->dma_buffer_pool = BUF_CHIP_ALLOCED;
+	    HDATA(cmd->device->host)->dma_buffer_pool = BUF_CHIP_ALLOCED;
 	}
 
 	/* check if the address of the bounce buffer is OK */
-	addr = virt_to_bus(HDATA(cmd->host)->dma_bounce_buffer);
+	addr = virt_to_bus(HDATA(cmd->device->host)->dma_bounce_buffer);
 
-	if (addr & HDATA(cmd->host)->dma_xfer_mask) {
+	if (addr & HDATA(cmd->device->host)->dma_xfer_mask) {
 	    /* fall back to Chip RAM if address out of range */
-	    if( HDATA(cmd->host)->dma_buffer_pool == BUF_SCSI_ALLOCED) {
-		kfree (HDATA(cmd->host)->dma_bounce_buffer);
+	    if( HDATA(cmd->device->host)->dma_buffer_pool == BUF_SCSI_ALLOCED) {
+		kfree (HDATA(cmd->device->host)->dma_bounce_buffer);
 		scsi_alloc_out_of_range = 1;
 	    } else {
-		amiga_chip_free (HDATA(cmd->host)->dma_bounce_buffer);
+		amiga_chip_free (HDATA(cmd->device->host)->dma_bounce_buffer);
             }
 		
-	    HDATA(cmd->host)->dma_bounce_buffer =
-		amiga_chip_alloc(HDATA(cmd->host)->dma_bounce_len,
+	    HDATA(cmd->device->host)->dma_bounce_buffer =
+		amiga_chip_alloc(HDATA(cmd->device->host)->dma_bounce_len,
 				       "GVP II SCSI Bounce Buffer");
 
-	    if(!HDATA(cmd->host)->dma_bounce_buffer)
+	    if(!HDATA(cmd->device->host)->dma_bounce_buffer)
 	    {
-		HDATA(cmd->host)->dma_bounce_len = 0;
+		HDATA(cmd->device->host)->dma_bounce_len = 0;
 		return 1;
 	    }
 
-	    addr = virt_to_bus(HDATA(cmd->host)->dma_bounce_buffer);
-	    HDATA(cmd->host)->dma_buffer_pool = BUF_CHIP_ALLOCED;
+	    addr = virt_to_bus(HDATA(cmd->device->host)->dma_bounce_buffer);
+	    HDATA(cmd->device->host)->dma_buffer_pool = BUF_CHIP_ALLOCED;
 	}
 	    
 	if (!dir_in) {
 	    /* copy to bounce buffer for a write */
-	    memcpy (HDATA(cmd->host)->dma_bounce_buffer,
+	    memcpy (HDATA(cmd->device->host)->dma_bounce_buffer,
 		    cmd->SCp.ptr, cmd->SCp.this_residual);
 	}
     }
@@ -125,11 +126,11 @@
     if (!dir_in)
 	cntr |= GVP11_DMAC_DIR_WRITE;
 
-    HDATA(cmd->host)->dma_dir = dir_in;
-    DMA(cmd->host)->CNTR = cntr;
+    HDATA(cmd->device->host)->dma_dir = dir_in;
+    DMA(cmd->device->host)->CNTR = cntr;
 
     /* setup DMA *physical* address */
-    DMA(cmd->host)->ACR = addr;
+    DMA(cmd->device->host)->ACR = addr;
 
     if (dir_in)
 	/* invalidate any cache */
@@ -138,11 +139,11 @@
 	/* push any dirty cache */
 	cache_push (addr, cmd->SCp.this_residual);
 
-    if ((bank_mask = (~HDATA(cmd->host)->dma_xfer_mask >> 18) & 0x01c0))
-	    DMA(cmd->host)->BANK = bank_mask & (addr >> 18);
+    if ((bank_mask = (~HDATA(cmd->device->host)->dma_xfer_mask >> 18) & 0x01c0))
+	    DMA(cmd->device->host)->BANK = bank_mask & (addr >> 18);
 
     /* start DMA */
-    DMA(cmd->host)->ST_DMA = 1;
+    DMA(cmd->device->host)->ST_DMA = 1;
 
     /* return success */
     return 0;
diff -Nru a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
--- a/drivers/scsi/mac53c94.c	Tue Feb  5 07:28:32 2002
+++ b/drivers/scsi/mac53c94.c	Sat Feb  8 21:38:15 2003
@@ -16,11 +16,13 @@
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #include <linux/spinlock.h>
+#include <linux/interrupt.h>
 #include <asm/dbdma.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/prom.h>
 #include <asm/system.h>
+#include <asm/pci-bridge.h>
 
 #include "scsi.h"
 #include "hosts.h"
@@ -48,6 +50,8 @@
 	enum fsc_phase phase;		/* what we're currently trying to do */
 	struct dbdma_cmd *dma_cmds;	/* space for dbdma commands, aligned */
 	void	*dma_cmd_space;
+	struct	pci_dev *pdev;
+	dma_addr_t dma_addr;
 };
 
 static struct fsc_state *all_53c94s;
@@ -70,36 +74,66 @@
 	void *dma_cmd_space;
 	unsigned char *clkprop;
 	int proplen;
+	struct pci_dev *pdev;
+	u8 pbus, devfn;
 
 	nfscs = 0;
 	prev_statep = &all_53c94s;
 	for (node = find_devices("53c94"); node != 0; node = node->next) {
-		if (node->n_addrs != 2 || node->n_intrs != 2)
-			panic("53c94: expected 2 addrs and intrs (got %d/%d)",
-			      node->n_addrs, node->n_intrs);
+		if (node->n_addrs != 2 || node->n_intrs != 2) {
+			printk(KERN_ERR "mac53c94: expected 2 addrs and intrs"
+			       " (got %d/%d) for node %s\n",
+			       node->n_addrs, node->n_intrs, node->full_name);
+			continue;
+		}
+
+		pdev = NULL;
+		if (node->parent != NULL
+		    && !pci_device_from_OF_node(node->parent, &pbus, &devfn))
+			pdev = pci_find_slot(pbus, devfn);
+		if (pdev == NULL) {
+			printk(KERN_ERR "mac53c94: can't find PCI device "
+			       "for %s\n", node->full_name);
+			continue;
+		}
+
 		host = scsi_register(tp, sizeof(struct fsc_state));
 		if (host == NULL)
 			break;
 		host->unique_id = nfscs;
-#ifndef MODULE
-		note_scsi_host(node, host);
-#endif
 
 		state = (struct fsc_state *) host->hostdata;
-		if (state == 0)
-			panic("no 53c94 state");
+		if (state == 0) {
+			/* "can't happen" */
+			printk(KERN_ERR "mac53c94: no state for %s?!\n",
+			       node->full_name);
+			scsi_unregister(host);
+			break;
+		}
 		state->host = host;
+		state->pdev = pdev;
+
 		state->regs = (volatile struct mac53c94_regs *)
 			ioremap(node->addrs[0].address, 0x1000);
 		state->intr = node->intrs[0].line;
 		state->dma = (volatile struct dbdma_regs *)
 			ioremap(node->addrs[1].address, 0x1000);
 		state->dmaintr = node->intrs[1].line;
+		if (state->regs == NULL || state->dma == NULL) {
+			printk(KERN_ERR "mac53c94: ioremap failed for %s\n",
+			       node->full_name);
+			if (state->dma != NULL)
+				iounmap(state->dma);
+			if (state->regs != NULL)
+				iounmap(state->regs);
+			scsi_unregister(host);
+			break;
+		}
 
 		clkprop = get_property(node, "clock-frequency", &proplen);
 		if (clkprop == NULL || proplen != sizeof(int)) {
-			printk(KERN_ERR "%s: can't get clock frequency\n",
-			       node->full_name);
+			printk(KERN_ERR "%s: can't get clock frequency, "
+			       "assuming 25MHz\n", node->full_name);
 			state->clk_freq = 25000000;
 		} else
 			state->clk_freq = *(int *)clkprop;
@@ -108,8 +142,11 @@
 		   +1 to allow for aligning. */
 		dma_cmd_space = kmalloc((host->sg_tablesize + 2) *
 					sizeof(struct dbdma_cmd), GFP_KERNEL);
-		if (dma_cmd_space == 0)
-			panic("53c94: couldn't allocate dma command space");
+		if (dma_cmd_space == 0) {
+			printk(KERN_ERR "mac53c94: couldn't allocate dma "
+			       "command space for %s\n", node->full_name);
+			goto err_cleanup;
+		}
 		state->dma_cmds = (struct dbdma_cmd *)
 			DBDMA_ALIGN(dma_cmd_space);
 		memset(state->dma_cmds, 0, (host->sg_tablesize + 1)
@@ -121,7 +158,13 @@
 
 		if (request_irq(state->intr, do_mac53c94_interrupt, 0,
 				"53C94", state)) {
-			printk(KERN_ERR "mac53C94: can't get irq %d\n", state->intr);
+			printk(KERN_ERR "mac53C94: can't get irq %d for %s\n",
+			       state->intr, node->full_name);
+		err_cleanup:
+			iounmap(state->dma);
+			iounmap(state->regs);
+			scsi_unregister(host);
+			break;
 		}
 
 		mac53c94_init(state);
@@ -150,7 +193,6 @@
 int
 mac53c94_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
-	unsigned long flags;
 	struct fsc_state *state;
 
 #if 0
@@ -167,10 +209,8 @@
 	cmd->scsi_done = done;
 	cmd->host_scribble = NULL;
 
-	state = (struct fsc_state *) cmd->host->hostdata;
+	state = (struct fsc_state *) cmd->device->host->hostdata;
 
-	save_flags(flags);
-	cli();
 	if (state->request_q == NULL)
 		state->request_q = cmd;
 	else
@@ -180,7 +220,6 @@
 	if (state->phase == idle)
 		mac53c94_start(state);
 
-	restore_flags(flags);
 	return 0;
 }
 
@@ -191,15 +230,12 @@
 }
 
 int
-mac53c94_reset(Scsi_Cmnd *cmd, unsigned how)
+mac53c94_host_reset(Scsi_Cmnd *cmd)
 {
-	struct fsc_state *state = (struct fsc_state *) cmd->host->hostdata;
+	struct fsc_state *state = (struct fsc_state *) cmd->device->host->hostdata;
 	volatile struct mac53c94_regs *regs = state->regs;
 	volatile struct dbdma_regs *dma = state->dma;
-	unsigned long flags;
 
-	save_flags(flags);
-	cli();
 	st_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
 	regs->command = CMD_SCSI_RESET;	/* assert RST */
 	eieio();
@@ -210,15 +246,7 @@
 	mac53c94_init(state);
 	regs->command = CMD_NOP;
 	eieio();
-	restore_flags(flags);
-	return SCSI_RESET_PENDING;
-}
-
-int
-mac53c94_command(Scsi_Cmnd *cmd)
-{
-	printk(KERN_DEBUG "whoops... mac53c94_command called\n");
-	return -1;
+	return SUCCESS;
 }
 
 static void
@@ -269,7 +297,7 @@
 	regs->command = CMD_FLUSH;
 	udelay(1);
 	eieio();
-	regs->dest_id = cmd->target;
+	regs->dest_id = cmd->device->id;
 	regs->sync_period = 0;
 	regs->sync_offset = 0;
 	eieio();
@@ -292,7 +320,7 @@
 do_mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
 {
 	unsigned long flags;
-	struct Scsi_Host *dev = ((struct fsc_state *) dev_id)->current_req->host;
+	struct Scsi_Host *dev = ((struct fsc_state *) dev_id)->current_req->device->host;
 	
 	spin_lock_irqsave(dev->host_lock, flags);
 	mac53c94_interrupt(irq, dev_id, ptregs);
@@ -308,6 +336,7 @@
 	Scsi_Cmnd *cmd = state->current_req;
 	int nb, stat, seq, intr;
 	static int mac53c94_errors;
+	int dma_dir;
 
 	/*
 	 * Apparently, reading the interrupt register unlatches
@@ -427,7 +456,16 @@
 		if ((stat & STAT_PHASE) != STAT_CD + STAT_IO) {
 			printk(KERN_DEBUG "intr %x before data xfer complete\n", intr);
 		}
-		st_le32(&dma->control, RUN << 16);	/* stop dma */
+		out_le32(&dma->control, RUN << 16);	/* stop dma */
+		dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+		if (cmd->use_sg != 0) {
+			pci_unmap_sg(state->pdev,
+				(struct scatterlist *)cmd->request_buffer,
+				cmd->use_sg, dma_dir);
+		} else {
+			pci_unmap_single(state->pdev, state->dma_addr,
+				cmd->request_bufflen, dma_dir);
+		}
 		/* should check dma status */
 		regs->command = CMD_I_COMPLETE;
 		state->phase = completing;
@@ -480,19 +518,27 @@
 	int i, dma_cmd, total;
 	struct scatterlist *scl;
 	struct dbdma_cmd *dcmds;
+	dma_addr_t dma_addr;
+	u32 dma_len;
+	int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
 
 	dma_cmd = data_goes_out(cmd)? OUTPUT_MORE: INPUT_MORE;
 	dcmds = state->dma_cmds;
 	if (cmd->use_sg > 0) {
+		int nseg;
+
 		total = 0;
 		scl = (struct scatterlist *) cmd->buffer;
-		for (i = 0; i < cmd->use_sg; ++i) {
-			if (scl->length > 0xffff)
+		nseg = pci_map_sg(state->pdev, scl, cmd->use_sg, dma_dir);
+		for (i = 0; i < nseg; ++i) {
+			dma_addr = sg_dma_address(scl);
+			dma_len = sg_dma_len(scl);
+			if (dma_len > 0xffff)
 				panic("mac53c94: scatterlist element >= 64k");
-			total += scl->length;
-			st_le16(&dcmds->req_count, scl->length);
+			total += dma_len;
+			st_le16(&dcmds->req_count, dma_len);
 			st_le16(&dcmds->command, dma_cmd);
-			st_le32(&dcmds->phy_addr, virt_to_phys(scl->address));
+			st_le32(&dcmds->phy_addr, dma_addr);
 			dcmds->xfer_status = 0;
 			++scl;
 			++dcmds;
@@ -501,8 +547,11 @@
 		total = cmd->request_bufflen;
 		if (total > 0xffff)
 			panic("mac53c94: transfer size >= 64k");
+		dma_addr = pci_map_single(state->pdev, cmd->request_buffer,
+					  total, dma_dir);
+		state->dma_addr = dma_addr;
 		st_le16(&dcmds->req_count, total);
-		st_le32(&dcmds->phy_addr, virt_to_phys(cmd->request_buffer));
+		st_le32(&dcmds->phy_addr, dma_addr);
 		dcmds->xfer_status = 0;
 		++dcmds;
 	}
@@ -514,12 +563,19 @@
 
 /*
  * Work out whether data will be going out from the host adaptor or into it.
- * (If this information is available from somewhere else in the scsi
- * code, somebody please let me know :-)
  */
 static int
 data_goes_out(Scsi_Cmnd *cmd)
 {
+	switch (cmd->sc_data_direction) {
+	case SCSI_DATA_WRITE:
+		return 1;
+	case SCSI_DATA_READ:
+		return 0;
+	}
+
+	/* for SCSI_DATA_UNKNOWN or SCSI_DATA_NONE, fall back on the
+	   old method for now... */
 	switch (cmd->cmnd[0]) {
 	case CHANGE_DEFINITION: 
 	case COMPARE:	  
@@ -557,6 +613,19 @@
 	}
 }
 
-static Scsi_Host_Template driver_template = SCSI_MAC53C94;
+static Scsi_Host_Template driver_template = {
+	.proc_name	= "53c94",
+	.name		= "53C94",
+	.detect		= mac53c94_detect,
+	.release	= mac53c94_release,
+	.queuecommand	= mac53c94_queue,
+	.eh_abort_handler = mac53c94_abort,
+	.eh_host_reset_handler = mac53c94_host_reset,
+	.can_queue	= 1,
+	.this_id	= 7,
+	.sg_tablesize	= SG_ALL,
+	.cmd_per_lun	= 1,
+	.use_clustering	= DISABLE_CLUSTERING,
+};
 
 #include "scsi_module.c"
diff -Nru a/drivers/scsi/mac53c94.h b/drivers/scsi/mac53c94.h
--- a/drivers/scsi/mac53c94.h	Tue Dec 10 12:28:33 2002
+++ b/drivers/scsi/mac53c94.h	Wed Jan  8 14:48:37 2003
@@ -7,29 +7,6 @@
 #ifndef _MAC53C94_H
 #define _MAC53C94_H
 
-int mac53c94_detect(Scsi_Host_Template *);
-int mac53c94_release(struct Scsi_Host *);
-int mac53c94_command(Scsi_Cmnd *);
-int mac53c94_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int mac53c94_abort(Scsi_Cmnd *);
-int mac53c94_reset(Scsi_Cmnd *, unsigned int);
-
-#define SCSI_MAC53C94 {					\
-	.proc_name	= "53c94",			\
-	.name		= "53C94",			\
-	.detect		= mac53c94_detect,		\
-	.release	= mac53c94_release,		\
-	.command	= mac53c94_command,		\
-	.queuecommand	= mac53c94_queue,			\
-	.abort		= mac53c94_abort,			\
-	.reset		= mac53c94_reset,			\
-	.can_queue	= 1,				\
-	.this_id	= 7,				\
-	.sg_tablesize	= SG_ALL,				\
-	.cmd_per_lun	= 1,				\
-	.use_clustering	= DISABLE_CLUSTERING,		\
-}
-
 /*
  * Registers in the 53C94 controller.
  */
diff -Nru a/drivers/scsi/mac_NCR5380.c b/drivers/scsi/mac_NCR5380.c
--- a/drivers/scsi/mac_NCR5380.c	Wed Feb 26 19:03:04 2003
+++ b/drivers/scsi/mac_NCR5380.c	Wed Feb 12 09:43:38 2003
@@ -850,7 +850,7 @@
 
 
 /* 
- * Function : void NCR5380_init (struct Scsi_Host *instance)
+ * Function : void NCR5380_init (struct Scsi_Host *instance, int flags)
  *
  * Purpose : initializes *instance and corresponding 5380 chip.
  *
@@ -861,7 +861,7 @@
  * 
  */
 
-static void NCR5380_init (struct Scsi_Host *instance, int flags)
+static int NCR5380_init (struct Scsi_Host *instance, int flags)
 {
     int i;
     SETUP_HOSTDATA(instance);
@@ -905,6 +905,8 @@
     NCR5380_write(MODE_REG, MR_BASE);
     NCR5380_write(TARGET_COMMAND_REG, 0);
     NCR5380_write(SELECT_ENABLE_REG, 0);
+
+    return 0;
 }
 
 /* 
@@ -925,17 +927,13 @@
  *
  */
 
-/* Only make static if a wrapper function is used */
-#ifndef NCR5380_queue_command
 static
-#endif
 int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
     SETUP_HOSTDATA(cmd->host);
     Scsi_Cmnd *tmp;
     int oldto;
     unsigned long flags;
-    extern int update_timeout(Scsi_Cmnd * SCset, int timeout);
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
     switch (cmd->cmnd[0]) {
@@ -1025,12 +1023,12 @@
     if (in_interrupt() > 0 || ((flags >> 8) & 7) >= 6)
 	queue_main();
     else
-	NCR5380_main();
+	NCR5380_main(NULL);
     return 0;
 }
 
 /*
- * Function : NCR5380_main (void) 
+ * Function : NCR5380_main (void *bl)
  *
  * Purpose : NCR5380_main is a coroutine that runs as long as more work can 
  *	be done on the NCR5380 host adapters in a system.  Both 
@@ -1041,7 +1039,7 @@
  *  reenable them.  This prevents reentrancy and kernel stack overflow.
  */ 	
     
-static void NCR5380_main (void)
+static void NCR5380_main (void *bl)
 {
     Scsi_Cmnd *tmp, *prev;
     struct Scsi_Host *instance = first_instance;
@@ -2790,9 +2788,6 @@
  * 	 called where the loop started in NCR5380_main().
  */
 
-#ifndef NCR5380_abort
-static
-#endif
 int NCR5380_abort (Scsi_Cmnd *cmd)
 {
     struct Scsi_Host *instance = cmd->host;
@@ -2982,7 +2977,7 @@
 
 
 /* 
- * Function : int NCR5380_reset (Scsi_Cmnd *cmd, unsigned int reset_flags)
+ * Function : int NCR5380_bus_reset (Scsi_Cmnd *cmd)
  * 
  * Purpose : reset the SCSI bus.
  *
@@ -2990,7 +2985,7 @@
  *
  */ 
 
-static int NCR5380_reset( Scsi_Cmnd *cmd, unsigned int reset_flags)
+static int NCR5380_bus_reset( Scsi_Cmnd *cmd)
 {
     SETUP_HOSTDATA(cmd->host);
     int           i;
diff -Nru a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
--- a/drivers/scsi/mesh.c	Tue Oct 22 13:53:01 2002
+++ b/drivers/scsi/mesh.c	Sat Feb  8 21:38:15 2003
@@ -80,7 +80,7 @@
 #define ALLOW_SYNC(tgt)		((sync_targets >> (tgt)) & 1)
 #define ALLOW_RESEL(tgt)	((resel_targets >> (tgt)) & 1)
 #define ALLOW_DEBUG(tgt)	((debug_targets >> (tgt)) & 1)
-#define DEBUG_TARGET(cmd)	((cmd) && ALLOW_DEBUG((cmd)->target))
+#define DEBUG_TARGET(cmd)	((cmd) && ALLOW_DEBUG((cmd)->device->id))
 
 #undef MESH_DBG
 #define N_DBG_LOG	50
@@ -465,7 +465,7 @@
 	cmd->scsi_done = done;
 	cmd->host_scribble = NULL;
 
-	ms = (struct mesh_state *) cmd->host->hostdata;
+	ms = (struct mesh_state *) cmd->device->host->hostdata;
 
 	if (ms->request_q == NULL)
 		ms->request_q = cmd;
@@ -486,15 +486,12 @@
 int
 mesh_abort(Scsi_Cmnd *cmd)
 {
-	struct mesh_state *ms = (struct mesh_state *) cmd->host->hostdata;
-	unsigned long flags;
+	struct mesh_state *ms = (struct mesh_state *) cmd->device->host->hostdata;
 
 	printk(KERN_DEBUG "mesh_abort(%p)\n", cmd);
-	spin_lock_irqsave(ms->host->host_lock, flags);
 	mesh_dump_regs(ms);
-	dumplog(ms, cmd->target);
+	dumplog(ms, cmd->device->id);
 	dumpslog(ms);
-	spin_unlock_irqrestore(ms->host->host_lock, flags);
 	return SCSI_ABORT_SNOOZE;
 }
 
@@ -540,7 +537,7 @@
 int
 mesh_host_reset(Scsi_Cmnd *cmd)
 {
-	struct mesh_state *ms = (struct mesh_state *) cmd->host->hostdata;
+	struct mesh_state *ms = (struct mesh_state *) cmd->device->host->hostdata;
 	volatile struct mesh_regs *mr = ms->mesh;
 	volatile struct dbdma_regs *md = ms->dma;
 
@@ -661,7 +658,7 @@
 		for (cmd = ms->request_q; ; cmd = (Scsi_Cmnd *) cmd->host_scribble) {
 			if (cmd == NULL)
 				return;
-			if (ms->tgts[cmd->target].current_req == NULL)
+			if (ms->tgts[cmd->device->id].current_req == NULL)
 				break;
 			prev = cmd;
 		}
@@ -681,17 +678,18 @@
 mesh_start_cmd(struct mesh_state *ms, Scsi_Cmnd *cmd)
 {
 	volatile struct mesh_regs *mr = ms->mesh;
-	int t;
+	int t, id;
 
+	id = cmd->device->id;
 	ms->current_req = cmd;
-	ms->tgts[cmd->target].data_goes_out = data_goes_out(cmd);
-	ms->tgts[cmd->target].current_req = cmd;
+	ms->tgts[id].data_goes_out = data_goes_out(cmd);
+	ms->tgts[id].current_req = cmd;
 
 #if 1
 	if (DEBUG_TARGET(cmd)) {
 		int i;
 		printk(KERN_DEBUG "mesh_start: %p ser=%lu tgt=%d cmd=",
-		       cmd, cmd->serial_number, cmd->target);
+		       cmd, cmd->serial_number, id);
 		for (i = 0; i < cmd->cmd_len; ++i)
 			printk(" %x", cmd->cmnd[i]);
 		printk(" use_sg=%d buffer=%p bufflen=%u\n",
@@ -708,12 +706,12 @@
 	ms->n_msgout = 0;
 	ms->last_n_msgout = 0;
 	ms->expect_reply = 0;
-	ms->conn_tgt = cmd->target;
-	ms->tgts[cmd->target].saved_ptr = 0;
+	ms->conn_tgt = id;
+	ms->tgts[id].saved_ptr = 0;
 	ms->stat = DID_OK;
 	ms->aborting = 0;
 #ifdef MESH_DBG
-	ms->tgts[cmd->target].n_log = 0;
+	ms->tgts[id].n_log = 0;
 	dlog(ms, "start cmd=%x", (int) cmd);
 #endif
 
@@ -1160,7 +1158,7 @@
 		case selecting:
 			dlog(ms, "Selecting phase at command completion",0);
 			ms->msgout[0] = IDENTIFY(ALLOW_RESEL(ms->conn_tgt),
-						 (cmd? cmd->lun: 0));
+						 (cmd? cmd->device->lun: 0));
 			ms->n_msgout = 1;
 			ms->expect_reply = 0;
 			if (ms->aborting) {
@@ -1331,7 +1329,7 @@
 			if (ms->request_q == NULL)
 				ms->request_qtail = cmd;
 			ms->request_q = cmd;
-			tp = &ms->tgts[cmd->target];
+			tp = &ms->tgts[cmd->device->id];
 			tp->current_req = NULL;
 		}
 		break;
@@ -1714,10 +1712,10 @@
 			if (cmd == NULL) {
 				do_abort(ms);
 				ms->msgphase = msg_out;
-			} else if (code != cmd->lun + IDENTIFY_BASE) {
+			} else if (code != cmd->device->lun + IDENTIFY_BASE) {
 				printk(KERN_WARNING "mesh: lun mismatch "
 				       "(%d != %d) on reselection from "
-				       "target %d\n", i, cmd->lun,
+				       "target %d\n", i, cmd->device->lun,
 				       ms->conn_tgt);
 			}
 			break;
@@ -1902,12 +1900,19 @@
 
 /*
  * Work out whether we expect data to go out from the host adaptor or into it.
- * (If this information is available from somewhere else in the scsi
- * code, somebody please let me know :-)
  */
 static int
 data_goes_out(Scsi_Cmnd *cmd)
 {
+	switch (cmd->sc_data_direction) {
+	case SCSI_DATA_WRITE:
+		return 1;
+	case SCSI_DATA_READ:
+		return 0;
+	}
+
+	/* for SCSI_DATA_UNKNOWN or SCSI_DATA_NONE, fall back on the
+	   old method for now... */
 	switch (cmd->cmnd[0]) {
 	case CHANGE_DEFINITION: 
 	case COMPARE:	  
@@ -2036,6 +2041,22 @@
 }
 #endif /* MESH_DBG */
 
-static Scsi_Host_Template driver_template = SCSI_MESH;
+static Scsi_Host_Template driver_template = {
+	.proc_name			= "mesh",
+	.name				= "MESH",
+	.detect				= mesh_detect,
+	.release			= mesh_release,
+	.command			= NULL,
+	.queuecommand			= mesh_queue,
+	.eh_abort_handler		= mesh_abort,
+	.eh_device_reset_handler	= NULL,
+	.eh_bus_reset_handler		= NULL,
+	.eh_host_reset_handler		= mesh_host_reset,
+	.can_queue			= 20,
+	.this_id			= 7,
+	.sg_tablesize			= SG_ALL,
+	.cmd_per_lun			= 2,
+	.use_clustering			= DISABLE_CLUSTERING,
+};
 
 #include "scsi_module.c"
diff -Nru a/drivers/scsi/mesh.h b/drivers/scsi/mesh.h
--- a/drivers/scsi/mesh.h	Tue Dec 10 12:28:33 2002
+++ b/drivers/scsi/mesh.h	Sat Feb  8 21:38:15 2003
@@ -7,30 +7,6 @@
 #ifndef _MESH_H
 #define _MESH_H
 
-int mesh_detect(Scsi_Host_Template *);
-int mesh_release(struct Scsi_Host *);
-int mesh_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int mesh_abort(Scsi_Cmnd *);
-int mesh_host_reset(Scsi_Cmnd *);
-
-#define SCSI_MESH {						\
-	.proc_name			= "mesh",			\
-	.name				= "MESH",			\
-	.detect				= mesh_detect,		\
-	.release			= mesh_release,		\
-	.command			= NULL,			\
-	.queuecommand			= mesh_queue,		\
-	.eh_abort_handler		= mesh_abort,		\
-	.eh_device_reset_handler	= NULL,			\
-	.eh_bus_reset_handler		= NULL,			\
-	.eh_host_reset_handler		= mesh_host_reset,	\
-	.can_queue			= 20,			\
-	.this_id			= 7,			\
-	.sg_tablesize			= SG_ALL,			\
-	.cmd_per_lun			= 2,			\
-	.use_clustering			= DISABLE_CLUSTERING,	\
-}
-
 /*
  * Registers in the MESH controller.
  */
diff -Nru a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
--- a/drivers/scsi/pcmcia/nsp_cs.c	Wed Feb 26 12:18:50 2003
+++ b/drivers/scsi/pcmcia/nsp_cs.c	Sun Mar 23 03:30:39 2003
@@ -1987,32 +1987,26 @@
 	return 0;
 } /* nsp_cs_event */
 
-/*======================================================================*
- *	module entry point
- *====================================================================*/
+static struct pcmcia_driver nsp_driver = {
+	.owner		= THIS_MODULE,
+	.drv		= {
+		.name	= "nsp_cs",
+	},
+	.attach		= nsp_cs_attach,
+	.detach		= nsp_cs_detach,
+};
+
 static int __init nsp_cs_init(void)
 {
-	servinfo_t serv;
-
-	DEBUG(0, "%s: in\n", __FUNCTION__);
-	DEBUG(0, "%s\n", version);
-	CardServices(GetCardServicesInfo, &serv);
-	if (serv.Revision != CS_RELEASE_CODE) {
-		printk(KERN_DEBUG "nsp_cs: Card Services release "
-		       "does not match!\n");
-		return -1;
-	}
-	register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
-
-	DEBUG(0, "%s: out\n", __FUNCTION__);
-	return 0;
+	return pcmcia_register_driver(&nsp_driver);
 }
 
 
-static void __exit nsp_cs_cleanup(void)
+static void __exit nsp_cs_exit(void)
 {
-	DEBUG(0, "%s: unloading\n", __FUNCTION__);
-	unregister_pcmcia_driver(&dev_info);
+	pcmcia_unregister_driver(&nsp_driver);
+
+	/* XXX: this really needs to move into generic code.. */
 	while (dev_list != NULL) {
 		if (dev_list->state & DEV_CONFIG) {
 			nsp_cs_release((u_long)dev_list);
@@ -2022,11 +2016,4 @@
 }
 
 module_init(nsp_cs_init)
-module_exit(nsp_cs_cleanup)
-
-/*
- *
- *
- */
-
-/* end */
+module_exit(nsp_cs_exit)
diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c	Mon Mar  3 10:48:16 2003
+++ b/drivers/scsi/scsi.c	Sat Mar 22 07:38:05 2003
@@ -1495,7 +1495,7 @@
 		INIT_LIST_HEAD(&done_q[i]);
 
 	scsi_host_init();
-	devfs_mk_dir(NULL, "scsi", NULL);
+	devfs_mk_dir("scsi");
 	open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL);
 	printk(KERN_NOTICE "SCSI subsystem initialized\n");
 	return 0;
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c	Mon Mar 10 06:23:23 2003
+++ b/drivers/scsi/scsi_scan.c	Sat Mar 22 07:38:05 2003
@@ -1128,8 +1128,6 @@
 static int scsi_add_lun(Scsi_Device *sdev, Scsi_Request *sreq,
 		char *inq_result, int *bflags)
 {
-	char devname[64];
-
 	/*
 	 * XXX do not save the inquiry, since it can change underneath us,
 	 * save just vendor/model/rev.
@@ -1230,13 +1228,10 @@
 	
 	scsi_device_register(sdev);
 
-	sprintf(devname, "scsi/host%d/bus%d/target%d/lun%d",
-		sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
-	if (sdev->de)
-		printk(KERN_WARNING "scsi devfs dir: \"%s\" already exists\n",
-		       devname);
-	else
-		sdev->de = devfs_mk_dir(NULL, devname, NULL);
+	sdev->de = devfs_mk_dir("scsi/host%d/bus%d/target%d/lun%d",
+				sdev->host->host_no, sdev->channel,
+				sdev->id, sdev->lun);
+
 	/*
 	 * End driverfs/devfs code.
 	 */
diff -Nru a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
--- a/drivers/scsi/sun3_NCR5380.c	Wed Feb 26 19:03:04 2003
+++ b/drivers/scsi/sun3_NCR5380.c	Mon Oct  7 15:21:40 2002
@@ -268,7 +268,7 @@
 #define	NEXTADDR(cmd)	((Scsi_Cmnd **)&((cmd)->host_scribble))
 
 #define	HOSTNO		instance->host_no
-#define	H_NO(cmd)	(cmd)->host->host_no
+#define	H_NO(cmd)	(cmd)->device->host->host_no
 
 #define SGADDR(buffer) (void *)(((unsigned long)page_address((buffer)->page)) + \
 			(buffer)->offset)
@@ -360,17 +360,17 @@
 
 static int is_lun_busy( Scsi_Cmnd *cmd, int should_be_tagged )
 {
-    SETUP_HOSTDATA(cmd->host);
+    SETUP_HOSTDATA(cmd->device->host);
 
-    if (hostdata->busy[cmd->target] & (1 << cmd->lun))
+    if (hostdata->busy[cmd->device->id] & (1 << cmd->device->lun))
 	return( 1 );
     if (!should_be_tagged ||
 	!setup_use_tagged_queuing || !cmd->device->tagged_supported)
 	return( 0 );
-    if (TagAlloc[cmd->target][cmd->lun].nr_allocated >=
-	TagAlloc[cmd->target][cmd->lun].queue_size ) {
+    if (TagAlloc[cmd->device->id][cmd->device->lun].nr_allocated >=
+	TagAlloc[cmd->device->id][cmd->device->lun].queue_size ) {
 	TAG_PRINTK( "scsi%d: target %d lun %d: no free tags\n",
-		    H_NO(cmd), cmd->target, cmd->lun );
+		    H_NO(cmd), cmd->device->id, cmd->device->lun );
 	return( 1 );
     }
     return( 0 );
@@ -384,7 +384,7 @@
 
 static void cmd_get_tag( Scsi_Cmnd *cmd, int should_be_tagged )
 {
-    SETUP_HOSTDATA(cmd->host);
+    SETUP_HOSTDATA(cmd->device->host);
 
     /* If we or the target don't support tagged queuing, allocate the LUN for
      * an untagged command.
@@ -392,19 +392,19 @@
     if (!should_be_tagged ||
 	!setup_use_tagged_queuing || !cmd->device->tagged_supported) {
 	cmd->tag = TAG_NONE;
-	hostdata->busy[cmd->target] |= (1 << cmd->lun);
+	hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
 	TAG_PRINTK( "scsi%d: target %d lun %d now allocated by untagged "
-		    "command\n", H_NO(cmd), cmd->target, cmd->lun );
+		    "command\n", H_NO(cmd), cmd->device->id, cmd->device->lun );
     }
     else {
-	TAG_ALLOC *ta = &TagAlloc[cmd->target][cmd->lun];
+	TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
 
 	cmd->tag = find_first_zero_bit( &ta->allocated, MAX_TAGS );
 	set_bit( cmd->tag, &ta->allocated );
 	ta->nr_allocated++;
 	TAG_PRINTK( "scsi%d: using tag %d for target %d lun %d "
 		    "(now %d tags in use)\n",
-		    H_NO(cmd), cmd->tag, cmd->target, cmd->lun,
+		    H_NO(cmd), cmd->tag, cmd->device->id, cmd->device->lun,
 		    ta->nr_allocated );
     }
 }
@@ -416,23 +416,23 @@
 
 static void cmd_free_tag( Scsi_Cmnd *cmd )
 {
-    SETUP_HOSTDATA(cmd->host);
+    SETUP_HOSTDATA(cmd->device->host);
 
     if (cmd->tag == TAG_NONE) {
-	hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+	hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 	TAG_PRINTK( "scsi%d: target %d lun %d untagged cmd finished\n",
-		    H_NO(cmd), cmd->target, cmd->lun );
+		    H_NO(cmd), cmd->device->id, cmd->device->lun );
     }
     else if (cmd->tag >= MAX_TAGS) {
 	printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n",
 		H_NO(cmd), cmd->tag );
     }
     else {
-	TAG_ALLOC *ta = &TagAlloc[cmd->target][cmd->lun];
+	TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
 	clear_bit( cmd->tag, &ta->allocated );
 	ta->nr_allocated--;
 	TAG_PRINTK( "scsi%d: freed tag %d for target %d lun %d\n",
-		    H_NO(cmd), cmd->tag, cmd->target, cmd->lun );
+		    H_NO(cmd), cmd->tag, cmd->device->id, cmd->device->lun );
     }
 }
 
@@ -616,11 +616,11 @@
 
     status = NCR5380_read(STATUS_REG);
     if (!(status & SR_REQ)) 
-	printk("scsi%d: REQ not asserted, phase unknown.\n", HOSTNO);
+	printk(KERN_DEBUG "scsi%d: REQ not asserted, phase unknown.\n", HOSTNO);
     else {
 	for (i = 0; (phases[i].value != PHASE_UNKNOWN) && 
 	    (phases[i].value != (status & PHASE_MASK)); ++i); 
-	printk("scsi%d: phase %s\n", HOSTNO, phases[i].name);
+	printk(KERN_DEBUG "scsi%d: phase %s\n", HOSTNO, phases[i].name);
     }
 }
 
@@ -819,7 +819,7 @@
     int i, s;
     unsigned char *command;
     SPRINTF("scsi%d: destination target %d, lun %d\n",
-	    H_NO(cmd), cmd->target, cmd->lun);
+	    H_NO(cmd), cmd->device->id, cmd->device->lun);
     SPRINTF("        command = ");
     command = cmd->cmnd;
     SPRINTF("%2d (0x%02x)", command[0], command[0]);
@@ -842,7 +842,7 @@
  * 
  */
 
-static void __init NCR5380_init (struct Scsi_Host *instance, int flags)
+static int NCR5380_init (struct Scsi_Host *instance, int flags)
 {
     int i;
     SETUP_HOSTDATA(instance);
@@ -886,6 +886,8 @@
     NCR5380_write(MODE_REG, MR_BASE);
     NCR5380_write(TARGET_COMMAND_REG, 0);
     NCR5380_write(SELECT_ENABLE_REG, 0);
+
+    return 0;
 }
 
 /* 
@@ -909,10 +911,9 @@
 /* Only make static if a wrapper function is used */
 static int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
-    SETUP_HOSTDATA(cmd->host);
+    SETUP_HOSTDATA(cmd->device->host);
     Scsi_Cmnd *tmp;
     unsigned long flags;
-    extern int update_timeout(Scsi_Cmnd * SCset, int timeout);
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
     switch (cmd->cmnd[0]) {
@@ -942,15 +943,15 @@
 	    case WRITE:
 	    case WRITE_6:
 	    case WRITE_10:
-		hostdata->time_write[cmd->target] -= (jiffies - hostdata->timebase);
-		hostdata->bytes_write[cmd->target] += cmd->request_bufflen;
+		hostdata->time_write[cmd->device->id] -= (jiffies - hostdata->timebase);
+		hostdata->bytes_write[cmd->device->id] += cmd->request_bufflen;
 		hostdata->pendingw++;
 		break;
 	    case READ:
 	    case READ_6:
 	    case READ_10:
-		hostdata->time_read[cmd->target] -= (jiffies - hostdata->timebase);
-		hostdata->bytes_read[cmd->target] += cmd->request_bufflen;
+		hostdata->time_read[cmd->device->id] -= (jiffies - hostdata->timebase);
+		hostdata->bytes_read[cmd->device->id] += cmd->request_bufflen;
 		hostdata->pendingr++;
 		break;
 	}
@@ -1014,7 +1015,7 @@
     if (in_interrupt() || ((flags >> 8) & 7) >= 6)
 	queue_main();
     else
-	NCR5380_main();
+	NCR5380_main(NULL);
     return 0;
 }
 
@@ -1030,7 +1031,7 @@
  *  reenable them.  This prevents reentrancy and kernel stack overflow.
  */ 	
     
-static void NCR5380_main (void)
+static void NCR5380_main (void *bl)
 {
     Scsi_Cmnd *tmp, *prev;
     struct Scsi_Host *instance = first_instance;
@@ -1065,7 +1066,7 @@
 
     local_save_flags(flags);
     do {
-	local_irq_disable(flags); /* Freeze request queues */
+	local_irq_disable(); /* Freeze request queues */
 	done = 1;
 	
 	if (!hostdata->connected) {
@@ -1095,7 +1096,7 @@
 #ifdef SUPPORT_TAGS
 		    !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE)
 #else
-		    !(hostdata->busy[tmp->target] & (1 << tmp->lun))
+		    !(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))
 #endif
 		    ) {
 		    /* ++guenther: just to be sure, this must be atomic */
@@ -1217,8 +1218,8 @@
 					    BASR_ACK)) ==
        (BASR_PHASE_MATCH | BASR_ACK)) {
 	    printk("scsi%d: BASR %02x\n", HOSTNO, NCR5380_read(BUS_AND_STATUS_REG));
-	    printk("scsi%d: bus stuck in data phase -- probably a
- single byte overrun!\n", HOSTNO); 
+	    printk("scsi%d: bus stuck in data phase -- probably a single byte "
+		   "overrun!\n", HOSTNO);
 	    printk("not prepared for this error!\n");
 	    printk("please e-mail sammy@sammy.net with a description of how this\n");
 	    printk("error was produced.\n");
@@ -1349,15 +1350,15 @@
 	    case WRITE:
 	    case WRITE_6:
 	    case WRITE_10:
-		hostdata->time_write[cmd->target] += (jiffies - hostdata->timebase);
-		/*hostdata->bytes_write[cmd->target] += cmd->request_bufflen;*/
+		hostdata->time_write[cmd->device->id] += (jiffies - hostdata->timebase);
+		/*hostdata->bytes_write[cmd->device->id] += cmd->request_bufflen;*/
 		hostdata->pendingw--;
 		break;
 	    case READ:
 	    case READ_6:
 	    case READ_10:
-		hostdata->time_read[cmd->target] += (jiffies - hostdata->timebase);
-		/*hostdata->bytes_read[cmd->target] += cmd->request_bufflen;*/
+		hostdata->time_read[cmd->device->id] += (jiffies - hostdata->timebase);
+		/*hostdata->bytes_read[cmd->device->id] += cmd->request_bufflen;*/
 		hostdata->pendingr--;
 		break;
 	}
@@ -1518,7 +1519,7 @@
      * the host and target ID's on the SCSI bus.
      */
 
-    NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->target)));
+    NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id)));
 
     /* 
      * Raise ATN while SEL is true before BSY goes false from arbitration,
@@ -1571,7 +1572,7 @@
 
     udelay(1);
 
-    SEL_PRINTK("scsi%d: selecting target %d\n", HOSTNO, cmd->target);
+    SEL_PRINTK("scsi%d: selecting target %d\n", HOSTNO, cmd->device->id);
 
     /* 
      * The SCSI specification calls for a 250 ms timeout for the actual 
@@ -1622,7 +1623,7 @@
 
     if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-	if (hostdata->targets_present & (1 << cmd->target)) {
+	if (hostdata->targets_present & (1 << cmd->device->id)) {
 	    printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO);
 	    if (hostdata->restart_select)
 		printk(KERN_NOTICE "\trestart select\n");
@@ -1644,7 +1645,7 @@
 	return 0;
     } 
 
-    hostdata->targets_present |= (1 << cmd->target);
+    hostdata->targets_present |= (1 << cmd->device->id);
 
     /*
      * Since we followed the SCSI spec, and raised ATN while SEL 
@@ -1665,8 +1666,8 @@
     while (!(NCR5380_read(STATUS_REG) & SR_REQ));
 
     SEL_PRINTK("scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
-	       HOSTNO, cmd->target);
-    tmp[0] = IDENTIFY(1, cmd->lun);
+	       HOSTNO, cmd->device->id);
+    tmp[0] = IDENTIFY(1, cmd->device->lun);
 
 #ifdef SUPPORT_TAGS
     if (cmd->tag != TAG_NONE) {
@@ -1688,7 +1689,7 @@
     /* XXX need to handle errors here */
     hostdata->connected = cmd;
 #ifndef SUPPORT_TAGS
-    hostdata->busy[cmd->target] |= (1 << cmd->lun);
+    hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
 #endif    
 #ifdef SUN3_SCSI_VME
     dregs->csr |= CSR_INTR;
@@ -2103,7 +2104,7 @@
 			 * polled-IO. */ 
 			printk(KERN_NOTICE "scsi%d: switching target %d "
 			       "lun %d to slow handshake\n", HOSTNO,
-			       cmd->target, cmd->lun);
+			       cmd->device->id, cmd->device->lun);
 			cmd->device->borken = 1;
 			NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
 			    ICR_ASSERT_ATN);
@@ -2161,7 +2162,7 @@
 		    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		    
 		    LNK_PRINTK("scsi%d: target %d lun %d linked command "
-			       "complete.\n", HOSTNO, cmd->target, cmd->lun);
+			       "complete.\n", HOSTNO, cmd->device->id, cmd->device->lun);
 
 		    /* Enable reselect interrupts */
 		    NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
@@ -2174,7 +2175,7 @@
 		    if (!cmd->next_link) {
 			 printk(KERN_NOTICE "scsi%d: target %d lun %d "
 				"linked command complete, no next_link\n",
-				HOSTNO, cmd->target, cmd->lun);
+				HOSTNO, cmd->device->id, cmd->device->lun);
 			    sink = 1;
 			    do_abort (instance);
 			    return;
@@ -2187,7 +2188,7 @@
 		    cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); 
 		    LNK_PRINTK("scsi%d: target %d lun %d linked request "
 			       "done, calling scsi_done().\n",
-			       HOSTNO, cmd->target, cmd->lun);
+			       HOSTNO, cmd->device->id, cmd->device->lun);
 #ifdef NCR5380_STATS
 		    collect_stats(hostdata, cmd);
 #endif
@@ -2201,7 +2202,7 @@
 		    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 		    hostdata->connected = NULL;
 		    QU_PRINTK("scsi%d: command for target %d, lun %d "
-			      "completed\n", HOSTNO, cmd->target, cmd->lun);
+			      "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
 #ifdef SUPPORT_TAGS
 		    cmd_free_tag( cmd );
 		    if (status_byte(cmd->SCp.Status) == QUEUE_FULL) {
@@ -2213,16 +2214,16 @@
 			 */
 			/* ++Andreas: the mid level code knows about
 			   QUEUE_FULL now. */
-			TAG_ALLOC *ta = &TagAlloc[cmd->target][cmd->lun];
+			TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
 			TAG_PRINTK("scsi%d: target %d lun %d returned "
 				   "QUEUE_FULL after %d commands\n",
-				   HOSTNO, cmd->target, cmd->lun,
+				   HOSTNO, cmd->device->id, cmd->device->lun,
 				   ta->nr_allocated);
 			if (ta->queue_size > ta->nr_allocated)
 			    ta->nr_allocated = ta->queue_size;
 		    }
 #else
-		    hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+		    hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 		    /* Enable reselect interrupts */
 		    NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
@@ -2312,12 +2313,12 @@
 			 * the command is treated as untagged further on.
 			 */
 			cmd->device->tagged_supported = 0;
-			hostdata->busy[cmd->target] |= (1 << cmd->lun);
+			hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
 			cmd->tag = TAG_NONE;
 			TAG_PRINTK("scsi%d: target %d lun %d rejected "
 				   "QUEUE_TAG message; tagged queuing "
 				   "disabled\n",
-				   HOSTNO, cmd->target, cmd->lun);
+				   HOSTNO, cmd->device->id, cmd->device->lun);
 			break;
 		    }
 		    break;
@@ -2334,7 +2335,7 @@
 		    QU_PRINTK("scsi%d: command for target %d lun %d was "
 			      "moved from connected to the "
 			      "disconnected_queue\n", HOSTNO, 
-			      cmd->target, cmd->lun);
+			      cmd->device->id, cmd->device->lun);
 		    /* 
 		     * Restore phase bits to 0 so an interrupted selection, 
 		     * arbitration can resume.
@@ -2436,13 +2437,13 @@
 		    } else if (tmp != EXTENDED_MESSAGE)
 			printk(KERN_DEBUG "scsi%d: rejecting unknown "
 			       "message %02x from target %d, lun %d\n",
-			       HOSTNO, tmp, cmd->target, cmd->lun);
+			       HOSTNO, tmp, cmd->device->id, cmd->device->lun);
 		    else
 			printk(KERN_DEBUG "scsi%d: rejecting unknown "
 			       "extended message "
 			       "code %02x, length %d from target %d, lun %d\n",
 			       HOSTNO, extended_msg[1], extended_msg[0],
-			       cmd->target, cmd->lun);
+			       cmd->device->id, cmd->device->lun);
    
 
 		    msgout = MESSAGE_REJECT;
@@ -2460,7 +2461,7 @@
 #ifdef SUPPORT_TAGS
 		    cmd_free_tag( cmd );
 #else
-		    hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+		    hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 		    hostdata->connected = NULL;
 		    cmd->result = DID_ERROR << 16;
@@ -2579,7 +2580,7 @@
 
     for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; 
 	 tmp; prev = tmp, tmp = NEXT(tmp) ) {
-	if ((target_mask == (1 << tmp->target)) && (lun == tmp->lun)
+	if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun)
 #ifdef SUPPORT_TAGS
 	    && (tag == tmp->tag) 
 #endif
@@ -2686,7 +2687,7 @@
 
 static int NCR5380_abort (Scsi_Cmnd *cmd)
 {
-    struct Scsi_Host *instance = cmd->host;
+    struct Scsi_Host *instance = cmd->device->host;
     SETUP_HOSTDATA(instance);
     Scsi_Cmnd *tmp, **prev;
     unsigned long flags;
@@ -2736,7 +2737,7 @@
 #ifdef SUPPORT_TAGS
 	  cmd_free_tag( cmd );
 #else
-	  hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+	  hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 	  local_irq_restore(flags);
 	  cmd->scsi_done(cmd);
@@ -2841,7 +2842,7 @@
 #ifdef SUPPORT_TAGS
 		    cmd_free_tag( tmp );
 #else
-		    hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
+		    hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
 		    local_irq_restore(flags);
 		    tmp->scsi_done(tmp);
@@ -2868,7 +2869,7 @@
 
 
 /* 
- * Function : int NCR5380_reset (Scsi_Cmnd *cmd, unsigned int reset_flags)
+ * Function : int NCR5380_bus_reset (Scsi_Cmnd *cmd)
  * 
  * Purpose : reset the SCSI bus.
  *
@@ -2876,9 +2877,9 @@
  *
  */ 
 
-static int NCR5380_reset( Scsi_Cmnd *cmd, unsigned int reset_flags)
+static int NCR5380_bus_reset( Scsi_Cmnd *cmd)
 {
-    SETUP_HOSTDATA(cmd->host);
+    SETUP_HOSTDATA(cmd->device->host);
     int           i;
     unsigned long flags;
 #if 1
@@ -2886,7 +2887,7 @@
 #endif
 
 
-    NCR5380_print_status (cmd->host);
+    NCR5380_print_status (cmd->device->host);
 
     /* get in phase */
     NCR5380_write( TARGET_COMMAND_REG,
diff -Nru a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c
--- a/drivers/scsi/sun3_scsi.c	Sun Dec 29 05:24:40 2002
+++ b/drivers/scsi/sun3_scsi.c	Wed Mar  5 05:19:23 2003
@@ -79,6 +79,8 @@
 #include "sun3_scsi.h"
 #include "NCR5380.h"
 
+static void NCR5380_print(struct Scsi_Host *instance);
+
 /* #define OLDDMA */
 
 #define USE_WRAPPER
@@ -312,7 +314,7 @@
 	if (shpnt->irq != IRQ_NONE)
 		free_irq (shpnt->irq, NULL);
 
-	iounmap(sun3_scsi_regp);
+	iounmap((void *)sun3_scsi_regp);
 
 	return 0;
 }
@@ -621,8 +623,8 @@
 	.release		= sun3scsi_release,
 	.info			= sun3scsi_info,
 	.queuecommand		= sun3scsi_queue_command,
-	.abort			= sun3scsi_abort,
-	.reset			= sun3scsi_reset,
+	.eh_abort_handler      	= sun3scsi_abort,
+	.eh_bus_reset_handler  	= sun3scsi_bus_reset,
 	.can_queue		= CAN_QUEUE,
 	.this_id		= 7,
 	.sg_tablesize		= SG_TABLESIZE,
diff -Nru a/drivers/scsi/sun3_scsi.h b/drivers/scsi/sun3_scsi.h
--- a/drivers/scsi/sun3_scsi.h	Wed Nov 20 03:36:31 2002
+++ b/drivers/scsi/sun3_scsi.h	Fri Feb  7 14:02:17 2003
@@ -55,7 +55,7 @@
 static int sun3scsi_abort (Scsi_Cmnd *);
 static int sun3scsi_detect (Scsi_Host_Template *);
 static const char *sun3scsi_info (struct Scsi_Host *);
-static int sun3scsi_reset(Scsi_Cmnd *, unsigned int);
+static int sun3scsi_bus_reset(Scsi_Cmnd *);
 static int sun3scsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 static int sun3scsi_proc_info (char *buffer, char **start, off_t offset,
 			int length, int hostno, int inout);
@@ -109,7 +109,7 @@
 
 #define NCR5380_intr sun3scsi_intr
 #define NCR5380_queue_command sun3scsi_queue_command
-#define NCR5380_reset sun3scsi_reset
+#define NCR5380_bus_reset sun3scsi_bus_reset
 #define NCR5380_abort sun3scsi_abort
 #define NCR5380_proc_info sun3scsi_proc_info
 #define NCR5380_dma_xfer_len(i, cmd, phase) \
diff -Nru a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c
--- a/drivers/scsi/sun3_scsi_vme.c	Thu Nov  7 15:13:51 2002
+++ b/drivers/scsi/sun3_scsi_vme.c	Fri Feb  7 14:02:17 2003
@@ -1,4 +1,4 @@
-/*
+ /*
  * Sun3 SCSI stuff by Erik Verbruggen (erik@bigmama.xtdnet.nl)
  *
  * Sun3 DMA routines added by Sam Creasey (sammy@sammy.net)
@@ -566,8 +566,8 @@
 	.release		= sun3scsi_release,
 	.info			= sun3scsi_info,
 	.queuecommand		= sun3scsi_queue_command,
-	.abort			= sun3scsi_abort,
-	.reset			= sun3scsi_reset,
+	.eh_abort_handler      	= sun3scsi_abort,
+	.eh_bus_reset_handler  	= sun3scsi_bus_reset,
 	.can_queue		= CAN_QUEUE,
 	.this_id		= 7,
 	.sg_tablesize		= SG_TABLESIZE,
diff -Nru a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c
--- a/drivers/scsi/sun3x_esp.c	Mon Nov 18 09:40:33 2002
+++ b/drivers/scsi/sun3x_esp.c	Fri Feb  7 14:02:17 2003
@@ -374,11 +374,44 @@
     sp->SCp.ptr = (char *)((unsigned long)sp->SCp.buffer->dvma_address);
 }
 
+
+static int esp_slave_alloc(Scsi_Device *SDptr)
+{
+	struct esp_device *esp_dev =
+		kmalloc(sizeof(struct esp_device), GFP_ATOMIC);
+
+	if (!esp_dev)
+		return -ENOMEM;
+	memset(esp_dev, 0, sizeof(struct esp_device));
+	SDptr->hostdata = esp_dev;
+	return 0;
+}
+
+static void esp_slave_destroy(Scsi_Device *SDptr)
+{
+	struct NCR_ESP *esp = (struct NCR_ESP *) SDptr->host->hostdata;
+
+	esp->targets_present &= ~(1 << SDptr->id);
+	kfree(SDptr->hostdata);
+	SDptr->hostdata = NULL;
+}
+
+
+static int sun3x_esp_release(struct Scsi_Host *instance)
+{
+	/* this code does not support being compiled as a module */	 
+	return 1;
+
+}
+
 static Scsi_Host_Template driver_template = {
 	.proc_name		= "esp",
 	.proc_info		= &esp_proc_info,
 	.name			= "Sun ESP 100/100a/200",
 	.detect			= sun3x_esp_detect,
+	.release                = sun3x_esp_release,
+	.slave_alloc		= esp_slave_alloc,
+	.slave_destroy		= esp_slave_destroy,
 	.info			= esp_info,
 	.command		= esp_command,
 	.queuecommand		= esp_queue,
diff -Nru a/drivers/scsi/sym53c416.h b/drivers/scsi/sym53c416.h
--- a/drivers/scsi/sym53c416.h	Mon Oct 28 16:27:36 2002
+++ b/drivers/scsi/sym53c416.h	Thu Mar  6 15:56:54 2003
@@ -18,14 +18,6 @@
 #ifndef _SYM53C416_H
 #define _SYM53C416_H
 
-#if !defined(LINUX_VERSION_CODE)
-#include <linux/version.h>
-#endif
-
-#ifndef LinuxVersionCode
-#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
-#endif
-
 #include <linux/types.h>
 
 #define SYM53C416_SCSI_ID 7
diff -Nru a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
--- a/drivers/scsi/wd33c93.c	Wed Feb 26 13:42:42 2003
+++ b/drivers/scsi/wd33c93.c	Thu Mar  6 04:03:12 2003
@@ -1471,7 +1471,7 @@
 		int busycount = 0;
 		extern void sgiwd93_reset(unsigned long);
 		/* wait 'til the chip gets some time for us */
-		while ((READ_AUX_STAT() & ASR_BSY) && busycount++ < 100)
+		while ((read_aux_stat(regs) & ASR_BSY) && busycount++ < 100)
 			udelay (10);
 	/*
  	 * there are scsi devices out there, which manage to lock up
@@ -1481,7 +1481,7 @@
 	 * does this for the SGI Indy, where this is possible
 	 */
 	/* still busy ? */
-	if (READ_AUX_STAT() & ASR_BSY)
+	if (read_aux_stat(regs) & ASR_BSY)
 		sgiwd93_reset(instance->base); /* yeah, give it the hard one */
 	}
 #endif
@@ -2086,3 +2086,4 @@
 EXPORT_SYMBOL(wd33c93_abort);
 EXPORT_SYMBOL(wd33c93_queuecommand);
 EXPORT_SYMBOL(wd33c93_intr);
+EXPORT_SYMBOL(wd33c93_proc_info);
diff -Nru a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
--- a/drivers/scsi/wd7000.c	Thu Feb 20 09:57:04 2003
+++ b/drivers/scsi/wd7000.c	Sat Mar 22 22:14:13 2003
@@ -1710,7 +1710,11 @@
 static int wd7000_biosparam(struct scsi_device *sdev,
 		struct block_device *bdev, sector_t capacity, int *ip)
 {
-	dprintk("wd7000_biosparam: dev=%s, size=%d, ", bdevname(bdev), capacity);
+	char b[BDEVNAME_SIZE];
+
+	dprintk("wd7000_biosparam: dev=%s, size=%d, ",
+		bdevname(bdev, b), capacity);
+	(void)b;	/* unused var warning? */
 
 	/*
 	 * try default translation
diff -Nru a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
--- a/drivers/serial/8250_pnp.c	Fri Feb 21 13:56:44 2003
+++ b/drivers/serial/8250_pnp.c	Thu Mar 13 17:07:59 2003
@@ -188,6 +188,8 @@
 	{	"MVX00A1",		0	},
 	/* PC Rider K56 Phone System PnP */
 	{	"MVX00F2",		0	},
+	/* NEC 98NOTE SPEAKER PHONE FAX MODEM(33600bps) */
+	{	"nEC8241",		0	},
 	/* Pace 56 Voice Internal Plug & Play Modem */
 	{	"PMC2430",		0	},
 	/* Generic */
@@ -373,6 +375,9 @@
 			    ((port->min == 0x2f8) ||
 			     (port->min == 0x3f8) ||
 			     (port->min == 0x2e8) ||
+#ifdef CONFIG_X86_PC9800
+			     (port->min == 0x8b0) ||
+#endif
 			     (port->min == 0x3e8)))
 				return 0;
 	}
diff -Nru a/drivers/serial/serial98.c b/drivers/serial/serial98.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/serial98.c	Thu Mar 20 10:43:51 2003
@@ -0,0 +1,1124 @@
+/*
+ *  linux/drivers/serial/serial98.c
+ *
+ *  Driver for NEC PC-9801/PC-9821 standard serial ports
+ *
+ *  Based on drivers/serial/8250.c, by Russell King.
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2002 Osamu Tomita <tomita@cinet.co.jp>
+ *
+ * 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/module.h>
+#include <linux/tty.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/serial_reg.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pc9800.h>
+#include <asm/pc9800_sca.h>
+
+#if defined(CONFIG_SERIAL98_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+#define SERIAL98_NR		1
+#define SERIAL98_ISR_PASS_LIMIT	256
+#define SERIAL98_EXT		0x434
+
+//#define RX_8251F		0x130	/* In: Receive buffer */
+//#define TX_8251F		0x130	/* Out: Transmit buffer */
+//#define LSR_8251F		0x132	/* In: Line Status Register */
+//#define MSR_8251F		0x134	/* In: Modem Status Register */
+#define IIR_8251F		0x136	/* In: Interrupt ID Register */
+#define FCR_8251F		0x138	/* I/O: FIFO Control Register */
+#define VFAST_8251F		0x13a	/* I/O: VFAST mode Register */
+
+#define CMD_8251F		0x32	/* Out: 8251 Command Resister */
+#define IER2_8251F		0x34	/* I/O: Interrupt Enable Register */
+#define IER1_8251F		0x35	/* I/O: Interrupt Enable Register */
+#define IER1_CTL		0x37	/* Out: Interrupt Enable Register */
+#define DIS_RXR_INT		0x00	/* disable RxRDY Interrupt */
+#define ENA_RXR_INT		0x01	/* enable RxRDY Interrupt */
+#define DIS_TXE_INT		0x02	/* disable TxEMPTY Interrupt */
+#define ENA_TXE_INT		0x03	/* enable TxEMPTY Interrupt */
+#define DIS_TXR_INT		0x04	/* disable TxRDY Interrupt */
+#define ENA_TXR_INT		0x05	/* enable TxRDY Interrupt */
+
+#define CMD_RESET		0x40	/* Reset Command */
+#define CMD_RTS			0x20	/* Set RTS line */
+#define CMD_CLR_ERR		0x10	/* Clear error flag */
+#define CMD_BREAK		0x08	/* Send Break */
+#define CMD_RXE			0x04	/* Enable receive */
+#define CMD_DTR			0x02	/* Set DTR line */
+#define CMD_TXE			0x01	/* Enable send */
+#define CMD_DUMMY		0x00	/* Dummy Command */
+
+#define VFAST_ENABLE		0x80	/* V.Fast mode Enable */
+
+/* Interrupt masks */
+#define INTR_8251_TXRE		0x04
+#define INTR_8251_TXEE		0x02
+#define INTR_8251_RXRE		0x01
+/* I/O Port */
+//#define PORT_8251_DATA	0
+//#define PORT_8251_CMD		2
+//#define PORT_8251_MOD		2
+//#define PORT_8251_STS		2
+/* status read */
+#define STAT_8251_TXRDY		0x01
+#define STAT_8251_RXRDY		0x02
+#define STAT_8251_TXEMP		0x04
+#define STAT_8251_PER		0x08
+#define STAT_8251_OER		0x10
+#define STAT_8251_FER		0x20
+#define STAT_8251_BRK		0x40
+#define STAT_8251_DSR		0x80
+#if 1
+#define STAT_8251F_TXEMP	0x01
+#define STAT_8251F_TXRDY	0x02
+#define STAT_8251F_RXRDY	0x04
+#define STAT_8251F_DSR		0x08
+#define STAT_8251F_OER		0x10
+#define STAT_8251F_PER		0x20
+#define STAT_8251F_FER		0x40
+#define STAT_8251F_BRK		0x80
+#else
+#define STAT_8251F_TXEMP	0x01
+#define STAT_8251F_TEMT		0x01
+#define STAT_8251F_TXRDY	0x02
+#define STAT_8251F_THRE		0x02
+#define STAT_8251F_RXRDY	0x04
+#define STAT_8251F_DSR		0x04
+#define STAT_8251F_PER		0x08
+#define STAT_8251F_OER		0x10
+#define STAT_8251F_FER		0x20
+#define STAT_8251F_BRK		0x40
+#endif
+
+/*
+ * We wrap our port structure around the generic uart_port.
+ */
+struct serial98_port {
+	struct uart_port	port;
+	unsigned int		type;
+	unsigned int		ext;
+	unsigned int		lsr_break_flag;
+	unsigned char		cmd;
+	unsigned char		mode;
+	unsigned char		msr;
+	unsigned char		ier;
+	unsigned char		rxchk;
+	unsigned char		txemp;
+	unsigned char		txrdy;
+	unsigned char		rxrdy;
+	unsigned char		brk;
+	unsigned char		fe;
+	unsigned char		oe;
+	unsigned char		pe;
+	unsigned char		dr;
+};
+
+#ifdef CONFIG_SERIAL98_CONSOLE
+static void
+serial98_console_write(struct console *co, const char *s, unsigned int count);
+static kdev_t serial98_console_device(struct console *co);
+static int __init serial98_console_setup(struct console *co, char *options);
+
+static struct console serial98_console = {
+	.name		= "ttyS",
+	.write		= serial98_console_write,
+	.device		= serial98_console_device,
+	.setup		= serial98_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
+
+#define SERIAL98_CONSOLE	&serial98_console
+#else
+#define SERIAL98_CONSOLE	NULL
+#endif
+
+static struct uart_driver serial98_reg = {
+	.owner			= THIS_MODULE,
+	.driver_name		= "serial98",
+	.dev_name		= "ttyS%d",
+	.major			= TTY_MAJOR,
+	.minor			= 64,
+	.nr			= SERIAL98_NR,
+	.cons			= SERIAL98_CONSOLE,
+};
+
+static int serial98_clk;
+static char type_str[48];
+
+#define PORT98 ((struct serial98_port *)port)
+#define PORT (PORT98->port)
+
+static void serial98_fifo_enable(struct uart_port *port, int enable)
+{
+	unsigned char fcr;
+
+	if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
+		fcr = inb(FCR_8251F);
+		if (enable)
+			fcr |= UART_FCR_ENABLE_FIFO;
+		else
+			fcr &= ~UART_FCR_ENABLE_FIFO;
+		outb(fcr, FCR_8251F);
+	}
+
+	if (!enable)
+		return;
+
+	outb(0, 0x5f);	/* wait */
+	outb(0, 0x5f);
+	outb(0, 0x5f);
+	outb(0, 0x5f);
+}
+
+static void serial98_cmd_out(struct uart_port *port, unsigned char cmd)
+{
+	serial98_fifo_enable(port, 0);
+	outb(cmd, CMD_8251F);
+	serial98_fifo_enable(port, 1);
+}
+
+static void serial98_mode_set(struct uart_port *port)
+{
+	serial98_cmd_out(port, CMD_DUMMY);
+	serial98_cmd_out(port, CMD_DUMMY);
+	serial98_cmd_out(port, CMD_DUMMY);
+	serial98_cmd_out(port, CMD_RESET);
+	serial98_cmd_out(port, PORT98->mode);
+}
+
+static unsigned char serial98_msr_in(struct uart_port *port)
+{
+	unsigned long flags;
+	unsigned int ms, st;
+	unsigned int tmp;
+
+	spin_lock_irqsave(&PORT.lock, flags);
+	if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
+		PORT98->msr = inb(PORT.iobase + 4);
+	} else {
+		ms = inb(0x33);
+		st = inb(0x32);
+		tmp = 0;
+		if(!(ms & 0x20))
+			tmp |= UART_MSR_DCD;
+		if(!(ms & 0x80)) {
+			tmp |= UART_MSR_RI;
+			PORT98->msr |= UART_MSR_RI;
+		}
+		if(!(ms & 0x40))
+			tmp |= UART_MSR_CTS;
+		if(st & 0x80)
+			tmp |= UART_MSR_DSR;
+		PORT98->msr = ((PORT98->msr ^ tmp) >> 4) | tmp;
+	}
+
+	spin_unlock_irqrestore(&PORT.lock, flags);
+	return PORT98->msr;
+}
+
+static void serial98_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	unsigned int ier = inb(IER1_8251F);
+
+	ier &= ~(INTR_8251_TXRE | INTR_8251_TXEE);
+	outb(ier, IER1_8251F);
+}
+
+static void serial98_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	unsigned int ier = inb(IER1_8251F);
+
+	ier |= INTR_8251_TXRE | INTR_8251_TXEE;
+	outb(ier, IER1_8251F);
+}
+
+static void serial98_stop_rx(struct uart_port *port)
+{
+	PORT.read_status_mask &= ~PORT98->dr;
+	outb(DIS_RXR_INT, IER1_CTL);
+}
+
+static void serial98_enable_ms(struct uart_port *port)
+{
+	outb(PORT98->ier | 0x80, IER2_8251F);
+}
+
+static void serial98_rx_chars(struct uart_port *port, int *status,
+				struct pt_regs *regs)
+{
+	struct tty_struct *tty = PORT.info->tty;
+	unsigned char ch;
+	int max_count = 256;
+
+	do {
+		if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
+			tty->flip.work.func((void *)tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+				return; // if TTY_DONT_FLIP is set
+		}
+		ch = inb(PORT.iobase);
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		PORT.icount.rx++;
+
+		if (unlikely(*status & (PORT98->brk | PORT98->pe |
+				       PORT98->fe | PORT98->oe))) {
+			/*
+			 * For statistics only
+			 */
+			if (*status & PORT98->brk) {
+				*status &= ~(PORT98->fe | PORT98->pe);
+				PORT.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 (uart_handle_break(&PORT))
+					goto ignore_char;
+			} else if (*status & PORT98->pe)
+				PORT.icount.parity++;
+			else if (*status & PORT98->fe)
+				PORT.icount.frame++;
+			if (*status & PORT98->oe)
+				PORT.icount.overrun++;
+
+			/*
+			 * Mask off conditions which should be ingored.
+			 */
+			*status &= PORT.read_status_mask;
+
+#ifdef CONFIG_SERIAL98_CONSOLE
+			if (PORT.line == PORT.cons->index) {
+				/* Recover the break flag from console xmit */
+				*status |= PORT98->lsr_break_flag;
+				PORT98->lsr_break_flag = 0;
+			}
+#endif
+			if (*status & PORT98->brk) {
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			} else if (*status & PORT98->pe)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (*status & PORT98->fe)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+		if (uart_handle_sysrq_char(&PORT, ch, regs))
+			goto ignore_char;
+		if ((*status & PORT.ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((*status & PORT98->oe) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character.
+			 */
+			*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+	ignore_char:
+		*status = inb(PORT.iobase + 2);
+	} while ((*status & PORT98->rxchk) && (max_count-- > 0));
+	tty_flip_buffer_push(tty);
+}
+
+static void serial98_tx_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &PORT.info->xmit;
+	int count;
+
+	if (PORT.x_char) {
+		outb(PORT.x_char, PORT.iobase);
+		PORT.icount.tx++;
+		PORT.x_char = 0;
+		return;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(&PORT)) {
+		serial98_stop_tx(port, 0);
+		return;
+	}
+
+	count = PORT.fifosize;
+	do {
+		outb(xmit->buf[xmit->tail], PORT.iobase);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		PORT.icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (--count > 0);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(&PORT);
+
+	if (uart_circ_empty(xmit))
+		serial98_stop_tx(&PORT, 0);
+}
+
+static void serial98_modem_status(struct uart_port *port)
+{
+	int status;
+
+	status = serial98_msr_in(port);
+
+	if ((status & UART_MSR_ANY_DELTA) == 0)
+		return;
+
+	if (status & UART_MSR_TERI)
+		PORT.icount.rng++;
+	if (status & UART_MSR_DDSR)
+		PORT.icount.dsr++;
+	if (status & UART_MSR_DDCD)
+		uart_handle_dcd_change(&PORT, status & UART_MSR_DCD);
+	if (status & UART_MSR_DCTS)
+		uart_handle_cts_change(&PORT, status & UART_MSR_CTS);
+
+	wake_up_interruptible(&PORT.info->delta_msr_wait);
+}
+
+static void serial98_int(int irq, void *port, struct pt_regs *regs)
+{
+	unsigned int status;
+
+	spin_lock(&PORT.lock);
+	status = inb(PORT.iobase + 2);
+	if (status & PORT98->rxrdy) {
+		serial98_rx_chars(port, &status, regs);
+	}
+	serial98_modem_status(port);
+	if (status & PORT98->txrdy) {
+		serial98_tx_chars(port);
+	}
+	spin_unlock(&PORT.lock);
+}
+
+static unsigned int serial98_tx_empty(struct uart_port *port)
+{
+	unsigned long flags;
+	unsigned int ret = 0;
+
+	spin_lock_irqsave(&PORT.lock, flags);
+	if (inb(PORT.iobase + 2) & PORT98->txemp)
+			ret = TIOCSER_TEMT;
+
+	spin_unlock_irqrestore(&PORT.lock, flags);
+	return ret;
+}
+
+static unsigned int serial98_get_mctrl(struct uart_port *port)
+{
+	unsigned char status;
+	unsigned int ret = 0;
+
+	status = serial98_msr_in(port);
+	if (status & UART_MSR_DCD)
+		ret |= TIOCM_CAR;
+	if (status & UART_MSR_RI)
+		ret |= TIOCM_RNG;
+	if (status & UART_MSR_DSR)
+		ret |= TIOCM_DSR;
+	if (status & UART_MSR_CTS)
+		ret |= TIOCM_CTS;
+	return ret;
+}
+
+static void serial98_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	PORT98->cmd &= 0xdd;
+	if (mctrl & TIOCM_RTS)
+		PORT98->cmd |= CMD_RTS;
+
+	if (mctrl & TIOCM_DTR)
+		PORT98->cmd |= CMD_DTR;
+
+	serial98_cmd_out(port, PORT98->cmd);
+}
+
+static void serial98_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&PORT.lock, flags);
+	if (break_state == -1)
+		PORT98->cmd |= CMD_BREAK;
+	else
+		PORT98->cmd &= ~CMD_BREAK;
+
+	serial98_cmd_out(port, PORT98->cmd);
+	spin_unlock_irqrestore(&PORT.lock, flags);
+}
+
+static int serial98_startup(struct uart_port *port)
+{
+	int retval;
+
+	if (PORT.type == PORT_8251_PC98) {
+		/* Wake up UART */
+		PORT98->mode = 0xfc;
+		serial98_mode_set(port);
+		outb(DIS_RXR_INT, IER1_CTL);
+		outb(DIS_TXE_INT, IER1_CTL);
+		outb(DIS_TXR_INT, IER1_CTL);
+		PORT98->mode = 0;
+		serial98_mode_set(port);
+	}
+
+	/*
+	 * Clear the FIFO buffers and disable them.
+	 * (they will be reeanbled in set_termios())
+	 */
+	if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
+		outb(UART_FCR_ENABLE_FIFO, FCR_8251F);
+		outb((UART_FCR_ENABLE_FIFO
+			| UART_FCR_CLEAR_RCVR
+			| UART_FCR_CLEAR_XMIT), FCR_8251F);
+		outb(0, FCR_8251F);
+	}
+
+	/* Clear the interrupt registers. */
+	inb(0x30);
+	inb(0x32);
+	if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
+		inb(PORT.iobase);
+		inb(PORT.iobase + 2);
+		inb(PORT.iobase + 4);
+		inb(PORT.iobase + 6);
+	}
+
+	/* Allocate the IRQ */
+	retval = request_irq(PORT.irq, serial98_int, 0,
+				serial98_reg.driver_name, port);
+	if (retval)
+		return retval;
+
+	/*
+	 * Now, initialize the UART
+	 */
+	PORT98->mode = 0x4e;
+	serial98_mode_set(port);
+	PORT98->cmd = 0x15;
+	serial98_cmd_out(port, PORT98->cmd);
+	PORT98->cmd = 0x05;
+
+	/*
+	 * Finally, enable interrupts
+	 */
+	outb(0x00, IER2_8251F);
+	outb(ENA_RXR_INT, IER1_CTL);
+
+	/*
+	 * And clear the interrupt registers again for luck.
+	 */
+	inb(0x30);
+	inb(0x32);
+	if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
+		inb(PORT.iobase);
+		inb(PORT.iobase + 2);
+		inb(PORT.iobase + 4);
+		inb(PORT.iobase + 6);
+	}
+
+	return 0;
+}
+
+static void serial98_shutdown(struct uart_port *port)
+{
+	unsigned long flags;
+
+	/*
+	 * disable all interrupts
+	 */
+	spin_lock_irqsave(&PORT.lock, flags);
+	if (PORT.type == PORT_VFAST_PC98)
+		outb(0, VFAST_8251F);		/* V.FAST mode off */
+
+	/* disnable all modem status interrupt */
+	outb(0x80, IER2_8251F);
+
+	/* disnable TX/RX interrupt */
+	outb(0x00, IER2_8251F);
+	outb(DIS_RXR_INT, IER1_CTL);
+	outb(DIS_TXE_INT, IER1_CTL);
+	outb(DIS_TXR_INT, IER1_CTL);
+	PORT98->ier = 0;
+
+	spin_unlock_irqrestore(&PORT.lock, flags);
+
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(PORT.irq, port);
+
+	/* disable break condition and disable the port */
+	serial98_mode_set(port);
+
+	/* disable FIFO's */	
+	if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
+		outb((UART_FCR_ENABLE_FIFO
+			| UART_FCR_CLEAR_RCVR
+			| UART_FCR_CLEAR_XMIT), FCR_8251F);
+		outb(0, FCR_8251F);
+	}
+
+	inb(PORT.iobase);
+}
+
+static void
+serial98_set_termios(struct uart_port *port, struct termios *termios,
+		       struct termios *old)
+{
+	unsigned char stopbit, cval, fcr = 0, ier = 0;
+	unsigned long flags;
+	unsigned int baud, quot;
+
+	stopbit = 0x80;
+	switch (termios->c_cflag & CSIZE) {
+		case CS5:
+			cval = 0x42;
+			stopbit = 0xc0;
+			break;
+		case CS6:
+			cval = 0x46;
+			break;
+		case CS7:
+			cval = 0x4a;
+			break;
+		default:
+		case CS8:
+			cval = 0x4e;
+			break;
+	}
+
+	if (termios->c_cflag & CSTOPB)
+		cval ^= stopbit;
+	if (termios->c_cflag & PARENB)
+		cval |= 0x10;
+	if (!(termios->c_cflag & PARODD))
+		cval |= 0x20;
+
+	/*
+	 * Ask the core to calculate the divisor for us.
+	 */
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
+	quot = uart_get_divisor(port, baud);
+
+	if (PORT.type == PORT_FIFO_PC98 || PORT.type == PORT_VFAST_PC98) {
+		if ((PORT.uartclk / quot) < (2400 * 16))
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+		else
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
+	}
+
+	/*
+	 * Ok, we're now changing the port state.  Do it with
+	 * interrupts disabled.
+	 */
+	spin_lock_irqsave(&PORT.lock, flags);
+
+	/*
+	 * Update the per-port timeout.
+	 */
+	uart_update_timeout(port, termios->c_cflag, baud);
+
+	PORT.read_status_mask = PORT98->oe | PORT98->txemp | PORT98->dr;
+	if (termios->c_iflag & INPCK)
+		PORT.read_status_mask |= PORT98->fe | PORT98->pe;
+
+	if (termios->c_iflag & (BRKINT | PARMRK))
+		PORT.read_status_mask |= PORT98->brk;
+	/*
+	 * Characters to ignore
+	 */
+	PORT.ignore_status_mask = 0;
+	if (termios->c_iflag & IGNPAR)
+		PORT.ignore_status_mask |= PORT98->fe | PORT98->pe;
+
+	if (termios->c_iflag & IGNBRK) {
+		PORT.ignore_status_mask |= PORT98->brk;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (termios->c_iflag & IGNPAR)
+			PORT.ignore_status_mask |= PORT98->oe;
+	}
+
+	/*
+	 * ignore all characters if CREAD is not set
+	 */
+	if ((termios->c_cflag & CREAD) == 0)
+		PORT.ignore_status_mask |= PORT98->dr;
+
+	/*
+	 * CTS flow control flag and modem status interrupts
+	 */
+	if (PORT.flags & UPF_HARDPPS_CD)
+		ier |= 0x80;	/* enable modem status interrupt */
+	if (termios->c_cflag & CRTSCTS) {
+		ier |= 0x08;	/* enable CTS interrupt */
+		ier |= 0x80;	/* enable modem status interrupt */
+	}
+	if (!(termios->c_cflag & CLOCAL)) {
+		ier |= 0x20;	/* enable CD interrupt */
+		ier |= 0x80;	/* enable modem status interrupt */
+	}
+	PORT98->ier = ier;
+
+	PORT98->mode = cval;
+	serial98_mode_set(port);
+	if (PORT.type == PORT_VFAST_PC98 && quot <= 48) {
+		quot /= 4;
+		if (quot < 1)
+			quot = 1;
+		outb(quot | VFAST_ENABLE, VFAST_8251F);
+	} else {
+		quot /= 3;
+		if (quot < 1)
+			quot = 1;
+		if (PORT.type == PORT_VFAST_PC98)
+			outb(0, VFAST_8251F);		/* V.FAST mode off */
+		outb(0xb6, 0x77);
+		outb(quot & 0xff, 0x75);		/* LS of divisor */
+		outb(quot >> 8, 0x75);			/* MS of divisor */
+	}
+
+	if (fcr & UART_FCR_ENABLE_FIFO) {
+		outb(UART_FCR_ENABLE_FIFO, FCR_8251F);
+		outb(fcr, FCR_8251F);
+	}
+
+	/* enable RX/TX */
+	PORT98->cmd = 0x15;
+	serial98_cmd_out(port, PORT98->cmd);
+	PORT98->cmd = 0x05;
+	/* enable interrupts */
+	outb(0x00, IER2_8251F);
+	outb(ENA_RXR_INT, IER1_CTL);
+	spin_unlock_irqrestore(&PORT.lock, flags);
+}
+
+static const char *serial98_type(struct uart_port *port)
+{
+	char *p;
+
+	switch (PORT.type) {
+		case PORT_8251_PC98:
+			p = "PC98 onboard legacy 8251";
+			break;
+		case PORT_19K_PC98:
+			p =  "PC98 onboard max 19200bps";
+			break;
+		case PORT_FIFO_PC98:
+			p = "PC98 onboard with FIFO";
+			break;
+		case PORT_VFAST_PC98:
+			p = "PC98 onboard V.FAST";
+			break;
+		case PORT_PC9861:
+			p = "PC-9861K RS-232C ext. board";
+			break;
+		case PORT_PC9801_101:
+			p = "PC-9801-101 RS-232C ext. board";
+			break;
+		default:
+			return NULL;
+	}
+
+	sprintf(type_str, "%s  Clock %dMHz", p, serial98_clk);
+	return type_str;
+}
+
+/* Release the region(s) being used by 'port' */
+static void serial98_release_port(struct uart_port *port)
+{
+	switch (PORT.type) {
+		case PORT_VFAST_PC98:
+			release_region(PORT.iobase + 0xa, 1);
+		case PORT_FIFO_PC98:
+			release_region(PORT.iobase + 8, 1);
+			release_region(PORT.iobase + 6, 1);
+			release_region(PORT.iobase + 4, 1);
+			release_region(PORT.iobase + 2, 1);
+			release_region(PORT.iobase, 1);
+		case PORT_19K_PC98:
+			release_region(SERIAL98_EXT, 1);
+			release_region(0x34, 1);
+		case PORT_8251_PC98:
+			release_region(0x32, 1);
+			release_region(0x30, 1);
+	}
+}
+
+/* Request the region(s) being used by 'port' */
+#define REQ_REGION98(base) (request_region((base), 1, serial98_reg.driver_name))
+static int serial98_request_region(unsigned int type)
+{
+	if (!REQ_REGION98(0x30))
+		return -EBUSY;
+	if (REQ_REGION98(0x32)) {
+		if (type == PORT_8251_PC98)
+			return 0;
+		if (REQ_REGION98(0x34)) {
+			if (REQ_REGION98(SERIAL98_EXT)) {
+				unsigned long base;
+
+				if (type == PORT_19K_PC98)
+					return 0;
+				for (base = 0x130; base <= 0x138; base += 2) {
+					if (!REQ_REGION98(base)) {
+						base -= 2;
+						goto err;
+					}
+				}
+				if (type == PORT_FIFO_PC98)
+					return 0;
+				if (type == PORT_VFAST_PC98) {
+					if (REQ_REGION98(0x13a))
+						return 0;
+				}
+				err:
+				while (base >= 0x130) {
+					release_region(base, 1);
+					base -= 2;
+				}
+				release_region(SERIAL98_EXT, 1);
+			}
+			release_region(0x34, 1);
+		}
+		release_region(0x32, 1);
+	}
+	release_region(0x30, 1);
+	return -EBUSY;
+}
+
+static int serial98_request_port(struct uart_port *port)
+{
+	return serial98_request_region(PORT.type);
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void serial98_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE)
+		PORT.type = PORT98->type;
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int serial98_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	switch (ser->type) {
+		case PORT_VFAST_PC98:
+		case PORT_FIFO_PC98:
+		case PORT_19K_PC98:
+		case PORT_8251_PC98:
+		/* not implemented yet
+		case PORT_PC9861:
+		case PORT_PC9801_101:
+		*/
+		case PORT_UNKNOWN:
+			break;
+		default:
+			return -EINVAL;
+	}
+	if (ser->irq < 0 || ser->irq >= NR_IRQS)
+		return -EINVAL;
+	if (ser->baud_base < 9600)
+		return -EINVAL;
+	return 0;
+}
+
+static struct uart_ops serial98_ops = {
+	.tx_empty	= serial98_tx_empty,
+	.set_mctrl	= serial98_set_mctrl,
+	.get_mctrl	= serial98_get_mctrl,
+	.stop_tx	= serial98_stop_tx,
+	.start_tx	= serial98_start_tx,
+	.stop_rx	= serial98_stop_rx,
+	.enable_ms	= serial98_enable_ms,
+	.break_ctl	= serial98_break_ctl,
+	.startup	= serial98_startup,
+	.shutdown	= serial98_shutdown,
+	.set_termios	= serial98_set_termios,
+	.type		= serial98_type,
+	.release_port	= serial98_release_port,
+	.request_port	= serial98_request_port,
+	.config_port	= serial98_config_port,
+	.verify_port	= serial98_verify_port,
+};
+
+static struct serial98_port serial98_ports[SERIAL98_NR] = {
+	{
+		.port =	{
+				.iobase		= 0x30,
+				.iotype		= SERIAL_IO_PORT,
+				.irq		= 4,
+				.fifosize	= 1,
+				.ops		= &serial98_ops,
+				.flags		= ASYNC_BOOT_AUTOCONF,
+				.line		= 0,
+			},
+		.rxchk = STAT_8251_RXRDY,
+		.txemp = STAT_8251_TXEMP,
+		.txrdy = STAT_8251_TXRDY,
+		.rxrdy = STAT_8251_RXRDY,
+		.brk = STAT_8251_BRK,
+		.fe = STAT_8251_FER,
+		.oe = STAT_8251_OER,
+		.pe = STAT_8251_PER,
+		.dr = STAT_8251_DSR,
+	},
+};
+
+#ifdef CONFIG_SERIAL98_CONSOLE
+
+#define BOTH_EMPTY (PORT98->txemp | PORT98->txrdy)
+
+/*
+ *	Wait for transmitter & holding register to empty
+ */
+static inline void wait_for_xmitr(struct uart_port *port)
+{
+	unsigned int status, tmout = 10000;
+
+	/* Wait up to 10ms for the character(s) to be sent. */
+	do {
+		status = inb(PORT.iobase + 2);
+
+		if (status & PORT98->brk)
+			PORT98->lsr_break_flag = PORT98->brk;
+
+		if (--tmout == 0)
+			break;
+		udelay(1);
+	} while ((status & BOTH_EMPTY) != BOTH_EMPTY);
+
+	/* Wait up to 1s for flow control if necessary */
+	if (PORT.flags & UPF_CONS_FLOW) {
+		tmout = 1000000;
+		while (--tmout &&
+		       ((serial98_msr_in(port) & UART_MSR_CTS) == 0))
+			udelay(1);
+	}
+}
+
+/*
+ *	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
+serial98_console_write(struct console *co, const char *s, unsigned int count)
+{
+	struct uart_port *port = (struct uart_port *)&serial98_ports[co->index];
+	unsigned int ier1, ier2;
+	int i;
+
+	/*
+	 *	First save the UER then disable the interrupts
+	 */
+	ier1 = inb(IER1_8251F);
+	ier2 = inb(IER2_8251F);
+	/* disnable all modem status interrupt */
+	outb(0x80, IER2_8251F);
+
+	/* disnable TX/RX interrupt */
+	outb(0x00, IER2_8251F);
+	outb(DIS_RXR_INT, IER1_CTL);
+	outb(DIS_TXE_INT, IER1_CTL);
+	outb(DIS_TXR_INT, IER1_CTL);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++, s++) {
+		wait_for_xmitr(port);
+
+		/*
+		 *	Send the character out.
+		 *	If a LF, also do CR...
+		 */
+		outb(*s, PORT.iobase);
+		if (*s == 10) {
+			wait_for_xmitr(port);
+			outb(13, PORT.iobase);
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the IER
+	 */
+	wait_for_xmitr(port);
+
+	/* restore TX/RX interrupt */
+	outb(0x00, IER2_8251F);
+	if (ier1 & 0x01)
+		outb(ENA_RXR_INT, IER1_CTL);
+	if (ier1 & 0x02)
+		outb(ENA_TXE_INT, IER1_CTL);
+	if (ier1 & 0x04)
+		outb(ENA_TXR_INT, IER1_CTL);
+
+	/* restore modem status interrupt */
+	outb(ier2, IER2_8251F);
+}
+
+static kdev_t serial98_console_device(struct console *co)
+{
+	return mk_kdev(TTY_MAJOR, 64 + co->index);
+}
+
+static int __init serial98_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index >= SERIAL98_NR)
+		co->index = 0;
+	port = &serial98_ports[co->index].port;
+
+	/*
+	 * Temporary fix.
+	 */
+	spin_lock_init(&port->lock);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+void __init serial98_console_init(void)
+{
+	register_console(&serial98_console);
+}
+
+#endif /* CONFIG_SERIAL98_CONSOLE */
+
+
+static int __init serial98_init(void)
+{
+	int ret;
+	unsigned char iir1, iir2;
+
+	if (PC9800_8MHz_P()) {
+		serial98_clk = 8;
+		serial98_ports[0].port.uartclk = 374400 * 16;
+	} else {
+		serial98_clk = 5;
+		serial98_ports[0].port.uartclk = 460800 * 16;
+	}
+
+	printk(KERN_INFO "serial98: PC-9801 standard serial port driver Version 0.1alpha\n");
+	serial98_ports[0].type = PORT_8251_PC98;
+	/* Check FIFO exist */
+	iir1 = inb(IIR_8251F);
+	iir2 = inb(IIR_8251F);
+	if ((iir1 & 0x40) != (iir2 & 0x40) && (iir1 & 0x20) == (iir2 & 0x20)) {
+		serial98_ports[0].port.iobase = 0x130;
+		serial98_ports[0].port.fifosize = 16;
+		serial98_ports[0].rxchk = STAT_8251F_DSR;
+		serial98_ports[0].txemp = STAT_8251F_TXEMP;
+		serial98_ports[0].txrdy = STAT_8251F_TXRDY;
+		serial98_ports[0].rxrdy = STAT_8251F_RXRDY;
+		serial98_ports[0].brk = STAT_8251F_BRK;
+		serial98_ports[0].fe = STAT_8251F_FER;
+		serial98_ports[0].oe = STAT_8251F_OER;
+		serial98_ports[0].pe = STAT_8251F_PER;
+		serial98_ports[0].dr = STAT_8251F_DSR;
+
+		if (*(unsigned char*)__va(PC9821SCA_RSFLAGS) & 0x10)
+			serial98_ports[0].type = PORT_VFAST_PC98;
+		else {
+			outb(serial98_ports[0].ext | 0x40, SERIAL98_EXT);
+			serial98_ports[0].port.uartclk *= 4;
+			serial98_ports[0].type = PORT_FIFO_PC98;
+		}
+	} else if ((serial98_ports[0].ext = inb(SERIAL98_EXT)) != 0xff) {
+		outb(serial98_ports[0].ext | 0x40, SERIAL98_EXT);
+		if (inb(SERIAL98_EXT) == (serial98_ports[0].ext | 0x40)) {
+			serial98_ports[0].port.uartclk *= 4;
+			serial98_ports[0].type = PORT_19K_PC98;
+		} else {
+			serial98_ops.enable_ms = NULL;
+			outb(serial98_ports[0].ext, SERIAL98_EXT);
+		}
+	}
+
+	if (serial98_request_region(serial98_ports[0].type))
+		return -EBUSY;
+
+	ret = uart_register_driver(&serial98_reg);
+	if (ret == 0) {
+		int i;
+
+		for (i = 0; i < SERIAL98_NR; i++) {
+			uart_add_one_port(&serial98_reg,
+					(struct uart_port *)&serial98_ports[i]);
+		}
+	}
+
+	return ret;
+}
+
+static void __exit serial98_exit(void)
+{
+	int i;
+
+	if (serial98_ports[0].type == PORT_19K_PC98
+			|| serial98_ports[0].type == PORT_FIFO_PC98)
+		outb(serial98_ports[0].ext, SERIAL98_EXT);
+
+	for (i = 0; i < SERIAL98_NR; i++) {
+		uart_remove_one_port(&serial98_reg,
+					(struct uart_port *)&serial98_ports[i]);
+	}
+
+	uart_unregister_driver(&serial98_reg);
+}
+
+module_init(serial98_init);
+module_exit(serial98_exit);
+
+MODULE_AUTHOR("Osamu Tomita <tomita@cinet.co.jp>");
+MODULE_DESCRIPTION("PC-9801 standard serial port driver Version 0.1alpha");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/serial/uart00.c b/drivers/serial/uart00.c
--- a/drivers/serial/uart00.c	Thu Mar  6 09:30:07 2003
+++ b/drivers/serial/uart00.c	Sun Mar  2 03:03:34 2003
@@ -235,8 +235,8 @@
 
 	status = UART_GET_MSR(port);
 
-	if (!status & (UART_MSR_DCTS_MSK | UART_MSR_DDSR_MSK | 
-		       UART_MSR_TERI_MSK | UART_MSR_DDCD_MSK))
+	if (!(status & (UART_MSR_DCTS_MSK | UART_MSR_DDSR_MSK | 
+			UART_MSR_TERI_MSK | UART_MSR_DDCD_MSK)))
 		return;
 
 	if (status & UART_MSR_DDCD_MSK)
diff -Nru a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
--- a/drivers/telephony/ixj.c	Tue Feb 25 11:50:51 2003
+++ b/drivers/telephony/ixj.c	Thu Mar 13 16:42:07 2003
@@ -5999,12 +5999,14 @@
 		if(ixjdebug & 0x0001) {
 			printk(KERN_INFO "Could not copy cadence to kernel\n");
 		}
+		kfree(lcp);
 		return -EFAULT;
 	}
 	if (lcp->filter > 5) {
 		if(ixjdebug & 0x0001) {
 			printk(KERN_INFO "Cadence out of range\n");
 		}
+		kfree(lcp);
 		return -1;
 	}
 	j->cadence_f[lcp->filter].state = 0;
diff -Nru a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
--- a/drivers/telephony/ixj_pcmcia.c	Sun Feb  2 13:40:35 2003
+++ b/drivers/telephony/ixj_pcmcia.c	Sun Mar 23 03:34:31 2003
@@ -310,29 +310,30 @@
 	return 0;
 }
 
-int __init ixj_register_pcmcia(void)
+static struct pcmcia_driver ixj_driver = {
+	.owner		= THIS_MODULE,
+	.drv		= {
+		.name	= "ixj_cs",
+	},
+	.attach		= ixj_attach,
+	.detach		= ixj_detach,
+};
+
+static int __init ixj_pcmcia_init(void)
 {
-	servinfo_t serv;
-	DEBUG(0, "%s\n", version);
-	CardServices(GetCardServicesInfo, &serv);
-	if (serv.Revision != CS_RELEASE_CODE) {
-		printk(KERN_NOTICE "ixj_cs: Card Services release does not match!\n");
-		return -EINVAL;
-	}
-	register_pcmcia_driver(&dev_info, &ixj_attach, &ixj_detach);
-	return 0;
+	return pcmcia_register_driver(&ixj_driver);
 }
 
-static void ixj_pcmcia_unload(void)
+static void ixj_pcmcia_exit(void)
 {
-	DEBUG(0, "ixj_cs: unloading\n");
-	unregister_pcmcia_driver(&dev_info);
+	pcmcia_unregister_driver(&ixj_driver);
+
+	/* XXX: this really needs to move into generic code.. */
 	while (dev_list != NULL)
 		ixj_detach(dev_list);
 }
 
-module_init(ixj_register_pcmcia);
-module_exit(ixj_pcmcia_unload);
+module_init(ixj_pcmcia_init);
+module_exit(ixj_pcmcia_exit);
 
 MODULE_LICENSE("GPL");
-
diff -Nru a/drivers/usb/core/file.c b/drivers/usb/core/file.c
--- a/drivers/usb/core/file.c	Tue Jul 30 14:35:47 2002
+++ b/drivers/usb/core/file.c	Sat Mar 22 07:38:05 2003
@@ -76,7 +76,7 @@
 		return -EBUSY;
 	}
 
-	usb_devfs_handle = devfs_mk_dir(NULL, "usb", NULL);
+	usb_devfs_handle = devfs_mk_dir("usb");
 
 	return 0;
 }
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c	Thu Mar 13 10:36:02 2003
+++ b/drivers/usb/core/hub.c	Fri Mar 14 14:59:45 2003
@@ -1175,7 +1175,7 @@
 int usb_reset_device(struct usb_device *dev)
 {
 	struct usb_device *parent = dev->parent;
-	struct usb_device_descriptor descriptor;
+	struct usb_device_descriptor *descriptor;
 	int i, ret, port = -1;
 
 	if (!parent) {
@@ -1224,17 +1224,24 @@
 	 * If nothing changed, we reprogram the configuration and then
 	 * the alternate settings.
 	 */
-	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &descriptor,
-			sizeof(descriptor));
-	if (ret < 0)
+	descriptor = kmalloc(sizeof *descriptor, GFP_NOIO);
+	if (!descriptor) {
+		return -ENOMEM;
+	}
+	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, descriptor,
+			sizeof(*descriptor));
+	if (ret < 0) {
+		kfree(descriptor);
 		return ret;
+	}
 
-	le16_to_cpus(&descriptor.bcdUSB);
-	le16_to_cpus(&descriptor.idVendor);
-	le16_to_cpus(&descriptor.idProduct);
-	le16_to_cpus(&descriptor.bcdDevice);
+	le16_to_cpus(&descriptor->bcdUSB);
+	le16_to_cpus(&descriptor->idVendor);
+	le16_to_cpus(&descriptor->idProduct);
+	le16_to_cpus(&descriptor->bcdDevice);
 
-	if (memcmp(&dev->descriptor, &descriptor, sizeof(descriptor))) {
+	if (memcmp(&dev->descriptor, descriptor, sizeof(*descriptor))) {
+		kfree(descriptor);
 		usb_destroy_configuration(dev);
 
 		ret = usb_get_device_descriptor(dev);
@@ -1267,6 +1274,8 @@
 
 		return 1;
 	}
+
+	kfree(descriptor);
 
 	ret = usb_set_configuration(dev, dev->actconfig->desc.bConfigurationValue);
 	if (ret < 0) {
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c	Wed Mar  5 07:24:34 2003
+++ b/drivers/usb/core/message.c	Tue Mar 18 02:21:55 2003
@@ -88,7 +88,7 @@
 	int retv;
 	int length;
 
-	urb = usb_alloc_urb(0, GFP_KERNEL);
+	urb = usb_alloc_urb(0, GFP_NOIO);
 	if (!urb)
 		return -ENOMEM;
   
@@ -131,7 +131,7 @@
 int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype,
 			 __u16 value, __u16 index, void *data, __u16 size, int timeout)
 {
-	struct usb_ctrlrequest *dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
+	struct usb_ctrlrequest *dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
 	int ret;
 	
 	if (!dr)
diff -Nru a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
--- a/drivers/usb/host/ehci-dbg.c	Mon Feb 24 03:30:38 2003
+++ b/drivers/usb/host/ehci-dbg.c	Wed Mar 19 02:25:01 2003
@@ -117,10 +117,10 @@
 static void __attribute__((__unused__))
 dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
-	dbg ("%s %p info1 %x info2 %x hw_curr %x qtd_next %x", label,
-		qh, qh->hw_info1, qh->hw_info2,
+	dbg ("%s %p n%08x info1 %x info2 %x hw_curr %x qtd_next %x", label,
+		qh, qh->hw_next, qh->hw_info1, qh->hw_info2,
 		qh->hw_current, qh->hw_qtd_next);
-	dbg ("  alt+errs= %x, token= %x, page0= %x, page1= %x",
+	dbg ("  alt+nak+t= %x, token= %x, page0= %x, page1= %x",
 		qh->hw_alt_next, qh->hw_token,
 		qh->hw_buf [0], qh->hw_buf [1]);
 	if (qh->hw_buf [2]) {
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c	Mon Feb 24 03:30:38 2003
+++ b/drivers/usb/host/ehci-hcd.c	Wed Mar 19 02:25:01 2003
@@ -576,7 +576,7 @@
 	int			ports;
 	int			i;
 
-	dbg ("%s: suspend to %d", hcd_to_bus (hcd)->bus_name, state);
+	ehci_dbg (ehci, "suspend to %d\n", state);
 
 	ports = HCS_N_PORTS (ehci->hcs_params);
 
@@ -593,7 +593,7 @@
 		if ((temp & PORT_PE) == 0
 				|| (temp & PORT_OWNER) != 0)
 			continue;
-dbg ("%s: suspend port %d", hcd_to_bus (hcd)->bus_name, i);
+		ehci_dbg (ehci, "suspend port %d", i);
 		temp |= PORT_SUSPEND;
 		writel (temp, &ehci->regs->port_status [i]);
 	}
@@ -615,7 +615,7 @@
 	int			ports;
 	int			i;
 
-	dbg ("%s: resume", hcd_to_bus (hcd)->bus_name);
+	ehci_dbg (ehci, "resume\n");
 
 	ports = HCS_N_PORTS (ehci->hcs_params);
 
@@ -635,7 +635,7 @@
 		if ((temp & PORT_PE) == 0
 				|| (temp & PORT_SUSPEND) != 0)
 			continue;
-dbg ("%s: resume port %d", hcd_to_bus (hcd)->bus_name, i);
+		ehci_dbg (ehci, "resume port %d", i);
 		temp |= PORT_RESUME;
 		writel (temp, &ehci->regs->port_status [i]);
 		readl (&ehci->regs->command);	/* unblock posted writes */
@@ -880,8 +880,8 @@
 	/* ASSERT:  no requests/urbs are still linked (so no TDs) */
 	/* ASSERT:  nobody can be submitting urbs for this any more */
 
-	dbg ("%s: free_config devnum %d",
-		hcd_to_bus (hcd)->bus_name, udev->devnum);
+	ehci_dbg (ehci, "free_config %s devnum %d\n",
+			udev->devpath, udev->devnum);
 
 	spin_lock_irqsave (&ehci->lock, flags);
 	for (i = 0; i < 32; i++) {
@@ -912,7 +912,8 @@
 			dev->ep [i] = 0;
 			if (qh->qh_state == QH_STATE_IDLE)
 				goto idle;
-			dbg ("free_config, async ep 0x%02x qh %p", i, qh);
+			ehci_dbg (ehci, "free_config, async ep 0x%02x qh %p",
+					i, qh);
 
 			/* scan_async() empties the ring as it does its work,
 			 * using IAA, but doesn't (yet?) turn it off.  if it
diff -Nru a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c
--- a/drivers/usb/image/scanner.c	Thu Mar 13 10:37:44 2003
+++ b/drivers/usb/image/scanner.c	Thu Mar 20 08:31:08 2003
@@ -347,8 +347,9 @@
  *    - Don't print errors when the device is busy.
  *      
  * 0.4.11  2003-02-25
- *    - Added vendor/product ids for Artec, Avision, Brother, Medion, Primax,
- *      Prolink, Fujitsu, Plustek, and SYSCAN scanners.
+ *    - Added vendor/product ids for Artec, Avision, Brother, Canon, Compaq,
+ *      Fujitsu, Hewlett-Packard, Lexmark, LG Electronics, Medion, Microtek,
+ *      Primax, Prolink,  Plustek, SYSCAN, Trust and UMAX scanners.
  *    - Fixed generation of devfs names if dynamic minors are disabled.
  *    - Used kobject reference counting to free the scn struct when the device
  *      is closed and disconnected. Avoids crashes when writing to a 
diff -Nru a/drivers/usb/image/scanner.h b/drivers/usb/image/scanner.h
--- a/drivers/usb/image/scanner.h	Tue Mar 11 04:33:00 2003
+++ b/drivers/usb/image/scanner.h	Thu Mar 20 08:22:21 2003
@@ -105,6 +105,7 @@
 	{ USB_DEVICE(0x0638, 0x0a10) },	/* iVina FB1600 (=Umax Astra 4500) */
 	/* Benq: see Acer */
 	/* Brother */
+	{ USB_DEVICE(0x04f9, 0x010f) },	/* MFC 5100C */
 	{ USB_DEVICE(0x04f9, 0x0111) },	/* MFC 6800 */
 	/* Canon */
 	{ USB_DEVICE(0x04a9, 0x2201) }, /* CanoScan FB320U */
@@ -118,9 +119,11 @@
 	{ USB_DEVICE(0x04a9, 0x220c) },	/* CanoScan D1250U2 */
 	{ USB_DEVICE(0x04a9, 0x220d) }, /* CanoScan N670U/N676U/LIDE 20 */
 	{ USB_DEVICE(0x04a9, 0x220e) }, /* CanoScan N1240U/LIDE 30 */
+	{ USB_DEVICE(0x04a9, 0x2213) },	/* LIDE 50 */
 	{ USB_DEVICE(0x04a9, 0x3042) }, /* FS4000US */
 	/* Colorado -- See Primax/Colorado below */
 	/* Compaq */
+	{ USB_DEVICE(0x049f, 0x001a) },	/* S4 100 */
 	{ USB_DEVICE(0x049f, 0x0021) },	/* S200 */
 	/* Epson -- See Seiko/Epson below */
 	/* Fujitsu */
@@ -152,6 +155,8 @@
 	{ USB_DEVICE(0x03f0, 0x0705) }, /* ScanJet 4400C */
 	//	{ USB_DEVICE(0x03f0, 0x0801) },	/* ScanJet 7400C - NOT SUPPORTED - use hpusbscsi driver */
 	{ USB_DEVICE(0x03f0, 0x0901) }, /* ScanJet 2300C */
+	{ USB_DEVICE(0x03F0, 0x1005) },	/* ScanJet 5400C */
+	{ USB_DEVICE(0x03F0, 0x1105) },	/* ScanJet 5470C */
 	{ USB_DEVICE(0x03f0, 0x1305) },	/* Scanjet 4570c */
 	{ USB_DEVICE(0x03f0, 0x2005) },	/* ScanJet 3570c */
 	{ USB_DEVICE(0x03f0, 0x2205) },	/* ScanJet 3500c */
@@ -159,12 +164,16 @@
 	{ USB_DEVICE(0x0638, 0x0268) }, /* 1200U */
 	/* Lexmark */
 	{ USB_DEVICE(0x043d, 0x002d) }, /* X70/X73 */
+	{ USB_DEVICE(0x043d, 0x003d) }, /* X83 */
+	/* LG Electronics */
+	{ USB_DEVICE(0x0461, 0x0364) },	/* Scanworks 600U (repackaged Primax?) */
 	/* Medion */
 	{ USB_DEVICE(0x0461, 0x0377) },	/* MD 5345 - repackaged Primax? */
 	/* Memorex */
 	{ USB_DEVICE(0x0461, 0x0346) }, /* 6136u - repackaged Primax ? */
 	/* Microtek */
 	{ USB_DEVICE(0x05da, 0x30ce) },	/* ScanMaker 3800 */
+	{ USB_DEVICE(0x05da, 0x30cf) },	/* ScanMaker 4800 */
 	/* The following SCSI-over-USB Microtek devices are supported by the
 	   microtek driver: Enable SCSI and USB Microtek in kernel config */
 	//	{ USB_DEVICE(0x05da, 0x0099) },	/* ScanMaker X6 - X6U */
@@ -259,7 +268,11 @@
 	{ USB_DEVICE(0x04b8, 0x0802) }, /* Stylus CX3200 */
 	/* SYSCAN */
 	{ USB_DEVICE(0x0a82, 0x4600) }, /* TravelScan 460/464 */
+	/* Trust */
+	{ USB_DEVICE(0x05cb, 0x1483) }, /* CombiScan 19200 */
+	{ USB_DEVICE(0x05d8, 0x4006) }, /* Easy Webscan 19200 (repackaged Artec?) */
 	/* Umax */
+	{ USB_DEVICE(0x05d8, 0x4009) },	/* Astraslim (actually Artec?) */
 	{ USB_DEVICE(0x1606, 0x0010) },	/* Astra 1220U */
 	{ USB_DEVICE(0x1606, 0x0030) },	/* Astra 2000U */
 	{ USB_DEVICE(0x1606, 0x0060) }, /* Astra 3400U/3450U */
diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c	Thu Mar 13 10:45:41 2003
+++ b/drivers/usb/input/hid-core.c	Thu Mar 20 11:48:42 2003
@@ -1334,6 +1334,9 @@
 #define USB_VENDOR_ID_TANGTOP          0x0d3d
 #define USB_DEVICE_ID_TANGTOP_USBPS2   0x0001
 
+#define USB_VENDOR_ID_ESSENTIAL_REALITY	0x0d7f
+#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5	0x0100
+
 struct hid_blacklist {
 	__u16 idVendor;
 	__u16 idProduct;
@@ -1377,6 +1380,7 @@
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE },
 	{ 0, 0 }
 };
 
diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c	Wed Feb 12 01:41:01 2003
+++ b/drivers/usb/input/hiddev.c	Sat Mar 22 09:04:18 2003
@@ -684,7 +684,7 @@
 	struct hiddev *hiddev;
 	int minor, i;
 	int retval;
-	char devfs_name[16];
+	char devfs_name[24];
 
 	for (i = 0; i < hid->maxcollection; i++)
 		if (hid->collection[i].type == 
@@ -715,8 +715,8 @@
 	hiddev->hid = hid;
 	hiddev->exist = 1;
 
-	sprintf(devfs_name, "hiddev%d", minor);
-	hiddev->devfs = devfs_register(hiddev_devfs_handle, devfs_name,
+	sprintf(devfs_name, "usb/hid/hiddev%d", minor);
+	hiddev->devfs = devfs_register(NULL, devfs_name,
 		DEVFS_FL_DEFAULT, USB_MAJOR, minor + HIDDEV_MINOR_BASE,
 		S_IFCHR | S_IRUGO | S_IWUSR, &hiddev_fops, NULL);
 	hid->minor = minor;
@@ -774,7 +774,7 @@
 
 int __init hiddev_init(void)
 {
-	hiddev_devfs_handle = devfs_mk_dir(NULL, "usb/hid", NULL);
+	hiddev_devfs_handle = devfs_mk_dir("usb/hid");
 	usb_register(&hiddev_driver);
 	return 0;
 }
diff -Nru a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
--- a/drivers/usb/misc/Makefile	Wed Jan  8 03:12:56 2003
+++ b/drivers/usb/misc/Makefile	Tue Mar 18 04:15:55 2003
@@ -12,5 +12,3 @@
 obj-$(CONFIG_USB_TEST)		+= usbtest.o
 obj-$(CONFIG_USB_TIGL)		+= tiglusb.o
 obj-$(CONFIG_USB_USS720)	+= uss720.o
-
-speedtch-objs := speedtouch.o atmsar.o
diff -Nru a/drivers/usb/misc/atmsar.c b/drivers/usb/misc/atmsar.c
--- a/drivers/usb/misc/atmsar.c	Tue Feb 18 03:01:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,380 +0,0 @@
-/******************************************************************************
- *  atmsar.c  --  General SAR library for ATM devices.
- *
- *  Copyright (C) 2000, Johan Verrept
- *
- *  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.
- *
- ******************************************************************************/
-
-/*
- *  Written by Johan Verrept (Johan.Verrept@advalvas.be)
- *
- *  0.2.4A:	- Version for inclusion in 2.5 series kernel
- *		- Modifications by Richard Purdie (rpurdie@rpsys.net)
- *		- replaced "sarlib" with "atmsar"
- *		- adaptations for inclusion in kernel tree
- *
- *  0.2.4:	- Fixed wrong buffer overrun check in atmsar_decode_rawcell()
- *		reported by Stephen Robinson <stephen.robinson@zen.co.uk>
- *		- Fixed bug when input skb did not contain a multple of 52/53
- *		bytes (would happen when the speedtouch device resynced)
- *		also reported by Stephen Robinson <stephen.robinson@zen.co.uk>
- *
- *  0.2.3:	- Fixed wrong allocation size. caused memory corruption in some
- *		cases. Reported by Vladimir Dergachev <volodya@mindspring.com>
- *		- Added some comments
- *
- *  0.2.2:	- Fixed CRCASM
- *		patch from Linus Flannagan <linusf@netservices.eng.net>
- *		- Fixed problem when user did NOT use the
- *		ATMSAR_USE_53BYTE_CELL flag.
- *		reported by  Piers Scannell <email@lot105.com>
- *		- No more in-buffer rewriting for cloned buffers.
- *		- Removed the PII specific CFLAGS in the Makefile.
- *
- *  0.2.1:	- removed dependency on alloc_tx. tis presented problems when
- *		using this with the br2684 code.
- *
- *  0.2:	- added AAL0 reassembly
- *		- added alloc_tx support
- *		- replaced alloc_skb in decode functions to dev_alloc_skb to
- *		allow calling from interrupt
- *		- fixed embarassing AAL5 bug. I was setting the pti bit in the
- *		wrong byte...
- *		- fixed another emabrassing bug.. picked up the wrong crc type
- *		and forgot to invert the crc result...
- *		- fixed AAL5 length calculations.
- *		- removed automatic skb freeing from encode functions.
- *		This caused problems because i did kfree_skb it, while it
- *		needed to be popped. I cannot determine though whether it
- *		needs to be popped or not. Figu'e it out ye'self ;-)
- *		- added mru field. This is the buffersize. atmsar_decode_aal0
- *		will use when it allocates a receive buffer. A stop gap for
- *		real buffer management.
- *
- *  0.1:	- library created.
- *		- only contains AAL5, AAL0 can be easily added. (actually, only
- *		AAL0 reassembly is missing)
- *
- */
-
-#include <linux/crc32.h>
-#include "atmsar.h"
-
-/***********************
- **
- **  things to remember
- **
- ***********************/
-
-/*
-  1. the atmsar_vcc_data list pointer MUST be initialized to NULL
-  2. atmsar_encode_rawcell will drop incomplete cells.
-  3. ownership of the skb goes to the library !
-*/
-
-#define ATM_HDR_VPVC_MASK  (ATM_HDR_VPI_MASK | ATM_HDR_VCI_MASK)
-
-/***********************
- **
- **  LOCAL STRUCTURES
- **
- ***********************/
-
-/***********************
- **
- **  LOCAL MACROS
- **
- ***********************/
-/*
-#define DEBUG 1
-*/
-#ifdef DEBUG
-#define PDEBUG(arg...)  printk(KERN_DEBUG "atmsar: " arg)
-#else
-#define PDEBUG(arg...)
-#endif
-
-#define ADD_HEADER(dest, header) \
-  *dest++ = (unsigned char) (header >> 24); \
-  *dest++ = (unsigned char) (header >> 16); \
-  *dest++ = (unsigned char) (header >> 8); \
-  *dest++ = (unsigned char) (header & 0xff);
-
-
-struct atmsar_vcc_data *atmsar_open (struct atmsar_vcc_data **list, struct atm_vcc *vcc, uint type,
-				     ushort vpi, ushort vci, unchar pti, unchar gfc, uint flags)
-{
-	struct atmsar_vcc_data *new;
-
-	if (!vcc)
-		return NULL;
-
-	new = kmalloc (sizeof (struct atmsar_vcc_data), GFP_KERNEL);
-
-	if (!new)
-		return NULL;
-
-	memset (new, 0, sizeof (struct atmsar_vcc_data));
-	new->vcc = vcc;
-	new->stats = vcc->stats;
-	new->type = type;
-	new->next = NULL;
-	new->gfc = gfc;
-	new->vp = vpi;
-	new->vc = vci;
-	new->pti = pti;
-
-	switch (type) {
-	case ATMSAR_TYPE_AAL0:
-		new->mtu = ATMSAR_DEF_MTU_AAL0;
-		break;
-	case ATMSAR_TYPE_AAL1:
-		new->mtu = ATMSAR_DEF_MTU_AAL1;
-		break;
-	case ATMSAR_TYPE_AAL2:
-		new->mtu = ATMSAR_DEF_MTU_AAL2;
-		break;
-	case ATMSAR_TYPE_AAL34:
-		/* not supported */
-		new->mtu = ATMSAR_DEF_MTU_AAL34;
-		break;
-	case ATMSAR_TYPE_AAL5:
-		new->mtu = ATMSAR_DEF_MTU_AAL5;
-		break;
-	}
-
-	new->atmHeader = ((unsigned long) gfc << ATM_HDR_GFC_SHIFT)
-	    | ((unsigned long) vpi << ATM_HDR_VPI_SHIFT)
-	    | ((unsigned long) vci << ATM_HDR_VCI_SHIFT)
-	    | ((unsigned long) pti << ATM_HDR_PTI_SHIFT);
-	new->flags = flags;
-	new->next = NULL;
-	new->reasBuffer = NULL;
-
-	new->next = *list;
-	*list = new;
-
-	PDEBUG ("Allocated new SARLib vcc 0x%p with vp %d vc %d\n", new, vpi, vci);
-
-	return new;
-}
-
-void atmsar_close (struct atmsar_vcc_data **list, struct atmsar_vcc_data *vcc)
-{
-	struct atmsar_vcc_data *work;
-
-	if (*list == vcc) {
-		*list = (*list)->next;
-	} else {
-		for (work = *list; work && work->next && (work->next != vcc); work = work->next);
-
-		/* return if not found */
-		if (work->next != vcc)
-			return;
-
-		work->next = work->next->next;
-	}
-
-	if (vcc->reasBuffer) {
-		dev_kfree_skb (vcc->reasBuffer);
-	}
-
-	PDEBUG ("Allocated SARLib vcc 0x%p with vp %d vc %d\n", vcc, vcc->vp, vcc->vc);
-
-	kfree (vcc);
-}
-
-
-/***********************
- **
- **  DECODE FUNCTIONS
- **
- ***********************/
-
-struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_buff *skb,
-				       struct atmsar_vcc_data **ctx)
-{
-	while (skb->len) {
-		unsigned char *cell = skb->data;
-		unsigned char *cell_payload;
-		struct atmsar_vcc_data *vcc = list;
-		unsigned long atmHeader =
-		    ((unsigned long) (cell[0]) << 24) | ((unsigned long) (cell[1]) << 16) |
-		    ((unsigned long) (cell[2]) << 8) | (cell[3] & 0xff);
-
-		PDEBUG ("atmsar_decode_rawcell (0x%p, 0x%p, 0x%p) called\n", list, skb, ctx);
-		PDEBUG ("atmsar_decode_rawcell skb->data %p, skb->tail %p\n", skb->data, skb->tail);
-
-		if (!list || !skb || !ctx)
-			return NULL;
-		if (!skb->data || !skb->tail)
-			return NULL;
-
-		/* here should the header CRC check be... */
-
-		/* look up correct vcc */
-		for (;
-		     vcc
-		     && ((vcc->atmHeader & ATM_HDR_VPVC_MASK) != (atmHeader & ATM_HDR_VPVC_MASK));
-		     vcc = vcc->next);
-
-		PDEBUG ("atmsar_decode_rawcell found vcc %p for packet on vp %d, vc %d\n", vcc,
-			(int) ((atmHeader & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT),
-			(int) ((atmHeader & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT));
-
-		if (vcc && (skb->len >= (vcc->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52))) {
-			cell_payload = cell + (vcc->flags & ATMSAR_USE_53BYTE_CELL ? 5 : 4);
-
-			switch (vcc->type) {
-			case ATMSAR_TYPE_AAL0:
-				/* case ATMSAR_TYPE_AAL1: when we have a decode AAL1 function... */
-				{
-					struct sk_buff *tmp = dev_alloc_skb (vcc->mtu);
-
-					if (tmp) {
-						memcpy (tmp->tail, cell_payload, 48);
-						skb_put (tmp, 48);
-
-						if (vcc->stats)
-							atomic_inc (&vcc->stats->rx);
-
-						skb_pull (skb,
-							  (vcc->
-							   flags & ATMSAR_USE_53BYTE_CELL ? 53 :
-							   52));
-						PDEBUG
-						    ("atmsar_decode_rawcell returns ATMSAR_TYPE_AAL0 pdu 0x%p with length %d\n",
-						     tmp, tmp->len);
-						return tmp;
-					};
-				}
-				break;
-			case ATMSAR_TYPE_AAL1:
-			case ATMSAR_TYPE_AAL2:
-			case ATMSAR_TYPE_AAL34:
-				/* not supported */
-				break;
-			case ATMSAR_TYPE_AAL5:
-				if (!vcc->reasBuffer)
-					vcc->reasBuffer = dev_alloc_skb (vcc->mtu);
-
-				/* if alloc fails, we just drop the cell. it is possible that we can still
-				 * receive cells on other vcc's
-				 */
-				if (vcc->reasBuffer) {
-					/* if (buffer overrun) discard received cells until now */
-					if ((vcc->reasBuffer->len) > (vcc->mtu - 48))
-						skb_trim (vcc->reasBuffer, 0);
-
-					/* copy data */
-					memcpy (vcc->reasBuffer->tail, cell_payload, 48);
-					skb_put (vcc->reasBuffer, 48);
-
-					/* check for end of buffer */
-					if (cell[3] & 0x2) {
-						struct sk_buff *tmp;
-
-						/* the aal5 buffer ends here, cut the buffer. */
-						/* buffer will always have at least one whole cell, so */
-						/* don't need to check return from skb_pull */
-						skb_pull (skb,
-							  (vcc->
-							   flags & ATMSAR_USE_53BYTE_CELL ? 53 :
-							   52));
-						*ctx = vcc;
-						tmp = vcc->reasBuffer;
-						vcc->reasBuffer = NULL;
-
-						PDEBUG
-						    ("atmsar_decode_rawcell returns ATMSAR_TYPE_AAL5 pdu 0x%p with length %d\n",
-						     tmp, tmp->len);
-						return tmp;
-					}
-				}
-				break;
-			};
-			/* flush the cell */
-			/* buffer will always contain at least one whole cell, so don't */
-			/* need to check return value from skb_pull */
-			skb_pull (skb, (vcc->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52));
-		} else {
-			/* If data is corrupt and skb doesn't hold a whole cell, flush the lot */
-			if (skb_pull (skb, (list->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52)) ==
-			    NULL)
-				return NULL;
-		}
-	}
-
-	return NULL;
-};
-
-struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff *skb)
-{
-	uint crc = 0xffffffff;
-	uint length, pdu_crc, pdu_length;
-
-	PDEBUG ("atmsar_decode_aal5 (0x%p, 0x%p) called\n", ctx, skb);
-
-	if (skb->len && (skb->len % 48))
-		return NULL;
-
-	length = (skb->tail[-6] << 8) + skb->tail[-5];
-	pdu_crc =
-	    (skb->tail[-4] << 24) + (skb->tail[-3] << 16) + (skb->tail[-2] << 8) + skb->tail[-1];
-	pdu_length = ((length + 47 + 8) / 48) * 48;
-
-	PDEBUG ("atmsar_decode_aal5: skb->len = %d, length = %d, pdu_crc = 0x%x, pdu_length = %d\n",
-		skb->len, length, pdu_crc, pdu_length);
-
-	/* is skb long enough ? */
-	if (skb->len < pdu_length) {
-		if (ctx->stats)
-			atomic_inc (&ctx->stats->rx_err);
-		return NULL;
-	}
-
-	/* is skb too long ? */
-	if (skb->len > pdu_length) {
-		PDEBUG ("atmsar_decode_aal5: Warning: readjusting illeagl size %d -> %d\n",
-			skb->len, pdu_length);
-		/* buffer is too long. we can try to recover
-		 * if we discard the first part of the skb.
-		 * the crc will decide whether this was ok
-		 */
-		skb_pull (skb, skb->len - pdu_length);
-	}
-
-	crc = ~crc32_be (crc, skb->data, pdu_length - 4);
-
-	/* check crc */
-	if (pdu_crc != crc) {
-		PDEBUG ("atmsar_decode_aal5: crc check failed!\n");
-		if (ctx->stats)
-			atomic_inc (&ctx->stats->rx_err);
-		return NULL;
-	}
-
-	/* pdu is ok */
-	skb_trim (skb, length);
-
-	/* update stats */
-	if (ctx->stats)
-		atomic_inc (&ctx->stats->rx);
-
-	PDEBUG ("atmsar_decode_aal5 returns pdu 0x%p with length %d\n", skb, skb->len);
-	return skb;
-};
diff -Nru a/drivers/usb/misc/atmsar.h b/drivers/usb/misc/atmsar.h
--- a/drivers/usb/misc/atmsar.h	Tue Feb 18 03:01:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,87 +0,0 @@
-#ifndef _ATMSAR_H_
-#define _ATMSAR_H_
-
-/******************************************************************************
- *  atmsar.h  --  General SAR library for ATM devices.
- *
- *  Copyright (C) 2000, Johan Verrept
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the Free
- *  Software Foundation; either version 2 of the License, or (at your option)
- *  any later version.
- *
- *  This program is distributed in the hope that it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- *  more details.
- *
- *  You should have received a copy of the GNU General Public License along with
- *  this program; if not, write to the Free Software Foundation, Inc., 59
- *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- ******************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/atmdev.h>
-#include <linux/skbuff.h>
-#include <linux/types.h>
-#include <linux/atm.h>
-
-#define ATMSAR_USE_53BYTE_CELL  0x1L
-#define ATMSAR_SET_PTI          0x2L
-
-#define ATM_CELL_HEADER		(ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
-
-/* types */
-#define ATMSAR_TYPE_AAL0        ATM_AAL0
-#define ATMSAR_TYPE_AAL1        ATM_AAL1
-#define ATMSAR_TYPE_AAL2        ATM_AAL2
-#define ATMSAR_TYPE_AAL34       ATM_AAL34
-#define ATMSAR_TYPE_AAL5        ATM_AAL5
-
-
-/* default MTU's */
-#define ATMSAR_DEF_MTU_AAL0         48
-#define ATMSAR_DEF_MTU_AAL1         47
-#define ATMSAR_DEF_MTU_AAL2          0	/* not supported */
-#define ATMSAR_DEF_MTU_AAL34         0	/* not supported */
-#define ATMSAR_DEF_MTU_AAL5      65535	/* max mtu ..    */
-
-struct atmsar_vcc_data {
-	struct atmsar_vcc_data *next;
-
-	/* general atmsar flags, per connection */
-	int flags;
-	int type;
-
-	/* connection specific non-atmsar data */
-	struct atm_vcc *vcc;
-	struct k_atm_aal_stats *stats;
-	unsigned short mtu;	/* max is actually  65k for AAL5... */
-
-	/* cell data */
-	unsigned int vp;
-	unsigned int vc;
-	unsigned char gfc;
-	unsigned char pti;
-	unsigned int headerFlags;
-	unsigned long atmHeader;
-
-	/* raw cell reassembly */
-	struct sk_buff *reasBuffer;
-};
-
-
-extern struct atmsar_vcc_data *atmsar_open (struct atmsar_vcc_data **list, struct atm_vcc *vcc,
-					    uint type, ushort vpi, ushort vci, unchar pti,
-					    unchar gfc, uint flags);
-extern void atmsar_close (struct atmsar_vcc_data **list, struct atmsar_vcc_data *vcc);
-
-struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_buff *skb,
-				       struct atmsar_vcc_data **ctx);
-struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff *skb);
-
-#endif				/* _ATMSAR_H_ */
diff -Nru a/drivers/usb/misc/speedtch.c b/drivers/usb/misc/speedtch.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/misc/speedtch.c	Tue Mar 18 04:15:55 2003
@@ -0,0 +1,1514 @@
+/******************************************************************************
+ *  speedtouch.c  --  Alcatel SpeedTouch USB xDSL modem driver.
+ *
+ *  Copyright (C) 2001, Alcatel
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/*
+ *  Written by Johan Verrept (Johan.Verrept@advalvas.be)
+ *
+ *  1.5A:	- Version for inclusion in 2.5 series kernel
+ *		- Modifications by Richard Purdie (rpurdie@rpsys.net)
+ *		- made compatible with kernel 2.5.6 onwards by changing
+ *		udsl_usb_send_data_context->urb to a pointer and adding code
+ *		to alloc and free it
+ *		- remove_wait_queue() added to udsl_atm_processqueue_thread()
+ *
+ *  1.5:	- fixed memory leak when atmsar_decode_aal5 returned NULL.
+ *		(reported by stephen.robinson@zen.co.uk)
+ *
+ *  1.4:	- changed the spin_lock() under interrupt to spin_lock_irqsave()
+ *		- unlink all active send urbs of a vcc that is being closed.
+ *
+ *  1.3.1:	- added the version number
+ *
+ *  1.3:	- Added multiple send urb support
+ *		- fixed memory leak and vcc->tx_inuse starvation bug
+ *		  when not enough memory left in vcc.
+ *
+ *  1.2:	- Fixed race condition in udsl_usb_send_data()
+ *  1.1:	- Turned off packet debugging
+ *
+ */
+
+#include <asm/semaphore.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <asm/uaccess.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/atm.h>
+#include <linux/atmdev.h>
+#include <linux/crc32.h>
+
+/*
+#define DEBUG 1
+#define DEBUG_PACKET 1
+*/
+
+#include <linux/usb.h>
+
+
+#ifdef DEBUG_PACKET
+static int udsl_print_packet (const unsigned char *data, int len);
+#define PACKETDEBUG(arg...) udsl_print_packet (arg)
+#else
+#define PACKETDEBUG(arg...)
+#endif
+
+#define DRIVER_AUTHOR	"Johan Verrept, Johan.Verrept@advalvas.be"
+#define DRIVER_DESC	"Driver for the Alcatel SpeedTouch USB ADSL modem"
+#define DRIVER_VERSION	"1.5A"
+
+#define SPEEDTOUCH_VENDORID		0x06b9
+#define SPEEDTOUCH_PRODUCTID		0x4061
+
+#define UDSL_NUMBER_RCV_URBS		1
+#define UDSL_NUMBER_SND_URBS		1
+#define UDSL_NUMBER_SND_BUFS		(2*UDSL_NUMBER_SND_URBS)
+#define UDSL_RCV_BUFFER_SIZE		(1*64) /* ATM cells */
+#define UDSL_SND_BUFFER_SIZE		(1*64) /* ATM cells */
+/* max should be (1500 IP mtu + 2 ppp bytes + 32 * 5 cellheader overhead) for
+ * PPPoA and (1500 + 14 + 32*5 cellheader overhead) for PPPoE */
+#define UDSL_MAX_AAL5_MRU		2048
+
+#define UDSL_IOCTL_START		1
+#define UDSL_IOCTL_STOP			2
+
+/* endpoint declarations */
+
+#define UDSL_ENDPOINT_DATA_OUT		0x07
+#define UDSL_ENDPOINT_DATA_IN		0x87
+
+#define ATM_CELL_HEADER			(ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
+
+#define hex2int(c) ( (c >= '0')&&(c <= '9') ?  (c - '0') : ((c & 0xf)+9) )
+
+/* usb_device_id struct */
+
+static struct usb_device_id udsl_usb_ids [] = {
+	{ USB_DEVICE (SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID) },
+	{ }			/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, udsl_usb_ids);
+
+/* context declarations */
+
+struct udsl_receiver {
+	struct list_head list;
+	struct sk_buff *skb;
+	struct urb *urb;
+	struct udsl_instance_data *instance;
+};
+
+struct udsl_send_buffer {
+	struct list_head list;
+	unsigned char *base;
+	unsigned char *free_start;
+	unsigned int free_cells;
+};
+
+struct udsl_sender {
+	struct list_head list;
+	struct udsl_send_buffer *buffer;
+	struct urb *urb;
+	struct udsl_instance_data *instance;
+};
+
+struct udsl_control {
+	struct atm_skb_data atm_data;
+	unsigned int num_cells;
+	unsigned int num_entire;
+	unsigned char cell_header [ATM_CELL_HEADER];
+	unsigned int pdu_padding;
+	unsigned char aal5_trailer [ATM_AAL5_TRAILER];
+};
+
+#define UDSL_SKB(x)		((struct udsl_control *)(x)->cb)
+
+struct atmsar_vcc_data {
+	struct atmsar_vcc_data *next;
+
+	/* general atmsar flags, per connection */
+	int flags;
+	int type;
+
+	/* connection specific non-atmsar data */
+	struct atm_vcc *vcc;
+	struct k_atm_aal_stats *stats;
+	unsigned short mtu;	/* max is actually  65k for AAL5... */
+
+	/* cell data */
+	unsigned int vp;
+	unsigned int vc;
+	unsigned char gfc;
+	unsigned char pti;
+	unsigned int headerFlags;
+	unsigned long atmHeader;
+
+	/* raw cell reassembly */
+	struct sk_buff *reasBuffer;
+};
+
+/*
+ * UDSL main driver data
+ */
+
+struct udsl_instance_data {
+	struct semaphore serialize;
+
+	/* usb device part */
+	struct usb_device *usb_dev;
+	char description [64];
+	int firmware_loaded;
+
+	/* atm device part */
+	struct atm_dev *atm_dev;
+	struct atmsar_vcc_data *atmsar_vcc_list;
+
+	/* receiving */
+	struct udsl_receiver all_receivers [UDSL_NUMBER_RCV_URBS];
+
+	spinlock_t spare_receivers_lock;
+	struct list_head spare_receivers;
+
+	spinlock_t completed_receivers_lock;
+	struct list_head completed_receivers;
+
+	struct tasklet_struct receive_tasklet;
+
+	/* sending */
+	struct udsl_sender all_senders [UDSL_NUMBER_SND_URBS];
+	struct udsl_send_buffer all_buffers [UDSL_NUMBER_SND_BUFS];
+
+	struct sk_buff_head sndqueue;
+
+	spinlock_t send_lock;
+	struct list_head spare_senders;
+	struct list_head spare_buffers;
+
+	struct tasklet_struct send_tasklet;
+	struct sk_buff *current_skb;			/* being emptied */
+	struct udsl_send_buffer *current_buffer;	/* being filled */
+	struct list_head filled_buffers;
+};
+
+static const char udsl_driver_name [] = "speedtch";
+
+/*
+ * atm driver prototypes and structures
+ */
+
+static void udsl_atm_dev_close (struct atm_dev *dev);
+static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci);
+static void udsl_atm_close (struct atm_vcc *vcc);
+static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg);
+static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb);
+static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page);
+
+static struct atmdev_ops udsl_atm_devops = {
+	.dev_close =	udsl_atm_dev_close,
+	.open =		udsl_atm_open,
+	.close =	udsl_atm_close,
+	.ioctl =	udsl_atm_ioctl,
+	.send =		udsl_atm_send,
+	.proc_read =	udsl_atm_proc_read,
+};
+
+/*
+ * usb driver prototypes and structures
+ */
+static int udsl_usb_probe (struct usb_interface *intf,
+			   const struct usb_device_id *id);
+static void udsl_usb_disconnect (struct usb_interface *intf);
+static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data);
+
+static struct usb_driver udsl_usb_driver = {
+	.name =		udsl_driver_name,
+	.probe =	udsl_usb_probe,
+	.disconnect =	udsl_usb_disconnect,
+	.ioctl =	udsl_usb_ioctl,
+	.id_table =	udsl_usb_ids,
+};
+
+
+/*************
+**  decode  **
+*************/
+
+#define ATM_HDR_VPVC_MASK		(ATM_HDR_VPI_MASK | ATM_HDR_VCI_MASK)
+#define ATMSAR_USE_53BYTE_CELL		0x1L
+
+struct sk_buff *atmsar_decode_rawcell (struct atmsar_vcc_data *list, struct sk_buff *skb,
+				       struct atmsar_vcc_data **ctx)
+{
+	while (skb->len) {
+		unsigned char *cell = skb->data;
+		unsigned char *cell_payload;
+		struct atmsar_vcc_data *vcc = list;
+		unsigned long atmHeader =
+		    ((unsigned long) (cell[0]) << 24) | ((unsigned long) (cell[1]) << 16) |
+		    ((unsigned long) (cell[2]) << 8) | (cell[3] & 0xff);
+
+		dbg ("atmsar_decode_rawcell (0x%p, 0x%p, 0x%p) called", list, skb, ctx);
+		dbg ("atmsar_decode_rawcell skb->data %p, skb->tail %p", skb->data, skb->tail);
+
+		if (!list || !skb || !ctx)
+			return NULL;
+		if (!skb->data || !skb->tail)
+			return NULL;
+
+		/* here should the header CRC check be... */
+
+		/* look up correct vcc */
+		for (;
+		     vcc
+		     && ((vcc->atmHeader & ATM_HDR_VPVC_MASK) != (atmHeader & ATM_HDR_VPVC_MASK));
+		     vcc = vcc->next);
+
+		dbg ("atmsar_decode_rawcell found vcc %p for packet on vp %d, vc %d", vcc,
+			(int) ((atmHeader & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT),
+			(int) ((atmHeader & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT));
+
+		if (vcc && (skb->len >= (vcc->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52))) {
+			cell_payload = cell + (vcc->flags & ATMSAR_USE_53BYTE_CELL ? 5 : 4);
+
+			switch (vcc->type) {
+			case ATM_AAL0:
+				/* case ATM_AAL1: when we have a decode AAL1 function... */
+				{
+					struct sk_buff *tmp = dev_alloc_skb (vcc->mtu);
+
+					if (tmp) {
+						memcpy (tmp->tail, cell_payload, 48);
+						skb_put (tmp, 48);
+
+						if (vcc->stats)
+							atomic_inc (&vcc->stats->rx);
+
+						skb_pull (skb,
+							  (vcc->
+							   flags & ATMSAR_USE_53BYTE_CELL ? 53 :
+							   52));
+						dbg
+						    ("atmsar_decode_rawcell returns ATM_AAL0 pdu 0x%p with length %d",
+						     tmp, tmp->len);
+						return tmp;
+					};
+				}
+				break;
+			case ATM_AAL1:
+			case ATM_AAL2:
+			case ATM_AAL34:
+				/* not supported */
+				break;
+			case ATM_AAL5:
+				if (!vcc->reasBuffer)
+					vcc->reasBuffer = dev_alloc_skb (vcc->mtu);
+
+				/* if alloc fails, we just drop the cell. it is possible that we can still
+				 * receive cells on other vcc's
+				 */
+				if (vcc->reasBuffer) {
+					/* if (buffer overrun) discard received cells until now */
+					if ((vcc->reasBuffer->len) > (vcc->mtu - 48))
+						skb_trim (vcc->reasBuffer, 0);
+
+					/* copy data */
+					memcpy (vcc->reasBuffer->tail, cell_payload, 48);
+					skb_put (vcc->reasBuffer, 48);
+
+					/* check for end of buffer */
+					if (cell[3] & 0x2) {
+						struct sk_buff *tmp;
+
+						/* the aal5 buffer ends here, cut the buffer. */
+						/* buffer will always have at least one whole cell, so */
+						/* don't need to check return from skb_pull */
+						skb_pull (skb,
+							  (vcc->
+							   flags & ATMSAR_USE_53BYTE_CELL ? 53 :
+							   52));
+						*ctx = vcc;
+						tmp = vcc->reasBuffer;
+						vcc->reasBuffer = NULL;
+
+						dbg
+						    ("atmsar_decode_rawcell returns ATM_AAL5 pdu 0x%p with length %d",
+						     tmp, tmp->len);
+						return tmp;
+					}
+				}
+				break;
+			};
+			/* flush the cell */
+			/* buffer will always contain at least one whole cell, so don't */
+			/* need to check return value from skb_pull */
+			skb_pull (skb, (vcc->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52));
+		} else {
+			/* If data is corrupt and skb doesn't hold a whole cell, flush the lot */
+			if (skb_pull (skb, (list->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52)) ==
+			    NULL)
+				return NULL;
+		}
+	}
+
+	return NULL;
+};
+
+struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff *skb)
+{
+	uint crc = 0xffffffff;
+	uint length, pdu_crc, pdu_length;
+
+	dbg ("atmsar_decode_aal5 (0x%p, 0x%p) called", ctx, skb);
+
+	if (skb->len && (skb->len % 48))
+		return NULL;
+
+	length = (skb->tail[-6] << 8) + skb->tail[-5];
+	pdu_crc =
+	    (skb->tail[-4] << 24) + (skb->tail[-3] << 16) + (skb->tail[-2] << 8) + skb->tail[-1];
+	pdu_length = ((length + 47 + 8) / 48) * 48;
+
+	dbg ("atmsar_decode_aal5: skb->len = %d, length = %d, pdu_crc = 0x%x, pdu_length = %d",
+		skb->len, length, pdu_crc, pdu_length);
+
+	/* is skb long enough ? */
+	if (skb->len < pdu_length) {
+		if (ctx->stats)
+			atomic_inc (&ctx->stats->rx_err);
+		return NULL;
+	}
+
+	/* is skb too long ? */
+	if (skb->len > pdu_length) {
+		dbg ("atmsar_decode_aal5: Warning: readjusting illeagl size %d -> %d",
+			skb->len, pdu_length);
+		/* buffer is too long. we can try to recover
+		 * if we discard the first part of the skb.
+		 * the crc will decide whether this was ok
+		 */
+		skb_pull (skb, skb->len - pdu_length);
+	}
+
+	crc = ~crc32_be (crc, skb->data, pdu_length - 4);
+
+	/* check crc */
+	if (pdu_crc != crc) {
+		dbg ("atmsar_decode_aal5: crc check failed!");
+		if (ctx->stats)
+			atomic_inc (&ctx->stats->rx_err);
+		return NULL;
+	}
+
+	/* pdu is ok */
+	skb_trim (skb, length);
+
+	/* update stats */
+	if (ctx->stats)
+		atomic_inc (&ctx->stats->rx);
+
+	dbg ("atmsar_decode_aal5 returns pdu 0x%p with length %d", skb, skb->len);
+	return skb;
+};
+
+
+/*************
+**  encode  **
+*************/
+
+static void udsl_groom_skb (struct atm_vcc *vcc, struct sk_buff *skb) {
+	struct udsl_control *ctrl = UDSL_SKB (skb);
+	unsigned int i, zero_padding;
+	unsigned char zero = 0;
+	u32 crc;
+
+	ctrl->atm_data.vcc = vcc;
+	ctrl->cell_header [0] = vcc->vpi >> 4;
+	ctrl->cell_header [1] = (vcc->vpi << 4) | (vcc->vci >> 12);
+	ctrl->cell_header [2] = vcc->vci >> 4;
+	ctrl->cell_header [3] = vcc->vci << 4;
+	ctrl->cell_header [4] = 0xec;
+
+	ctrl->num_cells = (skb->len + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD;
+	ctrl->num_entire = skb->len / ATM_CELL_PAYLOAD;
+
+	zero_padding = ctrl->num_cells * ATM_CELL_PAYLOAD - skb->len - ATM_AAL5_TRAILER;
+
+	if (ctrl->num_entire + 1 < ctrl->num_cells)
+		ctrl->pdu_padding = zero_padding - (ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
+	else
+		ctrl->pdu_padding = zero_padding;
+
+	ctrl->aal5_trailer [0] = 0; /* UU = 0 */
+	ctrl->aal5_trailer [1] = 0; /* CPI = 0 */
+	ctrl->aal5_trailer [2] = skb->len >> 8;
+	ctrl->aal5_trailer [3] = skb->len;
+
+	crc = crc32_be (~0, skb->data, skb->len);
+	for (i = 0; i < zero_padding; i++)
+		crc = crc32_be (crc, &zero, 1);
+	crc = crc32_be (crc, ctrl->aal5_trailer, 4);
+	crc = ~crc;
+
+	ctrl->aal5_trailer [4] = crc >> 24;
+	ctrl->aal5_trailer [5] = crc >> 16;
+	ctrl->aal5_trailer [6] = crc >> 8;
+	ctrl->aal5_trailer [7] = crc;
+}
+
+unsigned int udsl_write_cells (unsigned int howmany, struct sk_buff *skb, unsigned char **target_p) {
+	struct udsl_control *ctrl = UDSL_SKB (skb);
+	unsigned char *target = *target_p;
+	unsigned int nc, ne, i;
+
+	dbg ("udsl_write_cells: howmany=%u, skb->len=%d, num_cells=%u, num_entire=%u, pdu_padding=%u", howmany, skb->len, ctrl->num_cells, ctrl->num_entire, ctrl->pdu_padding);
+
+	nc = ctrl->num_cells;
+	ne = min (howmany, ctrl->num_entire);
+
+	for (i = 0; i < ne; i++) {
+		memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
+		target += ATM_CELL_HEADER;
+		memcpy (target, skb->data, ATM_CELL_PAYLOAD);
+		target += ATM_CELL_PAYLOAD;
+		__skb_pull (skb, ATM_CELL_PAYLOAD);
+	}
+
+	ctrl->num_entire -= ne;
+
+	if (!(ctrl->num_cells -= ne) || !(howmany -= ne))
+		goto out;
+
+	memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
+	target += ATM_CELL_HEADER;
+	memcpy (target, skb->data, skb->len);
+	target += skb->len;
+	__skb_pull (skb, skb->len);
+	memset (target, 0, ctrl->pdu_padding);
+	target += ctrl->pdu_padding;
+
+	if (--ctrl->num_cells) {
+		if (!--howmany) {
+			ctrl->pdu_padding = ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
+			goto out;
+		}
+
+		memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
+		target += ATM_CELL_HEADER;
+		memset (target, 0, ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
+		target += ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
+
+		if (--ctrl->num_cells)
+			BUG();
+	}
+
+	memcpy (target, ctrl->aal5_trailer, ATM_AAL5_TRAILER);
+	target += ATM_AAL5_TRAILER;
+	/* set pti bit in last cell */
+	*(target + 3 - ATM_CELL_SIZE) |= 0x2;
+
+out:
+	*target_p = target;
+	return nc - ctrl->num_cells;
+}
+
+
+/**************
+**  receive  **
+**************/
+
+static void udsl_complete_receive (struct urb *urb, struct pt_regs *regs)
+{
+	struct udsl_instance_data *instance;
+	struct udsl_receiver *rcv;
+	unsigned long flags;
+
+	if (!urb || !(rcv = urb->context) || !(instance = rcv->instance)) {
+		dbg ("udsl_complete_receive: bad urb!");
+		return;
+	}
+
+	dbg ("udsl_complete_receive entered (urb 0x%p, status %d)", urb, urb->status);
+
+	/* may not be in_interrupt() */
+	spin_lock_irqsave (&instance->completed_receivers_lock, flags);
+	list_add_tail (&rcv->list, &instance->completed_receivers);
+	tasklet_schedule (&instance->receive_tasklet);
+	spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
+}
+
+static void udsl_process_receive (unsigned long data)
+{
+	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
+	struct udsl_receiver *rcv;
+	unsigned long flags;
+	unsigned char *data_start;
+	struct sk_buff *skb;
+	struct urb *urb;
+	struct atmsar_vcc_data *atmsar_vcc = NULL;
+	struct sk_buff *new = NULL, *tmp = NULL;
+	int err;
+
+	dbg ("udsl_process_receive entered");
+
+	spin_lock_irqsave (&instance->completed_receivers_lock, flags);
+	while (!list_empty (&instance->completed_receivers)) {
+		rcv = list_entry (instance->completed_receivers.next, struct udsl_receiver, list);
+		list_del (&rcv->list);
+		spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
+
+		urb = rcv->urb;
+		dbg ("udsl_process_receive: got packet %p with length %d and status %d", urb, urb->actual_length, urb->status);
+
+		switch (urb->status) {
+		case 0:
+			dbg ("udsl_process_receive: processing urb with rcv %p, urb %p, skb %p", rcv, urb, rcv->skb);
+
+			/* update the skb structure */
+			skb = rcv->skb;
+			skb_trim (skb, 0);
+			skb_put (skb, urb->actual_length);
+			data_start = skb->data;
+
+			dbg ("skb->len = %d", skb->len);
+			PACKETDEBUG (skb->data, skb->len);
+
+			while ((new =
+				atmsar_decode_rawcell (instance->atmsar_vcc_list, skb,
+						       &atmsar_vcc)) != NULL) {
+				dbg ("(after cell processing)skb->len = %d", new->len);
+
+				switch (atmsar_vcc->type) {
+				case ATM_AAL5:
+					tmp = new;
+					new = atmsar_decode_aal5 (atmsar_vcc, new);
+
+					/* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */
+					if (new) {
+						dbg ("(after aal5 decap) skb->len = %d", new->len);
+						if (new->len && atm_charge (atmsar_vcc->vcc, new->truesize)) {
+							PACKETDEBUG (new->data, new->len);
+							atmsar_vcc->vcc->push (atmsar_vcc->vcc, new);
+						} else {
+							dbg
+							    ("dropping incoming packet : rx_inuse = %d, vcc->sk->rcvbuf = %d, skb->true_size = %d",
+							     atomic_read (&atmsar_vcc->vcc->rx_inuse),
+							     atmsar_vcc->vcc->sk->rcvbuf, new->truesize);
+							dev_kfree_skb (new);
+						}
+					} else {
+						dbg ("atmsar_decode_aal5 returned NULL!");
+						dev_kfree_skb (tmp);
+					}
+					break;
+				default:
+					/* not supported. we delete the skb. */
+					printk (KERN_INFO
+						"SpeedTouch USB: illegal vcc type. Dropping packet.\n");
+					dev_kfree_skb (new);
+					break;
+				}
+			}
+
+			/* restore skb */
+			skb_push (skb, skb->data - data_start);
+
+			usb_fill_bulk_urb (urb,
+					   instance->usb_dev,
+					   usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
+					   (unsigned char *) rcv->skb->data,
+					   UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE,
+					   udsl_complete_receive,
+					   rcv);
+			if (!(err = usb_submit_urb (urb, GFP_ATOMIC)))
+				break;
+			dbg ("udsl_process_receive: submission failed (%d)", err);
+			/* fall through */
+		default: /* error or urb unlinked */
+			dbg ("udsl_process_receive: adding to spare_receivers");
+			spin_lock_irqsave (&instance->spare_receivers_lock, flags);
+			list_add (&rcv->list, &instance->spare_receivers);
+			spin_unlock_irqrestore (&instance->spare_receivers_lock, flags);
+			break;
+		} /* switch */
+
+		spin_lock_irqsave (&instance->completed_receivers_lock, flags);
+	} /* while */
+	spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
+	dbg ("udsl_process_receive successful");
+}
+
+static void udsl_fire_receivers (struct udsl_instance_data *instance)
+{
+	struct list_head receivers, *pos, *n;
+	unsigned long flags;
+
+	INIT_LIST_HEAD (&receivers);
+
+	down (&instance->serialize);
+
+	spin_lock_irqsave (&instance->spare_receivers_lock, flags);
+	list_splice_init (&instance->spare_receivers, &receivers);
+	spin_unlock_irqrestore (&instance->spare_receivers_lock, flags);
+
+	list_for_each_safe (pos, n, &receivers) {
+		struct udsl_receiver *rcv = list_entry (pos, struct udsl_receiver, list);
+
+		dbg ("udsl_fire_receivers: firing urb %p", rcv->urb);
+
+		usb_fill_bulk_urb (rcv->urb,
+				   instance->usb_dev,
+				   usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
+				   (unsigned char *) rcv->skb->data,
+				   UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE,
+				   udsl_complete_receive,
+				   rcv);
+
+		if (usb_submit_urb (rcv->urb, GFP_KERNEL) < 0) {
+			dbg ("udsl_fire_receivers: submit failed!");
+			spin_lock_irqsave (&instance->spare_receivers_lock, flags);
+			list_move (pos, &instance->spare_receivers);
+			spin_unlock_irqrestore (&instance->spare_receivers_lock, flags);
+		}
+	}
+
+	up (&instance->serialize);
+}
+
+
+/***********
+**  send  **
+***********/
+
+static void udsl_complete_send (struct urb *urb, struct pt_regs *regs)
+{
+	struct udsl_instance_data *instance;
+	struct udsl_sender *snd;
+	unsigned long flags;
+
+	if (!urb || !(snd = urb->context) || !(instance = snd->instance)) {
+		dbg ("udsl_complete_send: bad urb!");
+		return;
+	}
+
+	dbg ("udsl_complete_send entered (urb 0x%p, status %d)", urb, urb->status);
+
+	/* may not be in_interrupt() */
+	spin_lock_irqsave (&instance->send_lock, flags);
+	list_add (&snd->list, &instance->spare_senders);
+	list_add (&snd->buffer->list, &instance->spare_buffers);
+	tasklet_schedule (&instance->send_tasklet);
+	spin_unlock_irqrestore (&instance->send_lock, flags);
+}
+
+static void udsl_process_send (unsigned long data)
+{
+	struct udsl_send_buffer *buf;
+	int err;
+	unsigned long flags;
+	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
+	unsigned int num_written;
+	struct sk_buff *skb;
+	struct udsl_sender *snd;
+
+	dbg ("udsl_process_send entered");
+
+made_progress:
+	spin_lock_irqsave (&instance->send_lock, flags);
+	while (!list_empty (&instance->spare_senders)) {
+		if (!list_empty (&instance->filled_buffers)) {
+			buf = list_entry (instance->filled_buffers.next, struct udsl_send_buffer, list);
+			list_del (&buf->list);
+			dbg ("sending filled buffer (0x%p)", buf);
+		} else if ((buf = instance->current_buffer)) {
+			instance->current_buffer = NULL;
+			dbg ("sending current buffer (0x%p)", buf);
+		} else /* all buffers empty */
+			break;
+
+		snd = list_entry (instance->spare_senders.next, struct udsl_sender, list);
+		list_del (&snd->list);
+		spin_unlock_irqrestore (&instance->send_lock, flags);
+
+		snd->buffer = buf;
+	        usb_fill_bulk_urb (snd->urb,
+				   instance->usb_dev,
+				   usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT),
+				   buf->base,
+				   (UDSL_SND_BUFFER_SIZE - buf->free_cells) * ATM_CELL_SIZE,
+				   udsl_complete_send,
+				   snd);
+
+		dbg ("submitting urb 0x%p, contains %d cells", snd->urb, UDSL_SND_BUFFER_SIZE - buf->free_cells);
+
+		if ((err = usb_submit_urb(snd->urb, GFP_ATOMIC)) < 0) {
+			dbg ("submission failed (%d)!", err);
+			spin_lock_irqsave (&instance->send_lock, flags);
+			list_add (&snd->list, &instance->spare_senders);
+			spin_unlock_irqrestore (&instance->send_lock, flags);
+			list_add (&buf->list, &instance->filled_buffers);
+			return;
+		}
+
+		spin_lock_irqsave (&instance->send_lock, flags);
+	} /* while */
+	spin_unlock_irqrestore (&instance->send_lock, flags);
+
+	if (!instance->current_skb && !(instance->current_skb = skb_dequeue (&instance->sndqueue))) {
+		dbg ("done - no more skbs");
+		return;
+	}
+
+	skb = instance->current_skb;
+
+	if (!(buf = instance->current_buffer)) {
+		spin_lock_irqsave (&instance->send_lock, flags);
+		if (list_empty (&instance->spare_buffers)) {
+			instance->current_buffer = NULL;
+			spin_unlock_irqrestore (&instance->send_lock, flags);
+			dbg ("done - no more buffers");
+			return;
+		}
+		buf = list_entry (instance->spare_buffers.next, struct udsl_send_buffer, list);
+		list_del (&buf->list);
+		spin_unlock_irqrestore (&instance->send_lock, flags);
+
+		buf->free_start = buf->base;
+		buf->free_cells = UDSL_SND_BUFFER_SIZE;
+
+		instance->current_buffer = buf;
+	}
+
+	num_written = udsl_write_cells (buf->free_cells, skb, &buf->free_start);
+
+	dbg ("wrote %u cells from skb 0x%p to buffer 0x%p", num_written, skb, buf);
+
+	if (!(buf->free_cells -= num_written)) {
+		list_add_tail (&buf->list, &instance->filled_buffers);
+		instance->current_buffer = NULL;
+		dbg ("queued filled buffer");
+	}
+
+	dbg ("buffer contains %d cells, %d left", UDSL_SND_BUFFER_SIZE - buf->free_cells, buf->free_cells);
+
+	if (!UDSL_SKB (skb)->num_cells) {
+		struct atm_vcc *vcc = UDSL_SKB (skb)->atm_data.vcc;
+
+		dbg ("discarding empty skb");
+		if (vcc->pop)
+			vcc->pop (vcc, skb);
+		else
+			kfree_skb (skb);
+		instance->current_skb = NULL;
+
+		if (vcc->stats)
+			atomic_inc (&vcc->stats->tx);
+	}
+
+	goto made_progress;
+}
+
+static void udsl_cancel_send (struct udsl_instance_data *instance, struct atm_vcc *vcc)
+{
+	unsigned long flags;
+	struct sk_buff *skb, *n;
+
+	dbg ("udsl_cancel_send entered");
+	spin_lock_irqsave (&instance->sndqueue.lock, flags);
+	for (skb = instance->sndqueue.next, n = skb->next; skb != (struct sk_buff *)&instance->sndqueue; skb = n, n = skb->next)
+		if (UDSL_SKB (skb)->atm_data.vcc == vcc) {
+			dbg ("popping skb 0x%p", skb);
+			__skb_unlink (skb, &instance->sndqueue);
+			if (vcc->pop)
+				vcc->pop (vcc, skb);
+			else
+				kfree_skb (skb);
+		}
+	spin_unlock_irqrestore (&instance->sndqueue.lock, flags);
+
+	tasklet_disable (&instance->send_tasklet);
+	if ((skb = instance->current_skb) && (UDSL_SKB (skb)->atm_data.vcc == vcc)) {
+		dbg ("popping current skb (0x%p)", skb);
+		instance->current_skb = NULL;
+		if (vcc->pop)
+			vcc->pop (vcc, skb);
+		else
+			kfree_skb (skb);
+	}
+	tasklet_enable (&instance->send_tasklet);
+	dbg ("udsl_cancel_send done");
+}
+
+static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
+{
+	struct udsl_instance_data *instance = vcc->dev->dev_data;
+
+	dbg ("udsl_atm_send called (skb 0x%p, len %u)", skb, skb->len);
+
+	if (!instance || !instance->usb_dev) {
+		dbg ("NULL data!");
+		return -ENODEV;
+	}
+
+	if (!instance->firmware_loaded)
+		return -EAGAIN;
+
+	if (vcc->qos.aal != ATM_AAL5) {
+		dbg ("unsupported ATM type %d!", vcc->qos.aal);
+		return -EINVAL;
+	}
+
+	if (skb->len > ATM_MAX_AAL5_PDU) {
+		dbg ("packet too long (%d vs %d)!", skb->len, ATM_MAX_AAL5_PDU);
+		return -EINVAL;
+	}
+
+	PACKETDEBUG (skb->data, skb->len);
+
+	udsl_groom_skb (vcc, skb);
+	skb_queue_tail (&instance->sndqueue, skb);
+	tasklet_schedule (&instance->send_tasklet);
+
+	return 0;
+}
+
+
+/**********
+**  ATM  **
+**********/
+
+#define ATMSAR_DEF_MTU_AAL0		48
+#define ATMSAR_DEF_MTU_AAL1		47
+#define ATMSAR_DEF_MTU_AAL2		0  /* not supported */
+#define ATMSAR_DEF_MTU_AAL34		0  /* not supported */
+#define ATMSAR_DEF_MTU_AAL5		65535  /* max mtu ..    */
+
+struct atmsar_vcc_data *atmsar_open (struct atmsar_vcc_data **list, struct atm_vcc *vcc, uint type,
+				     ushort vpi, ushort vci, unchar pti, unchar gfc, uint flags)
+{
+	struct atmsar_vcc_data *new;
+
+	if (!vcc)
+		return NULL;
+
+	new = kmalloc (sizeof (struct atmsar_vcc_data), GFP_KERNEL);
+
+	if (!new)
+		return NULL;
+
+	memset (new, 0, sizeof (struct atmsar_vcc_data));
+	new->vcc = vcc;
+	new->stats = vcc->stats;
+	new->type = type;
+	new->next = NULL;
+	new->gfc = gfc;
+	new->vp = vpi;
+	new->vc = vci;
+	new->pti = pti;
+
+	switch (type) {
+	case ATM_AAL0:
+		new->mtu = ATMSAR_DEF_MTU_AAL0;
+		break;
+	case ATM_AAL1:
+		new->mtu = ATMSAR_DEF_MTU_AAL1;
+		break;
+	case ATM_AAL2:
+		new->mtu = ATMSAR_DEF_MTU_AAL2;
+		break;
+	case ATM_AAL34:
+		/* not supported */
+		new->mtu = ATMSAR_DEF_MTU_AAL34;
+		break;
+	case ATM_AAL5:
+		new->mtu = ATMSAR_DEF_MTU_AAL5;
+		break;
+	}
+
+	new->atmHeader = ((unsigned long) gfc << ATM_HDR_GFC_SHIFT)
+	    | ((unsigned long) vpi << ATM_HDR_VPI_SHIFT)
+	    | ((unsigned long) vci << ATM_HDR_VCI_SHIFT)
+	    | ((unsigned long) pti << ATM_HDR_PTI_SHIFT);
+	new->flags = flags;
+	new->next = NULL;
+	new->reasBuffer = NULL;
+
+	new->next = *list;
+	*list = new;
+
+	dbg ("Allocated new SARLib vcc 0x%p with vp %d vc %d", new, vpi, vci);
+
+	return new;
+}
+
+void atmsar_close (struct atmsar_vcc_data **list, struct atmsar_vcc_data *vcc)
+{
+	struct atmsar_vcc_data *work;
+
+	if (*list == vcc) {
+		*list = (*list)->next;
+	} else {
+		for (work = *list; work && work->next && (work->next != vcc); work = work->next);
+
+		/* return if not found */
+		if (work->next != vcc)
+			return;
+
+		work->next = work->next->next;
+	}
+
+	if (vcc->reasBuffer) {
+		dev_kfree_skb (vcc->reasBuffer);
+	}
+
+	dbg ("Allocated SARLib vcc 0x%p with vp %d vc %d", vcc, vcc->vp, vcc->vc);
+
+	kfree (vcc);
+}
+
+static void udsl_atm_dev_close (struct atm_dev *dev)
+{
+	struct udsl_instance_data *instance = dev->dev_data;
+
+	if (!instance) {
+		dbg ("udsl_atm_dev_close: NULL instance!");
+		return;
+	}
+
+	dbg ("udsl_atm_dev_close: queue has %u elements", instance->sndqueue.qlen);
+
+	dbg ("udsl_atm_dev_close: killing tasklet");
+	tasklet_kill (&instance->send_tasklet);
+	dbg ("udsl_atm_dev_close: freeing instance");
+	kfree (instance);
+	dev->dev_data = NULL;
+}
+
+static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page)
+{
+	struct udsl_instance_data *instance = atm_dev->dev_data;
+	int left = *pos;
+
+	if (!instance) {
+		dbg ("NULL instance!");
+		return -ENODEV;
+	}
+
+	if (!left--)
+		return sprintf (page, "%s\n", instance->description);
+
+	if (!left--)
+		return sprintf (page, "MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+				atm_dev->esi[0], atm_dev->esi[1], atm_dev->esi[2],
+				atm_dev->esi[3], atm_dev->esi[4], atm_dev->esi[5]);
+
+	if (!left--)
+		return sprintf (page, "AAL5: tx %d ( %d err ), rx %d ( %d err, %d drop )\n",
+				atomic_read (&atm_dev->stats.aal5.tx),
+				atomic_read (&atm_dev->stats.aal5.tx_err),
+				atomic_read (&atm_dev->stats.aal5.rx),
+				atomic_read (&atm_dev->stats.aal5.rx_err),
+				atomic_read (&atm_dev->stats.aal5.rx_drop));
+
+	if (!left--) {
+		switch (atm_dev->signal) {
+		case ATM_PHY_SIG_FOUND:
+			sprintf (page, "Line up");
+			break;
+		case ATM_PHY_SIG_LOST:
+			sprintf (page, "Line down");
+			break;
+		default:
+			sprintf (page, "Line state unknown");
+			break;
+		}
+
+		if (instance->usb_dev) {
+			if (!instance->firmware_loaded)
+				strcat (page, ", no firmware\n");
+			else
+				strcat (page, ", firmware loaded\n");
+		} else
+			strcat (page, ", disconnected\n");
+
+		return strlen (page);
+	}
+
+	return 0;
+}
+
+#define ATMSAR_SET_PTI		0x2L
+
+static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
+{
+	struct udsl_instance_data *instance = vcc->dev->dev_data;
+
+	dbg ("udsl_atm_open called");
+
+	if (!instance || !instance->usb_dev) {
+		dbg ("NULL data!");
+		return -ENODEV;
+	}
+
+	/* at the moment only AAL5 support */
+	if (vcc->qos.aal != ATM_AAL5)
+		return -EINVAL;
+
+	MOD_INC_USE_COUNT;
+
+	vcc->dev_data =
+	    atmsar_open (&(instance->atmsar_vcc_list), vcc, ATM_AAL5, vpi, vci, 0, 0,
+			 ATMSAR_USE_53BYTE_CELL | ATMSAR_SET_PTI);
+	if (!vcc->dev_data) {
+		MOD_DEC_USE_COUNT;
+		return -ENOMEM;	/* this is the only reason atmsar_open can fail... */
+	}
+
+	vcc->vpi = vpi;
+	vcc->vci = vci;
+	set_bit (ATM_VF_ADDR, &vcc->flags);
+	set_bit (ATM_VF_PARTIAL, &vcc->flags);
+	set_bit (ATM_VF_READY, &vcc->flags);
+
+	((struct atmsar_vcc_data *)vcc->dev_data)->mtu = UDSL_MAX_AAL5_MRU;
+
+	if (instance->firmware_loaded)
+		udsl_fire_receivers (instance);
+
+	dbg ("udsl_atm_open successful");
+	return 0;
+}
+
+static void udsl_atm_close (struct atm_vcc *vcc)
+{
+	struct udsl_instance_data *instance = vcc->dev->dev_data;
+
+	dbg ("udsl_atm_close called");
+
+	if (!instance) {
+		dbg ("NULL instance!");
+		return;
+	}
+
+	/* freeing resources */
+	/* cancel all sends on this vcc */
+	udsl_cancel_send (instance, vcc);
+
+	atmsar_close (&(instance->atmsar_vcc_list), vcc->dev_data);
+	vcc->dev_data = NULL;
+	clear_bit (ATM_VF_PARTIAL, &vcc->flags);
+
+	/* freeing address */
+	vcc->vpi = ATM_VPI_UNSPEC;
+	vcc->vci = ATM_VCI_UNSPEC;
+	clear_bit (ATM_VF_ADDR, &vcc->flags);
+
+	MOD_DEC_USE_COUNT;
+
+	dbg ("udsl_atm_close successful");
+	return;
+}
+
+static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg)
+{
+	switch (cmd) {
+	case ATM_QUERYLOOP:
+		return put_user (ATM_LM_NONE, (int *) arg) ? -EFAULT : 0;
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+
+/**********
+**  USB  **
+**********/
+
+static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data)
+{
+	struct udsl_instance_data *instance = usb_get_intfdata (intf);
+
+	dbg ("udsl_usb_ioctl entered");
+
+	if (!instance) {
+		dbg ("NULL instance!");
+		return -ENODEV;
+	}
+
+	switch (code) {
+	case UDSL_IOCTL_START:
+		instance->atm_dev->signal = ATM_PHY_SIG_FOUND;
+		down (&instance->serialize); /* vs self */
+		if (!instance->firmware_loaded) {
+			usb_set_interface (instance->usb_dev, 1, 1);
+			instance->firmware_loaded = 1;
+		}
+		up (&instance->serialize);
+		udsl_fire_receivers (instance);
+		return 0;
+	case UDSL_IOCTL_STOP:
+		instance->atm_dev->signal = ATM_PHY_SIG_LOST;
+		return 0;
+	default:
+		return -ENOTTY;
+	}
+}
+
+static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_id *id)
+{
+	struct usb_device *dev = interface_to_usbdev(intf);
+	int ifnum = intf->altsetting->desc.bInterfaceNumber;
+	struct udsl_instance_data *instance;
+	unsigned char mac_str [13];
+	int i, length;
+	char *buf;
+
+	dbg ("Trying device with Vendor=0x%x, Product=0x%x, ifnum %d",
+		dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
+
+	if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) ||
+	    (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) ||
+	    (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1))
+		return -ENODEV;
+
+	dbg ("Device Accepted");
+
+	/* instance init */
+	if (!(instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL))) {
+		dbg ("No memory for Instance data!");
+		return -ENOMEM;
+	}
+
+	memset (instance, 0, sizeof (struct udsl_instance_data));
+
+	init_MUTEX (&instance->serialize);
+
+	instance->usb_dev = dev;
+
+	spin_lock_init (&instance->spare_receivers_lock);
+	INIT_LIST_HEAD (&instance->spare_receivers);
+
+	spin_lock_init (&instance->completed_receivers_lock);
+	INIT_LIST_HEAD (&instance->completed_receivers);
+
+	tasklet_init (&instance->receive_tasklet, udsl_process_receive, (unsigned long) instance);
+
+	skb_queue_head_init (&instance->sndqueue);
+
+	spin_lock_init (&instance->send_lock);
+	INIT_LIST_HEAD (&instance->spare_senders);
+	INIT_LIST_HEAD (&instance->spare_buffers);
+
+	tasklet_init (&instance->send_tasklet, udsl_process_send, (unsigned long) instance);
+	INIT_LIST_HEAD (&instance->filled_buffers);
+
+	/* receive init */
+	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
+		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
+
+		if (!(rcv->skb = dev_alloc_skb (UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE))) {
+			dbg ("No memory for skb %d!", i);
+			goto fail;
+		}
+
+		if (!(rcv->urb = usb_alloc_urb (0, GFP_KERNEL))) {
+			dbg ("No memory for receive urb %d!", i);
+			goto fail;
+		}
+
+		rcv->instance = instance;
+
+		list_add (&rcv->list, &instance->spare_receivers);
+
+		dbg ("skb->truesize = %d (asked for %d)", rcv->skb->truesize, UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE);
+	}
+
+	/* send init */
+	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) {
+		struct udsl_sender *snd = &(instance->all_senders[i]);
+
+		if (!(snd->urb = usb_alloc_urb (0, GFP_KERNEL))) {
+			dbg ("No memory for send urb %d!", i);
+			goto fail;
+		}
+
+		snd->instance = instance;
+
+		list_add (&snd->list, &instance->spare_senders);
+	}
+
+	for (i = 0; i < UDSL_NUMBER_SND_BUFS; i++) {
+		struct udsl_send_buffer *buf = &(instance->all_buffers[i]);
+
+		if (!(buf->base = kmalloc (UDSL_SND_BUFFER_SIZE * ATM_CELL_SIZE, GFP_KERNEL))) {
+			dbg ("No memory for send buffer %d!", i);
+			goto fail;
+		}
+
+		list_add (&buf->list, &instance->spare_buffers);
+	}
+
+	/* atm init */
+	if (!(instance->atm_dev = atm_dev_register (udsl_driver_name, &udsl_atm_devops, -1, 0))) {
+		dbg ("failed to register ATM device!");
+		goto fail;
+	}
+
+	instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
+	instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;
+	instance->atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
+
+	/* tmp init atm device, set to 128kbit */
+	instance->atm_dev->link_rate = 128 * 1000 / 424;
+
+	/* set MAC address, it is stored in the serial number */
+	memset (instance->atm_dev->esi, 0, sizeof (instance->atm_dev->esi));
+	if (usb_string (dev, dev->descriptor.iSerialNumber, mac_str, sizeof (mac_str)) == 12)
+		for (i = 0; i < 6; i++)
+			instance->atm_dev->esi[i] = (hex2int (mac_str[i * 2]) * 16) + (hex2int (mac_str[i * 2 + 1]));
+
+	/* device description */
+	buf = instance->description;
+	length = sizeof (instance->description);
+
+	if ((i = usb_string (dev, dev->descriptor.iProduct, buf, length)) < 0)
+		goto finish;
+
+	buf += i;
+	length -= i;
+
+	i = snprintf (buf, length, " (");
+	buf += i;
+	length -= i;
+
+	if (length <= 0 || (i = usb_make_path (dev, buf, length)) < 0)
+		goto finish;
+
+	buf += i;
+	length -= i;
+
+	snprintf (buf, length, ")");
+
+finish:
+	/* ready for ATM callbacks */
+	instance->atm_dev->dev_data = instance;
+
+	usb_set_intfdata (intf, instance);
+
+	return 0;
+
+fail:
+	for (i = 0; i < UDSL_NUMBER_SND_BUFS; i++)
+		kfree (instance->all_buffers[i].base);
+
+	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++)
+		usb_free_urb (instance->all_senders[i].urb);
+
+	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
+		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
+
+		usb_free_urb (rcv->urb);
+
+		if (rcv->skb)
+			kfree_skb (rcv->skb);
+	}
+
+	kfree (instance);
+
+	return -ENOMEM;
+}
+
+static void udsl_usb_disconnect (struct usb_interface *intf)
+{
+	struct udsl_instance_data *instance = usb_get_intfdata (intf);
+	struct list_head *pos;
+	unsigned long flags;
+	unsigned int count = 0;
+	int result, i;
+
+	dbg ("disconnecting");
+
+	usb_set_intfdata (intf, NULL);
+
+	if (!instance) {
+		dbg ("NULL instance!");
+		return;
+	}
+
+	tasklet_disable (&instance->receive_tasklet);
+
+	/* receive finalize */
+	down (&instance->serialize); /* vs udsl_fire_receivers */
+	/* no need to take the spinlock */
+	list_for_each (pos, &instance->spare_receivers)
+		if (++count > UDSL_NUMBER_RCV_URBS)
+			panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
+	INIT_LIST_HEAD (&instance->spare_receivers);
+	up (&instance->serialize);
+
+	dbg ("udsl_usb_disconnect: flushed %u spare receivers", count);
+
+	count = UDSL_NUMBER_RCV_URBS - count;
+
+	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++)
+		if ((result = usb_unlink_urb (instance->all_receivers[i].urb)) < 0)
+			dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d", i, result);
+
+	/* wait for completion handlers to finish */
+	do {
+		unsigned int completed = 0;
+
+		spin_lock_irqsave (&instance->completed_receivers_lock, flags);
+		list_for_each (pos, &instance->completed_receivers)
+			if (++completed > count)
+				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
+		spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
+
+		dbg ("udsl_usb_disconnect: found %u completed receivers", completed);
+
+		if (completed == count)
+			break;
+
+		yield ();
+	} while (1);
+
+	dbg ("udsl_usb_disconnect: flushing");
+	/* no need to take the spinlock */
+	INIT_LIST_HEAD (&instance->completed_receivers);
+
+	tasklet_enable (&instance->receive_tasklet);
+	tasklet_kill (&instance->receive_tasklet);
+
+	dbg ("udsl_usb_disconnect: freeing receivers");
+	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
+		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
+
+		usb_free_urb (rcv->urb);
+		kfree_skb (rcv->skb);
+	}
+
+	/* send finalize */
+	tasklet_disable (&instance->send_tasklet);
+
+	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++)
+		if ((result = usb_unlink_urb (instance->all_senders[i].urb)) < 0)
+			dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d", i, result);
+
+	/* wait for completion handlers to finish */
+	do {
+		count = 0;
+		spin_lock_irqsave (&instance->send_lock, flags);
+		list_for_each (pos, &instance->spare_senders)
+			if (++count > UDSL_NUMBER_SND_URBS)
+				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
+		spin_unlock_irqrestore (&instance->send_lock, flags);
+
+		dbg ("udsl_usb_disconnect: found %u spare senders", count);
+
+		if (count == UDSL_NUMBER_SND_URBS)
+			break;
+
+		yield ();
+	} while (1);
+
+	dbg ("udsl_usb_disconnect: flushing");
+	/* no need to take the spinlock */
+	INIT_LIST_HEAD (&instance->spare_senders);
+	INIT_LIST_HEAD (&instance->spare_buffers);
+	instance->current_buffer = NULL;
+
+	tasklet_enable (&instance->send_tasklet);
+
+	dbg ("udsl_usb_disconnect: freeing senders");
+	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++)
+		usb_free_urb (instance->all_senders[i].urb);
+
+	dbg ("udsl_usb_disconnect: freeing buffers");
+	for (i = 0; i < UDSL_NUMBER_SND_BUFS; i++)
+		kfree (instance->all_buffers[i].base);
+
+	instance->usb_dev = NULL;
+
+	/* atm finalize */
+	shutdown_atm_dev (instance->atm_dev); /* frees instance */
+}
+
+
+/***********
+**  init  **
+***********/
+
+static int __init udsl_usb_init (void)
+{
+	struct sk_buff *skb; /* dummy for sizeof */
+
+	dbg ("udsl_usb_init: driver version " DRIVER_VERSION);
+
+	if (sizeof (struct udsl_control) > sizeof (skb->cb)) {
+		printk (KERN_ERR __FILE__ ": unusable with this kernel!\n");
+		return -EIO;
+	}
+
+	return usb_register (&udsl_usb_driver);
+}
+
+static void __exit udsl_usb_cleanup (void)
+{
+	dbg ("udsl_usb_cleanup");
+
+	usb_deregister (&udsl_usb_driver);
+}
+
+module_init (udsl_usb_init);
+module_exit (udsl_usb_cleanup);
+
+MODULE_AUTHOR (DRIVER_AUTHOR);
+MODULE_DESCRIPTION (DRIVER_DESC);
+MODULE_LICENSE ("GPL");
+
+
+/************
+**  debug  **
+************/
+
+#ifdef DEBUG_PACKET
+static int udsl_print_packet (const unsigned char *data, int len)
+{
+	unsigned char buffer [256];
+	int i = 0, j = 0;
+
+	for (i = 0; i < len;) {
+		buffer[0] = '\0';
+		sprintf (buffer, "%.3d :", i);
+		for (j = 0; (j < 16) && (i < len); j++, i++) {
+			sprintf (buffer, "%s %2.2x", buffer, data[i]);
+		}
+		dbg ("%s", buffer);
+	}
+	return i;
+}
+#endif
diff -Nru a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c
--- a/drivers/usb/misc/speedtouch.c	Thu Mar 13 10:36:02 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1241 +0,0 @@
-/******************************************************************************
- *  speedtouch.c  --  Alcatel SpeedTouch USB xDSL modem driver.
- *
- *  Copyright (C) 2001, Alcatel
- *
- *  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.
- *
- ******************************************************************************/
-
-/*
- *  Written by Johan Verrept (Johan.Verrept@advalvas.be)
- *
- *  1.5A:	- Version for inclusion in 2.5 series kernel
- *		- Modifications by Richard Purdie (rpurdie@rpsys.net)
- *		- made compatible with kernel 2.5.6 onwards by changing
- *		udsl_usb_send_data_context->urb to a pointer and adding code
- *		to alloc and free it
- *		- remove_wait_queue() added to udsl_atm_processqueue_thread()
- *
- *  1.5:	- fixed memory leak when atmsar_decode_aal5 returned NULL.
- *		(reported by stephen.robinson@zen.co.uk)
- *
- *  1.4:	- changed the spin_lock() under interrupt to spin_lock_irqsave()
- *		- unlink all active send urbs of a vcc that is being closed.
- *
- *  1.3.1:	- added the version number
- *
- *  1.3:	- Added multiple send urb support
- *		- fixed memory leak and vcc->tx_inuse starvation bug
- *		  when not enough memory left in vcc.
- *
- *  1.2:	- Fixed race condition in udsl_usb_send_data()
- *  1.1:	- Turned off packet debugging
- *
- */
-
-#include <asm/semaphore.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <asm/uaccess.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/crc32.h>
-#include "atmsar.h"
-
-/*
-#define DEBUG 1
-#define DEBUG_PACKET 1
-*/
-
-#include <linux/usb.h>
-
-
-#ifdef DEBUG_PACKET
-static int udsl_print_packet (const unsigned char *data, int len);
-#define PACKETDEBUG(arg...) udsl_print_packet (arg)
-#else
-#define PACKETDEBUG(arg...)
-#endif
-
-#define DRIVER_AUTHOR	"Johan Verrept, Johan.Verrept@advalvas.be"
-#define DRIVER_DESC	"Driver for the Alcatel SpeedTouch USB ADSL modem"
-#define DRIVER_VERSION	"1.5A"
-
-#define SPEEDTOUCH_VENDORID		0x06b9
-#define SPEEDTOUCH_PRODUCTID		0x4061
-
-#define UDSL_NUMBER_RCV_URBS		1
-#define UDSL_NUMBER_SND_URBS		1
-#define UDSL_NUMBER_SND_BUFS		(2*UDSL_NUMBER_SND_URBS)
-#define UDSL_RCV_BUFFER_SIZE		(1*64) /* ATM cells */
-#define UDSL_SND_BUFFER_SIZE		(1*64) /* ATM cells */
-/* max should be (1500 IP mtu + 2 ppp bytes + 32 * 5 cellheader overhead) for
- * PPPoA and (1500 + 14 + 32*5 cellheader overhead) for PPPoE */
-#define UDSL_MAX_AAL5_MRU		2048
-
-#define UDSL_IOCTL_START		1
-#define UDSL_IOCTL_STOP			2
-
-/* endpoint declarations */
-
-#define UDSL_ENDPOINT_DATA_OUT		0x07
-#define UDSL_ENDPOINT_DATA_IN		0x87
-
-#define hex2int(c) ( (c >= '0')&&(c <= '9') ?  (c - '0') : ((c & 0xf)+9) )
-
-/* usb_device_id struct */
-
-static struct usb_device_id udsl_usb_ids [] = {
-	{ USB_DEVICE (SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID) },
-	{ }			/* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, udsl_usb_ids);
-
-/* context declarations */
-
-struct udsl_receiver {
-	struct list_head list;
-	struct sk_buff *skb;
-	struct urb *urb;
-	struct udsl_instance_data *instance;
-};
-
-struct udsl_send_buffer {
-	struct list_head list;
-	unsigned char *base;
-	unsigned char *free_start;
-	unsigned int free_cells;
-};
-
-struct udsl_sender {
-	struct list_head list;
-	struct udsl_send_buffer *buffer;
-	struct urb *urb;
-	struct udsl_instance_data *instance;
-};
-
-struct udsl_control {
-	struct atm_skb_data atm_data;
-	unsigned int num_cells;
-	unsigned int num_entire;
-	unsigned char cell_header [ATM_CELL_HEADER];
-	unsigned int pdu_padding;
-	unsigned char aal5_trailer [ATM_AAL5_TRAILER];
-};
-
-#define UDSL_SKB(x)		((struct udsl_control *)(x)->cb)
-
-/*
- * UDSL main driver data
- */
-
-struct udsl_instance_data {
-	struct semaphore serialize;
-
-	/* usb device part */
-	struct usb_device *usb_dev;
-	char description [64];
-	int firmware_loaded;
-
-	/* atm device part */
-	struct atm_dev *atm_dev;
-	struct atmsar_vcc_data *atmsar_vcc_list;
-
-	/* receiving */
-	struct udsl_receiver all_receivers [UDSL_NUMBER_RCV_URBS];
-
-	spinlock_t spare_receivers_lock;
-	struct list_head spare_receivers;
-
-	spinlock_t completed_receivers_lock;
-	struct list_head completed_receivers;
-
-	struct tasklet_struct receive_tasklet;
-
-	/* sending */
-	struct udsl_sender all_senders [UDSL_NUMBER_SND_URBS];
-	struct udsl_send_buffer all_buffers [UDSL_NUMBER_SND_BUFS];
-
-	struct sk_buff_head sndqueue;
-
-	spinlock_t send_lock;
-	struct list_head spare_senders;
-	struct list_head spare_buffers;
-
-	struct tasklet_struct send_tasklet;
-	struct sk_buff *current_skb;			/* being emptied */
-	struct udsl_send_buffer *current_buffer;	/* being filled */
-	struct list_head filled_buffers;
-};
-
-static const char udsl_driver_name [] = "speedtch";
-
-/*
- * atm driver prototypes and structures
- */
-
-static void udsl_atm_dev_close (struct atm_dev *dev);
-static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci);
-static void udsl_atm_close (struct atm_vcc *vcc);
-static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg);
-static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb);
-static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page);
-
-static struct atmdev_ops udsl_atm_devops = {
-	.dev_close =	udsl_atm_dev_close,
-	.open =		udsl_atm_open,
-	.close =	udsl_atm_close,
-	.ioctl =	udsl_atm_ioctl,
-	.send =		udsl_atm_send,
-	.proc_read =	udsl_atm_proc_read,
-};
-
-/*
- * usb driver prototypes and structures
- */
-static int udsl_usb_probe (struct usb_interface *intf,
-			   const struct usb_device_id *id);
-static void udsl_usb_disconnect (struct usb_interface *intf);
-static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data);
-
-static struct usb_driver udsl_usb_driver = {
-	.name =		udsl_driver_name,
-	.probe =	udsl_usb_probe,
-	.disconnect =	udsl_usb_disconnect,
-	.ioctl =	udsl_usb_ioctl,
-	.id_table =	udsl_usb_ids,
-};
-
-
-/*************
-**  encode  **
-*************/
-
-static void udsl_groom_skb (struct atm_vcc *vcc, struct sk_buff *skb) {
-	struct udsl_control *ctrl = UDSL_SKB (skb);
-	unsigned int i, zero_padding;
-	unsigned char zero = 0;
-	u32 crc;
-
-	ctrl->atm_data.vcc = vcc;
-	ctrl->cell_header [0] = vcc->vpi >> 4;
-	ctrl->cell_header [1] = (vcc->vpi << 4) | (vcc->vci >> 12);
-	ctrl->cell_header [2] = vcc->vci >> 4;
-	ctrl->cell_header [3] = vcc->vci << 4;
-	ctrl->cell_header [4] = 0xec;
-
-	ctrl->num_cells = (skb->len + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD;
-	ctrl->num_entire = skb->len / ATM_CELL_PAYLOAD;
-
-	zero_padding = ctrl->num_cells * ATM_CELL_PAYLOAD - skb->len - ATM_AAL5_TRAILER;
-
-	if (ctrl->num_entire + 1 < ctrl->num_cells)
-		ctrl->pdu_padding = zero_padding - (ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
-	else
-		ctrl->pdu_padding = zero_padding;
-
-	ctrl->aal5_trailer [0] = 0; /* UU = 0 */
-	ctrl->aal5_trailer [1] = 0; /* CPI = 0 */
-	ctrl->aal5_trailer [2] = skb->len >> 8;
-	ctrl->aal5_trailer [3] = skb->len;
-
-	crc = crc32_be (~0, skb->data, skb->len);
-	for (i = 0; i < zero_padding; i++)
-		crc = crc32_be (crc, &zero, 1);
-	crc = crc32_be (crc, ctrl->aal5_trailer, 4);
-	crc = ~crc;
-
-	ctrl->aal5_trailer [4] = crc >> 24;
-	ctrl->aal5_trailer [5] = crc >> 16;
-	ctrl->aal5_trailer [6] = crc >> 8;
-	ctrl->aal5_trailer [7] = crc;
-}
-
-unsigned int udsl_write_cells (unsigned int howmany, struct sk_buff *skb, unsigned char **target_p) {
-	struct udsl_control *ctrl = UDSL_SKB (skb);
-	unsigned char *target = *target_p;
-	unsigned int nc, ne, i;
-
-	dbg ("udsl_write_cells: howmany=%u, skb->len=%d, num_cells=%u, num_entire=%u, pdu_padding=%u", howmany, skb->len, ctrl->num_cells, ctrl->num_entire, ctrl->pdu_padding);
-
-	nc = ctrl->num_cells;
-	ne = min (howmany, ctrl->num_entire);
-
-	for (i = 0; i < ne; i++) {
-		memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
-		target += ATM_CELL_HEADER;
-		memcpy (target, skb->data, ATM_CELL_PAYLOAD);
-		target += ATM_CELL_PAYLOAD;
-		__skb_pull (skb, ATM_CELL_PAYLOAD);
-	}
-
-	ctrl->num_entire -= ne;
-
-	if (!(ctrl->num_cells -= ne) || !(howmany -= ne))
-		goto out;
-
-	memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
-	target += ATM_CELL_HEADER;
-	memcpy (target, skb->data, skb->len);
-	target += skb->len;
-	__skb_pull (skb, skb->len);
-	memset (target, 0, ctrl->pdu_padding);
-	target += ctrl->pdu_padding;
-
-	if (--ctrl->num_cells) {
-		if (!--howmany) {
-			ctrl->pdu_padding = ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
-			goto out;
-		}
-
-		memcpy (target, ctrl->cell_header, ATM_CELL_HEADER);
-		target += ATM_CELL_HEADER;
-		memset (target, 0, ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
-		target += ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
-
-		if (--ctrl->num_cells)
-			BUG();
-	}
-
-	memcpy (target, ctrl->aal5_trailer, ATM_AAL5_TRAILER);
-	target += ATM_AAL5_TRAILER;
-	/* set pti bit in last cell */
-	*(target + 3 - ATM_CELL_SIZE) |= 0x2;
-
-out:
-	*target_p = target;
-	return nc - ctrl->num_cells;
-}
-
-
-/**************
-**  receive  **
-**************/
-
-static void udsl_complete_receive (struct urb *urb, struct pt_regs *regs)
-{
-	struct udsl_instance_data *instance;
-	struct udsl_receiver *rcv;
-	unsigned long flags;
-
-	if (!urb || !(rcv = urb->context) || !(instance = rcv->instance)) {
-		dbg ("udsl_complete_receive: bad urb!");
-		return;
-	}
-
-	dbg ("udsl_complete_receive entered (urb 0x%p, status %d)", urb, urb->status);
-
-	/* may not be in_interrupt() */
-	spin_lock_irqsave (&instance->completed_receivers_lock, flags);
-	list_add_tail (&rcv->list, &instance->completed_receivers);
-	tasklet_schedule (&instance->receive_tasklet);
-	spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
-}
-
-static void udsl_process_receive (unsigned long data)
-{
-	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
-	struct udsl_receiver *rcv;
-	unsigned long flags;
-	unsigned char *data_start;
-	struct sk_buff *skb;
-	struct urb *urb;
-	struct atmsar_vcc_data *atmsar_vcc = NULL;
-	struct sk_buff *new = NULL, *tmp = NULL;
-	int err;
-
-	dbg ("udsl_process_receive entered");
-
-	spin_lock_irqsave (&instance->completed_receivers_lock, flags);
-	while (!list_empty (&instance->completed_receivers)) {
-		rcv = list_entry (instance->completed_receivers.next, struct udsl_receiver, list);
-		list_del (&rcv->list);
-		spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
-
-		urb = rcv->urb;
-		dbg ("udsl_process_receive: got packet %p with length %d and status %d", urb, urb->actual_length, urb->status);
-
-		switch (urb->status) {
-		case 0:
-			dbg ("udsl_process_receive: processing urb with rcv %p, urb %p, skb %p", rcv, urb, rcv->skb);
-
-			/* update the skb structure */
-			skb = rcv->skb;
-			skb_trim (skb, 0);
-			skb_put (skb, urb->actual_length);
-			data_start = skb->data;
-
-			dbg ("skb->len = %d", skb->len);
-			PACKETDEBUG (skb->data, skb->len);
-
-			while ((new =
-				atmsar_decode_rawcell (instance->atmsar_vcc_list, skb,
-						       &atmsar_vcc)) != NULL) {
-				dbg ("(after cell processing)skb->len = %d", new->len);
-
-				switch (atmsar_vcc->type) {
-				case ATMSAR_TYPE_AAL5:
-					tmp = new;
-					new = atmsar_decode_aal5 (atmsar_vcc, new);
-
-					/* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */
-					if (new) {
-						dbg ("(after aal5 decap) skb->len = %d", new->len);
-						if (new->len && atm_charge (atmsar_vcc->vcc, new->truesize)) {
-							PACKETDEBUG (new->data, new->len);
-							atmsar_vcc->vcc->push (atmsar_vcc->vcc, new);
-						} else {
-							dbg
-							    ("dropping incoming packet : rx_inuse = %d, vcc->sk->rcvbuf = %d, skb->true_size = %d",
-							     atomic_read (&atmsar_vcc->vcc->rx_inuse),
-							     atmsar_vcc->vcc->sk->rcvbuf, new->truesize);
-							dev_kfree_skb (new);
-						}
-					} else {
-						dbg ("atmsar_decode_aal5 returned NULL!");
-						dev_kfree_skb (tmp);
-					}
-					break;
-				default:
-					/* not supported. we delete the skb. */
-					printk (KERN_INFO
-						"SpeedTouch USB: illegal vcc type. Dropping packet.\n");
-					dev_kfree_skb (new);
-					break;
-				}
-			}
-
-			/* restore skb */
-			skb_push (skb, skb->data - data_start);
-
-			usb_fill_bulk_urb (urb,
-					   instance->usb_dev,
-					   usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
-					   (unsigned char *) rcv->skb->data,
-					   UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE,
-					   udsl_complete_receive,
-					   rcv);
-			if (!(err = usb_submit_urb (urb, GFP_ATOMIC)))
-				break;
-			dbg ("udsl_process_receive: submission failed (%d)", err);
-			/* fall through */
-		default: /* error or urb unlinked */
-			dbg ("udsl_process_receive: adding to spare_receivers");
-			spin_lock_irqsave (&instance->spare_receivers_lock, flags);
-			list_add (&rcv->list, &instance->spare_receivers);
-			spin_unlock_irqrestore (&instance->spare_receivers_lock, flags);
-			break;
-		} /* switch */
-
-		spin_lock_irqsave (&instance->completed_receivers_lock, flags);
-	} /* while */
-	spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
-	dbg ("udsl_process_receive successful");
-}
-
-static void udsl_fire_receivers (struct udsl_instance_data *instance)
-{
-	struct list_head receivers, *pos, *n;
-	unsigned long flags;
-
-	INIT_LIST_HEAD (&receivers);
-
-	down (&instance->serialize);
-
-	spin_lock_irqsave (&instance->spare_receivers_lock, flags);
-	list_splice_init (&instance->spare_receivers, &receivers);
-	spin_unlock_irqrestore (&instance->spare_receivers_lock, flags);
-
-	list_for_each_safe (pos, n, &receivers) {
-		struct udsl_receiver *rcv = list_entry (pos, struct udsl_receiver, list);
-
-		dbg ("udsl_fire_receivers: firing urb %p", rcv->urb);
-
-		usb_fill_bulk_urb (rcv->urb,
-				   instance->usb_dev,
-				   usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
-				   (unsigned char *) rcv->skb->data,
-				   UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE,
-				   udsl_complete_receive,
-				   rcv);
-
-		if (usb_submit_urb (rcv->urb, GFP_KERNEL) < 0) {
-			dbg ("udsl_fire_receivers: submit failed!");
-			spin_lock_irqsave (&instance->spare_receivers_lock, flags);
-			list_move (pos, &instance->spare_receivers);
-			spin_unlock_irqrestore (&instance->spare_receivers_lock, flags);
-		}
-	}
-
-	up (&instance->serialize);
-}
-
-
-/***********
-**  send  **
-***********/
-
-static void udsl_complete_send (struct urb *urb, struct pt_regs *regs)
-{
-	struct udsl_instance_data *instance;
-	struct udsl_sender *snd;
-	unsigned long flags;
-
-	if (!urb || !(snd = urb->context) || !(instance = snd->instance)) {
-		dbg ("udsl_complete_send: bad urb!");
-		return;
-	}
-
-	dbg ("udsl_complete_send entered (urb 0x%p, status %d)", urb, urb->status);
-
-	/* may not be in_interrupt() */
-	spin_lock_irqsave (&instance->send_lock, flags);
-	list_add (&snd->list, &instance->spare_senders);
-	list_add (&snd->buffer->list, &instance->spare_buffers);
-	tasklet_schedule (&instance->send_tasklet);
-	spin_unlock_irqrestore (&instance->send_lock, flags);
-}
-
-static void udsl_process_send (unsigned long data)
-{
-	struct udsl_send_buffer *buf;
-	int err;
-	unsigned long flags;
-	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
-	unsigned int num_written;
-	struct sk_buff *skb;
-	struct udsl_sender *snd;
-
-	dbg ("udsl_process_send entered");
-
-made_progress:
-	spin_lock_irqsave (&instance->send_lock, flags);
-	while (!list_empty (&instance->spare_senders)) {
-		if (!list_empty (&instance->filled_buffers)) {
-			buf = list_entry (instance->filled_buffers.next, struct udsl_send_buffer, list);
-			list_del (&buf->list);
-			dbg ("sending filled buffer (0x%p)", buf);
-		} else if ((buf = instance->current_buffer)) {
-			instance->current_buffer = NULL;
-			dbg ("sending current buffer (0x%p)", buf);
-		} else /* all buffers empty */
-			break;
-
-		snd = list_entry (instance->spare_senders.next, struct udsl_sender, list);
-		list_del (&snd->list);
-		spin_unlock_irqrestore (&instance->send_lock, flags);
-
-		snd->buffer = buf;
-	        usb_fill_bulk_urb (snd->urb,
-				   instance->usb_dev,
-				   usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT),
-				   buf->base,
-				   (UDSL_SND_BUFFER_SIZE - buf->free_cells) * ATM_CELL_SIZE,
-				   udsl_complete_send,
-				   snd);
-
-		dbg ("submitting urb 0x%p, contains %d cells", snd->urb, UDSL_SND_BUFFER_SIZE - buf->free_cells);
-
-		if ((err = usb_submit_urb(snd->urb, GFP_ATOMIC)) < 0) {
-			dbg ("submission failed (%d)!", err);
-			spin_lock_irqsave (&instance->send_lock, flags);
-			list_add (&snd->list, &instance->spare_senders);
-			spin_unlock_irqrestore (&instance->send_lock, flags);
-			list_add (&buf->list, &instance->filled_buffers);
-			return;
-		}
-
-		spin_lock_irqsave (&instance->send_lock, flags);
-	} /* while */
-	spin_unlock_irqrestore (&instance->send_lock, flags);
-
-	if (!instance->current_skb && !(instance->current_skb = skb_dequeue (&instance->sndqueue))) {
-		dbg ("done - no more skbs");
-		return;
-	}
-
-	skb = instance->current_skb;
-
-	if (!(buf = instance->current_buffer)) {
-		spin_lock_irqsave (&instance->send_lock, flags);
-		if (list_empty (&instance->spare_buffers)) {
-			instance->current_buffer = NULL;
-			spin_unlock_irqrestore (&instance->send_lock, flags);
-			dbg ("done - no more buffers");
-			return;
-		}
-		buf = list_entry (instance->spare_buffers.next, struct udsl_send_buffer, list);
-		list_del (&buf->list);
-		spin_unlock_irqrestore (&instance->send_lock, flags);
-
-		buf->free_start = buf->base;
-		buf->free_cells = UDSL_SND_BUFFER_SIZE;
-
-		instance->current_buffer = buf;
-	}
-
-	num_written = udsl_write_cells (buf->free_cells, skb, &buf->free_start);
-
-	dbg ("wrote %u cells from skb 0x%p to buffer 0x%p", num_written, skb, buf);
-
-	if (!(buf->free_cells -= num_written)) {
-		list_add_tail (&buf->list, &instance->filled_buffers);
-		instance->current_buffer = NULL;
-		dbg ("queued filled buffer");
-	}
-
-	dbg ("buffer contains %d cells, %d left", UDSL_SND_BUFFER_SIZE - buf->free_cells, buf->free_cells);
-
-	if (!UDSL_SKB (skb)->num_cells) {
-		struct atm_vcc *vcc = UDSL_SKB (skb)->atm_data.vcc;
-
-		dbg ("discarding empty skb");
-		if (vcc->pop)
-			vcc->pop (vcc, skb);
-		else
-			kfree_skb (skb);
-		instance->current_skb = NULL;
-
-		if (vcc->stats)
-			atomic_inc (&vcc->stats->tx);
-	}
-
-	goto made_progress;
-}
-
-static void udsl_cancel_send (struct udsl_instance_data *instance, struct atm_vcc *vcc)
-{
-	unsigned long flags;
-	struct sk_buff *skb, *n;
-
-	dbg ("udsl_cancel_send entered");
-	spin_lock_irqsave (&instance->sndqueue.lock, flags);
-	for (skb = instance->sndqueue.next, n = skb->next; skb != (struct sk_buff *)&instance->sndqueue; skb = n, n = skb->next)
-		if (UDSL_SKB (skb)->atm_data.vcc == vcc) {
-			dbg ("popping skb 0x%p", skb);
-			__skb_unlink (skb, &instance->sndqueue);
-			if (vcc->pop)
-				vcc->pop (vcc, skb);
-			else
-				kfree_skb (skb);
-		}
-	spin_unlock_irqrestore (&instance->sndqueue.lock, flags);
-
-	tasklet_disable (&instance->send_tasklet);
-	if ((skb = instance->current_skb) && (UDSL_SKB (skb)->atm_data.vcc == vcc)) {
-		dbg ("popping current skb (0x%p)", skb);
-		instance->current_skb = NULL;
-		if (vcc->pop)
-			vcc->pop (vcc, skb);
-		else
-			kfree_skb (skb);
-	}
-	tasklet_enable (&instance->send_tasklet);
-	dbg ("udsl_cancel_send done");
-}
-
-static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct udsl_instance_data *instance = vcc->dev->dev_data;
-
-	dbg ("udsl_atm_send called (skb 0x%p, len %u)", skb, skb->len);
-
-	if (!instance || !instance->usb_dev) {
-		dbg ("NULL data!");
-		return -ENODEV;
-	}
-
-	if (!instance->firmware_loaded)
-		return -EAGAIN;
-
-	if (vcc->qos.aal != ATM_AAL5) {
-		dbg ("unsupported ATM type %d!", vcc->qos.aal);
-		return -EINVAL;
-	}
-
-	if (skb->len > ATM_MAX_AAL5_PDU) {
-		dbg ("packet too long (%d vs %d)!", skb->len, ATM_MAX_AAL5_PDU);
-		return -EINVAL;
-	}
-
-	PACKETDEBUG (skb->data, skb->len);
-
-	udsl_groom_skb (vcc, skb);
-	skb_queue_tail (&instance->sndqueue, skb);
-	tasklet_schedule (&instance->send_tasklet);
-
-	return 0;
-}
-
-
-/************
-**   ATM   **
-************/
-
-/***************************************************************************
-*
-* init functions
-*
-****************************************************************************/
-
-static void udsl_atm_dev_close (struct atm_dev *dev)
-{
-	struct udsl_instance_data *instance = dev->dev_data;
-
-	if (!instance) {
-		dbg ("udsl_atm_dev_close: NULL instance!");
-		return;
-	}
-
-	dbg ("udsl_atm_dev_close: queue has %u elements", instance->sndqueue.qlen);
-
-	dbg ("udsl_atm_dev_close: killing tasklet");
-	tasklet_kill (&instance->send_tasklet);
-	dbg ("udsl_atm_dev_close: freeing instance");
-	kfree (instance);
-	dev->dev_data = NULL;
-}
-
-
-/***************************************************************************
-*
-* ATM helper functions
-*
-****************************************************************************/
-
-static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page)
-{
-	struct udsl_instance_data *instance = atm_dev->dev_data;
-	int left = *pos;
-
-	if (!instance) {
-		dbg ("NULL instance!");
-		return -ENODEV;
-	}
-
-	if (!left--)
-		return sprintf (page, "%s\n", instance->description);
-
-	if (!left--)
-		return sprintf (page, "MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
-				atm_dev->esi[0], atm_dev->esi[1], atm_dev->esi[2],
-				atm_dev->esi[3], atm_dev->esi[4], atm_dev->esi[5]);
-
-	if (!left--)
-		return sprintf (page, "AAL5: tx %d ( %d err ), rx %d ( %d err, %d drop )\n",
-				atomic_read (&atm_dev->stats.aal5.tx),
-				atomic_read (&atm_dev->stats.aal5.tx_err),
-				atomic_read (&atm_dev->stats.aal5.rx),
-				atomic_read (&atm_dev->stats.aal5.rx_err),
-				atomic_read (&atm_dev->stats.aal5.rx_drop));
-
-	if (!left--) {
-		switch (atm_dev->signal) {
-		case ATM_PHY_SIG_FOUND:
-			sprintf (page, "Line up");
-			break;
-		case ATM_PHY_SIG_LOST:
-			sprintf (page, "Line down");
-			break;
-		default:
-			sprintf (page, "Line state unknown");
-			break;
-		}
-
-		if (instance->usb_dev) {
-			if (!instance->firmware_loaded)
-				strcat (page, ", no firmware\n");
-			else
-				strcat (page, ", firmware loaded\n");
-		} else
-			strcat (page, ", disconnected\n");
-
-		return strlen (page);
-	}
-
-	return 0;
-}
-
-
-/***************************************************************************
-*
-* SAR driver entries
-*
-****************************************************************************/
-
-static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
-{
-	struct udsl_instance_data *instance = vcc->dev->dev_data;
-
-	dbg ("udsl_atm_open called");
-
-	if (!instance || !instance->usb_dev) {
-		dbg ("NULL data!");
-		return -ENODEV;
-	}
-
-	/* at the moment only AAL5 support */
-	if (vcc->qos.aal != ATM_AAL5)
-		return -EINVAL;
-
-	MOD_INC_USE_COUNT;
-
-	vcc->dev_data =
-	    atmsar_open (&(instance->atmsar_vcc_list), vcc, ATMSAR_TYPE_AAL5, vpi, vci, 0, 0,
-			 ATMSAR_USE_53BYTE_CELL | ATMSAR_SET_PTI);
-	if (!vcc->dev_data) {
-		MOD_DEC_USE_COUNT;
-		return -ENOMEM;	/* this is the only reason atmsar_open can fail... */
-	}
-
-	vcc->vpi = vpi;
-	vcc->vci = vci;
-	set_bit (ATM_VF_ADDR, &vcc->flags);
-	set_bit (ATM_VF_PARTIAL, &vcc->flags);
-	set_bit (ATM_VF_READY, &vcc->flags);
-
-	((struct atmsar_vcc_data *)vcc->dev_data)->mtu = UDSL_MAX_AAL5_MRU;
-
-	if (instance->firmware_loaded)
-		udsl_fire_receivers (instance);
-
-	dbg ("udsl_atm_open successful");
-	return 0;
-}
-
-static void udsl_atm_close (struct atm_vcc *vcc)
-{
-	struct udsl_instance_data *instance = vcc->dev->dev_data;
-
-	dbg ("udsl_atm_close called");
-
-	if (!instance) {
-		dbg ("NULL instance!");
-		return;
-	}
-
-	/* freeing resources */
-	/* cancel all sends on this vcc */
-	udsl_cancel_send (instance, vcc);
-
-	atmsar_close (&(instance->atmsar_vcc_list), vcc->dev_data);
-	vcc->dev_data = NULL;
-	clear_bit (ATM_VF_PARTIAL, &vcc->flags);
-
-	/* freeing address */
-	vcc->vpi = ATM_VPI_UNSPEC;
-	vcc->vci = ATM_VCI_UNSPEC;
-	clear_bit (ATM_VF_ADDR, &vcc->flags);
-
-	MOD_DEC_USE_COUNT;
-
-	dbg ("udsl_atm_close successful");
-	return;
-}
-
-static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg)
-{
-	switch (cmd) {
-	case ATM_QUERYLOOP:
-		return put_user (ATM_LM_NONE, (int *) arg) ? -EFAULT : 0;
-	default:
-		return -ENOIOCTLCMD;
-	}
-}
-
-
-/************
-**   USB   **
-************/
-
-static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data)
-{
-	struct udsl_instance_data *instance = usb_get_intfdata (intf);
-
-	dbg ("udsl_usb_ioctl entered");
-
-	if (!instance) {
-		dbg ("NULL instance!");
-		return -ENODEV;
-	}
-
-	switch (code) {
-	case UDSL_IOCTL_START:
-		instance->atm_dev->signal = ATM_PHY_SIG_FOUND;
-		down (&instance->serialize); /* vs self */
-		if (!instance->firmware_loaded) {
-			usb_set_interface (instance->usb_dev, 1, 1);
-			instance->firmware_loaded = 1;
-		}
-		up (&instance->serialize);
-		udsl_fire_receivers (instance);
-		return 0;
-	case UDSL_IOCTL_STOP:
-		instance->atm_dev->signal = ATM_PHY_SIG_LOST;
-		return 0;
-	default:
-		return -ENOTTY;
-	}
-}
-
-static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_id *id)
-{
-	struct usb_device *dev = interface_to_usbdev(intf);
-	int ifnum = intf->altsetting->desc.bInterfaceNumber;
-	struct udsl_instance_data *instance;
-	unsigned char mac_str [13];
-	int i, length;
-	char *buf;
-
-	dbg ("Trying device with Vendor=0x%x, Product=0x%x, ifnum %d",
-		dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum);
-
-	if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) ||
-	    (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) ||
-	    (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1))
-		return -ENODEV;
-
-	dbg ("Device Accepted");
-
-	/* instance init */
-	if (!(instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL))) {
-		dbg ("No memory for Instance data!");
-		return -ENOMEM;
-	}
-
-	memset (instance, 0, sizeof (struct udsl_instance_data));
-
-	init_MUTEX (&instance->serialize);
-
-	instance->usb_dev = dev;
-
-	spin_lock_init (&instance->spare_receivers_lock);
-	INIT_LIST_HEAD (&instance->spare_receivers);
-
-	spin_lock_init (&instance->completed_receivers_lock);
-	INIT_LIST_HEAD (&instance->completed_receivers);
-
-	tasklet_init (&instance->receive_tasklet, udsl_process_receive, (unsigned long) instance);
-
-	skb_queue_head_init (&instance->sndqueue);
-
-	spin_lock_init (&instance->send_lock);
-	INIT_LIST_HEAD (&instance->spare_senders);
-	INIT_LIST_HEAD (&instance->spare_buffers);
-
-	tasklet_init (&instance->send_tasklet, udsl_process_send, (unsigned long) instance);
-	INIT_LIST_HEAD (&instance->filled_buffers);
-
-	/* receive init */
-	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
-		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
-
-		if (!(rcv->skb = dev_alloc_skb (UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE))) {
-			dbg ("No memory for skb %d!", i);
-			goto fail;
-		}
-
-		if (!(rcv->urb = usb_alloc_urb (0, GFP_KERNEL))) {
-			dbg ("No memory for receive urb %d!", i);
-			goto fail;
-		}
-
-		rcv->instance = instance;
-
-		list_add (&rcv->list, &instance->spare_receivers);
-
-		dbg ("skb->truesize = %d (asked for %d)", rcv->skb->truesize, UDSL_RCV_BUFFER_SIZE * ATM_CELL_SIZE);
-	}
-
-	/* send init */
-	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) {
-		struct udsl_sender *snd = &(instance->all_senders[i]);
-
-		if (!(snd->urb = usb_alloc_urb (0, GFP_KERNEL))) {
-			dbg ("No memory for send urb %d!", i);
-			goto fail;
-		}
-
-		snd->instance = instance;
-
-		list_add (&snd->list, &instance->spare_senders);
-	}
-
-	for (i = 0; i < UDSL_NUMBER_SND_BUFS; i++) {
-		struct udsl_send_buffer *buf = &(instance->all_buffers[i]);
-
-		if (!(buf->base = kmalloc (UDSL_SND_BUFFER_SIZE * ATM_CELL_SIZE, GFP_KERNEL))) {
-			dbg ("No memory for send buffer %d!", i);
-			goto fail;
-		}
-
-		list_add (&buf->list, &instance->spare_buffers);
-	}
-
-	/* atm init */
-	if (!(instance->atm_dev = atm_dev_register (udsl_driver_name, &udsl_atm_devops, -1, 0))) {
-		dbg ("failed to register ATM device!");
-		goto fail;
-	}
-
-	instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
-	instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;
-	instance->atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
-
-	/* tmp init atm device, set to 128kbit */
-	instance->atm_dev->link_rate = 128 * 1000 / 424;
-
-	/* set MAC address, it is stored in the serial number */
-	memset (instance->atm_dev->esi, 0, sizeof (instance->atm_dev->esi));
-	if (usb_string (dev, dev->descriptor.iSerialNumber, mac_str, sizeof (mac_str)) == 12)
-		for (i = 0; i < 6; i++)
-			instance->atm_dev->esi[i] = (hex2int (mac_str[i * 2]) * 16) + (hex2int (mac_str[i * 2 + 1]));
-
-	/* device description */
-	buf = instance->description;
-	length = sizeof (instance->description);
-
-	if ((i = usb_string (dev, dev->descriptor.iProduct, buf, length)) < 0)
-		goto finish;
-
-	buf += i;
-	length -= i;
-
-	i = snprintf (buf, length, " (");
-	buf += i;
-	length -= i;
-
-	if (length <= 0 || (i = usb_make_path (dev, buf, length)) < 0)
-		goto finish;
-
-	buf += i;
-	length -= i;
-
-	snprintf (buf, length, ")");
-
-finish:
-	/* ready for ATM callbacks */
-	instance->atm_dev->dev_data = instance;
-
-	usb_set_intfdata (intf, instance);
-
-	return 0;
-
-fail:
-	for (i = 0; i < UDSL_NUMBER_SND_BUFS; i++)
-		kfree (instance->all_buffers[i].base);
-
-	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++)
-		usb_free_urb (instance->all_senders[i].urb);
-
-	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
-		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
-
-		usb_free_urb (rcv->urb);
-
-		if (rcv->skb)
-			kfree_skb (rcv->skb);
-	}
-
-	kfree (instance);
-
-	return -ENOMEM;
-}
-
-static void udsl_usb_disconnect (struct usb_interface *intf)
-{
-	struct udsl_instance_data *instance = usb_get_intfdata (intf);
-	struct list_head *pos;
-	unsigned long flags;
-	unsigned int count = 0;
-	int result, i;
-
-	dbg ("disconnecting");
-
-	usb_set_intfdata (intf, NULL);
-
-	if (!instance) {
-		dbg ("NULL instance!");
-		return;
-	}
-
-	tasklet_disable (&instance->receive_tasklet);
-
-	/* receive finalize */
-	down (&instance->serialize); /* vs udsl_fire_receivers */
-	/* no need to take the spinlock */
-	list_for_each (pos, &instance->spare_receivers)
-		if (++count > UDSL_NUMBER_RCV_URBS)
-			panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
-	INIT_LIST_HEAD (&instance->spare_receivers);
-	up (&instance->serialize);
-
-	dbg ("udsl_usb_disconnect: flushed %u spare receivers", count);
-
-	count = UDSL_NUMBER_RCV_URBS - count;
-
-	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++)
-		if ((result = usb_unlink_urb (instance->all_receivers[i].urb)) < 0)
-			dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d", i, result);
-
-	/* wait for completion handlers to finish */
-	do {
-		unsigned int completed = 0;
-
-		spin_lock_irqsave (&instance->completed_receivers_lock, flags);
-		list_for_each (pos, &instance->completed_receivers)
-			if (++completed > count)
-				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
-		spin_unlock_irqrestore (&instance->completed_receivers_lock, flags);
-
-		dbg ("udsl_usb_disconnect: found %u completed receivers", completed);
-
-		if (completed == count)
-			break;
-
-		yield ();
-	} while (1);
-
-	dbg ("udsl_usb_disconnect: flushing");
-	/* no need to take the spinlock */
-	INIT_LIST_HEAD (&instance->completed_receivers);
-
-	tasklet_enable (&instance->receive_tasklet);
-	tasklet_kill (&instance->receive_tasklet);
-
-	dbg ("udsl_usb_disconnect: freeing receivers");
-	for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) {
-		struct udsl_receiver *rcv = &(instance->all_receivers[i]);
-
-		usb_free_urb (rcv->urb);
-		kfree_skb (rcv->skb);
-	}
-
-	/* send finalize */
-	tasklet_disable (&instance->send_tasklet);
-
-	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++)
-		if ((result = usb_unlink_urb (instance->all_senders[i].urb)) < 0)
-			dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d", i, result);
-
-	/* wait for completion handlers to finish */
-	do {
-		count = 0;
-		spin_lock_irqsave (&instance->send_lock, flags);
-		list_for_each (pos, &instance->spare_senders)
-			if (++count > UDSL_NUMBER_SND_URBS)
-				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
-		spin_unlock_irqrestore (&instance->send_lock, flags);
-
-		dbg ("udsl_usb_disconnect: found %u spare senders", count);
-
-		if (count == UDSL_NUMBER_SND_URBS)
-			break;
-
-		yield ();
-	} while (1);
-
-	dbg ("udsl_usb_disconnect: flushing");
-	/* no need to take the spinlock */
-	INIT_LIST_HEAD (&instance->spare_senders);
-	INIT_LIST_HEAD (&instance->spare_buffers);
-	instance->current_buffer = NULL;
-
-	tasklet_enable (&instance->send_tasklet);
-
-	dbg ("udsl_usb_disconnect: freeing senders");
-	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++)
-		usb_free_urb (instance->all_senders[i].urb);
-
-	dbg ("udsl_usb_disconnect: freeing buffers");
-	for (i = 0; i < UDSL_NUMBER_SND_BUFS; i++)
-		kfree (instance->all_buffers[i].base);
-
-	instance->usb_dev = NULL;
-
-	/* atm finalize */
-	shutdown_atm_dev (instance->atm_dev); /* frees instance */
-}
-
-
-/***************************************************************************
-*
-* Driver Init
-*
-****************************************************************************/
-
-static int __init udsl_usb_init (void)
-{
-	struct sk_buff *skb; /* dummy for sizeof */
-
-	dbg ("udsl_usb_init: driver version " DRIVER_VERSION);
-
-	if (sizeof (struct udsl_control) > sizeof (skb->cb)) {
-		printk (KERN_ERR __FILE__ ": unusable with this kernel!\n");
-		return -EIO;
-	}
-
-	return usb_register (&udsl_usb_driver);
-}
-
-static void __exit udsl_usb_cleanup (void)
-{
-	dbg ("udsl_usb_cleanup");
-
-	usb_deregister (&udsl_usb_driver);
-}
-
-module_init (udsl_usb_init);
-module_exit (udsl_usb_cleanup);
-
-MODULE_AUTHOR (DRIVER_AUTHOR);
-MODULE_DESCRIPTION (DRIVER_DESC);
-MODULE_LICENSE ("GPL");
-
-
-#ifdef DEBUG_PACKET
-/*******************************************************************************
-*
-* Debug
-*
-*******************************************************************************/
-
-static int udsl_print_packet (const unsigned char *data, int len)
-{
-	unsigned char buffer [256];
-	int i = 0, j = 0;
-
-	for (i = 0; i < len;) {
-		buffer[0] = '\0';
-		sprintf (buffer, "%.3d :", i);
-		for (j = 0; (j < 16) && (i < len); j++, i++) {
-			sprintf (buffer, "%s %2.2x", buffer, data[i]);
-		}
-		dbg ("%s", buffer);
-	}
-	return i;
-}
-
-#endif				/* PACKETDEBUG */
diff -Nru a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c
--- a/drivers/usb/misc/tiglusb.c	Fri Dec 27 05:20:29 2002
+++ b/drivers/usb/misc/tiglusb.c	Sat Mar 22 07:38:04 2003
@@ -478,7 +478,7 @@
 	}
 
 	/* Use devfs, tree: /dev/ticables/usb/[0..3] */
-	devfs_mk_dir (NULL, "ticables/usb", NULL);
+	devfs_mk_dir ("ticables/usb");
 
 	/* register USB module */
 	result = usb_register (&tiglusb_driver);
diff -Nru a/drivers/usb/net/cdc-ether.c b/drivers/usb/net/cdc-ether.c
--- a/drivers/usb/net/cdc-ether.c	Fri Dec 27 05:19:31 2002
+++ b/drivers/usb/net/cdc-ether.c	Sun Mar 16 13:07:07 2003
@@ -1064,15 +1064,23 @@
 // Used by driver's probe routine ////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-void log_device_info(ether_dev_t *ether_dev)
+static void log_device_info(ether_dev_t *ether_dev)
 {
 	int len;
 	int string_num;
-	unsigned char manu[256];
-	unsigned char prod[256];
-	unsigned char sern[256];
+	unsigned char *manu = NULL;
+	unsigned char *prod = NULL;
+	unsigned char *sern = NULL;
 	unsigned char *mac_addr;
 
+	manu = kmalloc(256, GFP_KERNEL);
+	prod = kmalloc(256, GFP_KERNEL);
+	sern = kmalloc(256, GFP_KERNEL);
+	if (!manu || !prod || !sern) {
+		dbg("no mem for log_device_info");
+		goto fini;
+	}
+
 	// Default empty strings in case we don't find a real one
 	manu[0] = 0x00;
 	prod[0] = 0x00;
@@ -1113,6 +1121,10 @@
 	      ether_dev->net->name, manu, prod, sern, mac_addr[0], 
 	      mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], 
 	      mac_addr[5] );
+fini:
+	kfree(manu);
+	kfree(prod);
+	kfree(sern);
 }
 
 /* Forward declaration */
diff -Nru a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
--- a/drivers/usb/net/pegasus.c	Mon Jan  6 15:55:04 2003
+++ b/drivers/usb/net/pegasus.c	Thu Mar 20 05:54:04 2003
@@ -121,7 +121,7 @@
 	char *buffer;
 	DECLARE_WAITQUEUE(wait, current);
 
-	buffer = kmalloc(size, GFP_DMA);
+	buffer = kmalloc(size, GFP_KERNEL);
 	if (!buffer) {
 		warn("%s: looks like we're out of memory", __FUNCTION__);
 		return -ENOMEM;
@@ -170,7 +170,7 @@
 	char *buffer;
 	DECLARE_WAITQUEUE(wait, current);
 
-	buffer = kmalloc(size, GFP_DMA);
+	buffer = kmalloc(size, GFP_KERNEL);
 	if (!buffer) {
 		warn("%s: looks like we're out of memory", __FUNCTION__);
 		return -ENOMEM;
@@ -218,7 +218,7 @@
 	char *tmp;
 	DECLARE_WAITQUEUE(wait, current);
 
-	tmp = kmalloc(1, GFP_DMA);
+	tmp = kmalloc(1, GFP_KERNEL);
 	if (!tmp) {
 		warn("%s: looks like we're out of memory", __FUNCTION__);
 		return -ENOMEM;
diff -Nru a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
--- a/drivers/usb/serial/whiteheat.c	Tue Jan  7 07:45:05 2003
+++ b/drivers/usb/serial/whiteheat.c	Thu Mar 20 05:42:23 2003
@@ -783,7 +783,7 @@
 			if (info->mcr & UART_MCR_RTS)
 				modem_signals |= TIOCM_RTS;
 			
-			if (copy_to_user((unsigned int *)arg, &modem_signals, sizeof(unsigned int)));
+			if (copy_to_user((unsigned int *)arg, &modem_signals, sizeof(unsigned int)))
 				return -EFAULT;
 
 			break;
diff -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
--- a/drivers/usb/usb-skeleton.c	Thu Mar 13 10:36:03 2003
+++ b/drivers/usb/usb-skeleton.c	Thu Mar 20 05:59:24 2003
@@ -1,5 +1,5 @@
 /*
- * USB Skeleton driver - 0.9
+ * USB Skeleton driver - 1.0
  *
  * Copyright (c) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
  *
@@ -12,14 +12,17 @@
  * USB driver quickly.  The design of it is based on the usb-serial and
  * dc2xx drivers.
  *
- * Thanks to Oliver Neukum and David Brownell for their help in debugging
- * this driver.
+ * Thanks to Oliver Neukum, David Brownell, and Alan Stern for their help
+ * in debugging this driver.
  *
- * TODO:
- *	- fix urb->status race condition in write sequence
  *
  * History:
  *
+ * 2003-02-25 - 1.0 - fix races involving urb->status, unlink_urb(), and
+ *			disconnect.  Fix transfer amount in read().  Use
+ *			macros instead of magic numbers in probe().  Change
+ *			size variables to size_t.  Show how to eliminate
+ *			DMA bounce buffer.
  * 2002_12_12 - 0.9 - compile fixes and got rid of fixed minor array.
  * 2002_09_26 - 0.8 - changes due to USB core conversion to struct device
  *			driver.
@@ -33,7 +36,7 @@
  * 2001_05_29 - 0.3 - more bug fixes based on review from linux-usb-devel
  * 2001_05_24 - 0.2 - bug fixes based on review from linux-usb-devel people
  * 2001_05_01 - 0.1 - first version
- * 
+ *
  */
 
 #include <linux/config.h>
@@ -42,8 +45,8 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <linux/spinlock.h>
 #include <linux/smp_lock.h>
+#include <linux/completion.h>
 #include <linux/devfs_fs_kernel.h>
 #include <asm/uaccess.h>
 #include <linux/usb.h>
@@ -60,7 +63,7 @@
 
 
 /* Version Information */
-#define DRIVER_VERSION "v0.4"
+#define DRIVER_VERSION "v1.0"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com"
 #define DRIVER_DESC "USB Skeleton Driver"
 
@@ -101,15 +104,16 @@
 	char			num_bulk_out;		/* number of bulk out endpoints we have */
 
 	unsigned char *		bulk_in_buffer;		/* the buffer to receive data */
-	int			bulk_in_size;		/* the size of the receive buffer */
+	size_t			bulk_in_size;		/* the size of the receive buffer */
 	__u8			bulk_in_endpointAddr;	/* the address of the bulk in endpoint */
 
 	unsigned char *		bulk_out_buffer;	/* the buffer to send data */
-	int			bulk_out_size;		/* the size of the send buffer */
+	size_t			bulk_out_size;		/* the size of the send buffer */
 	struct urb *		write_urb;		/* the urb used to send data */
 	__u8			bulk_out_endpointAddr;	/* the address of the bulk out endpoint */
+	atomic_t		write_busy;		/* true iff write urb is busy */
+	struct completion	write_finished;		/* wait for the write to finish */
 
-	struct work_struct	work;			/* work queue entry for line discipline waking up */
 	int			open;			/* if the port is open or not */
 	struct semaphore	sem;			/* locks this structure */
 };
@@ -118,6 +122,8 @@
 /* the global usb devfs handle */
 extern devfs_handle_t usb_devfs_handle;
 
+/* prevent races between open() and disconnect() */
+static DECLARE_MUTEX (disconnect_sem);
 
 /* local function prototypes */
 static ssize_t skel_read	(struct file *file, char *buffer, size_t count, loff_t *ppos);
@@ -125,7 +131,7 @@
 static int skel_ioctl		(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
 static int skel_open		(struct inode *inode, struct file *file);
 static int skel_release		(struct inode *inode, struct file *file);
-	
+
 static int skel_probe		(struct usb_interface *intf, const struct usb_device_id *id);
 static void skel_disconnect	(struct usb_interface *intf);
 
@@ -138,7 +144,7 @@
  * to have a node in the /dev directory. If the USB
  * device were for a network interface then the driver
  * would use "struct net_driver" instead, and a serial
- * device would use "struct tty_driver". 
+ * device would use "struct tty_driver".
  */
 static struct file_operations skel_fops = {
 	/*
@@ -167,7 +173,7 @@
 	.ioctl =	skel_ioctl,
 	.open =		skel_open,
 	.release =	skel_release,
-};      
+};
 
 
 /* usb specific object needed to register this driver with the usb subsystem */
@@ -188,8 +194,8 @@
 
 	if (!debug)
 		return;
-	
-	printk (KERN_DEBUG __FILE__": %s - length = %d, data = ", 
+
+	printk (KERN_DEBUG __FILE__": %s - length = %d, data = ",
 		function, size);
 	for (i = 0; i < size; ++i) {
 		printk ("%.2x ", data[i]);
@@ -206,7 +212,9 @@
 	if (dev->bulk_in_buffer != NULL)
 		kfree (dev->bulk_in_buffer);
 	if (dev->bulk_out_buffer != NULL)
-		kfree (dev->bulk_out_buffer);
+		usb_buffer_free (dev->udev, dev->bulk_out_size,
+				dev->bulk_out_buffer,
+				dev->write_urb->transfer_dma);
 	if (dev->write_urb != NULL)
 		usb_free_urb (dev->write_urb);
 	kfree (dev);
@@ -222,22 +230,28 @@
 	struct usb_interface *interface;
 	int subminor;
 	int retval = 0;
-	
+
 	dbg("%s", __FUNCTION__);
 
 	subminor = minor (inode->i_rdev);
 
+	/* prevent disconnects */
+	down (&disconnect_sem);
+
 	interface = usb_find_interface (&skel_driver,
 					mk_kdev(USB_MAJOR, subminor));
 	if (!interface) {
 		err ("%s - error, can't find device for minor %d",
 		     __FUNCTION__, subminor);
-		return -ENODEV;
+		retval = -ENODEV;
+		goto exit_no_device;
 	}
-			
+
 	dev = usb_get_intfdata(interface);
-	if (!dev)
-		return -ENODEV;
+	if (!dev) {
+		retval = -ENODEV;
+		goto exit_no_device;
+	}
 
 	/* lock this device */
 	down (&dev->sem);
@@ -251,6 +265,8 @@
 	/* unlock this device */
 	up (&dev->sem);
 
+exit_no_device:
+	up (&disconnect_sem);
 	return retval;
 }
 
@@ -280,6 +296,12 @@
 		goto exit_not_opened;
 	}
 
+	/* wait for any bulk writes that might be going on to finish up */
+	if (atomic_read (&dev->write_busy))
+		wait_for_completion (&dev->write_finished);
+
+	dev->open = 0;
+
 	if (dev->udev == NULL) {
 		/* the device was unplugged before the file was released */
 		up (&dev->sem);
@@ -287,11 +309,6 @@
 		return 0;
 	}
 
-	/* shutdown any bulk writes that might be going on */
-	usb_unlink_urb (dev->write_urb);
-
-	dev->open = 0;
-
 exit_not_opened:
 	up (&dev->sem);
 
@@ -308,7 +325,7 @@
 	int retval = 0;
 
 	dev = (struct usb_skel *)file->private_data;
-	
+
 	dbg("%s - minor %d, count = %d", __FUNCTION__, dev->minor, count);
 
 	/* lock this object */
@@ -319,12 +336,13 @@
 		up (&dev->sem);
 		return -ENODEV;
 	}
-	
-	/* do an immediate bulk read to get data from the device */
+
+	/* do a blocking bulk read to get data from the device */
 	retval = usb_bulk_msg (dev->udev,
-			       usb_rcvbulkpipe (dev->udev, 
+			       usb_rcvbulkpipe (dev->udev,
 						dev->bulk_in_endpointAddr),
-			       dev->bulk_in_buffer, dev->bulk_in_size,
+			       dev->bulk_in_buffer,
+			       min (dev->bulk_in_size, count),
 			       &count, HZ*10);
 
 	/* if the read was successful, copy the data to userspace */
@@ -334,7 +352,7 @@
 		else
 			retval = count;
 	}
-	
+
 	/* unlock the device */
 	up (&dev->sem);
 	return retval;
@@ -343,6 +361,18 @@
 
 /**
  *	skel_write
+ *
+ *	A device driver has to decide how to report I/O errors back to the
+ *	user.  The safest course is to wait for the transfer to finish before
+ *	returning so that any errors will be reported reliably.  skel_read()
+ *	works like this.  But waiting for I/O is slow, so many drivers only
+ *	check for errors during I/O initiation and do not report problems
+ *	that occur during the actual transfer.  That's what we will do here.
+ *
+ *	A driver concerned with maximum I/O throughput would use double-
+ *	buffering:  Two urbs would be devoted to write transfers, so that
+ *	one urb could always be active while the other was waiting for the
+ *	user to send more data.
  */
 static ssize_t skel_write (struct file *file, const char *buffer, size_t count, loff_t *ppos)
 {
@@ -369,37 +399,38 @@
 		goto exit;
 	}
 
-	/* see if we are already in the middle of a write */
-	if (dev->write_urb->status == -EINPROGRESS) {
-		dbg ("%s - already writing", __FUNCTION__);
-		goto exit;
-	}
+	/* wait for a previous write to finish up; we don't use a timeout
+	 * and so a nonresponsive device can delay us indefinitely.
+	 */
+	if (atomic_read (&dev->write_busy))
+		wait_for_completion (&dev->write_finished);
 
-	/* we can only write as much as 1 urb will hold */
-	bytes_written = (count > dev->bulk_out_size) ? 
-				dev->bulk_out_size : count;
+	/* we can only write as much as our buffer will hold */
+	bytes_written = min (dev->bulk_out_size, count);
 
-	/* copy the data from userspace into our urb */
-	if (copy_from_user(dev->write_urb->transfer_buffer, buffer, 
+	/* copy the data from userspace into our transfer buffer;
+	 * this is the only copy required.
+	 */
+	if (copy_from_user(dev->write_urb->transfer_buffer, buffer,
 			   bytes_written)) {
 		retval = -EFAULT;
 		goto exit;
 	}
 
-	usb_skel_debug_data (__FUNCTION__, bytes_written, 
+	usb_skel_debug_data (__FUNCTION__, bytes_written,
 			     dev->write_urb->transfer_buffer);
 
-	/* set up our urb */
-	usb_fill_bulk_urb(dev->write_urb, dev->udev, 
-		      usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
-		      dev->write_urb->transfer_buffer, bytes_written,
-		      skel_write_bulk_callback, dev);
+	/* this urb was already set up, except for this write size */
+	dev->write_urb->transfer_buffer_length = bytes_written;
 
 	/* send the data out the bulk port */
 	/* a character device write uses GFP_KERNEL,
 	 unless a spinlock is held */
+	init_completion (&dev->write_finished);
+	atomic_set (&dev->write_busy, 1);
 	retval = usb_submit_urb(dev->write_urb, GFP_KERNEL);
 	if (retval) {
+		atomic_set (&dev->write_busy, 0);
 		err("%s - failed submitting write urb, error %d",
 		    __FUNCTION__, retval);
 	} else {
@@ -435,12 +466,11 @@
 	dbg("%s - minor %d, cmd 0x%.4x, arg %ld", __FUNCTION__,
 	    dev->minor, cmd, arg);
 
-
 	/* fill in your device specific stuff here */
-	
+
 	/* unlock the device */
 	up (&dev->sem);
-	
+
 	/* return that we did not understand this ioctl call */
 	return -ENOTTY;
 }
@@ -455,14 +485,16 @@
 
 	dbg("%s - minor %d", __FUNCTION__, dev->minor);
 
-	if ((urb->status != -ENOENT) && 
-	    (urb->status != -ECONNRESET)) {
+	/* sync/async unlink faults aren't errors */
+	if (urb->status && !(urb->status == -ENOENT ||
+				urb->status == -ECONNRESET)) {
 		dbg("%s - nonzero write bulk status received: %d",
 		    __FUNCTION__, urb->status);
-		return;
 	}
 
-	return;
+	/* notify anyone waiting that the write has finished */
+	atomic_set (&dev->write_busy, 0);
+	complete (&dev->write_finished);
 }
 
 
@@ -479,12 +511,12 @@
 	struct usb_host_interface *iface_desc;
 	struct usb_endpoint_descriptor *endpoint;
 	int minor;
-	int buffer_size;
+	size_t buffer_size;
 	int i;
 	int retval;
 	char name[10];
 
-	
+
 	/* See if the device offered us matches what we can accept */
 	if ((udev->descriptor.idVendor != USB_SKEL_VENDOR_ID) ||
 	    (udev->descriptor.idProduct != USB_SKEL_PRODUCT_ID)) {
@@ -513,12 +545,15 @@
 
 	/* set up the endpoint information */
 	/* check out the endpoints */
+	/* use only the first bulk-in and bulk-out endpoints */
 	iface_desc = &interface->altsetting[0];
 	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
 		endpoint = &iface_desc->endpoint[i].desc;
 
-		if ((endpoint->bEndpointAddress & 0x80) &&
-		    ((endpoint->bmAttributes & 3) == 0x02)) {
+		if (!dev->bulk_in_endpointAddr &&
+		    (endpoint->bEndpointAddress & USB_DIR_IN) &&
+		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+					== USB_ENDPOINT_XFER_BULK)) {
 			/* we found a bulk in endpoint */
 			buffer_size = endpoint->wMaxPacketSize;
 			dev->bulk_in_size = buffer_size;
@@ -529,9 +564,11 @@
 				goto error;
 			}
 		}
-		
-		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
-		    ((endpoint->bmAttributes & 3) == 0x02)) {
+
+		if (!dev->bulk_out_endpointAddr &&
+		    !(endpoint->bEndpointAddress & USB_DIR_IN) &&
+		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+					== USB_ENDPOINT_XFER_BULK)) {
 			/* we found a bulk out endpoint */
 			/* a probe() may sleep and has no restrictions on memory allocations */
 			dev->write_urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -539,40 +576,56 @@
 				err("No free urbs available");
 				goto error;
 			}
+			dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
+
+			/* on some platforms using this kind of buffer alloc
+			 * call eliminates a dma "bounce buffer".
+			 *
+			 * NOTE: you'd normally want i/o buffers that hold
+			 * more than one packet, so that i/o delays between
+			 * packets don't hurt throughput.
+			 */
 			buffer_size = endpoint->wMaxPacketSize;
 			dev->bulk_out_size = buffer_size;
-			dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
-			dev->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
+			dev->write_urb->transfer_flags = (URB_NO_DMA_MAP |
+					URB_ASYNC_UNLINK);
+			dev->bulk_out_buffer = usb_buffer_alloc (udev,
+					buffer_size, GFP_KERNEL,
+					&dev->write_urb->transfer_dma);
 			if (!dev->bulk_out_buffer) {
 				err("Couldn't allocate bulk_out_buffer");
 				goto error;
 			}
-			usb_fill_bulk_urb(dev->write_urb, udev, 
-				      usb_sndbulkpipe(udev, 
+			usb_fill_bulk_urb(dev->write_urb, udev,
+				      usb_sndbulkpipe(udev,
 						      endpoint->bEndpointAddress),
 				      dev->bulk_out_buffer, buffer_size,
 				      skel_write_bulk_callback, dev);
 		}
 	}
+	if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
+		err("Couldn't find both bulk-in and bulk-out endpoints");
+		goto error;
+	}
 
 	/* initialize the devfs node for this device and register it */
 	sprintf(name, "skel%d", dev->minor);
-	
+
 	dev->devfs = devfs_register (usb_devfs_handle, name,
 				     DEVFS_FL_DEFAULT, USB_MAJOR,
 				     dev->minor,
-				     S_IFCHR | S_IRUSR | S_IWUSR | 
-				     S_IRGRP | S_IWGRP | S_IROTH, 
+				     S_IFCHR | S_IRUSR | S_IWUSR |
+				     S_IRGRP | S_IWGRP | S_IROTH,
 				     &skel_fops, NULL);
 
 	/* let the user know what node this device is now attached to */
-	info ("USB Skeleton device now attached to USBSkel%d", dev->minor);
+	info ("USB Skeleton device now attached to USBSkel-%d", dev->minor);
 
 	/* add device id so the device works when advertised */
 	interface->kdev = mk_kdev(USB_MAJOR, dev->minor);
 
 	goto exit;
-	
+
 error:
 	skel_delete (dev);
 	dev = NULL;
@@ -593,12 +646,21 @@
  *	skel_disconnect
  *
  *	Called by the usb core when the device is removed from the system.
+ *
+ *	This routine guarantees that the driver will not submit any more urbs
+ *	by clearing dev->udev.  It is also supposed to terminate any currently
+ *	active urbs.  Unfortunately, usb_bulk_msg(), used in skel_read(), does
+ *	not provide any way to do this.  But at least we can cancel an active
+ *	write.
  */
 static void skel_disconnect(struct usb_interface *interface)
 {
 	struct usb_skel *dev;
 	int minor;
 
+	/* prevent races with open() */
+	down (&disconnect_sem);
+
 	dev = usb_get_intfdata (interface);
 	usb_set_intfdata (interface, NULL);
 
@@ -606,7 +668,7 @@
 		return;
 
 	down (&dev->sem);
-		
+
 	/* remove device id to disable open() */
 	interface->kdev = NODEV;
 
@@ -617,15 +679,21 @@
 
 	/* give back our dynamic minor */
 	usb_deregister_dev (1, minor);
-	
+
+	/* terminate an ongoing write */
+	if (atomic_read (&dev->write_busy)) {
+		usb_unlink_urb (dev->write_urb);
+		wait_for_completion (&dev->write_finished);
+	}
+
+	dev->udev = NULL;
+	up (&dev->sem);
+
 	/* if the device is not opened, then we clean up right now */
-	if (!dev->open) {
-		up (&dev->sem);
+	if (!dev->open)
 		skel_delete (dev);
-	} else {
-		dev->udev = NULL;
-		up (&dev->sem);
-	}
+
+	up (&disconnect_sem);
 
 	info("USB Skeleton #%d now disconnected", minor);
 }
@@ -668,4 +736,3 @@
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
-
diff -Nru a/drivers/video/Kconfig b/drivers/video/Kconfig
--- a/drivers/video/Kconfig	Sun Mar  2 23:19:23 2003
+++ b/drivers/video/Kconfig	Mon Mar 10 13:46:08 2003
@@ -38,7 +38,7 @@
 	  (e.g. an accelerated X server) and that are not frame buffer
 	  device-aware may cause unexpected results. If unsure, say N.
 
-config FB_CLGEN
+config FB_CIRRUS
 	tristate "Cirrus Logic support"
 	depends on FB && (AMIGA || PCI)
 	---help---
@@ -48,7 +48,7 @@
 	  If you have a PCI-based system, this enables support for these
 	  chips: GD-543x, GD-544x, GD-5480.
 
-	  Please read the file <file:Documentation/fb/clgenfb.txt>.
+	  Please read the file <file:Documentation/fb/cirrusfb.txt>.
 
 	  Say N unless you have such a graphics board or plan to get one
 	  before you next recompile the kernel.
@@ -282,7 +282,7 @@
 	  If you have a S3 Trio say Y. Say N for S3 Virge.
 
 config FB_VGA16
-	tristate "VGA 16-color graphics console"
+	tristate "VGA 16-color graphics support"
 	depends on FB && (X86 || PPC)
 	help
 	  This is the frame buffer device driver for VGA 16 color graphic
@@ -329,7 +329,7 @@
 	  cards. Say Y if you have one of those.
 
 config FB_VESA
-	bool "VESA VGA graphics console"
+	bool "VESA VGA graphics support"
 	depends on FB && (X86 || X86_64)
 	help
 	  This is the frame buffer device driver for generic VESA 2.0
@@ -343,7 +343,7 @@
 	default y
 
 config FB_HGA
-	tristate "Hercules mono graphics console"
+	tristate "Hercules mono graphics support"
 	depends on FB && X86
 	help
 	  Say Y here if you have a Hercules mono graphics card.
@@ -715,6 +715,12 @@
 	  is at
 	  <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
 
+config FB_ATY_XL_INIT
+	bool "  Rage XL No-BIOS Init support" if FB_ATY_CT
+	depends on FB_ATY
+	help
+	  Say Y here to support booting a Rage XL without BIOS support.
+
 config FB_SIS
 	tristate "SIS acceleration"
 	depends on FB && PCI
@@ -921,8 +927,13 @@
 	  say M here and read <file:Documentation/modules.txt>.
 
 	  If unsure, say N.
-
-source "drivers/video/console/Kconfig"
+if VT
+	source "drivers/video/console/Kconfig"
+endif
+
+if FB || SGI_NEWPORT_CONSOLE
+	source "drivers/video/logo/Kconfig"
+endif
 
 endmenu
 
diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile
--- a/drivers/video/Makefile	Tue Mar 11 05:57:06 2003
+++ b/drivers/video/Makefile	Fri Mar 21 14:20:23 2003
@@ -5,6 +5,7 @@
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_VT)		  += console/
+obj-$(CONFIG_LOGO)		  += logo/
 
 obj-$(CONFIG_FB)                  += fbmem.o fbmon.o fbcmap.o modedb.o softcursor.o
 # Only include macmodes.o if we have FB support and are PPC
@@ -13,14 +14,13 @@
 endif
 
 obj-$(CONFIG_FB_ACORN)            += acornfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_AMIGA)            += amifb.o
+obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p.o
 obj-$(CONFIG_FB_PM2)              += pm2fb.o
 obj-$(CONFIG_FB_PM3)		  += pm3fb.o
 obj-$(CONFIG_FB_APOLLO)           += dnfb.o cfbfillrect.o cfbimgblt.o
 obj-$(CONFIG_FB_Q40)              += q40fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_ATARI)            += atafb.o
 obj-$(CONFIG_FB_68328)            += 68328fb.o
-obj-$(CONFIG_FB_ATY128)           += aty128fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_RADEON)		  += radeonfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_NEOMAGIC)         += neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_IGA)              += igafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
@@ -37,9 +37,9 @@
 obj-$(CONFIG_FB_MAC)              += macfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
 obj-$(CONFIG_FB_HP300)            += hpfb.o cfbfillrect.o cfbimgblt.o
 obj-$(CONFIG_FB_OF)               += offb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o
-obj-$(CONFIG_FB_IMSTT)            += imsttfb.o
+obj-$(CONFIG_FB_IMSTT)            += imsttfb.o cfbimgblt.o
 obj-$(CONFIG_FB_RETINAZ3)         += retz3fb.o
-obj-$(CONFIG_FB_CLGEN)            += clgenfb.o
+obj-$(CONFIG_FB_CIRRUS)		  += cirrusfb.o
 obj-$(CONFIG_FB_TRIDENT)	  += tridentfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o
 obj-$(CONFIG_FB_S3TRIO)           += S3triofb.o
 obj-$(CONFIG_FB_TGA)              += tgafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
@@ -57,8 +57,9 @@
 
 obj-$(CONFIG_FB_MATROX)		  += matrox/
 obj-$(CONFIG_FB_RIVA)		  += riva/ cfbimgblt.o vgastate.o 
-obj-$(CONFIG_FB_SIS)		  += sis/
-obj-$(CONFIG_FB_ATY)		  += aty/ cfbimgblt.o cfbfillrect.o cfbimgblt.o
+obj-$(CONFIG_FB_SIS)		  += sis/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o
+obj-$(CONFIG_FB_ATY)		  += aty/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o
+obj-$(CONFIG_FB_ATY128)		  += aty/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o
 obj-$(CONFIG_FB_I810)             += i810/ cfbfillrect.o cfbcopyarea.o \
 	                             cfbimgblt.o vgastate.o
 
@@ -85,12 +86,4 @@
 				      cfbfillrect.o
 obj-$(CONFIG_FB_LEO)               += leo.o sbuslib.o cfbimgblt.o cfbcopyarea.o \
 				      cfbfillrect.o
-
-# Files generated that shall be removed upon make clean
-clean-files := promcon_tbl.c
-
-$(obj)/promcon_tbl.c: $(src)/prom.uni
-	$(objtree)/scripts/conmakehash $< | \
-	sed -e '/#include <[^>]*>/p' -e 's/types/init/' \
-	    -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > $@
 
diff -Nru a/drivers/video/amifb.c b/drivers/video/amifb.c
--- a/drivers/video/amifb.c	Mon Feb 24 12:16:14 2003
+++ b/drivers/video/amifb.c	Fri Mar 21 14:13:56 2003
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/video/amifb.c -- Amiga builtin chipset frame buffer device
  *
- *    Copyright (C) 1995 Geert Uytterhoeven
+ *    Copyright (C) 1995-2003 Geert Uytterhoeven
  *
  *          with work by Roman Zippel
  *
@@ -52,7 +52,6 @@
 #include <linux/interrupt.h>
 #include <linux/fb.h>
 #include <linux/init.h>
-#include <linux/console.h>
 #include <linux/ioport.h>
 
 #include <asm/uaccess.h>
@@ -62,10 +61,7 @@
 #include <asm/amigaints.h>
 #include <asm/setup.h>
 
-#include <video/fbcon.h>
-#include <video/fbcon-afb.h>
-#include <video/fbcon-ilbm.h>
-#include <video/fbcon-mfb.h>
+#include "c2p.h"
 
 
 #define DEBUG
@@ -613,12 +609,11 @@
 
 #define SPRITEMEMSIZE		(64*64/4) /* max 64*64*4 */
 #define DUMMYSPRITEMEMSIZE	(8)
+static u_long spritememory;
 
 #define CHIPRAM_SAFETY_LIMIT	(16384)
 
-static u_long videomemory, spritememory;
-static u_long videomemorysize;
-static u_long videomemory_phys;
+static u_long videomemory;
 
 	/*
 	 * This is the earliest allowed start of fetching display data.
@@ -660,6 +655,47 @@
 static u_short currentcop = 0;
 
 	/*
+	 * Hardware Cursor API Definitions
+	 * These used to be in linux/fb.h, but were preliminary and used by
+	 * amifb only anyway
+	 */
+
+#define FBIOGET_FCURSORINFO     0x4607
+#define FBIOGET_VCURSORINFO     0x4608
+#define FBIOPUT_VCURSORINFO     0x4609
+#define FBIOGET_CURSORSTATE     0x460A
+#define FBIOPUT_CURSORSTATE     0x460B
+
+
+struct fb_fix_cursorinfo {
+	__u16 crsr_width;		/* width and height of the cursor in */
+	__u16 crsr_height;		/* pixels (zero if no cursor)	*/
+	__u16 crsr_xsize;		/* cursor size in display pixels */
+	__u16 crsr_ysize;
+	__u16 crsr_color1;		/* colormap entry for cursor color1 */
+	__u16 crsr_color2;		/* colormap entry for cursor color2 */
+};
+
+struct fb_var_cursorinfo {
+	__u16 width;
+	__u16 height;
+	__u16 xspot;
+	__u16 yspot;
+	__u8 data[1];			/* field with [height][width]        */
+};
+
+struct fb_cursorstate {
+	__s16 xoffset;
+	__s16 yoffset;
+	__u16 mode;
+};
+
+#define FB_CURSOR_OFF		0
+#define FB_CURSOR_ON		1
+#define FB_CURSOR_FLASH		2
+
+
+	/*
 	 * Hardware Cursor
 	 */
 
@@ -738,28 +774,28 @@
 	u_short fmode;		/* vmode */
 } currentpar;
 
-static struct display disp;
 
-static struct fb_info fb_info;
+static struct fb_info fb_info = {
+    .fix = {
+	.id		= "Amiga ",
+	.visual		= FB_VISUAL_PSEUDOCOLOR,
+	.accel		= FB_ACCEL_AMIGABLITT
+    }
+};
 
 
 	/*
-	 * Since we can't read the palette on OCS/ECS, and since reading one
-	 * single color palette entry requires 5 expensive custom chip bus accesses
-	 * on AGA, we keep a copy of the current palette.
-	 * Note that the entries are always 24 bit!
+	 *  Saved color entry 0 so we can restore it when unblanking
 	 */
 
-#if defined(CONFIG_FB_AMIGA_AGA)
-static struct { u_char red, green, blue, pad; } palette[256];
-#else
-static struct { u_char red, green, blue, pad; } palette[32];
-#endif
+static u_char red0, green0, blue0;
+
 
 #if defined(CONFIG_FB_AMIGA_ECS)
 static u_short ecs_palette[32];
 #endif
 
+
 	/*
 	 * Latches for Display Changes during VBlank
 	 */
@@ -778,15 +814,6 @@
 static u_short is_lace = 0;		/* Screen is laced */
 
 	/*
-	 * Frame Buffer Name
-	 *
-	 * The rest of the name is filled in during initialization
-	 */
-
-static char amifb_name[16] = "Amiga ";
-
-
-	/*
 	 * Predefined Video Modes
 	 *
 	 */
@@ -1087,29 +1114,22 @@
 
 int amifb_setup(char*);
 
-static int amifb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			 struct fb_info *info);
-static int amifb_get_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info);
-static int amifb_set_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info);
-static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                           u_int transp, struct fb_info *info);
+static int amifb_check_var(struct fb_var_screeninfo *var,
+			   struct fb_info *info);
+static int amifb_set_par(struct fb_info *info);
+static int amifb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp,
+			   struct fb_info *info);
 static int amifb_blank(int blank, struct fb_info *info);
-static int amifb_pan_display(struct fb_var_screeninfo *var, int con,
+static int amifb_pan_display(struct fb_var_screeninfo *var,
 			     struct fb_info *info);
-static int amifb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info);
-static int amifb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-		       u_long arg, int con, struct fb_info *info);
-
-static int amifb_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con);
-static int amifb_get_var_cursorinfo(struct fb_var_cursorinfo *var,
-				       u_char *data, int con);
-static int amifb_set_var_cursorinfo(struct fb_var_cursorinfo *var,
-				       u_char *data, int con);
-static int amifb_get_cursorstate(struct fb_cursorstate *state, int con);
-static int amifb_set_cursorstate(struct fb_cursorstate *state, int con);
+static void amifb_fillrect(struct fb_info *info, struct fb_fillrect *rect);
+static void amifb_copyarea(struct fb_info *info, struct fb_copyarea *region);
+static void amifb_imageblit(struct fb_info *info, struct fb_image *image);
+static int amifb_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg,
+		       struct fb_info *info);
+
 
 	/*
 	 * Interface to the low level console driver
@@ -1117,8 +1137,6 @@
 
 int amifb_init(void);
 static void amifb_deinit(void);
-static int amifbcon_switch(int con, struct fb_info *info);
-static int amifbcon_updatevar(int con, struct fb_info *info);
 
 	/*
 	 * Internal routines
@@ -1133,29 +1151,20 @@
 	 * Hardware routines
 	 */
 
-static int ami_encode_fix(struct fb_fix_screeninfo *fix,
-                          struct amifb_par *par);
 static int ami_decode_var(struct fb_var_screeninfo *var,
                           struct amifb_par *par);
 static int ami_encode_var(struct fb_var_screeninfo *var,
                           struct amifb_par *par);
-static void ami_get_par(struct amifb_par *par);
-static void ami_set_var(struct fb_var_screeninfo *var);
-#ifdef DEBUG
-static void ami_set_par(struct amifb_par *par);
-#endif
 static void ami_pan_var(struct fb_var_screeninfo *var);
 static int ami_update_par(void);
-static int ami_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp, struct fb_info *info);
 static void ami_update_display(void);
 static void ami_init_display(void);
 static void ami_do_blank(void);
-static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con);
-static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con);
-static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con);
-static int ami_get_cursorstate(struct fb_cursorstate *state, int con);
-static int ami_set_cursorstate(struct fb_cursorstate *state, int con);
+static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix);
+static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data);
+static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data);
+static int ami_get_cursorstate(struct fb_cursorstate *state);
+static int ami_set_cursorstate(struct fb_cursorstate *state);
 static void ami_set_sprite(void);
 static void ami_init_copper(void);
 static void ami_reinit_copper(void);
@@ -1165,14 +1174,15 @@
 
 static struct fb_ops amifb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_get_fix	= amifb_get_fix,
-	.fb_get_var	= amifb_get_var,
-	.fb_set_var	= amifb_set_var,
-	.fb_get_cmap	= amifb_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
+	.fb_check_var	= amifb_check_var,
+	.fb_set_par	= amifb_set_par,
 	.fb_setcolreg	= amifb_setcolreg,
-	.fb_pan_display	= amifb_pan_display,
 	.fb_blank	= amifb_blank,
+	.fb_pan_display	= amifb_pan_display,
+	.fb_fillrect	= amifb_fillrect,
+	.fb_copyarea	= amifb_copyarea,
+	.fb_imageblit	= amifb_imageblit,
+	.fb_cursor	= soft_cursor,
 	.fb_ioctl	= amifb_ioctl,
 };
 
@@ -1217,8 +1227,6 @@
 {
 	char *this_opt;
 
-	fb_info.fontname[0] = '\0';
-
 	if (!options || !*options)
 		return 0;
 
@@ -1234,8 +1242,6 @@
 			amifb_ilbm = 1;
 		else if (!strncmp(this_opt, "monitorcap:", 11))
 			amifb_setup_mcap(this_opt+11);
-		else if (!strncmp(this_opt, "font:", 5))
-			strcpy(fb_info.fontname, this_opt+5);
 		else if (!strncmp(this_opt, "fstart:", 7))
 			min_fstrt = simple_strtoul(this_opt+7, NULL, 0);
 		else
@@ -1248,293 +1254,975 @@
 	return 0;
 }
 
-	/*
-	 * Get the Fixed Part of the Display
-	 */
 
-static int amifb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			 struct fb_info *info)
+static int amifb_check_var(struct fb_var_screeninfo *var,
+			   struct fb_info *info)
 {
+	int err;
 	struct amifb_par par;
 
-	if (con == -1)
-		ami_get_par(&par);
-	else {
-		int err;
+	/* Validate wanted screen parameters */
+	if ((err = ami_decode_var(var, &par)))
+		return err;
 
-		if ((err = ami_decode_var(&fb_display[con].var, &par)))
-			return err;
-	}
-	return ami_encode_fix(fix, &par);
+	/* Encode (possibly rounded) screen parameters */
+	ami_encode_var(var, &par);
+	return 0;
 }
 
-	/*
-	 * Get the User Defined Part of the Display
-	 */
 
-static int amifb_get_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info)
+static int amifb_set_par(struct fb_info *info)
 {
-	int err = 0;
-
-	if (con == -1) {
-		struct amifb_par par;
+	struct amifb_par *par = (struct amifb_par *)info->par;
 
-		ami_get_par(&par);
-		err = ami_encode_var(var, &par);
-	} else
-		*var = fb_display[con].var;
-	return err;
-}
-
-	/*
-	 * Set the User Defined Part of the Display
-	 */
+	do_vmode_pan = 0;
+	do_vmode_full = 0;
 
-static int amifb_set_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info)
-{
-	int err, activate = var->activate;
-	int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
-	struct amifb_par par;
+	/* Decode wanted screen parameters */
+	ami_decode_var(&info->var, par);
 
-	struct display *display;
-	if (con >= 0)
-		display = &fb_display[con];
-	else
-		display = &disp;	/* used during initialization */
+	/* Set new videomode */
+	ami_build_copper();
 
-	/*
-	 * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
-	 * as FB_VMODE_SMOOTH_XPAN is only used internally
-	 */
+	/* Set VBlank trigger */
+	do_vmode_full = 1;
 
-	if (var->vmode & FB_VMODE_CONUPDATE) {
-		var->vmode |= FB_VMODE_YWRAP;
-		var->xoffset = display->var.xoffset;
-		var->yoffset = display->var.yoffset;
+	/* Update fix for new screen parameters */
+	if (par->bpp == 1) {
+		info->fix.type = FB_TYPE_PACKED_PIXELS;
+		info->fix.type_aux = 0;
+	} else if (amifb_ilbm) {
+		info->fix.type = FB_TYPE_INTERLEAVED_PLANES;
+		info->fix.type_aux = par->next_line;
+	} else {
+		info->fix.type = FB_TYPE_PLANES;
+		info->fix.type_aux = 0;
 	}
-	if ((err = ami_decode_var(var, &par)))
-		return err;
-	ami_encode_var(var, &par);
-	if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
-		oldxres = display->var.xres;
-		oldyres = display->var.yres;
-		oldvxres = display->var.xres_virtual;
-		oldvyres = display->var.yres_virtual;
-		oldbpp = display->var.bits_per_pixel;
-		display->var = *var;
-		if (oldxres != var->xres || oldyres != var->yres ||
-		    oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
-		    oldbpp != var->bits_per_pixel) {
-			struct fb_fix_screeninfo fix;
-
-			ami_encode_fix(&fix, &par);
-			display->visual = fix.visual;
-			display->type = fix.type;
-			display->type_aux = fix.type_aux;
-			display->ypanstep = fix.ypanstep;
-			display->ywrapstep = fix.ywrapstep;
-			display->line_length = fix.line_length;
-			display->can_soft_blank = 1;
-			display->inverse = amifb_inverse;
-			switch (fix.type) {
-#ifdef FBCON_HAS_ILBM
-			    case FB_TYPE_INTERLEAVED_PLANES:
-				display->dispsw = &fbcon_ilbm;
-				break;
-#endif
-#ifdef FBCON_HAS_AFB
-			    case FB_TYPE_PLANES:
-				display->dispsw = &fbcon_afb;
-				break;
-#endif
-#ifdef FBCON_HAS_MFB
-			    case FB_TYPE_PACKED_PIXELS:	/* depth == 1 */
-				display->dispsw = &fbcon_mfb;
-				break;
-#endif
-			    default:
-				display->dispsw = &fbcon_dummy;
-			}
-			if (fb_info.changevar)
-				(*fb_info.changevar)(con);
-		}
-		if (oldbpp != var->bits_per_pixel) {
-			if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
-				return err;
-			do_install_cmap(con, info);
-		}
-		if (con == info->currcon)
-			ami_set_var(&display->var);
+	info->fix.line_length = div8(upx(16<<maxfmode, par->vxres));
+
+	if (par->vmode & FB_VMODE_YWRAP) {
+		info->fix.ywrapstep = 1;
+		info->fix.xpanstep = 0;
+		info->fix.ypanstep = 0;
+	} else {
+		info->fix.ywrapstep = 0;
+		if (par->vmode &= FB_VMODE_SMOOTH_XPAN)
+			info->fix.xpanstep = 1;
+		else
+			info->fix.xpanstep = 16<<maxfmode;
+		info->fix.ypanstep = 1;
 	}
 	return 0;
 }
 
+
 	/*
 	 * Pan or Wrap the Display
 	 *
 	 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
 	 */
 
-static int amifb_pan_display(struct fb_var_screeninfo *var, int con,
-				struct fb_info *info)
+static int amifb_pan_display(struct fb_var_screeninfo *var,
+			     struct fb_info *info)
 {
 	if (var->vmode & FB_VMODE_YWRAP) {
-		if (var->yoffset<0 || var->yoffset >= fb_display[con].var.yres_virtual || var->xoffset)
+		if (var->yoffset < 0 ||
+		    var->yoffset >= info->var.yres_virtual || var->xoffset)
 			return -EINVAL;
 	} else {
 		/*
 		 * TODO: There will be problems when xpan!=1, so some columns
 		 * on the right side will never be seen
 		 */
-		if (var->xoffset+fb_display[con].var.xres > upx(16<<maxfmode, fb_display[con].var.xres_virtual) ||
-		    var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)
+		if (var->xoffset+info->var.xres > upx(16<<maxfmode, info->var.xres_virtual) ||
+		    var->yoffset+info->var.yres > info->var.yres_virtual)
 			return -EINVAL;
 	}
-	if (con == info->currcon)
-		ami_pan_var(var);
-	fb_display[con].var.xoffset = var->xoffset;
-	fb_display[con].var.yoffset = var->yoffset;
+	ami_pan_var(var);
+	info->var.xoffset = var->xoffset;
+	info->var.yoffset = var->yoffset;
 	if (var->vmode & FB_VMODE_YWRAP)
-		fb_display[con].var.vmode |= FB_VMODE_YWRAP;
+		info->var.vmode |= FB_VMODE_YWRAP;
 	else
-		fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
+		info->var.vmode &= ~FB_VMODE_YWRAP;
 	return 0;
 }
 
-	/*
-	 * Get the Colormap
-	 */
 
-static int amifb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info)
+#if BITS_PER_LONG == 32
+#define BYTES_PER_LONG	4
+#define SHIFT_PER_LONG	5
+#elif BITS_PER_LONG == 64
+#define BYTES_PER_LONG	8
+#define SHIFT_PER_LONG	6
+#else
+#define Please update me
+#endif
+
+
+    /*
+     *  Compose two values, using a bitmask as decision value
+     *  This is equivalent to (a & mask) | (b & ~mask)
+     */
+
+static inline unsigned long comp(unsigned long a, unsigned long b,
+				 unsigned long mask)
 {
-	if (con == info->currcon) /* current console? */
-		return fb_get_cmap(cmap, kspc, ami_getcolreg, info);
-	else if (fb_display[con].cmap.len) /* non default colormap? */
-		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-	else
-		fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
-			     cmap, kspc ? 0 : 2);
-	return 0;
+	return ((a ^ b) & mask) ^ b;
 }
-	
-	/*
-	 * Amiga Frame Buffer Specific ioctls
-	 */
 
-static int amifb_ioctl(struct inode *inode, struct file *file,
-                       u_int cmd, u_long arg, int con, struct fb_info *info)
+
+static inline unsigned long xor(unsigned long a, unsigned long b,
+				unsigned long mask)
 {
-	int i;
+	return (a & mask) ^ b;
+}
 
-	switch (cmd) {
-		case FBIOGET_FCURSORINFO : {
-			struct fb_fix_cursorinfo crsrfix;
-			
-			i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrfix));
-			if (!i) {
-				i = amifb_get_fix_cursorinfo(&crsrfix, con);
-				copy_to_user((void *)arg, &crsrfix, sizeof(crsrfix));
-			}
-			return i;
-		}
-		case FBIOGET_VCURSORINFO : {
-			struct fb_var_cursorinfo crsrvar;
 
-			i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrvar));
-			if (!i) {
-				i = amifb_get_var_cursorinfo(&crsrvar,
-					((struct fb_var_cursorinfo *)arg)->data, con);
-				copy_to_user((void *)arg, &crsrvar, sizeof(crsrvar));
-			}
-			return i;
+    /*
+     *  Unaligned forward bit copy using 32-bit or 64-bit memory accesses
+     */
+
+static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
+		   int src_idx, u32 n)
+{
+	unsigned long first, last;
+	int shift = dst_idx-src_idx, left, right;
+	unsigned long d0, d1;
+	int m;
+
+	if (!n)
+		return;
+
+	shift = dst_idx-src_idx;
+	first = ~0UL >> dst_idx;
+	last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+
+	if (!shift) {
+		// Same alignment for source and dest
+
+		if (dst_idx+n <= BITS_PER_LONG) {
+			// Single word
+			if (last)
+				first &= last;
+			*dst = comp(*src, *dst, first);
+		} else {
+			// Multiple destination words
+			// Leading bits
+			if (first) {
+				*dst = comp(*src, *dst, first);
+				dst++;
+				src++;
+				n -= BITS_PER_LONG-dst_idx;
+			}
+
+			// Main chunk
+			n /= BITS_PER_LONG;
+			while (n >= 8) {
+				*dst++ = *src++;
+				*dst++ = *src++;
+				*dst++ = *src++;
+				*dst++ = *src++;
+				*dst++ = *src++;
+				*dst++ = *src++;
+				*dst++ = *src++;
+				*dst++ = *src++;
+				n -= 8;
+			}
+			while (n--)
+				*dst++ = *src++;
+
+			// Trailing bits
+			if (last)
+				*dst = comp(*src, *dst, last);
 		}
-		case FBIOPUT_VCURSORINFO : {
-			struct fb_var_cursorinfo crsrvar;
+	} else {
+		// Different alignment for source and dest
+
+		right = shift & (BITS_PER_LONG-1);
+		left = -shift & (BITS_PER_LONG-1);
 
-			i = verify_area(VERIFY_READ, (void *)arg, sizeof(crsrvar));
-			if (!i) {
-				copy_from_user(&crsrvar, (void *)arg, sizeof(crsrvar));
-				i = amifb_set_var_cursorinfo(&crsrvar,
-					((struct fb_var_cursorinfo *)arg)->data, con);
+		if (dst_idx+n <= BITS_PER_LONG) {
+			// Single destination word
+			if (last)
+				first &= last;
+			if (shift > 0) {
+				// Single source word
+				*dst = comp(*src >> right, *dst, first);
+			} else if (src_idx+n <= BITS_PER_LONG) {
+				// Single source word
+				*dst = comp(*src << left, *dst, first);
+			} else {
+				// 2 source words
+				d0 = *src++;
+				d1 = *src;
+				*dst = comp(d0 << left | d1 >> right, *dst,
+					    first);
+			}
+		} else {
+			// Multiple destination words
+			d0 = *src++;
+			// Leading bits
+			if (shift > 0) {
+				// Single source word
+				*dst = comp(d0 >> right, *dst, first);
+				dst++;
+				n -= BITS_PER_LONG-dst_idx;
+			} else {
+				// 2 source words
+				d1 = *src++;
+				*dst = comp(d0 << left | d1 >> right, *dst,
+					    first);
+				d0 = d1;
+				dst++;
+				n -= BITS_PER_LONG-dst_idx;
+			}
+
+			// Main chunk
+			m = n % BITS_PER_LONG;
+			n /= BITS_PER_LONG;
+			while (n >= 4) {
+				d1 = *src++;
+				*dst++ = d0 << left | d1 >> right;
+				d0 = d1;
+				d1 = *src++;
+				*dst++ = d0 << left | d1 >> right;
+				d0 = d1;
+				d1 = *src++;
+				*dst++ = d0 << left | d1 >> right;
+				d0 = d1;
+				d1 = *src++;
+				*dst++ = d0 << left | d1 >> right;
+				d0 = d1;
+				n -= 4;
+			}
+			while (n--) {
+				d1 = *src++;
+				*dst++ = d0 << left | d1 >> right;
+				d0 = d1;
+			}
+
+			// Trailing bits
+			if (last) {
+				if (m <= right) {
+					// Single source word
+					*dst = comp(d0 << left, *dst, last);
+				} else {
+					// 2 source words
+					d1 = *src;
+					*dst = comp(d0 << left | d1 >> right,
+						    *dst, last);
+				}
 			}
-			return i;
 		}
-		case FBIOGET_CURSORSTATE : {
-			struct fb_cursorstate crsrstate;
+	}
+}
 
-			i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrstate));
-			if (!i) {
-				i = amifb_get_cursorstate(&crsrstate, con);
-				copy_to_user((void *)arg, &crsrstate, sizeof(crsrstate));
-			}
-			return i;
+
+    /*
+     *  Unaligned reverse bit copy using 32-bit or 64-bit memory accesses
+     */
+
+static void bitcpy_rev(unsigned long *dst, int dst_idx,
+		       const unsigned long *src, int src_idx, u32 n)
+{
+	unsigned long first, last;
+	int shift = dst_idx-src_idx, left, right;
+	unsigned long d0, d1;
+	int m;
+
+	if (!n)
+		return;
+
+	dst += (n-1)/BITS_PER_LONG;
+	src += (n-1)/BITS_PER_LONG;
+	if ((n-1) % BITS_PER_LONG) {
+		dst_idx += (n-1) % BITS_PER_LONG;
+		dst += dst_idx >> SHIFT_PER_LONG;
+		dst_idx &= BITS_PER_LONG-1;
+		src_idx += (n-1) % BITS_PER_LONG;
+		src += src_idx >> SHIFT_PER_LONG;
+		src_idx &= BITS_PER_LONG-1;
+	}
+
+	shift = dst_idx-src_idx;
+	first = ~0UL << (BITS_PER_LONG-1-dst_idx);
+	last = ~(~0UL << (BITS_PER_LONG-1-((dst_idx-n) % BITS_PER_LONG)));
+
+	if (!shift) {
+		// Same alignment for source and dest
+
+		if ((unsigned long)dst_idx+1 >= n) {
+			// Single word
+			if (last)
+				first &= last;
+			*dst = comp(*src, *dst, first);
+		} else {
+			// Multiple destination words
+			// Leading bits
+			if (first) {
+				*dst = comp(*src, *dst, first);
+				dst--;
+				src--;
+				n -= dst_idx+1;
+			}
+
+			// Main chunk
+			n /= BITS_PER_LONG;
+			while (n >= 8) {
+				*dst-- = *src--;
+				*dst-- = *src--;
+				*dst-- = *src--;
+				*dst-- = *src--;
+				*dst-- = *src--;
+				*dst-- = *src--;
+				*dst-- = *src--;
+				*dst-- = *src--;
+				n -= 8;
+			}
+			while (n--)
+				*dst-- = *src--;
+
+			// Trailing bits
+			if (last)
+				*dst = comp(*src, *dst, last);
 		}
-		case FBIOPUT_CURSORSTATE : {
-			struct fb_cursorstate crsrstate;
+	} else {
+		// Different alignment for source and dest
+
+		right = shift & (BITS_PER_LONG-1);
+		left = -shift & (BITS_PER_LONG-1);
 
-			i = verify_area(VERIFY_READ, (void *)arg, sizeof(crsrstate));
-			if (!i) {
-				copy_from_user(&crsrstate, (void *)arg, sizeof(crsrstate));
-				i = amifb_set_cursorstate(&crsrstate, con);
+		if ((unsigned long)dst_idx+1 >= n) {
+			// Single destination word
+			if (last)
+				first &= last;
+			if (shift < 0) {
+				// Single source word
+				*dst = comp(*src << left, *dst, first);
+			} else if (1+(unsigned long)src_idx >= n) {
+				// Single source word
+				*dst = comp(*src >> right, *dst, first);
+			} else {
+				// 2 source words
+				d0 = *src--;
+				d1 = *src;
+				*dst = comp(d0 >> right | d1 << left, *dst,
+					    first);
+			}
+		} else {
+			// Multiple destination words
+			d0 = *src--;
+			// Leading bits
+			if (shift < 0) {
+				// Single source word
+				*dst = comp(d0 << left, *dst, first);
+				dst--;
+				n -= dst_idx+1;
+			} else {
+				// 2 source words
+				d1 = *src--;
+				*dst = comp(d0 >> right | d1 << left, *dst,
+					    first);
+				d0 = d1;
+				dst--;
+				n -= dst_idx+1;
+			}
+
+			// Main chunk
+			m = n % BITS_PER_LONG;
+			n /= BITS_PER_LONG;
+			while (n >= 4) {
+				d1 = *src--;
+				*dst-- = d0 >> right | d1 << left;
+				d0 = d1;
+				d1 = *src--;
+				*dst-- = d0 >> right | d1 << left;
+				d0 = d1;
+				d1 = *src--;
+				*dst-- = d0 >> right | d1 << left;
+				d0 = d1;
+				d1 = *src--;
+				*dst-- = d0 >> right | d1 << left;
+				d0 = d1;
+				n -= 4;
+			}
+			while (n--) {
+				d1 = *src--;
+				*dst-- = d0 >> right | d1 << left;
+				d0 = d1;
+			}
+
+			// Trailing bits
+			if (last) {
+				if (m <= left) {
+					// Single source word
+					*dst = comp(d0 >> right, *dst, last);
+				} else {
+					// 2 source words
+					d1 = *src;
+					*dst = comp(d0 >> right | d1 << left,
+						    *dst, last);
+				}
 			}
-			return i;
 		}
-#ifdef DEBUG
-		case FBCMD_GET_CURRENTPAR : {
-			struct amifb_par par;
+	}
+}
 
-			i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct amifb_par));
-			if (!i) {
-				ami_get_par(&par);
-				copy_to_user((void *)arg, &par, sizeof(struct amifb_par));
-			}
-			return i;
+
+    /*
+     *  Unaligned forward inverting bit copy using 32-bit or 64-bit memory
+     *  accesses
+     */
+
+static void bitcpy_not(unsigned long *dst, int dst_idx,
+		       const unsigned long *src, int src_idx, u32 n)
+{
+	unsigned long first, last;
+	int shift = dst_idx-src_idx, left, right;
+	unsigned long d0, d1;
+	int m;
+
+	if (!n)
+		return;
+
+	shift = dst_idx-src_idx;
+	first = ~0UL >> dst_idx;
+	last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+
+	if (!shift) {
+		// Same alignment for source and dest
+
+		if (dst_idx+n <= BITS_PER_LONG) {
+			// Single word
+			if (last)
+				first &= last;
+			*dst = comp(~*src, *dst, first);
+		} else {
+			// Multiple destination words
+			// Leading bits
+			if (first) {
+				*dst = comp(~*src, *dst, first);
+				dst++;
+				src++;
+				n -= BITS_PER_LONG-dst_idx;
+			}
+
+			// Main chunk
+			n /= BITS_PER_LONG;
+			while (n >= 8) {
+				*dst++ = ~*src++;
+				*dst++ = ~*src++;
+				*dst++ = ~*src++;
+				*dst++ = ~*src++;
+				*dst++ = ~*src++;
+				*dst++ = ~*src++;
+				*dst++ = ~*src++;
+				*dst++ = ~*src++;
+				n -= 8;
+			}
+			while (n--)
+				*dst++ = ~*src++;
+
+			// Trailing bits
+			if (last)
+				*dst = comp(~*src, *dst, last);
 		}
-		case FBCMD_SET_CURRENTPAR : {
-			struct amifb_par par;
+	} else {
+		// Different alignment for source and dest
+
+		right = shift & (BITS_PER_LONG-1);
+		left = -shift & (BITS_PER_LONG-1);
 
-			i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct amifb_par));
-			if (!i) {
-				copy_from_user(&par, (void *)arg, sizeof(struct amifb_par));
-				ami_set_par(&par);
+		if (dst_idx+n <= BITS_PER_LONG) {
+			// Single destination word
+			if (last)
+				first &= last;
+			if (shift > 0) {
+				// Single source word
+				*dst = comp(~*src >> right, *dst, first);
+			} else if (src_idx+n <= BITS_PER_LONG) {
+				// Single source word
+				*dst = comp(~*src << left, *dst, first);
+			} else {
+				// 2 source words
+				d0 = ~*src++;
+				d1 = ~*src;
+				*dst = comp(d0 << left | d1 >> right, *dst,
+					    first);
+			}
+		} else {
+			// Multiple destination words
+			d0 = ~*src++;
+			// Leading bits
+			if (shift > 0) {
+				// Single source word
+				*dst = comp(d0 >> right, *dst, first);
+				dst++;
+				n -= BITS_PER_LONG-dst_idx;
+			} else {
+				// 2 source words
+				d1 = ~*src++;
+				*dst = comp(d0 << left | d1 >> right, *dst,
+					    first);
+				d0 = d1;
+				dst++;
+				n -= BITS_PER_LONG-dst_idx;
+			}
+
+			// Main chunk
+			m = n % BITS_PER_LONG;
+			n /= BITS_PER_LONG;
+			while (n >= 4) {
+				d1 = ~*src++;
+				*dst++ = d0 << left | d1 >> right;
+				d0 = d1;
+				d1 = ~*src++;
+				*dst++ = d0 << left | d1 >> right;
+				d0 = d1;
+				d1 = ~*src++;
+				*dst++ = d0 << left | d1 >> right;
+				d0 = d1;
+				d1 = ~*src++;
+				*dst++ = d0 << left | d1 >> right;
+				d0 = d1;
+				n -= 4;
+			}
+			while (n--) {
+				d1 = ~*src++;
+				*dst++ = d0 << left | d1 >> right;
+				d0 = d1;
+			}
+
+			// Trailing bits
+			if (last) {
+				if (m <= right) {
+					// Single source word
+					*dst = comp(d0 << left, *dst, last);
+				} else {
+					// 2 source words
+					d1 = ~*src;
+					*dst = comp(d0 << left | d1 >> right,
+						    *dst, last);
+				}
 			}
-			return i;
 		}
-#endif	/* DEBUG */
 	}
-	return -EINVAL;
 }
 
-	/*
-	 * Hardware Cursor
-	 */
 
-static int amifb_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con)
+    /*
+     *  Unaligned 32-bit pattern fill using 32/64-bit memory accesses
+     */
+
+static void bitfill32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
 {
-	return ami_get_fix_cursorinfo(fix, con);
+	unsigned long val = pat;
+	unsigned long first, last;
+
+	if (!n)
+		return;
+
+#if BITS_PER_LONG == 64
+	val |= val << 32;
+#endif
+
+	first = ~0UL >> dst_idx;
+	last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+
+	if (dst_idx+n <= BITS_PER_LONG) {
+		// Single word
+		if (last)
+			first &= last;
+		*dst = comp(val, *dst, first);
+	} else {
+		// Multiple destination words
+		// Leading bits
+		if (first) {
+			*dst = comp(val, *dst, first);
+			dst++;
+			n -= BITS_PER_LONG-dst_idx;
+		}
+
+		// Main chunk
+		n /= BITS_PER_LONG;
+		while (n >= 8) {
+			*dst++ = val;
+			*dst++ = val;
+			*dst++ = val;
+			*dst++ = val;
+			*dst++ = val;
+			*dst++ = val;
+			*dst++ = val;
+			*dst++ = val;
+			n -= 8;
+		}
+		while (n--)
+			*dst++ = val;
+
+		// Trailing bits
+		if (last)
+			*dst = comp(val, *dst, last);
+	}
 }
 
-static int amifb_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con)
+
+    /*
+     *  Unaligned 32-bit pattern xor using 32/64-bit memory accesses
+     */
+
+static void bitxor32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
 {
-	return ami_get_var_cursorinfo(var, data, con);
+	unsigned long val = pat;
+	unsigned long first, last;
+
+	if (!n)
+		return;
+
+#if BITS_PER_LONG == 64
+	val |= val << 32;
+#endif
+
+	first = ~0UL >> dst_idx;
+	last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+
+	if (dst_idx+n <= BITS_PER_LONG) {
+		// Single word
+		if (last)
+			first &= last;
+		*dst = xor(val, *dst, first);
+	} else {
+		// Multiple destination words
+		// Leading bits
+		if (first) {
+			*dst = xor(val, *dst, first);
+			dst++;
+			n -= BITS_PER_LONG-dst_idx;
+		}
+
+		// Main chunk
+		n /= BITS_PER_LONG;
+		while (n >= 4) {
+			*dst++ ^= val;
+			*dst++ ^= val;
+			*dst++ ^= val;
+			*dst++ ^= val;
+			n -= 4;
+		}
+		while (n--)
+			*dst++ ^= val;
+
+		// Trailing bits
+		if (last)
+			*dst = xor(val, *dst, last);
+	}
+}
+
+static inline void fill_one_line(int bpp, unsigned long next_plane,
+				 unsigned long *dst, int dst_idx, u32 n,
+				 u32 color)
+{
+	while (1) {
+		dst += dst_idx >> SHIFT_PER_LONG;
+		dst_idx &= (BITS_PER_LONG-1);
+		bitfill32(dst, dst_idx, color & 1 ? ~0 : 0, n);
+		if (!--bpp)
+			break;
+		color >>= 1;
+		dst_idx += next_plane*8;
+	}
+}
+
+static inline void xor_one_line(int bpp, unsigned long next_plane,
+				unsigned long *dst, int dst_idx, u32 n,
+				u32 color)
+{
+	while (color) {
+		dst += dst_idx >> SHIFT_PER_LONG;
+		dst_idx &= (BITS_PER_LONG-1);
+		bitxor32(dst, dst_idx, color & 1 ? ~0 : 0, n);
+		if (!--bpp)
+			break;
+		color >>= 1;
+		dst_idx += next_plane*8;
+	}
+}
+
+
+static void amifb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+	struct amifb_par *par = (struct amifb_par *)info->par;
+	int dst_idx, x2, y2;
+	unsigned long *dst;
+
+	if (!rect->width || !rect->height)
+		return;
+
+	/*
+	 * We could use hardware clipping but on many cards you get around
+	 * hardware clipping by writing to framebuffer directly.
+	 * */
+	x2 = rect->dx + rect->width;
+	y2 = rect->dy + rect->height;
+	x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
+	y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
+	rect->width = x2 - rect->dx;
+	rect->height = y2 - rect->dy;
+
+	dst = (unsigned long *)
+		((unsigned long)info->screen_base & ~(BYTES_PER_LONG-1));
+	dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG-1))*8;
+	dst_idx += rect->dy*par->next_line*8+rect->dx;
+	while (rect->height--) {
+		switch (rect->rop) {
+		    case ROP_COPY:
+			fill_one_line(info->var.bits_per_pixel,
+				      par->next_plane, dst, dst_idx,
+				      rect->width, rect->color);
+			break;
+
+		    case ROP_XOR:
+			xor_one_line(info->var.bits_per_pixel,
+				     par->next_plane, dst, dst_idx,
+				     rect->width, rect->color);
+			break;
+		}
+		dst_idx += par->next_line*8;
+	}
 }
 
-static int amifb_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con)
+static inline void copy_one_line(int bpp, unsigned long next_plane,
+				 unsigned long *dst, int dst_idx,
+				 unsigned long *src, int src_idx, u32 n)
+{
+	while (1) {
+		dst += dst_idx >> SHIFT_PER_LONG;
+		dst_idx &= (BITS_PER_LONG-1);
+		src += src_idx >> SHIFT_PER_LONG;
+		src_idx &= (BITS_PER_LONG-1);
+		bitcpy(dst, dst_idx, src, src_idx, n);
+		if (!--bpp)
+			break;
+		dst_idx += next_plane*8;
+		src_idx += next_plane*8;
+	}
+}
+
+static inline void copy_one_line_rev(int bpp, unsigned long next_plane,
+				     unsigned long *dst, int dst_idx,
+				     unsigned long *src, int src_idx, u32 n)
+{
+	while (1) {
+		dst += dst_idx >> SHIFT_PER_LONG;
+		dst_idx &= (BITS_PER_LONG-1);
+		src += src_idx >> SHIFT_PER_LONG;
+		src_idx &= (BITS_PER_LONG-1);
+		bitcpy_rev(dst, dst_idx, src, src_idx, n);
+		if (!--bpp)
+			break;
+		dst_idx += next_plane*8;
+		src_idx += next_plane*8;
+	}
+}
+
+
+static void amifb_copyarea(struct fb_info *info, struct fb_copyarea *area)
 {
-	return ami_set_var_cursorinfo(var, data, con);
+	struct amifb_par *par = (struct amifb_par *)info->par;
+	int x2, y2, old_dx, old_dy;
+	unsigned long *dst, *src;
+	int dst_idx, src_idx, height;
+	int rev_copy = 0;
+
+	/* clip the destination */
+	old_dx = area->dx;
+	old_dy = area->dy;
+
+	/*
+	 * We could use hardware clipping but on many cards you get around
+	 * hardware clipping by writing to framebuffer directly.
+	 */
+	x2 = area->dx + area->width;
+	y2 = area->dy + area->height;
+	area->dx = area->dx > 0 ? area->dx : 0;
+	area->dy = area->dy > 0 ? area->dy : 0;
+	x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
+	y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
+	area->width = x2 - area->dx;
+	area->height = y2 - area->dy;
+
+	/* update sx1,sy1 */
+	area->sx += (area->dx - old_dx);
+	area->sy += (area->dy - old_dy);
+
+	height = area->height;
+
+	/* the source must be completely inside the virtual screen */
+	if (area->sx < 0 || area->sy < 0 ||
+	    (area->sx + area->width) > info->var.xres_virtual ||
+	    (area->sy + area->height) > info->var.yres_virtual)
+		return;
+
+	if (area->dy > area->sy ||
+	    (area->dy == area->sy && area->dx > area->sx)) {
+		area->dy += area->height;
+		area->sy += area->height;
+		rev_copy = 1;
+	}
+	dst = (unsigned long *)
+		((unsigned long)info->screen_base & ~(BYTES_PER_LONG-1));
+	src = dst;
+	dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG-1))*8;
+	src_idx = dst_idx;
+	dst_idx += area->dy*par->next_line*8+area->dx;
+	src_idx += area->sy*par->next_line*8+area->sx;
+	if (rev_copy) {
+		while (height--) {
+			dst_idx -= par->next_line*8;
+			src_idx -= par->next_line*8;
+			copy_one_line_rev(info->var.bits_per_pixel,
+					  par->next_plane, dst, dst_idx, src,
+					  src_idx, area->width);
+		}
+	} else {
+		while (height--) {
+			copy_one_line(info->var.bits_per_pixel,
+				      par->next_plane, dst, dst_idx, src,
+				      src_idx, area->width);
+			dst_idx += par->next_line*8;
+			src_idx += par->next_line*8;
+		}
+	}
+}
+
+
+static inline void expand_one_line(int bpp, unsigned long next_plane,
+				   unsigned long *dst, int dst_idx, u32 n,
+				   const u8 *data, u32 bgcolor, u32 fgcolor)
+{
+    const unsigned long *src;
+    int src_idx;
+
+    while (1) {
+	dst += dst_idx >> SHIFT_PER_LONG;
+	dst_idx &= (BITS_PER_LONG-1);
+	if ((bgcolor ^ fgcolor) & 1) {
+	    src = (unsigned long *)((unsigned long)data & ~(BYTES_PER_LONG-1));
+	    src_idx = ((unsigned long)data & (BYTES_PER_LONG-1))*8;
+	    if (fgcolor & 1)
+		bitcpy(dst, dst_idx, src, src_idx, n);
+	    else
+		bitcpy_not(dst, dst_idx, src, src_idx, n);
+	    /* set or clear */
+	} else
+	    bitfill32(dst, dst_idx, fgcolor & 1 ? ~0 : 0, n);
+	if (!--bpp)
+	    break;
+	bgcolor >>= 1;
+	fgcolor >>= 1;
+	dst_idx += next_plane*8;
+    }
 }
 
-static int amifb_get_cursorstate(struct fb_cursorstate *state, int con)
+
+static void amifb_imageblit(struct fb_info *info, struct fb_image *image)
 {
-	return ami_get_cursorstate(state, con);
+	struct amifb_par *par = (struct amifb_par *)info->par;
+	int x2, y2;
+	unsigned long *dst;
+	int dst_idx;
+	const char *src;
+	u32 dx, dy, width, height, pitch;
+
+	/*
+	 * We could use hardware clipping but on many cards you get around
+	 * hardware clipping by writing to framebuffer directly like we are
+	 * doing here.
+	 */
+	x2 = image->dx + image->width;
+	y2 = image->dy + image->height;
+	dx = image->dx;
+	dy = image->dy;
+	x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
+	y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
+	width  = x2 - dx;
+	height = y2 - dy;
+
+	if (image->depth == 1) {
+		dst = (unsigned long *)
+			((unsigned long)info->screen_base & ~(BYTES_PER_LONG-1));
+		dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG-1))*8;
+		dst_idx += dy*par->next_line*8+dx;
+		src = image->data;
+		pitch = (image->width+7)/8;
+		while (height--) {
+			expand_one_line(info->var.bits_per_pixel,
+					par->next_plane, dst, dst_idx, width,
+					src, image->bg_color,
+					image->fg_color);
+			dst_idx += par->next_line*8;
+			src += pitch;
+		}
+	} else {
+		c2p(info->screen_base, image->data, dx, dy, width, height,
+		    par->next_line, par->next_plane, image->width,
+		    info->var.bits_per_pixel);
+	}
 }
 
-static int amifb_set_cursorstate(struct fb_cursorstate *state, int con)
+
+	/*
+	 * Amiga Frame Buffer Specific ioctls
+	 */
+
+static int amifb_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg,
+		       struct fb_info *info)
 {
-	return ami_set_cursorstate(state, con);
+	union {
+		struct fb_fix_cursorinfo fix;
+		struct fb_var_cursorinfo var;
+		struct fb_cursorstate state;
+	} crsr;
+	int i;
+
+	switch (cmd) {
+		case FBIOGET_FCURSORINFO:
+			i = ami_get_fix_cursorinfo(&crsr.fix);
+			if (i)
+				return i;
+			return copy_to_user((void *)arg, &crsr.fix,
+					    sizeof(crsr.fix)) ? -EFAULT : 0;
+
+		case FBIOGET_VCURSORINFO:
+			i = ami_get_var_cursorinfo(&crsr.var,
+				((struct fb_var_cursorinfo *)arg)->data);
+			if (i)
+				return i;
+			return copy_to_user((void *)arg, &crsr.var,
+					    sizeof(crsr.var)) ? -EFAULT : 0;
+
+		case FBIOPUT_VCURSORINFO:
+			if (copy_from_user(&crsr.var, (void *)arg,
+					   sizeof(crsr.var)))
+				return -EFAULT;
+			return ami_set_var_cursorinfo(&crsr.var,
+				((struct fb_var_cursorinfo *)arg)->data);
+
+		case FBIOGET_CURSORSTATE:
+			i = ami_get_cursorstate(&crsr.state);
+			if (i)
+				return i;
+			return copy_to_user((void *)arg, &crsr.state,
+					    sizeof(crsr.state)) ? -EFAULT : 0;
+
+		case FBIOPUT_CURSORSTATE:
+			if (copy_from_user(&crsr.state, (void *)arg,
+					   sizeof(crsr.state)))
+				return -EFAULT;
+			return ami_set_cursorstate(&crsr.state);
+	}
+	return -EINVAL;
 }
 
 
@@ -1570,7 +2258,6 @@
 	int tag, i, err = 0;
 	u_long chipptr;
 	u_int defmode;
-	struct fb_var_screeninfo var;
 
 	if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_VIDEO))
 		return -ENXIO;
@@ -1600,7 +2287,7 @@
 	switch (amiga_chipset) {
 #ifdef CONFIG_FB_AMIGA_OCS
 		case CS_OCS:
-			strcat(amifb_name, "OCS");
+			strcat(fb_info.fix.id, "OCS");
 default_chipset:
 			chipset = TAG_OCS;
 			maxdepth[TAG_SHRES] = 0;	/* OCS means no SHRES */
@@ -1609,13 +2296,13 @@
 			maxfmode = TAG_FMODE_1;
 			defmode = amiga_vblank == 50 ? DEFMODE_PAL
 						     : DEFMODE_NTSC;
-			videomemorysize = VIDEOMEMSIZE_OCS;
+			fb_info.fix.smem_len = VIDEOMEMSIZE_OCS;
 			break;
 #endif /* CONFIG_FB_AMIGA_OCS */
 
 #ifdef CONFIG_FB_AMIGA_ECS
 		case CS_ECS:
-			strcat(amifb_name, "ECS");
+			strcat(fb_info.fix.id, "ECS");
 			chipset = TAG_ECS;
 			maxdepth[TAG_SHRES] = 2;
 			maxdepth[TAG_HIRES] = 4;
@@ -1629,15 +2316,15 @@
 							 : DEFMODE_NTSC;
 			if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT >
 			    VIDEOMEMSIZE_ECS_1M)
-				videomemorysize = VIDEOMEMSIZE_ECS_2M;
+				fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_2M;
 			else
-				videomemorysize = VIDEOMEMSIZE_ECS_1M;
+				fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_1M;
 			break;
 #endif /* CONFIG_FB_AMIGA_ECS */
 
 #ifdef CONFIG_FB_AMIGA_AGA
 		case CS_AGA:
-			strcat(amifb_name, "AGA");
+			strcat(fb_info.fix.id, "AGA");
 			chipset = TAG_AGA;
 			maxdepth[TAG_SHRES] = 8;
 			maxdepth[TAG_HIRES] = 8;
@@ -1646,16 +2333,16 @@
 			defmode = DEFMODE_AGA;
 			if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT >
 			    VIDEOMEMSIZE_AGA_1M)
-				videomemorysize = VIDEOMEMSIZE_AGA_2M;
+				fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_2M;
 			else
-				videomemorysize = VIDEOMEMSIZE_AGA_1M;
+				fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_1M;
 			break;
 #endif /* CONFIG_FB_AMIGA_AGA */
 
 		default:
 #ifdef CONFIG_FB_AMIGA_OCS
 			printk("Unknown graphics chipset, defaulting to OCS\n");
-			strcat(amifb_name, "Unknown");
+			strcat(fb_info.fix.id, "Unknown");
 			goto default_chipset;
 #else /* CONFIG_FB_AMIGA_OCS */
 			err = -ENXIO;
@@ -1698,31 +2385,25 @@
 	    fb_info.monspecs.vfmax = 90;
 	}
 
-	strcpy(fb_info.modename, amifb_name);
-	fb_info.changevar = NULL;
 	fb_info.node = NODEV;
 	fb_info.fbops = &amifb_ops;
-	fb_info.disp = &disp;
-	fb_info.currcon = 1;
-	fb_info.switch_con = &amifbcon_switch;
-	fb_info.updatevar = &amifbcon_updatevar;
+	fb_info.par = &currentpar;
 	fb_info.flags = FBINFO_FLAG_DEFAULT;
-	memset(&var, 0, sizeof(var));
 
-	if (!fb_find_mode(&var, &fb_info, mode_option, ami_modedb,
+	if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, ami_modedb,
 			  NUM_TOTAL_MODES, &ami_modedb[defmode], 4)) {
 		err = -EINVAL;
 		goto amifb_error;
 	}
 
 	round_down_bpp = 0;
-	chipptr = chipalloc(videomemorysize+
+	chipptr = chipalloc(fb_info.fix.smem_len+
 	                    SPRITEMEMSIZE+
 	                    DUMMYSPRITEMEMSIZE+
 	                    COPINITSIZE+
 	                    4*COPLISTSIZE);
 
-	assignchunk(videomemory, u_long, chipptr, videomemorysize);
+	assignchunk(videomemory, u_long, chipptr, fb_info.fix.smem_len);
 	assignchunk(spritememory, u_long, chipptr, SPRITEMEMSIZE);
 	assignchunk(dummysprite, u_short *, chipptr, DUMMYSPRITEMEMSIZE);
 	assignchunk(copdisplay.init, copins *, chipptr, COPINITSIZE);
@@ -1734,11 +2415,12 @@
 	/*
 	 * access the videomem with writethrough cache
 	 */
-	videomemory_phys = (u_long)ZTWO_PADDR(videomemory);
-	videomemory = (u_long)ioremap_writethrough(videomemory_phys, videomemorysize);
+	fb_info.fix.smem_start = (u_long)ZTWO_PADDR(videomemory);
+	videomemory = (u_long)ioremap_writethrough(fb_info.fix.smem_start,
+						   fb_info.fix.smem_len);
 	if (!videomemory) {
 		printk("amifb: WARNING! unable to map videomem cached writethrough\n");
-		videomemory = ZTWO_VADDR(videomemory_phys);
+		videomemory = ZTWO_VADDR(fb_info.fix.smem_start);
 	}
 
 	fb_info.screen_base = (char *)videomemory;
@@ -1757,25 +2439,24 @@
 
 	ami_init_copper();
 
-	if (request_irq(IRQ_AMIGA_VERTB, amifb_interrupt, 0,
+	if (request_irq(IRQ_AMIGA_COPPER, amifb_interrupt, 0,
 	                "fb vertb handler", &currentpar)) {
 		err = -EBUSY;
 		goto amifb_error;
 	}
 
-	amifb_set_var(&var, -1, &fb_info);
+	fb_alloc_cmap(&fb_info.cmap, 1<<fb_info.var.bits_per_pixel, 0);
 
 	if (register_framebuffer(&fb_info) < 0) {
 		err = -EINVAL;
 		goto amifb_error;
 	}
 
-	printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
-	       minor(fb_info.node), fb_info.modename,
-	       videomemorysize>>10);
+	printk("fb%d: %s frame buffer device, using %dK of video memory\n",
+	       minor(fb_info.node), fb_info.fix.id, fb_info.fix.smem_len>>10);
 
 	return 0;
-	
+
 amifb_error:
 	amifb_deinit();
 	return err;
@@ -1783,33 +2464,12 @@
 
 static void amifb_deinit(void)
 {
-	chipfree();    
+	fb_dealloc_cmap(&fb_info.cmap);
+	chipfree();
 	release_mem_region(CUSTOM_PHYSADDR+0xe0, 0x120);
 	custom.dmacon = DMAF_ALL | DMAF_MASTER;
 }
 
-static int amifbcon_switch(int con, struct fb_info *info)
-{
-	/* Do we have to save the colormap? */
-	if (fb_display[info->currcon].cmap.len)
-		fb_get_cmap(&fb_display[info->currcon].cmap, 1, ami_getcolreg, info);
-
-	info->currcon = con;
-	ami_set_var(&fb_display[con].var);
-	/* Install new colormap */
-	do_install_cmap(con, info);
-	return 0;
-}
-
-	/*
-	 * Update the `var' structure (called by fbcon.c)
-	 */
-
-static int amifbcon_updatevar(int con, struct fb_info *info)
-{
-	ami_pan_var(&fb_display[con].var);
-	return 0;
-}
 
 	/*
 	 * Blank the display.
@@ -1821,6 +2481,10 @@
 	return 0;
 }
 
+	/*
+	 * Flash the cursor (called by VBlank interrupt)
+	 */
+
 static int flash_cursor(void)
 {
 	static int cursorcount = 1;
@@ -1875,50 +2539,6 @@
 /* --------------------------- Hardware routines --------------------------- */
 
 	/*
-	 * This function should fill in the `fix' structure based on the
-	 * values in the `par' structure.
-	 */
-
-static int ami_encode_fix(struct fb_fix_screeninfo *fix,
-                          struct amifb_par *par)
-{
-	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-	strcpy(fix->id, amifb_name);
-	fix->smem_start = videomemory_phys;
-	fix->smem_len = videomemorysize;
-
-#ifdef FBCON_HAS_MFB
-	if (par->bpp == 1) {
-		fix->type = FB_TYPE_PACKED_PIXELS;
-		fix->type_aux = 0;
-	} else
-#endif
-	if (amifb_ilbm) {
-		fix->type = FB_TYPE_INTERLEAVED_PLANES;
-		fix->type_aux = par->next_line;
-	} else {
-		fix->type = FB_TYPE_PLANES;
-		fix->type_aux = 0;
-	}
-	fix->line_length = div8(upx(16<<maxfmode, par->vxres));
-	fix->visual = FB_VISUAL_PSEUDOCOLOR;
-
-	if (par->vmode & FB_VMODE_YWRAP) {
-		fix->ywrapstep = 1;
-		fix->xpanstep = fix->ypanstep = 0;
-	} else {
-		fix->ywrapstep = 0;
-		if (par->vmode &= FB_VMODE_SMOOTH_XPAN)
-			fix->xpanstep = 1;
-		else
-			fix->xpanstep = 16<<maxfmode;
-		fix->ypanstep = 1;
-	}
-	fix->accel = FB_ACCEL_AMIGABLITT;
-	return 0;
-}
-
-	/*
 	 * Get the video params out of `var'. If a value doesn't fit, round
 	 * it up, if it's too big, return -EINVAL.
 	 */
@@ -2074,7 +2694,7 @@
 			if (!IS_OCS) {
 				par->beamcon0 = BMC0_PAL;
 				par->bplcon3 |= BPC3_BRDRBLNK;
-			} else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) || 
+			} else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) ||
 			           AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
 				par->beamcon0 = BMC0_PAL;
 				par->hsstop = 1;
@@ -2104,7 +2724,7 @@
 			if (!IS_OCS) {
 				par->beamcon0 = 0;
 				par->bplcon3 |= BPC3_BRDRBLNK;
-			} else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) || 
+			} else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) ||
 			           AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
 				par->beamcon0 = 0;
 				par->hsstop = 1;
@@ -2235,14 +2855,14 @@
 	if (amifb_ilbm) {
 		par->next_plane = div8(upx(16<<maxfmode, par->vxres));
 		par->next_line = par->bpp*par->next_plane;
-		if (par->next_line * par->vyres > videomemorysize) {
+		if (par->next_line * par->vyres > fb_info.fix.smem_len) {
 			DPRINTK("too few video mem\n");
 			return -EINVAL;
 		}
 	} else {
 		par->next_line = div8(upx(16<<maxfmode, par->vxres));
 		par->next_plane = par->vyres*par->next_line;
-		if (par->next_plane * par->bpp > videomemorysize) {
+		if (par->next_plane * par->bpp > fb_info.fix.smem_len) {
 			DPRINTK("too few video mem\n");
 			return -EINVAL;
 		}
@@ -2402,38 +3022,6 @@
 	return 0;
 }
 
-	/*
-	 * Get current hardware setting
-	 */
-
-static void ami_get_par(struct amifb_par *par)
-{
-	*par = currentpar;
-}
-
-	/*
-	 * Set new videomode
-	 */
-
-static void ami_set_var(struct fb_var_screeninfo *var)
-{
-	do_vmode_pan = 0;
-	do_vmode_full = 0;
-	ami_decode_var(var, &currentpar);
-	ami_build_copper();
-	do_vmode_full = 1;
-}
-
-#ifdef DEBUG
-static void ami_set_par(struct amifb_par *par)
-{
-	do_vmode_pan = 0;
-	do_vmode_full = 0;
-	currentpar = *par;
-	ami_build_copper();
-	do_vmode_full = 1;
-}
-#endif
 
 	/*
 	 * Pan or Wrap the Display
@@ -2506,16 +3094,16 @@
 		par->bpl1mod = par->bpl2mod;
 
 	if (par->yoffset) {
-		par->bplpt0 = videomemory_phys + par->next_line*par->yoffset + move;
+		par->bplpt0 = fb_info.fix.smem_start + par->next_line*par->yoffset + move;
 		if (par->vmode & FB_VMODE_YWRAP) {
 			if (par->yoffset > par->vyres-par->yres) {
-				par->bplpt0wrap = videomemory_phys + move;
+				par->bplpt0wrap = fb_info.fix.smem_start + move;
 				if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v+par->vyres-par->yoffset))
 					par->bplpt0wrap += par->next_line;
 			}
 		}
 	} else
-		par->bplpt0 = videomemory_phys + move;
+		par->bplpt0 = fb_info.fix.smem_start + move;
 
 	if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v))
 		par->bplpt0 += par->next_line;
@@ -2523,45 +3111,6 @@
 	return 0;
 }
 
-	/*
-	 * Read a single color register and split it into
-	 * colors/transparent. Return != 0 for invalid regno.
-	 */
-
-static int ami_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-                         u_int *transp, struct fb_info *info)
-{
-	int len, tr, tg, tb;
-
-	if (IS_AGA) {
-		if (regno > 255)
-			return 1;
-		len = 8;
-	} else if (currentpar.bplcon0 & BPC0_SHRES) {
-		if (regno > 3)
-			return 1;
-		len = 2;
-	} else {
-		if (regno > 31)
-			return 1;
-		len = 4;
-	}
-	tr = palette[regno].red>>(8-len);
-	tg = palette[regno].green>>(8-len);
-	tb = palette[regno].blue>>(8-len);
-	while (len < 16) {
-		tr |= tr<<len;
-		tg |= tg<<len;
-		tb |= tb<<len;
-		len <<= 1;
-	}
-	*red = tr;
-	*green = tg;
-	*blue = tb;
-	*transp = 0;
-	return 0;
-}
-
 
 	/*
 	 * Set a single color register. The values supplied are already
@@ -2585,9 +3134,11 @@
 	red >>= 8;
 	green >>= 8;
 	blue >>= 8;
-	palette[regno].red = red;
-	palette[regno].green = green;
-	palette[regno].blue = blue;
+	if (!regno) {
+		red0 = red;
+		green0 = green;
+		blue0 = blue;
+	}
 
 	/*
 	 * Update the corresponding Hardware Color Register, unless it's Color
@@ -2650,6 +3201,7 @@
 static void ami_init_display(void)
 {
 	struct amifb_par *par = &currentpar;
+	int i;
 
 	custom.bplcon0 = par->bplcon0 & ~BPC0_LACE;
 	custom.bplcon2 = (IS_OCS ? 0 : BPC2_KILLEHB) | BPC2_PF2P2 | BPC2_PF1P2;
@@ -2685,18 +3237,16 @@
 	is_lace = par->bplcon0 & BPC0_LACE ? 1 : 0;
 #if 1
 	if (is_lace) {
-		if (custom.vposr & 0x8000)
-			custom.cop2lc = (u_short *)ZTWO_PADDR(copdisplay.list[currentcop][1]);
-		else
-			custom.cop2lc = (u_short *)ZTWO_PADDR(copdisplay.list[currentcop][0]);
+		i = custom.vposr >> 15;
 	} else {
 		custom.vposw = custom.vposr | 0x8000;
-		custom.cop2lc = (u_short *)ZTWO_PADDR(copdisplay.list[currentcop][1]);
+		i = 1;
 	}
 #else
+	i = 1;
 	custom.vposw = custom.vposr | 0x8000;
-	custom.cop2lc = (u_short *)ZTWO_PADDR(copdisplay.list[currentcop][1]);
 #endif
+	custom.cop2lc = (u_short *)ZTWO_PADDR(copdisplay.list[currentcop][i]);
 }
 
 	/*
@@ -2744,9 +3294,9 @@
 		}
 	} else {
 		custom.dmacon = DMAF_SETCLR | DMAF_RASTER | DMAF_SPRITE;
-		red = palette[0].red;
-		green = palette[0].green;
-		blue = palette[0].blue;
+		red = red0;
+		green = green0;
+		blue = blue0;
 		if (!IS_OCS) {
 			custom.hsstrt = hsstrt2hw(par->hsstrt);
 			custom.hsstop = hsstop2hw(par->hsstop);
@@ -2782,11 +3332,7 @@
 	is_blanked = do_blank > 0 ? do_blank : 0;
 }
 
-	/*
-	 * Flash the cursor (called by VBlank interrupt)
-	 */
-
-static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix, int con)
+static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix)
 {
 	struct amifb_par *par = &currentpar;
 
@@ -2797,7 +3343,7 @@
 	return 0;
 }
 
-static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con)
+static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
 {
 	struct amifb_par *par = &currentpar;
 	register u_short *lspr, *sspr;
@@ -2846,7 +3392,7 @@
 				"swap %1 ; lslw #1,%1 ; roxlb #1,%0"
 				: "=d" (color), "=d" (datawords) : "1" (datawords));
 #else
-			color = (((datawords >> 30) & 2) 
+			color = (((datawords >> 30) & 2)
 				 | ((datawords >> 15) & 1));
 			datawords <<= 1;
 #endif
@@ -2872,7 +3418,7 @@
 	return 0;
 }
 
-static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, int con)
+static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data)
 {
 	struct amifb_par *par = &currentpar;
 	register u_short *lspr, *sspr;
@@ -2991,7 +3537,7 @@
 	return 0;
 }
 
-static int ami_get_cursorstate(struct fb_cursorstate *state, int con)
+static int ami_get_cursorstate(struct fb_cursorstate *state)
 {
 	struct amifb_par *par = &currentpar;
 
@@ -3001,7 +3547,7 @@
 	return 0;
 }
 
-static int ami_set_cursorstate(struct fb_cursorstate *state, int con)
+static int ami_set_cursorstate(struct fb_cursorstate *state)
 {
 	struct amifb_par *par = &currentpar;
 
@@ -3061,6 +3607,7 @@
 		cops[cop_spr0ptrl].w[1] = loww(ps);
 	}
 }
+
 
 	/*
 	 * Initialise the Copper Initialisation List
diff -Nru a/drivers/video/aty/Makefile b/drivers/video/aty/Makefile
--- a/drivers/video/aty/Makefile	Sat Dec 14 04:38:56 2002
+++ b/drivers/video/aty/Makefile	Thu Feb 27 17:17:32 2003
@@ -1,6 +1,8 @@
 obj-$(CONFIG_FB_ATY) += atyfb.o
+obj-$(CONFIG_FB_ATY128) += aty128fb.o
 
 atyfb-y				:= atyfb_base.o mach64_accel.o
 atyfb-$(CONFIG_FB_ATY_GX)	+= mach64_gx.o
 atyfb-$(CONFIG_FB_ATY_CT)	+= mach64_ct.o mach64_cursor.o
+atyfb-$(CONFIG_FB_ATY_XL_INIT)	+= xlinit.o
 atyfb-objs			:= $(atyfb-y)
diff -Nru a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/aty/aty128fb.c	Mon Mar  3 19:41:16 2003
@@ -0,0 +1,2354 @@
+/* $Id: aty128fb.c,v 1.1.1.1.36.1 1999/12/11 09:03:05 Exp $
+ *  linux/drivers/video/aty128fb.c -- Frame buffer device for ATI Rage128
+ *
+ *  Copyright (C) 1999-2003, Brad Douglas <brad@neruo.com>
+ *  Copyright (C) 1999, Anthony Tong <atong@uiuc.edu>
+ *
+ *                Ani Joshi / Jeff Garzik
+ *                      - Code cleanup
+ *
+ *                Michel Danzer <michdaen@iiic.ethz.ch>
+ *                      - 15/16 bit cleanup
+ *                      - fix panning
+ *
+ *                Benjamin Herrenschmidt
+ *                      - pmac-specific PM stuff
+ *
+ *                Andreas Hundt <andi@convergence.de>
+ *                      - FB_ACTIVATE fixes
+ *
+ *		  Paul Mackerras <paulus@samba.org>
+ *			- Convert to new framebuffer API,
+ *			  fix colormap setting at 16 bits/pixel (565)
+ *
+ *		  Paul Mundt 
+ *		  	- PCI hotplug
+ *
+ *  Based off of Geert's atyfb.c and vfb.c.
+ *
+ *  TODO:
+ *		- monitor sensing (DDC)
+ *              - virtual display
+ *		- other platform support (only ppc/x86 supported)
+ *		- hardware cursor support
+ *
+ *    Please cc: your patches to brad@neruo.com.
+ */
+
+/*
+ * A special note of gratitude to ATI's devrel for providing documentation,
+ * example code and hardware. Thanks Nitya.	-atong and brad
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <asm/uaccess.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_ALL_PPC
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include "macmodes.h"
+#endif
+
+#ifdef CONFIG_ADB_PMU
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#endif
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+
+#ifdef CONFIG_BOOTX_TEXT
+#include <asm/btext.h>
+#endif /* CONFIG_BOOTX_TEXT */
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include <video/aty128.h>
+
+/* Debug flag */
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt, args...)		printk(KERN_DEBUG "aty128fb: %s " fmt, __FUNCTION__, ##args);
+#else
+#define DBG(fmt, args...)
+#endif
+
+#ifndef CONFIG_ALL_PPC
+/* default mode */
+static struct fb_var_screeninfo default_var __initdata = {
+	/* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
+	640, 480, 640, 480, 0, 0, 8, 0,
+	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
+	0, FB_VMODE_NONINTERLACED
+};
+
+#else /* CONFIG_ALL_PPC */
+/* default to 1024x768 at 75Hz on PPC - this will work
+ * on the iMac, the usual 640x480 @ 60Hz doesn't. */
+static struct fb_var_screeninfo default_var = {
+	/* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
+	1024, 768, 1024, 768, 0, 0, 8, 0,
+	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	0, 0, -1, -1, 0, 12699, 160, 32, 28, 1, 96, 3,
+	FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	FB_VMODE_NONINTERLACED
+};
+#endif /* CONFIG_ALL_PPC */
+
+/* default modedb mode */
+/* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
+static struct fb_videomode defaultmode __initdata = {
+	.refresh =	60,
+	.xres =		640,
+	.yres =		480,
+	.pixclock =	39722,
+	.left_margin =	48,
+	.right_margin =	16,
+	.upper_margin =	33,
+	.lower_margin =	10,
+	.hsync_len =	96,
+	.vsync_len =	2,
+	.sync =		0,
+	.vmode =	FB_VMODE_NONINTERLACED
+};
+
+/* Chip generations */
+enum {
+	rage_128,
+	rage_128_pro,
+	rage_M3
+};
+
+/*
+ * PCI driver prototypes
+ */
+static int aty128_probe(struct pci_dev *pdev,
+                               const struct pci_device_id *ent);
+static void aty128_remove(struct pci_dev *pdev);
+
+/* supported Rage128 chipsets */
+static struct pci_device_id aty128_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RE,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RF,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RI,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RK,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RL,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_Rage128_PD,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PF,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PR,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PP,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_U3,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_U1,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LE,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LF,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 },
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, aty128_pci_tbl);
+
+static struct pci_driver aty128fb_driver = {
+	.name		= "aty128fb",
+	.id_table	= aty128_pci_tbl,
+	.probe		= aty128_probe,
+	.remove		= __devexit_p(aty128_remove),
+};
+
+/* packed BIOS settings */
+#ifndef CONFIG_PPC
+typedef struct {
+	u8 clock_chip_type;
+	u8 struct_size;
+	u8 accelerator_entry;
+	u8 VGA_entry;
+	u16 VGA_table_offset;
+	u16 POST_table_offset;
+	u16 XCLK;
+	u16 MCLK;
+	u8 num_PLL_blocks;
+	u8 size_PLL_blocks;
+	u16 PCLK_ref_freq;
+	u16 PCLK_ref_divider;
+	u32 PCLK_min_freq;
+	u32 PCLK_max_freq;
+	u16 MCLK_ref_freq;
+	u16 MCLK_ref_divider;
+	u32 MCLK_min_freq;
+	u32 MCLK_max_freq;
+	u16 XCLK_ref_freq;
+	u16 XCLK_ref_divider;
+	u32 XCLK_min_freq;
+	u32 XCLK_max_freq;
+} __attribute__ ((packed)) PLL_BLOCK;
+#endif /* !CONFIG_PPC */
+
+/* onboard memory information */
+struct aty128_meminfo {
+	u8 ML;
+	u8 MB;
+	u8 Trcd;
+	u8 Trp;
+	u8 Twr;
+	u8 CL;
+	u8 Tr2w;
+	u8 LoopLatency;
+	u8 DspOn;
+	u8 Rloop;
+	const char *name;
+};
+
+/* various memory configurations */
+static const struct aty128_meminfo sdr_128   =
+	{ 4, 4, 3, 3, 1, 3, 1, 16, 30, 16, "128-bit SDR SGRAM (1:1)" };
+static const struct aty128_meminfo sdr_64    =
+	{ 4, 8, 3, 3, 1, 3, 1, 17, 46, 17, "64-bit SDR SGRAM (1:1)" };
+static const struct aty128_meminfo sdr_sgram =
+	{ 4, 4, 1, 2, 1, 2, 1, 16, 24, 16, "64-bit SDR SGRAM (2:1)" };
+static const struct aty128_meminfo ddr_sgram =
+	{ 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" };
+
+static struct fb_fix_screeninfo aty128fb_fix __initdata = {
+	.id		= "ATY Rage128",
+	.type		= FB_TYPE_PACKED_PIXELS,
+	.visual		= FB_VISUAL_PSEUDOCOLOR,
+	.xpanstep	= 8,
+	.ypanstep	= 1,
+	.mmio_len	= 0x2000,
+	.accel		= FB_ACCEL_ATI_RAGE128,
+};
+
+#ifdef MODULE
+static char *mode __initdata = NULL;
+#ifdef CONFIG_MTRR
+static int  nomtrr __initdata = 0;
+#endif /* CONFIG_MTRR */
+#endif /* MODULE */
+
+static char *mode_option __initdata = NULL;
+
+#ifdef CONFIG_ALL_PPC
+static int default_vmode __initdata = VMODE_1024_768_60;
+static int default_cmode __initdata = CMODE_8;
+#endif
+
+#ifdef CONFIG_PMAC_PBOOK
+static int default_crt_on __initdata = 0;
+static int default_lcd_on __initdata = 1;
+#endif
+
+#ifdef CONFIG_MTRR
+static int mtrr = 1;
+#endif
+
+/* PLL constants */
+struct aty128_constants {
+	u32 dotclock;
+	u32 ppll_min;
+	u32 ppll_max;
+	u32 ref_divider;
+	u32 xclk;
+	u32 fifo_width;
+	u32 fifo_depth;
+};
+
+struct aty128_crtc {
+	u32 gen_cntl;
+	u32 h_total, h_sync_strt_wid;
+	u32 v_total, v_sync_strt_wid;
+	u32 pitch;
+	u32 offset, offset_cntl;
+	u32 xoffset, yoffset;
+	u32 vxres, vyres;
+	u32 depth, bpp;
+};
+
+struct aty128_pll {
+	u32 post_divider;
+	u32 feedback_divider;
+	u32 vclk;
+};
+
+struct aty128_ddafifo {
+	u32 dda_config;
+	u32 dda_on_off;
+};
+
+/* register values for a specific mode */
+struct aty128fb_par {
+	struct aty128_crtc crtc;
+	struct aty128_pll pll;
+	struct aty128_ddafifo fifo_reg;
+	u32 accel_flags;
+	struct aty128_constants constants;  /* PLL and others      */
+	void *regbase;                      /* remapped mmio       */
+	u32 vram_size;                      /* onboard video ram   */
+	int chip_gen;
+	const struct aty128_meminfo *mem;   /* onboard mem info    */
+#ifdef CONFIG_MTRR
+	struct { int vram; int vram_valid; } mtrr;
+#endif
+	int blitter_may_be_busy;
+	int fifo_slots;                 /* free slots in FIFO (64 max) */
+#ifdef CONFIG_PMAC_PBOOK
+	unsigned char *save_framebuffer;
+	int	pm_reg;
+	int crt_on, lcd_on;
+	struct pci_dev *pdev;
+	struct fb_info *next;
+#endif
+	u8	red[32];		/* see aty128fb_setcolreg */
+	u8	green[64];
+	u8	blue[32];
+	u32	pseudo_palette[16];	/* used for TRUECOLOR */
+};
+
+#ifdef CONFIG_PMAC_PBOOK
+int aty128_sleep_notify(struct pmu_sleep_notifier *self, int when);
+static struct pmu_sleep_notifier aty128_sleep_notifier = {
+	aty128_sleep_notify, SLEEP_LEVEL_VIDEO,
+};
+static struct fb_info *aty128_fb = NULL;
+#endif
+
+#define round_div(n, d) ((n+(d/2))/d)
+
+    /*
+     *  Interface used by the world
+     */
+int aty128fb_init(void);
+int aty128fb_setup(char *options);
+
+static int aty128fb_check_var(struct fb_var_screeninfo *var,
+			      struct fb_info *info);
+static int aty128fb_set_par(struct fb_info *info);
+static int aty128fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			      u_int transp, struct fb_info *info);
+static int aty128fb_pan_display(struct fb_var_screeninfo *var,
+			   struct fb_info *fb);
+static int aty128fb_blank(int blank, struct fb_info *fb);
+static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+			  u_long arg, struct fb_info *info);
+static int aty128fb_sync(struct fb_info *info);
+
+    /*
+     *  Internal routines
+     */
+
+static int aty128_encode_var(struct fb_var_screeninfo *var,
+                             const struct aty128fb_par *par);
+static int aty128_decode_var(struct fb_var_screeninfo *var,
+                             struct aty128fb_par *par);
+#if !defined(CONFIG_PPC) && !defined(__sparc__)
+static void __init aty128_get_pllinfo(struct aty128fb_par *par,
+				      void *bios);
+static void __init *aty128_map_ROM(struct pci_dev *pdev);
+static void __init aty128_unmap_ROM(struct pci_dev *dev, void * rom);
+#endif
+static void aty128_timings(struct aty128fb_par *par);
+static void aty128_init_engine(struct aty128fb_par *par);
+static void aty128_reset_engine(const struct aty128fb_par *par);
+static void aty128_flush_pixel_cache(const struct aty128fb_par *par);
+static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par);
+static void wait_for_fifo(u16 entries, struct aty128fb_par *par);
+static void wait_for_idle(struct aty128fb_par *par);
+static u32 depth_to_dst(u32 depth);
+
+static struct fb_ops aty128fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_check_var	= aty128fb_check_var,
+	.fb_set_par	= aty128fb_set_par,
+	.fb_setcolreg	= aty128fb_setcolreg,
+	.fb_pan_display = aty128fb_pan_display,
+	.fb_blank	= aty128fb_blank,
+	.fb_ioctl	= aty128fb_ioctl,
+	.fb_sync	= aty128fb_sync,
+#if 0
+	.fb_fillrect	= aty128fb_fillrect,
+	.fb_copyarea	= aty128fb_copyarea,
+	.fb_imageblit	= aty128fb_imageblit,
+#else
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+#endif
+	.fb_cursor	= soft_cursor,
+};
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int aty128_set_backlight_enable(int on, int level, void* data);
+static int aty128_set_backlight_level(int level, void* data);
+
+static struct backlight_controller aty128_backlight_controller = {
+	aty128_set_backlight_enable,
+	aty128_set_backlight_level
+};
+#endif /* CONFIG_PMAC_BACKLIGHT */
+
+    /*
+     * Functions to read from/write to the mmio registers
+     *	- endian conversions may possibly be avoided by
+     *    using the other register aperture. TODO.
+     */
+static inline u32
+_aty_ld_le32(volatile unsigned int regindex, const struct aty128fb_par *par)
+{
+	u32 val;
+
+#if defined(__powerpc__)
+	asm("lwbrx %0,%1,%2;eieio" : "=r"(val) : "b"(regindex), "r"(par->regbase));
+#else
+	val = readl (par->regbase + regindex);
+#endif
+
+	return val;
+}
+
+static inline void
+_aty_st_le32(volatile unsigned int regindex, u32 val, 
+                               const struct aty128fb_par *par)
+{
+#if defined(__powerpc__)
+	asm("stwbrx %0,%1,%2;eieio" : : "r"(val), "b"(regindex),
+	    "r"(par->regbase) : "memory");
+#else
+	writel (val, par->regbase + regindex);
+#endif
+}
+
+static inline u8
+_aty_ld_8(unsigned int regindex, const struct aty128fb_par *par)
+{
+	return readb (par->regbase + regindex);
+}
+
+static inline void
+_aty_st_8(unsigned int regindex, u8 val, const struct aty128fb_par *par)
+{
+	writeb (val, par->regbase + regindex);
+}
+
+#define aty_ld_le32(regindex)		_aty_ld_le32(regindex, par)
+#define aty_st_le32(regindex, val)	_aty_st_le32(regindex, val, par)
+#define aty_ld_8(regindex)		_aty_ld_8(regindex, par)
+#define aty_st_8(regindex, val)		_aty_st_8(regindex, val, par)
+
+    /*
+     * Functions to read from/write to the pll registers
+     */
+
+#define aty_ld_pll(pll_index)		_aty_ld_pll(pll_index, par)
+#define aty_st_pll(pll_index, val)	_aty_st_pll(pll_index, val, par)
+
+
+static u32
+_aty_ld_pll(unsigned int pll_index,
+			const struct aty128fb_par *par)
+{       
+	aty_st_8(CLOCK_CNTL_INDEX, pll_index & 0x3F);
+	return aty_ld_le32(CLOCK_CNTL_DATA);
+}
+
+    
+static void
+_aty_st_pll(unsigned int pll_index, u32 val,
+			const struct aty128fb_par *par)
+{
+	aty_st_8(CLOCK_CNTL_INDEX, (pll_index & 0x3F) | PLL_WR_EN);
+	aty_st_le32(CLOCK_CNTL_DATA, val);
+}
+
+
+/* return true when the PLL has completed an atomic update */
+static int
+aty_pll_readupdate(const struct aty128fb_par *par)
+{
+	return !(aty_ld_pll(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R);
+}
+
+
+static void
+aty_pll_wait_readupdate(const struct aty128fb_par *par)
+{
+	unsigned long timeout = jiffies + HZ/100; // should be more than enough
+	int reset = 1;
+
+	while (time_before(jiffies, timeout))
+		if (aty_pll_readupdate(par)) {
+			reset = 0;
+			break;
+		}
+
+	if (reset)	/* reset engine?? */
+		printk(KERN_DEBUG "aty128fb: PLL write timeout!\n");
+}
+
+
+/* tell PLL to update */
+static void
+aty_pll_writeupdate(const struct aty128fb_par *par)
+{
+	aty_pll_wait_readupdate(par);
+
+	aty_st_pll(PPLL_REF_DIV,
+		   aty_ld_pll(PPLL_REF_DIV) | PPLL_ATOMIC_UPDATE_W);
+}
+
+
+/* write to the scratch register to test r/w functionality */
+static int __init
+register_test(const struct aty128fb_par *par)
+{
+	u32 val;
+	int flag = 0;
+
+	val = aty_ld_le32(BIOS_0_SCRATCH);
+
+	aty_st_le32(BIOS_0_SCRATCH, 0x55555555);
+	if (aty_ld_le32(BIOS_0_SCRATCH) == 0x55555555) {
+		aty_st_le32(BIOS_0_SCRATCH, 0xAAAAAAAA);
+
+		if (aty_ld_le32(BIOS_0_SCRATCH) == 0xAAAAAAAA)
+			flag = 1; 
+	}
+
+	aty_st_le32(BIOS_0_SCRATCH, val);	// restore value
+	return flag;
+}
+
+
+/*
+ * Accelerator engine functions
+ */
+static void
+do_wait_for_fifo(u16 entries, struct aty128fb_par *par)
+{
+	int i;
+
+	for (;;) {
+		for (i = 0; i < 2000000; i++) {
+			par->fifo_slots = aty_ld_le32(GUI_STAT) & 0x0fff;
+			if (par->fifo_slots >= entries)
+				return;
+		}
+		aty128_reset_engine(par);
+	}
+}
+
+
+static void
+wait_for_idle(struct aty128fb_par *par)
+{
+	int i;
+
+	do_wait_for_fifo(64, par);
+
+	for (;;) {
+		for (i = 0; i < 2000000; i++) {
+			if (!(aty_ld_le32(GUI_STAT) & (1 << 31))) {
+				aty128_flush_pixel_cache(par);
+				par->blitter_may_be_busy = 0;
+				return;
+			}
+		}
+		aty128_reset_engine(par);
+	}
+}
+
+
+static void
+wait_for_fifo(u16 entries, struct aty128fb_par *par)
+{
+	if (par->fifo_slots < entries)
+		do_wait_for_fifo(64, par);
+	par->fifo_slots -= entries;
+}
+
+
+static void
+aty128_flush_pixel_cache(const struct aty128fb_par *par)
+{
+	int i;
+	u32 tmp;
+
+	tmp = aty_ld_le32(PC_NGUI_CTLSTAT);
+	tmp &= ~(0x00ff);
+	tmp |= 0x00ff;
+	aty_st_le32(PC_NGUI_CTLSTAT, tmp);
+
+	for (i = 0; i < 2000000; i++)
+		if (!(aty_ld_le32(PC_NGUI_CTLSTAT) & PC_BUSY))
+			break;
+}
+
+
+static void
+aty128_reset_engine(const struct aty128fb_par *par)
+{
+	u32 gen_reset_cntl, clock_cntl_index, mclk_cntl;
+
+	aty128_flush_pixel_cache(par);
+
+	clock_cntl_index = aty_ld_le32(CLOCK_CNTL_INDEX);
+	mclk_cntl = aty_ld_pll(MCLK_CNTL);
+
+	aty_st_pll(MCLK_CNTL, mclk_cntl | 0x00030000);
+
+	gen_reset_cntl = aty_ld_le32(GEN_RESET_CNTL);
+	aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl | SOFT_RESET_GUI);
+	aty_ld_le32(GEN_RESET_CNTL);
+	aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl & ~(SOFT_RESET_GUI));
+	aty_ld_le32(GEN_RESET_CNTL);
+
+	aty_st_pll(MCLK_CNTL, mclk_cntl);
+	aty_st_le32(CLOCK_CNTL_INDEX, clock_cntl_index);
+	aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl);
+
+	/* use old pio mode */
+	aty_st_le32(PM4_BUFFER_CNTL, PM4_BUFFER_CNTL_NONPM4);
+
+	DBG("engine reset");
+}
+
+
+static void
+aty128_init_engine(struct aty128fb_par *par)
+{
+	u32 pitch_value;
+
+	wait_for_idle(par);
+
+	/* 3D scaler not spoken here */
+	wait_for_fifo(1, par);
+	aty_st_le32(SCALE_3D_CNTL, 0x00000000);
+
+	aty128_reset_engine(par);
+
+	pitch_value = par->crtc.pitch;
+	if (par->crtc.bpp == 24) {
+		pitch_value = pitch_value * 3;
+	}
+
+	wait_for_fifo(4, par);
+	/* setup engine offset registers */
+	aty_st_le32(DEFAULT_OFFSET, 0x00000000);
+
+	/* setup engine pitch registers */
+	aty_st_le32(DEFAULT_PITCH, pitch_value);
+
+	/* set the default scissor register to max dimensions */
+	aty_st_le32(DEFAULT_SC_BOTTOM_RIGHT, (0x1FFF << 16) | 0x1FFF);
+
+	/* set the drawing controls registers */
+	aty_st_le32(DP_GUI_MASTER_CNTL,
+		    GMC_SRC_PITCH_OFFSET_DEFAULT		|
+		    GMC_DST_PITCH_OFFSET_DEFAULT		|
+		    GMC_SRC_CLIP_DEFAULT			|
+		    GMC_DST_CLIP_DEFAULT			|
+		    GMC_BRUSH_SOLIDCOLOR			|
+		    (depth_to_dst(par->crtc.depth) << 8)	|
+		    GMC_SRC_DSTCOLOR			|
+		    GMC_BYTE_ORDER_MSB_TO_LSB		|
+		    GMC_DP_CONVERSION_TEMP_6500		|
+		    ROP3_PATCOPY				|
+		    GMC_DP_SRC_RECT				|
+		    GMC_3D_FCN_EN_CLR			|
+		    GMC_DST_CLR_CMP_FCN_CLEAR		|
+		    GMC_AUX_CLIP_CLEAR			|
+		    GMC_WRITE_MASK_SET);
+
+	wait_for_fifo(8, par);
+	/* clear the line drawing registers */
+	aty_st_le32(DST_BRES_ERR, 0);
+	aty_st_le32(DST_BRES_INC, 0);
+	aty_st_le32(DST_BRES_DEC, 0);
+
+	/* set brush color registers */
+	aty_st_le32(DP_BRUSH_FRGD_CLR, 0xFFFFFFFF); /* white */
+	aty_st_le32(DP_BRUSH_BKGD_CLR, 0x00000000); /* black */
+
+	/* set source color registers */
+	aty_st_le32(DP_SRC_FRGD_CLR, 0xFFFFFFFF);   /* white */
+	aty_st_le32(DP_SRC_BKGD_CLR, 0x00000000);   /* black */
+
+	/* default write mask */
+	aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF);
+
+	/* Wait for all the writes to be completed before returning */
+	wait_for_idle(par);
+}
+
+
+/* convert depth values to their register representation */
+static u32
+depth_to_dst(u32 depth)
+{
+	if (depth <= 8)
+		return DST_8BPP;
+	else if (depth <= 15)
+		return DST_15BPP;
+	else if (depth == 16)
+		return DST_16BPP;
+	else if (depth <= 24)
+		return DST_24BPP;
+	else if (depth <= 32)
+		return DST_32BPP;
+
+	return -EINVAL;
+}
+
+
+/*
+     * CRTC programming
+     */
+
+/* Program the CRTC registers */
+static void
+aty128_set_crtc(const struct aty128_crtc *crtc,
+		const struct aty128fb_par *par)
+{
+	aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl);
+	aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_total);
+	aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);
+	aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_total);
+	aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid);
+	aty_st_le32(CRTC_PITCH, crtc->pitch);
+	aty_st_le32(CRTC_OFFSET, crtc->offset);
+	aty_st_le32(CRTC_OFFSET_CNTL, crtc->offset_cntl);
+	/* Disable ATOMIC updating.  Is this the right place? */
+	aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~(0x00030000));
+}
+
+
+static int
+aty128_var_to_crtc(const struct fb_var_screeninfo *var,
+		   struct aty128_crtc *crtc,
+		   const struct aty128fb_par *par)
+{
+	u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp, dst;
+	u32 left, right, upper, lower, hslen, vslen, sync, vmode;
+	u32 h_total, h_disp, h_sync_strt, h_sync_wid, h_sync_pol;
+	u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
+	u32 depth, bytpp;
+	u8 mode_bytpp[7] = { 0, 0, 1, 2, 2, 3, 4 };
+
+	/* input */
+	xres = var->xres;
+	yres = var->yres;
+	vxres   = var->xres_virtual;
+	vyres   = var->yres_virtual;
+	xoffset = var->xoffset;
+	yoffset = var->yoffset;
+	bpp   = var->bits_per_pixel;
+	left  = var->left_margin;
+	right = var->right_margin;
+	upper = var->upper_margin;
+	lower = var->lower_margin;
+	hslen = var->hsync_len;
+	vslen = var->vsync_len;
+	sync  = var->sync;
+	vmode = var->vmode;
+
+	if (bpp != 16)
+		depth = bpp;
+	else
+		depth = (var->green.length == 6) ? 16 : 15;
+
+	/* check for mode eligibility
+	 * accept only non interlaced modes */
+	if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+		return -EINVAL;
+
+	/* convert (and round up) and validate */
+	xres = (xres + 7) & ~7;
+	xoffset = (xoffset + 7) & ~7;
+
+	if (vxres < xres + xoffset)
+		vxres = xres + xoffset;
+
+	if (vyres < yres + yoffset)
+		vyres = yres + yoffset;
+
+	/* convert depth into ATI register depth */
+	dst = depth_to_dst(depth);
+
+	if (dst == -EINVAL) {
+		printk(KERN_ERR "aty128fb: Invalid depth or RGBA\n");
+		return -EINVAL;
+	}
+
+	/* convert register depth to bytes per pixel */
+	bytpp = mode_bytpp[dst];
+
+	/* make sure there is enough video ram for the mode */
+	if ((u32)(vxres * vyres * bytpp) > par->vram_size) {
+		printk(KERN_ERR "aty128fb: Not enough memory for mode\n");
+		return -EINVAL;
+	}
+
+	h_disp = (xres >> 3) - 1;
+	h_total = (((xres + right + hslen + left) >> 3) - 1) & 0xFFFFL;
+
+	v_disp = yres - 1;
+	v_total = (yres + upper + vslen + lower - 1) & 0xFFFFL;
+
+	/* check to make sure h_total and v_total are in range */
+	if (((h_total >> 3) - 1) > 0x1ff || (v_total - 1) > 0x7FF) {
+		printk(KERN_ERR "aty128fb: invalid width ranges\n");
+		return -EINVAL;
+	}
+
+	h_sync_wid = (hslen + 7) >> 3;
+	if (h_sync_wid == 0)
+		h_sync_wid = 1;
+	else if (h_sync_wid > 0x3f)        /* 0x3f = max hwidth */
+		h_sync_wid = 0x3f;
+
+	h_sync_strt = (h_disp << 3) + right;
+
+	v_sync_wid = vslen;
+	if (v_sync_wid == 0)
+		v_sync_wid = 1;
+	else if (v_sync_wid > 0x1f)        /* 0x1f = max vwidth */
+		v_sync_wid = 0x1f;
+    
+	v_sync_strt = v_disp + lower;
+
+	h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
+	v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
+    
+	c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
+
+	crtc->gen_cntl = 0x3000000L | c_sync | (dst << 8);
+
+	crtc->h_total = h_total | (h_disp << 16);
+	crtc->v_total = v_total | (v_disp << 16);
+
+	crtc->h_sync_strt_wid = h_sync_strt | (h_sync_wid << 16) |
+	        (h_sync_pol << 23);
+	crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) |
+                (v_sync_pol << 23);
+
+	crtc->pitch = vxres >> 3;
+
+	crtc->offset = 0;
+
+	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
+		crtc->offset_cntl = 0x00010000;
+	else
+		crtc->offset_cntl = 0;
+
+	crtc->vxres = vxres;
+	crtc->vyres = vyres;
+	crtc->xoffset = xoffset;
+	crtc->yoffset = yoffset;
+	crtc->depth = depth;
+	crtc->bpp = bpp;
+
+	return 0;
+}
+
+
+static int
+aty128_pix_width_to_var(int pix_width, struct fb_var_screeninfo *var)
+{
+
+	/* fill in pixel info */
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
+	var->blue.offset = 0;
+	var->blue.msb_right = 0;
+	var->transp.offset = 0;
+	var->transp.length = 0;
+	var->transp.msb_right = 0;
+	switch (pix_width) {
+	case CRTC_PIX_WIDTH_8BPP:
+		var->bits_per_pixel = 8;
+		var->red.offset = 0;
+		var->red.length = 8;
+		var->green.offset = 0;
+		var->green.length = 8;
+		var->blue.length = 8;
+		break;
+	case CRTC_PIX_WIDTH_15BPP:
+		var->bits_per_pixel = 16;
+		var->red.offset = 10;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 5;
+		var->blue.length = 5;
+		break;
+	case CRTC_PIX_WIDTH_16BPP:
+		var->bits_per_pixel = 16;
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.length = 5;
+		break;
+	case CRTC_PIX_WIDTH_24BPP:
+		var->bits_per_pixel = 24;
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
+		break;
+	case CRTC_PIX_WIDTH_32BPP:
+		var->bits_per_pixel = 32;
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
+		var->transp.offset = 24;
+		var->transp.length = 8;
+		break;
+	default:
+		printk(KERN_ERR "aty128fb: Invalid pixel width\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+static int
+aty128_crtc_to_var(const struct aty128_crtc *crtc,
+		   struct fb_var_screeninfo *var)
+{
+	u32 xres, yres, left, right, upper, lower, hslen, vslen, sync;
+	u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
+	u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
+	u32 pix_width;
+
+	/* fun with masking */
+	h_total     = crtc->h_total & 0x1ff;
+	h_disp      = (crtc->h_total >> 16) & 0xff;
+	h_sync_strt = (crtc->h_sync_strt_wid >> 3) & 0x1ff;
+	h_sync_dly  = crtc->h_sync_strt_wid & 0x7;
+	h_sync_wid  = (crtc->h_sync_strt_wid >> 16) & 0x3f;
+	h_sync_pol  = (crtc->h_sync_strt_wid >> 23) & 0x1;
+	v_total     = crtc->v_total & 0x7ff;
+	v_disp      = (crtc->v_total >> 16) & 0x7ff;
+	v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
+	v_sync_wid  = (crtc->v_sync_strt_wid >> 16) & 0x1f;
+	v_sync_pol  = (crtc->v_sync_strt_wid >> 23) & 0x1;
+	c_sync      = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
+	pix_width   = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
+
+	/* do conversions */
+	xres  = (h_disp + 1) << 3;
+	yres  = v_disp + 1;
+	left  = ((h_total - h_sync_strt - h_sync_wid) << 3) - h_sync_dly;
+	right = ((h_sync_strt - h_disp) << 3) + h_sync_dly;
+	hslen = h_sync_wid << 3;
+	upper = v_total - v_sync_strt - v_sync_wid;
+	lower = v_sync_strt - v_disp;
+	vslen = v_sync_wid;
+	sync  = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
+		(v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
+		(c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
+
+	aty128_pix_width_to_var(pix_width, var);
+
+	var->xres = xres;
+	var->yres = yres;
+	var->xres_virtual = crtc->vxres;
+	var->yres_virtual = crtc->vyres;
+	var->xoffset = crtc->xoffset;
+	var->yoffset = crtc->yoffset;
+	var->left_margin  = left;
+	var->right_margin = right;
+	var->upper_margin = upper;
+	var->lower_margin = lower;
+	var->hsync_len = hslen;
+	var->vsync_len = vslen;
+	var->sync  = sync;
+	var->vmode = FB_VMODE_NONINTERLACED;
+
+	return 0;
+}
+
+#ifdef CONFIG_PMAC_PBOOK
+static void
+aty128_set_crt_enable(struct aty128fb_par *par, int on)
+{
+	if (on) {
+		aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) | CRT_CRTC_ON);
+		aty_st_le32(DAC_CNTL, (aty_ld_le32(DAC_CNTL) | DAC_PALETTE2_SNOOP_EN));
+	} else
+		aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) & ~CRT_CRTC_ON);
+}
+
+static void
+aty128_set_lcd_enable(struct aty128fb_par *par, int on)
+{
+	u32 reg;
+
+	if (on) {
+		reg = aty_ld_le32(LVDS_GEN_CNTL);
+		reg |= LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION;
+		reg &= ~LVDS_DISPLAY_DIS;
+		aty_st_le32(LVDS_GEN_CNTL, reg);
+#ifdef CONFIG_PMAC_BACKLIGHT
+		aty128_set_backlight_enable(get_backlight_enable(),
+					    get_backlight_level(), par);
+#endif	
+	} else {
+#ifdef CONFIG_PMAC_BACKLIGHT
+		aty128_set_backlight_enable(0, 0, par);
+#endif	
+		reg = aty_ld_le32(LVDS_GEN_CNTL);
+		reg |= LVDS_DISPLAY_DIS;
+		aty_st_le32(LVDS_GEN_CNTL, reg);
+		mdelay(100);
+		reg &= ~(LVDS_ON /*| LVDS_EN*/);
+		aty_st_le32(LVDS_GEN_CNTL, reg);
+	}
+}
+#endif
+
+static void
+aty128_set_pll(struct aty128_pll *pll, const struct aty128fb_par *par)
+{
+	u32 div3;
+
+	unsigned char post_conv[] =	/* register values for post dividers */
+        { 2, 0, 1, 4, 2, 2, 6, 2, 3, 2, 2, 2, 7 };
+
+	/* select PPLL_DIV_3 */
+	aty_st_le32(CLOCK_CNTL_INDEX, aty_ld_le32(CLOCK_CNTL_INDEX) | (3 << 8));
+
+	/* reset PLL */
+	aty_st_pll(PPLL_CNTL,
+		   aty_ld_pll(PPLL_CNTL) | PPLL_RESET | PPLL_ATOMIC_UPDATE_EN);
+
+	/* write the reference divider */
+	aty_pll_wait_readupdate(par);
+	aty_st_pll(PPLL_REF_DIV, par->constants.ref_divider & 0x3ff);
+	aty_pll_writeupdate(par);
+
+	div3 = aty_ld_pll(PPLL_DIV_3);
+	div3 &= ~PPLL_FB3_DIV_MASK;
+	div3 |= pll->feedback_divider;
+	div3 &= ~PPLL_POST3_DIV_MASK;
+	div3 |= post_conv[pll->post_divider] << 16;
+
+	/* write feedback and post dividers */
+	aty_pll_wait_readupdate(par);
+	aty_st_pll(PPLL_DIV_3, div3);
+	aty_pll_writeupdate(par);
+
+	aty_pll_wait_readupdate(par);
+	aty_st_pll(HTOTAL_CNTL, 0);	/* no horiz crtc adjustment */
+	aty_pll_writeupdate(par);
+
+	/* clear the reset, just in case */
+	aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~PPLL_RESET);
+}
+
+
+static int
+aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
+		  const struct aty128fb_par *par)
+{
+	const struct aty128_constants c = par->constants;
+	unsigned char post_dividers[] = {1,2,4,8,3,6,12};
+	u32 output_freq;
+	u32 vclk;        /* in .01 MHz */
+	int i;
+	u32 n, d;
+
+	vclk = 100000000 / period_in_ps;	/* convert units to 10 kHz */
+
+	/* adjust pixel clock if necessary */
+	if (vclk > c.ppll_max)
+		vclk = c.ppll_max;
+	if (vclk * 12 < c.ppll_min)
+		vclk = c.ppll_min/12;
+
+	/* now, find an acceptable divider */
+	for (i = 0; i < sizeof(post_dividers); i++) {
+		output_freq = post_dividers[i] * vclk;
+		if (output_freq >= c.ppll_min && output_freq <= c.ppll_max)
+			break;
+	}
+
+	/* calculate feedback divider */
+	n = c.ref_divider * output_freq;
+	d = c.dotclock;
+
+	pll->post_divider = post_dividers[i];
+	pll->feedback_divider = round_div(n, d);
+	pll->vclk = vclk;
+
+	DBG("post %d feedback %d vlck %d output %d ref_divider %d "
+	    "vclk_per: %d\n", pll->post_divider,
+	    pll->feedback_divider, vclk, output_freq,
+	    c.ref_divider, period_in_ps);
+
+	return 0;
+}
+
+
+static int
+aty128_pll_to_var(const struct aty128_pll *pll, struct fb_var_screeninfo *var)
+{
+	var->pixclock = 100000000 / pll->vclk;
+
+	return 0;
+}
+
+
+static void
+aty128_set_fifo(const struct aty128_ddafifo *dsp,
+		const struct aty128fb_par *par)
+{
+	aty_st_le32(DDA_CONFIG, dsp->dda_config);
+	aty_st_le32(DDA_ON_OFF, dsp->dda_on_off);
+}
+
+
+static int
+aty128_ddafifo(struct aty128_ddafifo *dsp,
+	       const struct aty128_pll *pll,
+	       u32 depth,
+	       const struct aty128fb_par *par)
+{
+	const struct aty128_meminfo *m = par->mem;
+	u32 xclk = par->constants.xclk;
+	u32 fifo_width = par->constants.fifo_width;
+	u32 fifo_depth = par->constants.fifo_depth;
+	s32 x, b, p, ron, roff;
+	u32 n, d, bpp;
+
+	/* round up to multiple of 8 */
+	bpp = (depth+7) & ~7;
+
+	n = xclk * fifo_width;
+	d = pll->vclk * bpp;
+	x = round_div(n, d);
+
+	ron = 4 * m->MB +
+		3 * ((m->Trcd - 2 > 0) ? m->Trcd - 2 : 0) +
+		2 * m->Trp +
+		m->Twr +
+		m->CL +
+		m->Tr2w +
+		x;
+
+	DBG("x %x\n", x);
+
+	b = 0;
+	while (x) {
+		x >>= 1;
+		b++;
+	}
+	p = b + 1;
+
+	ron <<= (11 - p);
+
+	n <<= (11 - p);
+	x = round_div(n, d);
+	roff = x * (fifo_depth - 4);
+
+	if ((ron + m->Rloop) >= roff) {
+		printk(KERN_ERR "aty128fb: Mode out of range!\n");
+		return -EINVAL;
+	}
+
+	DBG("p: %x rloop: %x x: %x ron: %x roff: %x\n",
+	    p, m->Rloop, x, ron, roff);
+
+	dsp->dda_config = p << 16 | m->Rloop << 20 | x;
+	dsp->dda_on_off = ron << 16 | roff;
+
+	return 0;
+}
+
+
+/*
+ * This actually sets the video mode.
+ */
+static int
+aty128fb_set_par(struct fb_info *info)
+{ 
+	struct aty128fb_par *par = info->par;
+	u32 config;
+	int err;
+
+	if ((err = aty128_decode_var(&info->var, par)) != 0)
+		return err;
+
+	if (par->blitter_may_be_busy)
+		wait_for_idle(par);
+
+	/* clear all registers that may interfere with mode setting */
+	aty_st_le32(OVR_CLR, 0);
+	aty_st_le32(OVR_WID_LEFT_RIGHT, 0);
+	aty_st_le32(OVR_WID_TOP_BOTTOM, 0);
+	aty_st_le32(OV0_SCALE_CNTL, 0);
+	aty_st_le32(MPP_TB_CONFIG, 0);
+	aty_st_le32(MPP_GP_CONFIG, 0);
+	aty_st_le32(SUBPIC_CNTL, 0);
+	aty_st_le32(VIPH_CONTROL, 0);
+	aty_st_le32(I2C_CNTL_1, 0);         /* turn off i2c */
+	aty_st_le32(GEN_INT_CNTL, 0);	/* turn off interrupts */
+	aty_st_le32(CAP0_TRIG_CNTL, 0);
+	aty_st_le32(CAP1_TRIG_CNTL, 0);
+
+	aty_st_8(CRTC_EXT_CNTL + 1, 4);	/* turn video off */
+
+	aty128_set_crtc(&par->crtc, par);
+	aty128_set_pll(&par->pll, par);
+	aty128_set_fifo(&par->fifo_reg, par);
+
+	config = aty_ld_le32(CONFIG_CNTL) & ~3;
+
+#if defined(__BIG_ENDIAN)
+	if (par->crtc.bpp == 32)
+		config |= 2;	/* make aperture do 32 bit swapping */
+	else if (par->crtc.bpp == 16)
+		config |= 1;	/* make aperture do 16 bit swapping */
+#endif
+
+	aty_st_le32(CONFIG_CNTL, config);
+	aty_st_8(CRTC_EXT_CNTL + 1, 0);	/* turn the video back on */
+
+	info->fix.line_length = (par->crtc.vxres * par->crtc.bpp) >> 3;
+	info->fix.visual = par->crtc.bpp == 8 ? FB_VISUAL_PSEUDOCOLOR
+		: FB_VISUAL_DIRECTCOLOR;
+
+#ifdef CONFIG_PMAC_PBOOK
+	if (par->chip_gen == rage_M3) {
+		aty128_set_crt_enable(par, par->crt_on);
+		aty128_set_lcd_enable(par, par->lcd_on);
+	}
+#endif
+	if (par->accel_flags & FB_ACCELF_TEXT)
+		aty128_init_engine(par);
+
+#ifdef CONFIG_BOOTX_TEXT
+	btext_update_display(info->fix.smem_start,
+			     (((par->crtc.h_total>>16) & 0xff)+1)*8,
+			     ((par->crtc.v_total>>16) & 0x7ff)+1,
+			     par->crtc.bpp,
+			     par->crtc.vxres*par->crtc.bpp/8);
+#endif /* CONFIG_BOOTX_TEXT */
+
+	return 0;
+}
+
+/*
+ *  encode/decode the User Defined Part of the Display
+ */
+
+static int
+aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par)
+{
+	int err;
+	struct aty128_crtc crtc;
+	struct aty128_pll pll;
+	struct aty128_ddafifo fifo_reg;
+
+	if ((err = aty128_var_to_crtc(var, &crtc, par)))
+		return err;
+
+	if ((err = aty128_var_to_pll(var->pixclock, &pll, par)))
+		return err;
+
+	if ((err = aty128_ddafifo(&fifo_reg, &pll, crtc.depth, par)))
+		return err;
+
+	par->crtc = crtc;
+	par->pll = pll;
+	par->fifo_reg = fifo_reg;
+	par->accel_flags = var->accel_flags;
+
+	return 0;
+}
+
+
+static int
+aty128_encode_var(struct fb_var_screeninfo *var,
+		  const struct aty128fb_par *par)
+{
+	int err;
+
+	if ((err = aty128_crtc_to_var(&par->crtc, var)))
+		return err;
+
+	if ((err = aty128_pll_to_var(&par->pll, var)))
+		return err;
+
+	var->nonstd = 0;
+	var->activate = 0;
+
+	var->height = -1;
+	var->width = -1;
+	var->accel_flags = par->accel_flags;
+
+	return 0;
+}           
+
+
+static int
+aty128fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	struct aty128fb_par par;
+	int err;
+
+	par = *(struct aty128fb_par *)info->par;
+	if ((err = aty128_decode_var(var, &par)) != 0)
+		return err;
+	aty128_encode_var(var, &par);
+	return 0;
+}
+
+
+/*
+ *  Pan or Wrap the Display
+ */
+static int
+aty128fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fb) 
+{
+	struct aty128fb_par *par = fb->par;
+	u32 xoffset, yoffset;
+	u32 offset;
+	u32 xres, yres;
+
+	xres = (((par->crtc.h_total >> 16) & 0xff) + 1) << 3;
+	yres = ((par->crtc.v_total >> 16) & 0x7ff) + 1;
+
+	xoffset = (var->xoffset +7) & ~7;
+	yoffset = var->yoffset;
+
+	if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
+		return -EINVAL;
+
+	par->crtc.xoffset = xoffset;
+	par->crtc.yoffset = yoffset;
+
+	offset = ((yoffset * par->crtc.vxres + xoffset)*(par->crtc.bpp >> 3)) & ~7;
+
+	if (par->crtc.bpp == 24)
+		offset += 8 * (offset % 3); /* Must be multiple of 8 and 3 */
+
+	aty_st_le32(CRTC_OFFSET, offset);
+
+	return 0;
+}
+
+
+/*
+ *  Helper function to store a single palette register
+ */
+static void
+aty128_st_pal(u_int regno, u_int red, u_int green, u_int blue,
+	      struct aty128fb_par *par)
+{
+	if (par->chip_gen == rage_M3) {
+#if 0
+		/* Note: For now, on M3, we set palette on both heads, which may
+		 * be useless. Can someone with a M3 check this ?
+		 * 
+		 * This code would still be useful if using the second CRTC to 
+		 * do mirroring
+		 */
+
+		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
+		aty_st_8(PALETTE_INDEX, regno);
+		aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue);
+#endif
+		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
+	}
+
+	aty_st_8(PALETTE_INDEX, regno);
+	aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue);
+}
+
+static int
+aty128fb_sync(struct fb_info *info)
+{
+	struct aty128fb_par *par = info->par;
+
+	if (par->blitter_may_be_busy)
+		wait_for_idle(par);
+	return 0;
+}
+
+int __init
+aty128fb_setup(char *options)
+{
+	char *this_opt;
+
+	if (!options || !*options)
+		return 0;
+
+	while ((this_opt = strsep(&options, ",")) != NULL) {
+#ifdef CONFIG_PMAC_PBOOK
+		if (!strncmp(this_opt, "lcd:", 4)) {
+			default_lcd_on = simple_strtoul(this_opt+4, NULL, 0);
+			continue;
+		} else if (!strncmp(this_opt, "crt:", 4)) {
+			default_crt_on = simple_strtoul(this_opt+4, NULL, 0);
+			continue;
+		}
+#endif
+#ifdef CONFIG_MTRR
+		if(!strncmp(this_opt, "nomtrr", 6)) {
+			mtrr = 0;
+			continue;
+		}
+#endif
+#ifdef CONFIG_ALL_PPC
+		/* vmode and cmode deprecated */
+		if (!strncmp(this_opt, "vmode:", 6)) {
+			unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
+			if (vmode > 0 && vmode <= VMODE_MAX)
+				default_vmode = vmode;
+			continue;
+		} else if (!strncmp(this_opt, "cmode:", 6)) {
+			unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
+			switch (cmode) {
+			case 0:
+			case 8:
+				default_cmode = CMODE_8;
+				break;
+			case 15:
+			case 16:
+				default_cmode = CMODE_16;
+				break;
+			case 24:
+			case 32:
+				default_cmode = CMODE_32;
+				break;
+			}
+			continue;
+		}
+#endif /* CONFIG_ALL_PPC */
+		mode_option = this_opt;
+	}
+	return 0;
+}
+
+
+/*
+ *  Initialisation
+ */
+
+static int __init
+aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	struct fb_info *info = pci_get_drvdata(pdev);
+	struct aty128fb_par *par = info->par;
+	struct fb_var_screeninfo var;
+	char video_card[25];
+	u8 chip_rev;
+	u32 dac;
+
+	if (!par->vram_size)	/* may have already been probed */
+		par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
+
+	/* Get the chip revision */
+	chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
+
+	switch (pdev->device) {
+		case PCI_DEVICE_ID_ATI_RAGE128_RE:
+			strcpy(video_card, "Rage128 RE (PCI)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_RF:
+			strcpy(video_card, "Rage128 RF (AGP)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_RK:
+			strcpy(video_card, "Rage128 RK (PCI)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_RL:
+			strcpy(video_card, "Rage128 RL (AGP)");
+			break;
+		case PCI_DEVICE_ID_ATI_Rage128_PD:
+			strcpy(video_card, "Rage128 Pro PD (PCI)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_PF:
+			strcpy(video_card, "Rage128 Pro PF (AGP)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_PR:
+			strcpy(video_card, "Rage128 Pro PR (PCI)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_U3:
+			strcpy(video_card, "Rage128 Pro TR (AGP)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_U1:
+			strcpy(video_card, "Rage128 Pro TF (AGP)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_LE:
+			strcpy(video_card, "Rage Mobility M3 (PCI)");
+			break;
+		case PCI_DEVICE_ID_ATI_RAGE128_LF:
+			strcpy(video_card, "Rage Mobility M3 (AGP)");
+			break;
+		default:
+			return -ENODEV;
+	}
+
+	printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);
+
+	if (par->vram_size % (1024 * 1024) == 0)
+		printk("%dM %s\n", par->vram_size / (1024*1024), par->mem->name);
+	else
+		printk("%dk %s\n", par->vram_size / 1024, par->mem->name);
+
+	par->chip_gen = ent->driver_data;
+
+	/* fill in info */
+	info->node  = NODEV;
+	info->fbops = &aty128fb_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
+
+#ifdef CONFIG_PMAC_PBOOK
+	par->lcd_on = default_lcd_on;
+	par->crt_on = default_crt_on;
+#endif
+
+	var = default_var;
+#ifdef CONFIG_ALL_PPC
+	if (_machine == _MACH_Pmac) {
+		if (mode_option) {
+			if (!mac_find_mode(&var, info, mode_option, 8))
+				var = default_var;
+		} else {
+			if (default_vmode <= 0 || default_vmode > VMODE_MAX)
+				default_vmode = VMODE_1024_768_60;
+
+			/* iMacs need that resolution
+			 * PowerMac2,1 first r128 iMacs
+			 * PowerMac2,2 summer 2000 iMacs
+			 * PowerMac4,1 january 2001 iMacs "flower power"
+			 */
+			if (machine_is_compatible("PowerMac2,1") ||
+			    machine_is_compatible("PowerMac2,2") ||
+			    machine_is_compatible("PowerMac4,1"))
+				default_vmode = VMODE_1024_768_75;
+
+			/* iBook SE */
+			if (machine_is_compatible("PowerBook2,2"))
+				default_vmode = VMODE_800_600_60;
+
+			/* PowerBook Firewire (Pismo), iBook Dual USB */
+			if (machine_is_compatible("PowerBook3,1") ||
+			    machine_is_compatible("PowerBook4,1"))
+				default_vmode = VMODE_1024_768_60;
+
+			/* PowerBook Titanium */
+			if (machine_is_compatible("PowerBook3,2"))
+				default_vmode = VMODE_1152_768_60;
+	
+			if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
+				default_cmode = CMODE_8;
+
+			if (mac_vmode_to_var(default_vmode, default_cmode, &var))
+				var = default_var;
+		}
+	} else
+#endif /* CONFIG_ALL_PPC */
+	{
+		if (fb_find_mode(&var, info, mode_option, NULL, 0,
+				 &defaultmode, 8) == 0)
+			var = default_var;
+	}
+
+	var.accel_flags &= ~FB_ACCELF_TEXT;
+//	var.accel_flags |= FB_ACCELF_TEXT;/* FIXME Will add accel later */
+
+	if (aty128fb_check_var(&var, info)) {
+		printk(KERN_ERR "aty128fb: Cannot set default mode.\n");
+		return 0;
+	}
+
+	/* setup the DAC the way we like it */
+	dac = aty_ld_le32(DAC_CNTL);
+	dac |= (DAC_8BIT_EN | DAC_RANGE_CNTL);
+	dac |= DAC_MASK;
+	if (par->chip_gen == rage_M3)
+		dac |= DAC_PALETTE2_SNOOP_EN;
+	aty_st_le32(DAC_CNTL, dac);
+
+	/* turn off bus mastering, just in case */
+	aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_MASTER_DIS);
+
+	info->var = var;
+	fb_alloc_cmap(&info->cmap, 256, 0);
+
+	var.activate = FB_ACTIVATE_NOW;
+
+	aty128_init_engine(par);
+
+	if (register_framebuffer(info) < 0)
+		return 0;
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	/* Could be extended to Rage128Pro LVDS output too */
+	if (par->chip_gen == rage_M3)
+		register_backlight_controller(&aty128_backlight_controller, par, "ati");
+#endif /* CONFIG_PMAC_BACKLIGHT */
+#ifdef CONFIG_PMAC_PBOOK
+	par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
+	if (aty128_fb == NULL) {
+		/* XXX can only put one chip to sleep */
+		aty128_fb = info;
+	} else
+		printk(KERN_WARNING "aty128fb: can only sleep one Rage 128\n");
+	par->pdev = pdev;
+#endif
+
+	printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
+	       minor(info->node), info->fix.id, video_card);
+
+	return 1;	/* success! */
+}
+
+#ifdef CONFIG_PCI
+/* register a card    ++ajoshi */
+static int __init
+aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	unsigned long fb_addr, reg_addr;
+	struct aty128fb_par *par;
+	struct fb_info *info;
+	int err, size;
+#if !defined(CONFIG_PPC) && !defined(__sparc__)
+	void *bios = NULL;
+#endif
+
+	/* Enable device in PCI config */
+	if ((err = pci_enable_device(pdev))) {
+		printk(KERN_ERR "aty128fb: Cannot enable PCI device: %d\n",
+				err);
+		return -ENODEV;
+	}
+
+	fb_addr = pci_resource_start(pdev, 0);
+	if (!request_mem_region(fb_addr, pci_resource_len(pdev, 0),
+				"aty128fb FB")) {
+		printk(KERN_ERR "aty128fb: cannot reserve frame "
+				"buffer memory\n");
+		return -ENODEV;
+	}
+
+	reg_addr = pci_resource_start(pdev, 2);
+	if (!request_mem_region(reg_addr, pci_resource_len(pdev, 2),
+				"aty128fb MMIO")) {
+		printk(KERN_ERR "aty128fb: cannot reserve MMIO region\n");
+		goto err_free_fb;
+	}
+
+	/* We have the resources. Now virtualize them */
+	size = sizeof(struct fb_info) + sizeof(struct aty128fb_par);
+	if (!(info = kmalloc(size, GFP_ATOMIC))) {
+		printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n");
+		goto err_free_mmio;
+	}
+	memset(info, 0, size);
+
+	par = (struct aty128fb_par *)(info + 1);
+	info->pseudo_palette = par->pseudo_palette;
+
+	info->par = par;
+	info->fix = aty128fb_fix;
+
+	/* Virtualize mmio region */
+	info->fix.mmio_start = reg_addr;
+	par->regbase = ioremap(reg_addr, pci_resource_len(pdev, 2));
+	if (!par->regbase)
+		goto err_free_info;
+
+	/* Grab memory size from the card */
+	// How does this relate to the resource length from the PCI hardware?
+	par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
+
+	/* Virtualize the framebuffer */
+	info->screen_base = ioremap(fb_addr, par->vram_size);
+	if (!info->screen_base)
+		goto err_unmap_out;
+
+	/* Set up info->fix */
+	info->fix = aty128fb_fix;
+	info->fix.smem_start = fb_addr;
+	info->fix.smem_len = par->vram_size;
+	info->fix.mmio_start = reg_addr;
+
+	/* If we can't test scratch registers, something is seriously wrong */
+	if (!register_test(par)) {
+		printk(KERN_ERR "aty128fb: Can't write to video register!\n");
+		goto err_out;
+	}
+
+#if !defined(CONFIG_PPC) && !defined(__sparc__)
+	if (!(bios = aty128_map_ROM(pdev)))
+		printk(KERN_INFO "aty128fb: BIOS not located, guessing timings.\n");
+	else {
+		printk(KERN_INFO "aty128fb: Rage128 BIOS located at %lx\n",
+				pdev->resource[PCI_ROM_RESOURCE].start);
+		aty128_get_pllinfo(par, bios);
+		aty128_unmap_ROM(pdev, bios);
+	}
+#endif
+	aty128_timings(par);
+	pci_set_drvdata(pdev, info);
+
+	if (!aty128_init(pdev, ent))
+		goto err_out;
+
+#ifdef CONFIG_MTRR
+	if (mtrr) {
+		par->mtrr.vram = mtrr_add(info->fix.smem_start,
+				par->vram_size, MTRR_TYPE_WRCOMB, 1);
+		par->mtrr.vram_valid = 1;
+		/* let there be speed */
+		printk(KERN_INFO "aty128fb: Rage128 MTRR set to ON\n");
+	}
+#endif /* CONFIG_MTRR */
+	return 0;
+
+err_out:
+	iounmap(info->screen_base);
+err_unmap_out:
+	iounmap(par->regbase);
+err_free_info:
+	kfree(info);
+err_free_mmio:
+	release_mem_region(pci_resource_start(pdev, 2),
+			pci_resource_len(pdev, 2));
+err_free_fb:
+	release_mem_region(pci_resource_start(pdev, 0),
+			pci_resource_len(pdev, 0));
+	return -ENODEV;
+}
+
+static void __devexit aty128_remove(struct pci_dev *pdev)
+{
+	struct fb_info *info = pci_get_drvdata(pdev);
+	struct aty128fb_par *par = info->par;
+
+	if (!info)
+		return;
+
+	unregister_framebuffer(info);
+#ifdef CONFIG_MTRR
+	if (par->mtrr.vram_valid)
+		mtrr_del(par->mtrr.vram, info->fix.smem_start,
+			 par->vram_size);
+#endif /* CONFIG_MTRR */
+	iounmap(par->regbase);
+	iounmap(info->screen_base);
+
+	release_mem_region(pci_resource_start(pdev, 0),
+			   pci_resource_len(pdev, 0));
+	release_mem_region(pci_resource_start(pdev, 1),
+			   pci_resource_len(pdev, 1));
+	release_mem_region(pci_resource_start(pdev, 2),
+			   pci_resource_len(pdev, 2));
+#ifdef CONFIG_PMAC_PBOOK
+	if (info == aty128_fb)
+		aty128_fb = NULL;
+#endif
+	kfree(info);
+}
+#endif /* CONFIG_PCI */
+
+/* PPC and Sparc cannot read video ROM */
+#if !defined(CONFIG_PPC) && !defined(__sparc__)
+static void * __init aty128_map_ROM(struct pci_dev *dev)
+{
+	// If this is a primary card, there is a shadow copy of the
+	// ROM somewhere in the first meg. We will just ignore the copy
+	// and use the ROM directly.
+	
+	// no need to search for the ROM, just ask the card where it is.
+	struct resource *r = &dev->resource[PCI_ROM_RESOURCE];
+	unsigned char *addr;
+	
+	// assign the ROM an address if it doesn't have one
+	if (r->start == 0)
+		pci_assign_resource(dev, PCI_ROM_RESOURCE);
+	
+	// enable if needed
+	if (!(r->flags & PCI_ROM_ADDRESS_ENABLE))
+		pci_write_config_dword(dev, dev->rom_base_reg, r->start | PCI_ROM_ADDRESS_ENABLE);
+	
+	addr = ioremap(r->start, r->end - r->start + 1);
+	
+	// Very simple test to make sure it appeared
+	if (addr && (*addr != 0x55)) {
+		printk("aty128fb: Invalid ROM signature %x\n", *addr);
+		iounmap(addr);
+		return NULL;
+	}
+	return (void *)addr;
+}
+
+static void __init aty128_unmap_ROM(struct pci_dev *dev, void * rom)
+{
+	// leave it disabled and unassigned
+	struct resource *r = &dev->resource[PCI_ROM_RESOURCE];
+	
+	iounmap(rom);
+	
+	r->flags &= !PCI_ROM_ADDRESS_ENABLE;
+	r->end -= r->start;
+	r->start = 0;
+	pci_write_config_dword(dev, dev->rom_base_reg, 0);
+}
+
+static void __init
+aty128_get_pllinfo(struct aty128fb_par *par, void *bios)
+{
+	void *bios_header;
+	void *header_ptr;
+	u16 bios_header_offset, pll_info_offset;
+	PLL_BLOCK pll;
+
+	bios_header = (char *)bios + 0x48L;
+	header_ptr  = bios_header;
+
+	bios_header_offset = readw(header_ptr);
+	bios_header = (char *)bios + bios_header_offset;
+	bios_header += 0x30;
+
+	header_ptr = bios_header;
+	pll_info_offset = readw(header_ptr);
+	header_ptr = (char *)bios + pll_info_offset;
+
+	memcpy_fromio(&pll, header_ptr, 50);
+
+	par->constants.ppll_max = pll.PCLK_max_freq;
+	par->constants.ppll_min = pll.PCLK_min_freq;
+	par->constants.xclk = (u32)pll.XCLK;
+	par->constants.ref_divider = (u32)pll.PCLK_ref_divider;
+	par->constants.dotclock = (u32)pll.PCLK_ref_freq;
+
+	DBG("ppll_max %d ppll_min %d xclk %d ref_divider %d dotclock %d\n",
+			par->constants.ppll_max, par->constants.ppll_min,
+			par->constants.xclk, par->constants.ref_divider,
+			par->constants.dotclock);
+
+}           
+#endif /* !CONFIG_PPC */
+
+
+/* fill in known card constants if pll_block is not available */
+static void __init
+aty128_timings(struct aty128fb_par *par)
+{
+#ifdef CONFIG_ALL_PPC
+	/* instead of a table lookup, assume OF has properly
+	 * setup the PLL registers and use their values
+	 * to set the XCLK values and reference divider values */
+
+	u32 x_mpll_ref_fb_div;
+	u32 xclk_cntl;
+	u32 Nx, M;
+	unsigned PostDivSet[] = { 0, 1, 2, 4, 8, 3, 6, 12 };
+#endif
+
+	if (!par->constants.dotclock)
+		par->constants.dotclock = 2950;
+
+#ifdef CONFIG_ALL_PPC
+	x_mpll_ref_fb_div = aty_ld_pll(X_MPLL_REF_FB_DIV);
+	xclk_cntl = aty_ld_pll(XCLK_CNTL) & 0x7;
+	Nx = (x_mpll_ref_fb_div & 0x00ff00) >> 8;
+	M  = x_mpll_ref_fb_div & 0x0000ff;
+
+	par->constants.xclk = round_div((2 * Nx * par->constants.dotclock),
+					(M * PostDivSet[xclk_cntl]));
+
+	par->constants.ref_divider =
+		aty_ld_pll(PPLL_REF_DIV) & PPLL_REF_DIV_MASK;
+#endif
+
+	if (!par->constants.ref_divider) {
+		par->constants.ref_divider = 0x3b;
+
+		aty_st_pll(X_MPLL_REF_FB_DIV, 0x004c4c1e);
+		aty_pll_writeupdate(par);
+	}
+	aty_st_pll(PPLL_REF_DIV, par->constants.ref_divider);
+	aty_pll_writeupdate(par);
+
+	/* from documentation */
+	if (!par->constants.ppll_min)
+		par->constants.ppll_min = 12500;
+	if (!par->constants.ppll_max)
+		par->constants.ppll_max = 25000;    /* 23000 on some cards? */
+	if (!par->constants.xclk)
+		par->constants.xclk = 0x1d4d;	     /* same as mclk */
+
+	par->constants.fifo_width = 128;
+	par->constants.fifo_depth = 32;
+
+	switch (aty_ld_le32(MEM_CNTL) & 0x3) {
+	case 0:
+		par->mem = &sdr_128;
+		break;
+	case 1:
+		par->mem = &sdr_sgram;
+		break;
+	case 2:
+		par->mem = &ddr_sgram;
+		break;
+	default:
+		par->mem = &sdr_sgram;
+	}
+}
+
+
+    /*
+     *  Blank the display.
+     */
+static int
+aty128fb_blank(int blank, struct fb_info *fb)
+{
+	struct aty128fb_par *par = fb->par;
+	u8 state = 0;
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	if ((_machine == _MACH_Pmac) && blank)
+		set_backlight_enable(0);
+#endif /* CONFIG_PMAC_BACKLIGHT */
+
+	if (blank & VESA_VSYNC_SUSPEND)
+		state |= 2;
+	if (blank & VESA_HSYNC_SUSPEND)
+		state |= 1;
+	if (blank & VESA_POWERDOWN)
+		state |= 4;
+
+	aty_st_8(CRTC_EXT_CNTL+1, state);
+
+#ifdef CONFIG_PMAC_PBOOK
+	if (par->chip_gen == rage_M3) {
+		aty128_set_crt_enable(par, par->crt_on && !blank);
+		aty128_set_lcd_enable(par, par->lcd_on && !blank);
+	}
+#endif	
+#ifdef CONFIG_PMAC_BACKLIGHT
+	if ((_machine == _MACH_Pmac) && !blank)
+		set_backlight_enable(1);
+#endif /* CONFIG_PMAC_BACKLIGHT */
+	return 0;
+}
+
+/*
+ *  Set a single color register. The values supplied are already
+ *  rounded down to the hardware's capabilities (according to the
+ *  entries in the var structure). Return != 0 for invalid regno.
+ */
+static int
+aty128fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp, struct fb_info *info)
+{
+	struct aty128fb_par *par = info->par;
+
+	if (regno > 255
+	    || (par->crtc.depth == 16 && regno > 63)
+	    || (par->crtc.depth == 15 && regno > 31))
+		return 1;
+
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+
+	if (regno < 16) {
+		int i;
+		switch (par->crtc.depth) {
+		case 15:
+			((u16 *) (info->pseudo_palette))[regno] =
+			    (regno << 10) | (regno << 5) | regno;
+			break;
+		case 16:
+			((u16 *) (info->pseudo_palette))[regno] =
+			    (regno << 11) | (regno << 6) | regno;
+			break;
+		case 24:
+			((u32 *) (info->pseudo_palette))[regno] =
+			    (regno << 16) | (regno << 8) | regno;
+			break;
+		case 32:
+			i = (regno << 8) | regno;
+			((u32 *) (info->pseudo_palette))[regno] =
+			    (i << 16) | i;
+			break;
+		}
+	}
+
+	if (par->crtc.depth == 16 && regno > 0) {
+		/*
+		 * With the 5-6-5 split of bits for RGB at 16 bits/pixel, we
+		 * have 32 slots for R and B values but 64 slots for G values.
+		 * Thus the R and B values go in one slot but the G value
+		 * goes in a different slot, and we have to avoid disturbing
+		 * the other fields in the slots we touch.
+		 */
+		par->green[regno] = green;
+		if (regno < 32) {
+			par->red[regno] = red;
+			par->blue[regno] = blue;
+			aty128_st_pal(regno * 8, red, par->green[regno*2],
+				      blue, par);
+		}
+		red = par->red[regno/2];
+		blue = par->blue[regno/2];
+		regno <<= 2;
+	} else if (par->crtc.bpp == 16)
+		regno <<= 3;
+	aty128_st_pal(regno, red, green, blue, par);
+
+	return 0;
+}
+
+#define ATY_MIRROR_LCD_ON	0x00000001
+#define ATY_MIRROR_CRT_ON	0x00000002
+
+/* out param: u32*	backlight value: 0 to 15 */
+#define FBIO_ATY128_GET_MIRROR	_IOR('@', 1, sizeof(__u32*))
+/* in param: u32*	backlight value: 0 to 15 */
+#define FBIO_ATY128_SET_MIRROR	_IOW('@', 2, sizeof(__u32*))
+
+static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+			  u_long arg, struct fb_info *info)
+{
+#ifdef CONFIG_PMAC_PBOOK
+	struct aty128fb_par *par = info->par;
+	u32 value;
+	int rc;
+    
+	switch (cmd) {
+	case FBIO_ATY128_SET_MIRROR:
+		if (par->chip_gen != rage_M3)
+			return -EINVAL;
+		rc = get_user(value, (__u32*)arg);
+		if (rc)
+			return rc;
+		par->lcd_on = (value & 0x01) != 0;
+		par->crt_on = (value & 0x02) != 0;
+		if (!par->crt_on && !par->lcd_on)
+			par->lcd_on = 1;
+		aty128_set_crt_enable(par, par->crt_on);	
+		aty128_set_lcd_enable(par, par->lcd_on);	
+		return 0;
+	case FBIO_ATY128_GET_MIRROR:
+		if (par->chip_gen != rage_M3)
+			return -EINVAL;
+		value = (par->crt_on << 1) | par->lcd_on;
+		return put_user(value, (__u32*)arg);
+	}
+#endif
+	return -EINVAL;
+}
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int backlight_conv[] = {
+	0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
+	0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
+};
+
+/* We turn off the LCD completely instead of just dimming the backlight.
+ * This provides greater power saving and the display is useless without
+ * backlight anyway
+ */
+#define BACKLIGHT_LVDS_OFF
+/* That one prevents proper CRT output with LCD off */
+#undef BACKLIGHT_DAC_OFF
+
+static int
+aty128_set_backlight_enable(int on, int level, void *data)
+{
+	struct aty128fb_par *par = data;
+	unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
+
+	if (!par->lcd_on)
+		on = 0;
+	reg |= LVDS_BL_MOD_EN | LVDS_BLON;
+	if (on && level > BACKLIGHT_OFF) {
+		reg |= LVDS_DIGION;
+		if (!reg & LVDS_ON) {
+			reg &= ~LVDS_BLON;
+			aty_st_le32(LVDS_GEN_CNTL, reg);
+			(void)aty_ld_le32(LVDS_GEN_CNTL);
+			mdelay(10);
+			reg |= LVDS_BLON;
+			aty_st_le32(LVDS_GEN_CNTL, reg);
+		}
+		reg &= ~LVDS_BL_MOD_LEVEL_MASK;
+		reg |= (backlight_conv[level] << LVDS_BL_MOD_LEVEL_SHIFT);
+#ifdef BACKLIGHT_LVDS_OFF
+		reg |= LVDS_ON | LVDS_EN;
+		reg &= ~LVDS_DISPLAY_DIS;
+#endif
+		aty_st_le32(LVDS_GEN_CNTL, reg);
+#ifdef BACKLIGHT_DAC_OFF
+		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & (~DAC_PDWN));
+#endif		
+	} else {
+		reg &= ~LVDS_BL_MOD_LEVEL_MASK;
+		reg |= (backlight_conv[0] << LVDS_BL_MOD_LEVEL_SHIFT);
+#ifdef BACKLIGHT_LVDS_OFF
+		reg |= LVDS_DISPLAY_DIS;
+		aty_st_le32(LVDS_GEN_CNTL, reg);
+		(void)aty_ld_le32(LVDS_GEN_CNTL);
+		udelay(10);
+		reg &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION);
+#endif		
+		aty_st_le32(LVDS_GEN_CNTL, reg);
+#ifdef BACKLIGHT_DAC_OFF
+		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PDWN);
+#endif		
+	}
+
+	return 0;
+}
+
+static int
+aty128_set_backlight_level(int level, void* data)
+{
+	return aty128_set_backlight_enable(1, level, data);
+}
+#endif /* CONFIG_PMAC_BACKLIGHT */
+
+#if 0
+    /*
+     *  Accelerated functions
+     */
+
+static inline void
+aty128_rectcopy(int srcx, int srcy, int dstx, int dsty,
+		u_int width, u_int height,
+		struct fb_info_aty128 *par)
+{
+    u32 save_dp_datatype, save_dp_cntl, dstval;
+
+    if (!width || !height)
+        return;
+
+    dstval = depth_to_dst(par->current_par.crtc.depth);
+    if (dstval == DST_24BPP) {
+        srcx *= 3;
+        dstx *= 3;
+        width *= 3;
+    } else if (dstval == -EINVAL) {
+        printk("aty128fb: invalid depth or RGBA\n");
+        return;
+    }
+
+    wait_for_fifo(2, par);
+    save_dp_datatype = aty_ld_le32(DP_DATATYPE);
+    save_dp_cntl     = aty_ld_le32(DP_CNTL);
+
+    wait_for_fifo(6, par);
+    aty_st_le32(SRC_Y_X, (srcy << 16) | srcx);
+    aty_st_le32(DP_MIX, ROP3_SRCCOPY | DP_SRC_RECT);
+    aty_st_le32(DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+    aty_st_le32(DP_DATATYPE, save_dp_datatype | dstval | SRC_DSTCOLOR);
+
+    aty_st_le32(DST_Y_X, (dsty << 16) | dstx);
+    aty_st_le32(DST_HEIGHT_WIDTH, (height << 16) | width);
+
+    par->blitter_may_be_busy = 1;
+
+    wait_for_fifo(2, par);
+    aty_st_le32(DP_DATATYPE, save_dp_datatype);
+    aty_st_le32(DP_CNTL, save_dp_cntl); 
+}
+
+
+    /*
+     * Text mode accelerated functions
+     */
+
+static void
+fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, int dx,
+			int height, int width)
+{
+    sx     *= fontwidth(p);
+    sy     *= fontheight(p);
+    dx     *= fontwidth(p);
+    dy     *= fontheight(p);
+    width  *= fontwidth(p);
+    height *= fontheight(p);
+
+    aty128_rectcopy(sx, sy, dx, dy, width, height,
+			(struct fb_info_aty128 *)p->fb_info);
+}
+#endif /* 0 */
+
+#ifdef CONFIG_PMAC_PBOOK
+static void
+aty128_set_suspend(struct aty128fb_par *par, int suspend)
+{
+	u32	pmgt;
+	u16	pwr_command;
+	struct pci_dev *pdev = par->pdev;
+
+	if (!par->pm_reg)
+		return;
+		
+	/* Set the chip into the appropriate suspend mode (we use D2,
+	 * D3 would require a complete re-initialisation of the chip,
+	 * including PCI config registers, clocks, AGP configuration, ...)
+	 */
+	if (suspend) {
+		/* Make sure CRTC2 is reset. Remove that the day we decide to
+		 * actually use CRTC2 and replace it with real code for disabling
+		 * the CRTC2 output during sleep
+		 */
+		aty_st_le32(CRTC2_GEN_CNTL, aty_ld_le32(CRTC2_GEN_CNTL) &
+			~(CRTC2_EN));
+
+		/* Set the power management mode to be PCI based */
+		/* Use this magic value for now */
+		pmgt = 0x0c005407;
+		aty_st_pll(POWER_MANAGEMENT, pmgt);
+		(void)aty_ld_pll(POWER_MANAGEMENT);
+		aty_st_le32(BUS_CNTL1, 0x00000010);
+		aty_st_le32(MEM_POWER_MISC, 0x0c830000);
+		mdelay(100);
+		pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+		/* Switch PCI power management to D2 */
+		pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL,
+			(pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2);
+		pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+	} else {
+		/* Switch back PCI power management to D0 */
+		mdelay(100);
+		pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 0);
+		pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+		mdelay(100);
+	}
+}
+
+/*
+ * Save the contents of the frame buffer when we go to sleep,
+ * and restore it when we wake up again.
+ */
+int
+aty128_sleep_notify(struct pmu_sleep_notifier *self, int when)
+{
+ 	int nb;
+	struct fb_info *info = aty128_fb;
+	struct aty128fb_par *par;
+
+	if (info == NULL)
+		return PBOOK_SLEEP_OK;
+	par = info->par;
+	nb = info->var.yres * info->fix.line_length;
+
+	switch (when) {
+	case PBOOK_SLEEP_REQUEST:
+		par->save_framebuffer = vmalloc(nb);
+		if (par->save_framebuffer == NULL)
+			return PBOOK_SLEEP_REFUSE;
+		break;
+	case PBOOK_SLEEP_REJECT:
+		if (par->save_framebuffer) {
+			vfree(par->save_framebuffer);
+			par->save_framebuffer = 0;
+		}
+		break;
+	case PBOOK_SLEEP_NOW:
+		wait_for_idle(par);
+		aty128_reset_engine(par);
+		wait_for_idle(par);
+
+		/* Backup fb content */	
+		if (par->save_framebuffer)
+			memcpy_fromio(par->save_framebuffer,
+			       info->screen_base, nb);
+
+		/* Blank display and LCD */
+		aty128fb_blank(VESA_POWERDOWN, info);
+			
+		/* Sleep the chip */
+		aty128_set_suspend(par, 1);
+
+		break;
+	case PBOOK_WAKE:
+		/* Wake the chip */
+		aty128_set_suspend(par, 0);
+		
+		aty128_reset_engine(par);
+		wait_for_idle(par);
+
+		/* Restore fb content */			
+		if (par->save_framebuffer) {
+			memcpy_toio(info->screen_base,
+			       par->save_framebuffer, nb);
+			vfree(par->save_framebuffer);
+			par->save_framebuffer = 0;
+		}
+		aty128fb_blank(0, info);
+		break;
+	}
+	return PBOOK_SLEEP_OK;
+}
+#endif /* CONFIG_PMAC_PBOOK */
+
+int __init aty128fb_init(void)
+{
+#ifdef CONFIG_PMAC_PBOOK
+	pmu_register_sleep_notifier(&aty128_sleep_notifier);
+#endif
+	return pci_module_init(&aty128fb_driver);
+}
+
+static void __exit aty128fb_exit(void)
+{
+#ifdef CONFIG_PMAC_PBOOK
+	pmu_unregister_sleep_notifier(&aty128_sleep_notifier);
+#endif
+	pci_unregister_driver(&aty128fb_driver);
+}
+
+MODULE_AUTHOR("(c)1999-2003 Brad Douglas <brad@neruo.com>");
+MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards");
+MODULE_LICENSE("GPL");
+MODULE_PARM(mode, "s");
+MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
+#ifdef CONFIG_MTRR
+MODULE_PARM(nomtrr, "i");
+MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
+#endif
+
diff -Nru a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
--- a/drivers/video/aty/atyfb.h	Fri Jan 10 16:51:25 2003
+++ b/drivers/video/aty/atyfb.h	Thu Feb 27 17:17:32 2003
@@ -36,13 +36,17 @@
 	u8 pll_ref_div;
 	u8 pll_gen_cntl;
 	u8 mclk_fb_div;
+	u8 mclk_fb_mult;	/* 2 ro 4 */
+	u8 sclk_fb_div;
 	u8 pll_vclk_cntl;
 	u8 vclk_post_div;
 	u8 vclk_fb_div;
 	u8 pll_ext_cntl;
+	u8 spll_cntl2;
 	u32 dsp_config;		/* Mach64 GTB DSP */
 	u32 dsp_on_off;		/* Mach64 GTB DSP */
 	u8 mclk_post_div_real;
+	u8 xclk_post_div_real;
 	u8 vclk_post_div_real;
 };
 
@@ -75,6 +79,7 @@
 	u32 ref_clk_per;
 	u32 pll_per;
 	u32 mclk_per;
+	u32 xclk_per;
 	u8 bus_type;
 	u8 ram_type;
 	u8 mem_refresh_rate;
@@ -118,7 +123,7 @@
 #define M64F_EXTRA_BRIGHT	0x00020000
 #define M64F_LT_SLEEP		0x00040000
 #define M64F_XL_DLL		0x00080000
-
+#define M64F_MFB_TIMES_4	0x00100000
 
     /*
      *  Register access
@@ -151,6 +156,33 @@
 #endif
 }
 
+static inline u16 aty_ld_le16(int regindex, const struct atyfb_par *par)
+{
+	/* Hack for bloc 1, should be cleanly optimized by compiler */
+	if (regindex >= 0x400)
+		regindex -= 0x800;
+
+#if defined(__mc68000__)
+	return le16_to_cpu(*((volatile u16 *)(par->ati_regbase + regindex)));
+#else
+	return readw(par->ati_regbase + regindex);
+#endif
+}
+
+static inline void aty_st_le16(int regindex, u16 val,
+				const struct atyfb_par *par)
+{
+	/* Hack for bloc 1, should be cleanly optimized by compiler */
+	if (regindex >= 0x400)
+		regindex -= 0x800;
+
+#if defined(__mc68000__)
+	*((volatile u16 *)(par->ati_regbase + regindex)) = cpu_to_le16(val);
+#else
+	writew(val, par->ati_regbase + regindex);
+#endif
+}
+
 static inline u8 aty_ld_8(int regindex, const struct atyfb_par *par)
 {
 	/* Hack for bloc 1, should be cleanly optimized by compiler */
@@ -188,6 +220,19 @@
 	return res;
 }
 
+
+/* 
+ * CT Family only.
+ */
+static inline void aty_st_pll(int offset, u8 val,
+				const struct atyfb_par *par)
+{
+	/* write addr byte */
+	aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN, par);
+	/* write the register value */
+	aty_st_8(CLOCK_CNTL + 2, val, par);
+	aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, par); 
+}
 
     /*
      *  DAC operations
diff -Nru a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
--- a/drivers/video/aty/atyfb_base.c	Sun Feb  2 22:10:25 2003
+++ b/drivers/video/aty/atyfb_base.c	Thu Feb 27 17:17:32 2003
@@ -88,7 +88,6 @@
 #include <asm/backlight.h>
 #endif
 
-
 /*
  * Debug flags.
  */
@@ -99,11 +98,9 @@
 /*  - must be aligned to a PAGE boundary           */
 #define GUI_RESERVE	(1 * PAGE_SIZE)
 
-
 /* FIXME: remove the FAIL definition */
 #define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
 
-
     /*
      *  The Hardware parameters for each card
      */
@@ -148,9 +145,9 @@
 static int atyfb_blank(int blank, struct fb_info *info);
 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
 		       u_long arg, struct fb_info *info);
-extern void atyfb_fillrect(struct fb_info *info, struct fb_fillrect *rect);
-extern void atyfb_copyarea(struct fb_info *info, struct fb_copyarea *area);
-extern void atyfb_imageblit(struct fb_info *info, struct fb_image *image);
+extern void atyfb_fillrect(struct fb_info *info,const struct fb_fillrect *rect);
+extern void atyfb_copyarea(struct fb_info *info,const struct fb_copyarea *area);
+extern void atyfb_imageblit(struct fb_info *info,const struct fb_image *image);
 #ifdef __sparc__
 static int atyfb_mmap(struct fb_info *info, struct file *file,
 		      struct vm_area_struct *vma);
@@ -162,6 +159,9 @@
      */
 
 static int aty_init(struct fb_info *info, const char *name);
+#ifdef CONFIG_FB_ATY_XL_INIT
+extern int atyfb_xl_init(struct fb_info *info);
+#endif
 #ifdef CONFIG_ATARI
 static int store_video_par(char *videopar, unsigned char m64_num);
 #endif
@@ -214,6 +214,7 @@
 static u32 default_vram __initdata = 0;
 static int default_pll __initdata = 0;
 static int default_mclk __initdata = 0;
+static int default_xclk __initdata = 0;
 
 #ifndef MODULE
 static char *mode_option __initdata = NULL;
@@ -254,7 +255,8 @@
 static char m64n_gtc_pp[] __initdata = "3D RAGE PRO (PQFP, PCI)";
 static char m64n_gtc_ppl[] __initdata =
     "3D RAGE PRO (PQFP, PCI, limited 3D)";
-static char m64n_xl[] __initdata = "3D RAGE (XL)";
+static char m64n_xl_33[] __initdata = "3D RAGE (XL PCI-33MHz)";
+static char m64n_xl_66[] __initdata = "3D RAGE (XL PCI-66MHz)";
 static char m64n_ltp_a[] __initdata = "3D RAGE LT PRO (AGP)";
 static char m64n_ltp_p[] __initdata = "3D RAGE LT PRO (PCI)";
 static char m64n_mob_p[] __initdata = "3D RAGE Mobility (PCI)";
@@ -265,129 +267,62 @@
 	u16 pci_id, chip_type;
 	u8 rev_mask, rev_val;
 	const char *name;
-	int pll, mclk;
+	int pll, mclk, xclk;
 	u32 features;
 } aty_chips[] __initdata = {
 #ifdef CONFIG_FB_ATY_GX
 	/* Mach64 GX */
-	{
-	0x4758, 0x00d7, 0x00, 0x00, m64n_gx, 135, 50, M64F_GX}, {
-	0x4358, 0x0057, 0x00, 0x00, m64n_cx, 135, 50, M64F_GX},
-#endif				/* CONFIG_FB_ATY_GX */
+	{ 0x4758, 0x00d7, 0x00, 0x00, m64n_gx, 135, 50, 50, M64F_GX },
+	{ 0x4358, 0x0057, 0x00, 0x00, m64n_cx, 135, 50, 50, M64F_GX },
+#endif /* CONFIG_FB_ATY_GX */
+
 #ifdef CONFIG_FB_ATY_CT
-	    /* Mach64 CT */
-	{
-	0x4354, 0x4354, 0x00, 0x00, m64n_ct, 135, 60,
-		    M64F_CT | M64F_INTEGRATED | M64F_CT_BUS |
-		    M64F_MAGIC_FIFO}, {
-	0x4554, 0x4554, 0x00, 0x00, m64n_et, 135, 60,
-		    M64F_CT | M64F_INTEGRATED | M64F_CT_BUS |
-		    M64F_MAGIC_FIFO},
-	    /* Mach64 VT */
-	{
-	0x5654, 0x5654, 0xc7, 0x00, m64n_vta3, 170, 67,
-		    M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |
-		    M64F_MAGIC_FIFO | M64F_FIFO_24}, {
-	0x5654, 0x5654, 0xc7, 0x40, m64n_vta4, 200, 67,
-		    M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |
-		    M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_MAGIC_POSTDIV}, {
-	0x5654, 0x5654, 0x00, 0x00, m64n_vtb, 200, 67,
-		    M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |
-		    M64F_GTB_DSP | M64F_FIFO_24}, {
-	0x5655, 0x5655, 0x00, 0x00, m64n_vtb, 200, 67,
-		    M64F_VT | M64F_INTEGRATED | M64F_VT_BUS |
-		    M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL}, {
-	0x5656, 0x5656, 0x00, 0x00, m64n_vt4, 230, 83,
-		    M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP},
-	    /* Mach64 GT (3D RAGE) */
-	{
-	0x4754, 0x4754, 0x07, 0x00, m64n_gt, 135, 63,
-		    M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO |
-		    M64F_FIFO_24 | M64F_EXTRA_BRIGHT}, {
-	0x4754, 0x4754, 0x07, 0x01, m64n_gt, 170, 67,
-		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
-		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
-		    M64F_EXTRA_BRIGHT}, {
-	0x4754, 0x4754, 0x07, 0x02, m64n_gt, 200, 67,
-		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
-		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
-		    M64F_EXTRA_BRIGHT}, {
-	0x4755, 0x4755, 0x00, 0x00, m64n_gtb, 200, 67,
-		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
-		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
-		    M64F_EXTRA_BRIGHT}, {
-	0x4756, 0x4756, 0x00, 0x00, m64n_iic_p, 230, 83,
-		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
-		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
-		    M64F_EXTRA_BRIGHT}, {
-	0x4757, 0x4757, 0x00, 0x00, m64n_iic_a, 230, 83,
-		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
-		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
-		    M64F_EXTRA_BRIGHT}, {
-	0x475a, 0x475a, 0x00, 0x00, m64n_iic_a, 230, 83,
-		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
-		    M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL |
-		    M64F_EXTRA_BRIGHT},
-	    /* Mach64 LT */
-	{
-	0x4c54, 0x4c54, 0x00, 0x00, m64n_lt, 135, 63,
-		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP}, {
-	0x4c47, 0x4c47, 0x00, 0x00, m64n_ltg, 230, 63,
-		    M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP |
-		    M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT |
-		    M64F_LT_SLEEP | M64F_G3_PB_1024x768},
-	    /* Mach64 GTC (3D RAGE PRO) */
-	{
-	0x4742, 0x4742, 0x00, 0x00, m64n_gtc_ba, 230, 100,
-		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
-		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
-		    M64F_EXTRA_BRIGHT}, {
-	0x4744, 0x4744, 0x00, 0x00, m64n_gtc_ba1, 230, 100,
-		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
-		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
-		    M64F_EXTRA_BRIGHT}, {
-	0x4749, 0x4749, 0x00, 0x00, m64n_gtc_bp, 230, 100,
-		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
-		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
-		    M64F_EXTRA_BRIGHT | M64F_MAGIC_VRAM_SIZE}, {
-	0x4750, 0x4750, 0x00, 0x00, m64n_gtc_pp, 230, 100,
-		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
-		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
-		    M64F_EXTRA_BRIGHT}, {
-	0x4751, 0x4751, 0x00, 0x00, m64n_gtc_ppl, 230, 100,
-		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
-		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
-		    M64F_EXTRA_BRIGHT},
-	    /* 3D RAGE XL */
-	{
-	0x4752, 0x4752, 0x00, 0x00, m64n_xl, 230, 100,
-		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
-		    M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL |
-		    M64F_EXTRA_BRIGHT | M64F_XL_DLL},
-	    /* Mach64 LT PRO */
-	{
-	0x4c42, 0x4c42, 0x00, 0x00, m64n_ltp_a, 230, 100,
-		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
-		    M64F_GTB_DSP}, {
-	0x4c44, 0x4c44, 0x00, 0x00, m64n_ltp_p, 230, 100,
-		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
-		    M64F_GTB_DSP}, {
-	0x4c49, 0x4c49, 0x00, 0x00, m64n_ltp_p, 230, 100,
-		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
-		    M64F_GTB_DSP | M64F_EXTRA_BRIGHT |
-		    M64F_G3_PB_1_1 | M64F_G3_PB_1024x768}, {
-	0x4c50, 0x4c50, 0x00, 0x00, m64n_ltp_p, 230, 100,
-		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
-		    M64F_GTB_DSP},
-	    /* 3D RAGE Mobility */
-	{
-	0x4c4d, 0x4c4d, 0x00, 0x00, m64n_mob_p, 230, 50,
-		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
-		    M64F_GTB_DSP | M64F_MOBIL_BUS}, {
-	0x4c4e, 0x4c4e, 0x00, 0x00, m64n_mob_a, 230, 50,
-		    M64F_GT | M64F_INTEGRATED | M64F_RESET_3D |
-		    M64F_GTB_DSP | M64F_MOBIL_BUS},
-#endif				/* CONFIG_FB_ATY_CT */
+	/* Mach64 CT */
+	{ 0x4354, 0x4354, 0x00, 0x00, m64n_ct, 135, 60, 60, M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO },
+	{ 0x4554, 0x4554, 0x00, 0x00, m64n_et, 135, 60, 60, M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO },
+
+	/* Mach64 VT */
+	{ 0x5654, 0x5654, 0xc7, 0x00, m64n_vta3, 170, 67, 67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO | M64F_FIFO_24 },
+	{ 0x5654, 0x5654, 0xc7, 0x40, m64n_vta4, 200, 67, 67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_MAGIC_POSTDIV },
+	{ 0x5654, 0x5654, 0x00, 0x00, m64n_vtb, 200, 67, 67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_FIFO_24 }, 
+	{ 0x5655, 0x5655, 0x00, 0x00, m64n_vtb, 200, 67, 67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL },
+	{ 0x5656, 0x5656, 0x00, 0x00, m64n_vt4, 230, 83, 83, M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP },
+
+	/* Mach64 GT (3D RAGE) */
+	{ 0x4754, 0x4754, 0x07, 0x00, m64n_gt, 135, 63, 63, M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_EXTRA_BRIGHT }, 
+	{ 0x4754, 0x4754, 0x07, 0x01, m64n_gt, 170, 67, 67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+	{ 0x4754, 0x4754, 0x07, 0x02, m64n_gt, 200, 67, 67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+	{ 0x4755, 0x4755, 0x00, 0x00, m64n_gtb, 200, 67, 67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+	{ 0x4756, 0x4756, 0x00, 0x00, m64n_iic_p, 230, 83, 83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+	{ 0x4757, 0x4757, 0x00, 0x00, m64n_iic_a, 230, 83, 83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+	{ 0x475a, 0x475a, 0x00, 0x00, m64n_iic_a, 230, 83, 83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+
+	/* Mach64 LT */
+	{ 0x4c54, 0x4c54, 0x00, 0x00, m64n_lt, 135, 63, 63, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP },
+	{ 0x4c47, 0x4c47, 0x00, 0x00, m64n_ltg, 230, 63, 63, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_LT_SLEEP | M64F_G3_PB_1024x768 },
+
+	/* Mach64 GTC (3D RAGE PRO) */
+	{ 0x4742, 0x4742, 0x00, 0x00, m64n_gtc_ba, 230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+	{ 0x4744, 0x4744, 0x00, 0x00, m64n_gtc_ba1, 230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+	{ 0x4749, 0x4749, 0x00, 0x00, m64n_gtc_bp, 230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_MAGIC_VRAM_SIZE },
+	{ 0x4750, 0x4750, 0x00, 0x00, m64n_gtc_pp, 230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+	{ 0x4751, 0x4751, 0x00, 0x00, m64n_gtc_ppl, 230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+
+	/* 3D RAGE XL PCI-66/BGA */
+	{ 0x474f, 0x474f, 0x00, 0x00, m64n_xl_66, 230, 83, 63, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_XL_DLL | M64F_MFB_TIMES_4 },
+	/* 3D RAGE XL PCI-33/BGA */
+	{ 0x4752, 0x4752, 0x00, 0x00, m64n_xl_33, 230, 83, 63, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_XL_DLL | M64F_MFB_TIMES_4 },
+
+	/* Mach64 LT PRO */
+	{ 0x4c42, 0x4c42, 0x00, 0x00, m64n_ltp_a, 230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
+	{ 0x4c44, 0x4c44, 0x00, 0x00, m64n_ltp_p, 230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
+	{ 0x4c49, 0x4c49, 0x00, 0x00, m64n_ltp_p, 230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_EXTRA_BRIGHT | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 },
+	{ 0x4c50, 0x4c50, 0x00, 0x00, m64n_ltp_p, 230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
+
+	/* 3D RAGE Mobility */
+	{ 0x4c4d, 0x4c4d, 0x00, 0x00, m64n_mob_p, 230, 50, 50, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_MOBIL_BUS },
+	{ 0x4c4e, 0x4c4e, 0x00, 0x00, m64n_mob_a, 230, 50, 50, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_MOBIL_BUS },
+#endif /* CONFIG_FB_ATY_CT */
 };
 
 static char ram_dram[] __initdata = "DRAM";
@@ -1003,7 +938,10 @@
 	u32 ref_clk_per;
 	u8 pll_ref_div;
 	u8 mclk_fb_div;
+	u8 sclk_fb_div;
 	u8 mclk_post_div;	/* 1,2,3,4,8 */
+	u8 mclk_fb_mult;	/* 2 or 4 */
+	u8 xclk_post_div;	/* 1,2,3,4,8 */
 	u8 vclk_fb_div;
 	u8 vclk_post_div;	/* 1,2,3,4,6,8,12 */
 	u32 dsp_xclks_per_row;	/* 0-16383 */
@@ -1051,14 +989,17 @@
 			clk.ref_clk_per = par->ref_clk_per;
 			clk.pll_ref_div = pll->ct.pll_ref_div;
 			clk.mclk_fb_div = pll->ct.mclk_fb_div;
+			clk.sclk_fb_div = pll->ct.sclk_fb_div;
 			clk.mclk_post_div = pll->ct.mclk_post_div_real;
+			clk.mclk_fb_mult = pll->ct.mclk_fb_mult;
+			clk.xclk_post_div = pll->ct.xclk_post_div_real;
 			clk.vclk_fb_div = pll->ct.vclk_fb_div;
 			clk.vclk_post_div = pll->ct.vclk_post_div_real;
 			clk.dsp_xclks_per_row = dsp_config & 0x3fff;
 			clk.dsp_loop_latency = (dsp_config >> 16) & 0xf;
 			clk.dsp_precision = (dsp_config >> 20) & 7;
-			clk.dsp_on = dsp_on_off & 0x7ff;
-			clk.dsp_off = (dsp_on_off >> 16) & 0x7ff;
+			clk.dsp_off = dsp_on_off & 0x7ff;
+			clk.dsp_on = (dsp_on_off >> 16) & 0x7ff;
 			if (copy_to_user
 			    ((struct atyclk *) arg, &clk, sizeof(clk)))
 				return -EFAULT;
@@ -1075,19 +1016,18 @@
 			par->ref_clk_per = clk.ref_clk_per;
 			pll->ct.pll_ref_div = clk.pll_ref_div;
 			pll->ct.mclk_fb_div = clk.mclk_fb_div;
+			pll->ct.sclk_fb_div = clk.sclk_fb_div;
 			pll->ct.mclk_post_div_real = clk.mclk_post_div;
+			pll->ct.mclk_fb_mult = clk.mclk_fb_mult;
+			pll->ct.xclk_post_div_real = clk.xclk_post_div;
 			pll->ct.vclk_fb_div = clk.vclk_fb_div;
 			pll->ct.vclk_post_div_real = clk.vclk_post_div;
-			pll->ct.dsp_config =
-			    (clk.
-			     dsp_xclks_per_row & 0x3fff) | ((clk.
-							     dsp_loop_latency
-							     & 0xf) << 16)
+			pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
+					     ((clk.dsp_loop_latency & 0xf)<<16)|
+					     ((clk.dsp_precision & 7)<<20);
 			    | ((clk.dsp_precision & 7) << 20);
-			pll->ct.dsp_on_off =
-			    (clk.
-			     dsp_on & 0x7ff) | ((clk.
-						 dsp_off & 0x7ff) << 16);
+			pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) |
+					     ((clk.dsp_on & 0x7ff)<<16);
 			aty_calc_pll_ct(info, &pll->ct);
 			aty_set_pll_ct(info, pll);
 		} else
@@ -1252,8 +1192,6 @@
 }
 #endif				/* __sparc__ */
 
-
-
 #ifdef CONFIG_PMAC_PBOOK
 
 static struct fb_info *first_display = NULL;
@@ -1494,7 +1432,32 @@
 };
 #endif				/* CONFIG_PMAC_BACKLIGHT */
 
+static void __init aty_calc_mem_refresh(struct atyfb_par *par, u16 id, int xclk)
+{
+	const int ragepro_tbl[] = {
+		44, 50, 55, 66, 75, 80, 100
+	};
+	const int ragexl_tbl[] = {
+		50, 66, 75, 83, 90, 95, 100, 105,
+		110, 115, 120, 125, 133, 143, 166
+	};
+	const int *refresh_tbl;
+	int i, size;
+
+	if (IS_XL(id)) {
+		refresh_tbl = ragexl_tbl;
+		size = sizeof(ragexl_tbl)/sizeof(int);
+	} else {
+		refresh_tbl = ragepro_tbl;
+		size = sizeof(ragepro_tbl)/sizeof(int);
+	}
 
+	for (i=0; i < size; i++) {
+		if (xclk < refresh_tbl[i])
+		break;
+	}
+	par->mem_refresh_rate = i;
+}
 
     /*
      *  Initialisation
@@ -1506,15 +1469,14 @@
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
 	const char *chipname = NULL, *ramname = NULL, *xtal;
-	int j, pll, mclk, gtb_memsize;
+	int pll, mclk, xclk, gtb_memsize, j;
 	struct fb_var_screeninfo var;
+	u8 pll_ref_div, rev;
 	u32 chip_id, i;
-	u16 type;
-	u8 rev;
 #if defined(CONFIG_PPC)
 	int sense;
 #endif
-	u8 pll_ref_div;
+	u16 type;
 
 	par->aty_cmap_regs =
 	    (struct aty_cmap_regs *) (par->ati_regbase + 0xc0);
@@ -1528,6 +1490,7 @@
 			chipname = aty_chips[j].name;
 			pll = aty_chips[j].pll;
 			mclk = aty_chips[j].mclk;
+			xclk = aty_chips[j].xclk;
 			par->features = aty_chips[j].features;
 			goto found;
 		}
@@ -1604,17 +1567,38 @@
 #endif				/* CONFIG_FB_ATY_GX */
 #ifdef CONFIG_FB_ATY_CT
 	if (M64_HAS(INTEGRATED)) {
-		par->bus_type = PCI;
-		par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
-		ramname = aty_ct_ram[par->ram_type];
-		par->dac_ops = &aty_dac_ct;
-		par->pll_ops = &aty_pll_ct;
 		/* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
 		if (mclk == 67 && par->ram_type < SDRAM)
 			mclk = 63;
 	}
 #endif				/* CONFIG_FB_ATY_CT */
 
+	if (default_pll)
+		pll = default_pll;
+	if (default_mclk)
+		mclk = default_mclk;
+	if (default_xclk)
+		xclk = default_xclk;
+
+	aty_calc_mem_refresh(par, type, xclk);
+	par->pll_per = 1000000/pll;
+	par->mclk_per = 1000000/mclk;
+	par->xclk_per = 1000000/xclk;
+
+#ifdef CONFIG_FB_ATY_CT
+	if (M64_HAS(INTEGRATED)) {
+		par->dac_ops = &aty_dac_ct;
+		par->pll_ops = &aty_pll_ct;
+		par->bus_type = PCI;
+#ifdef CONFIG_FB_ATY_XL_INIT
+		if (IS_XL(type))
+			atyfb_xl_init(info);
+#endif
+		par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
+		ramname = aty_ct_ram[par->ram_type];
+	}
+#endif /* CONFIG_FB_ATY_CT */
+
 	par->ref_clk_per = 1000000000000ULL / 14318180;
 	xtal = "14.31818";
 	if (M64_HAS(GTB_DSP)
@@ -1724,35 +1708,10 @@
 		info->fix.accel = FB_ACCEL_ATI_MACH64GT;
 	}
 
-	if (default_pll)
-		pll = default_pll;
-	if (default_mclk)
-		mclk = default_mclk;
-
-	printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK\n",
-	       info->fix.smem_len ==
-	       0x80000 ? 512 : (info->fix.smem_len >> 20),
-	       info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname,
-	       xtal, pll, mclk);
-
-	if (mclk < 44)
-		par->mem_refresh_rate = 0;	/* 000 = 10 Mhz - 43 Mhz */
-	else if (mclk < 50)
-		par->mem_refresh_rate = 1;	/* 001 = 44 Mhz - 49 Mhz */
-	else if (mclk < 55)
-		par->mem_refresh_rate = 2;	/* 010 = 50 Mhz - 54 Mhz */
-	else if (mclk < 66)
-		par->mem_refresh_rate = 3;	/* 011 = 55 Mhz - 65 Mhz */
-	else if (mclk < 75)
-		par->mem_refresh_rate = 4;	/* 100 = 66 Mhz - 74 Mhz */
-	else if (mclk < 80)
-		par->mem_refresh_rate = 5;	/* 101 = 75 Mhz - 79 Mhz */
-	else if (mclk < 100)
-		par->mem_refresh_rate = 6;	/* 110 = 80 Mhz - 100 Mhz */
-	else
-		par->mem_refresh_rate = 7;	/* 111 = 100 Mhz and above */
-	par->pll_per = 1000000 / pll;
-	par->mclk_per = 1000000 / mclk;
+	printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d MHz XCLK\n",
+	       info->fix.smem_len == 0x80000 ? 512 : (info->fix.smem_len >> 20),
+	       info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, pll,
+	       mclk, xclk);
 
 #ifdef DEBUG
 	if (M64_HAS(INTEGRATED)) {
@@ -2079,7 +2038,7 @@
 				j++;
 			}
 
-			if (pdev->device != XL_CHIP_ID) {
+			if (!IS_XL(pdev->device)) {
 				/*
 				 * Fix PROMs idea of MEM_CNTL settings...
 				 */
@@ -2205,7 +2164,7 @@
 				 *
 				 * where R is XTALIN (= 14318 or 29498 kHz).
 				 */
-				if (pdev->device == XL_CHIP_ID)
+				if (IS_XL(pdev->device))
 					R = 29498;
 				else
 					R = 14318;
@@ -2374,14 +2333,13 @@
 		} else if (!strncmp(this_opt, "noaccel", 7)) {
 			noaccel = 1;
 		} else if (!strncmp(this_opt, "vram:", 5))
-			default_vram =
-			    simple_strtoul(this_opt + 5, NULL, 0);
+			default_vram = simple_strtoul(this_opt + 5, NULL, 0);
 		else if (!strncmp(this_opt, "pll:", 4))
-			default_pll =
-			    simple_strtoul(this_opt + 4, NULL, 0);
+			default_pll = simple_strtoul(this_opt + 4, NULL, 0);
 		else if (!strncmp(this_opt, "mclk:", 5))
-			default_mclk =
-			    simple_strtoul(this_opt + 5, NULL, 0);
+			default_mclk = simple_strtoul(this_opt + 5, NULL, 0); 
+		else if (!strncmp(this_opt, "xclk:", 5))
+			default_xclk = simple_strtoul(this_opt+5, NULL, 0);
 #ifdef CONFIG_PPC
 		else if (!strncmp(this_opt, "vmode:", 6)) {
 			unsigned int vmode =
diff -Nru a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c
--- a/drivers/video/aty/mach64_accel.c	Fri Jan 10 16:51:25 2003
+++ b/drivers/video/aty/mach64_accel.c	Tue Feb 11 11:59:08 2003
@@ -170,11 +170,11 @@
 	par->blitter_may_be_busy = 1;
 }
 
-void atyfb_copyarea(struct fb_info *info, struct fb_copyarea *area)
+void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
-	
-	u32 direction = DST_LAST_PEL;
+	u32 dy = area->dy, sy = area->sy, direction = DST_LAST_PEL;
+	u32 sx = area->sx, dx = area->dx, width = area->width;	
 	u32 pitch_value;
 
 	if (!area->width || !area->height)
@@ -191,34 +191,35 @@
 		/* In 24 bpp, the engine is in 8 bpp - this requires that all */
 		/* horizontal coordinates and widths must be adjusted */
 		pitch_value *= 3;
-		area->sx *= 3;
-		area->dx *= 3;
-		area->width *= 3;
+		sx *= 3;
+		dx *= 3;
+		width *= 3;
 	}
 
 	if (area->sy < area->dy) {
-		area->dy += area->height - 1;
-		area->sy += area->height - 1;
+		dy += area->height - 1;
+		sy += area->height - 1;
 	} else
 		direction |= DST_Y_TOP_TO_BOTTOM;
 
-	if (area->sx < area->dx) {
-		area->dx += area->width - 1;
-		area->sx += area->width - 1;
+	if (sx < dx) {
+		dx += width - 1;
+		sx += width - 1;
 	} else
 		direction |= DST_X_LEFT_TO_RIGHT;
 
 	wait_for_fifo(4, par);
 	aty_st_le32(DP_SRC, FRGD_SRC_BLIT, par);
-	aty_st_le32(SRC_Y_X, (area->sx << 16) | area->sy, par);
-	aty_st_le32(SRC_HEIGHT1_WIDTH1, (area->width << 16) | area->height,par);
+	aty_st_le32(SRC_Y_X, (sx << 16) | sy, par);
+	aty_st_le32(SRC_HEIGHT1_WIDTH1, (width << 16) | area->height, par);
 	aty_st_le32(DST_CNTL, direction, par);
-	draw_rect(area->dx, area->dy, area->width, area->height, par);
+	draw_rect(dx, dy, width, area->height, par);
 }
 
-void atyfb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u32 color = rect->color, dx = rect->dx, width = rect->width;
 
 	if (!rect->width || !rect->height)
 		return;
@@ -229,28 +230,28 @@
 		return;
 	}
 
-	rect->color |= (rect->color << 8);
-	rect->color |= (rect->color << 16);
+	color |= (rect->color << 8);
+	color |= (rect->color << 16);
 
 	if (info->var.bits_per_pixel == 24) {
 		/* In 24 bpp, the engine is in 8 bpp - this requires that all */
 		/* horizontal coordinates and widths must be adjusted */
-		rect->dx *= 3;
-		rect->width *= 3;
+		dx *= 3;
+		width *= 3;
 	}
 
 	wait_for_fifo(3, par);
-	aty_st_le32(DP_FRGD_CLR, rect->color, par);
+	aty_st_le32(DP_FRGD_CLR, color, par);
 	aty_st_le32(DP_SRC,
 		    BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE,
 		    par);
 	aty_st_le32(DST_CNTL,
 		    DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
 		    DST_X_LEFT_TO_RIGHT, par);
-	draw_rect(rect->dx, rect->dy, rect->width, rect->height, par);
+	draw_rect(dx, rect->dy, width, rect->height, par);
 }
 
-void atyfb_imageblit(struct fb_info *info, struct fb_image *image)
+void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
     
diff -Nru a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
--- a/drivers/video/aty/mach64_ct.c	Sat Oct 12 12:51:46 2002
+++ b/drivers/video/aty/mach64_ct.c	Thu Feb 27 17:17:32 2003
@@ -4,58 +4,47 @@
  */
 
 #include <linux/fb.h>
-
+#include <linux/delay.h>
 #include <asm/io.h>
-
 #include <video/mach64.h>
 #include "atyfb.h"
 
+#undef DEBUG
 
-/* FIXME: remove the FAIL definition */
-#define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
-
-static void aty_st_pll(int offset, u8 val, const struct atyfb_par *par);
 static int aty_valid_pll_ct(const struct fb_info *info, u32 vclk_per,
 			    struct pll_ct *pll);
-static int aty_dsp_gt(const struct fb_info *info, u8 bpp,
+static int aty_dsp_gt(const struct fb_info *info, u32 bpp,
 		      struct pll_ct *pll);
 static int aty_var_to_pll_ct(const struct fb_info *info, u32 vclk_per,
 			     u8 bpp, union aty_pll *pll);
 static u32 aty_pll_ct_to_var(const struct fb_info *info,
 			     const union aty_pll *pll);
 
-
-
-static void aty_st_pll(int offset, u8 val, const struct atyfb_par *par)
-{
-	/* write addr byte */
-	aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN, par);
-	/* write the register value */
-	aty_st_8(CLOCK_CNTL + 2, val, par);
-	aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, par);
-}
-
-
 /* ------------------------------------------------------------------------- */
 
     /*
      *  PLL programming (Mach64 CT family)
      */
 
-static int aty_dsp_gt(const struct fb_info *info, u8 bpp,
+static int aty_dsp_gt(const struct fb_info *info, u32 bpp,
 		      struct pll_ct *pll)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
-	u32 dsp_xclks_per_row, dsp_loop_latency, dsp_precision, dsp_off,
-	    dsp_on;
-	u32 xclks_per_row, fifo_off, fifo_on, y, fifo_size, page_size;
-
-	/* xclocks_per_row<<11 */
-	xclks_per_row =
-	    (pll->mclk_fb_div * pll->vclk_post_div_real * 64 << 11) /
-	    (pll->vclk_fb_div * pll->mclk_post_div_real * bpp);
+	u32 dsp_xclks_per_row, dsp_loop_latency, dsp_precision, dsp_off, dsp_on;
+	u32 xclks_per_row, fifo_off, fifo_on, y, fifo_size;
+	u32 memcntl, n, t_pfc, t_rp, t_ras, t_rcd, t_crd, t_rcc, t_lat;
+
+#ifdef DEBUG
+	printk(__FUNCTION__ ": mclk_fb_mult=%d\n", pll->mclk_fb_mult);
+#endif
+	
+	/* (64*xclk/vclk/bpp)<<11 = xclocks_per_row<<11 */
+	xclks_per_row = ((u32)pll->mclk_fb_mult * (u32)pll->mclk_fb_div *
+			 (u32)pll->vclk_post_div_real * 64) << 11;
+	xclks_per_row /=
+		(2 * (u32)pll->vclk_fb_div * (u32)pll->xclk_post_div_real * bpp);	
 	if (xclks_per_row < (1 << 11))
-		FAIL("Dotclock to high");
+		printk("Dotclock too high\n");
 	if (M64_HAS(FIFO_24)) {
 		fifo_size = 24;
 		dsp_loop_latency = 0;
@@ -70,36 +59,53 @@
 		dsp_precision++;
 	}
 	dsp_precision -= 5;
+
 	/* fifo_off<<6 */
-	fifo_off = ((xclks_per_row * (fifo_size - 1)) >> 5) + (3 << 6);
+	fifo_off = ((xclks_per_row * (fifo_size - 1)) >> 5); // + (3 << 6);
 
 	if (info->fix.smem_len > 1 * 1024 * 1024) {
-		if (par->ram_type >= SDRAM) {
+		switch (par->ram_type) {
+		case WRAM:
+			/* >1 MB SDRAM */
+			dsp_loop_latency += 9;
+			n = 4;
+			break;
+		case SDRAM:	
+		case SGRAM:
 			/* >1 MB SDRAM */
 			dsp_loop_latency += 8;
-			page_size = 8;
-		} else {
+			n = 2;
+			break;
+		default:
 			/* >1 MB DRAM */
 			dsp_loop_latency += 6;
-			page_size = 9;
+			n = 3;
+			break;
 		}
 	} else {
 		if (par->ram_type >= SDRAM) {
 			/* <2 MB SDRAM */
 			dsp_loop_latency += 9;
-			page_size = 10;
+			n = 2;
 		} else {
 			/* <2 MB DRAM */
 			dsp_loop_latency += 8;
-			page_size = 10;
+			n = 3;
 		}
 	}
+
+	memcntl = aty_ld_le32(MEM_CNTL, par);
+	t_rcd = ((memcntl >> 10) & 0x03) + 1;
+	t_crd = ((memcntl >> 12) & 0x01);
+	t_rp  = ((memcntl >>  8) & 0x03) + 1;
+	t_ras = ((memcntl >> 16) & 0x07) + 1;
+	t_lat =  (memcntl >>  4) & 0x03;
+
+	t_pfc = t_rp + t_rcd + t_crd;
+	t_rcc = max(t_rp + t_ras, t_pfc + n);
+
 	/* fifo_on<<6 */
-	if (xclks_per_row >= (page_size << 11))
-		fifo_on =
-		    ((2 * page_size + 1) << 6) + (xclks_per_row >> 5);
-	else
-		fifo_on = (3 * page_size + 2) << 6;
+	fifo_on = (2 * t_rcc + t_pfc + n - 1) << 6;
 
 	dsp_xclks_per_row = xclks_per_row >> dsp_precision;
 	dsp_on = fifo_on >> dsp_precision;
@@ -107,7 +113,7 @@
 
 	pll->dsp_config = (dsp_xclks_per_row & 0x3fff) |
 	    ((dsp_loop_latency & 0xf) << 16) | ((dsp_precision & 7) << 20);
-	pll->dsp_on_off = (dsp_on & 0x7ff) | ((dsp_off & 0x7ff) << 16);
+	pll->dsp_on_off = (dsp_off & 0x7ff) | ((dsp_on & 0x7ff) << 16);
 	return 0;
 }
 
@@ -115,15 +121,21 @@
 			    struct pll_ct *pll)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
+#ifdef DEBUG
+	int pllmclk, pllsclk;
+#endif
 	u32 q, x;		/* x is a workaround for sparc64-linux-gcc */
 	x = x;			/* x is a workaround for sparc64-linux-gcc */
 
 	pll->pll_ref_div = par->pll_per * 2 * 255 / par->ref_clk_per;
 
-	/* FIXME: use the VTB/GTB /3 post divider if it's better suited */
-	q = par->ref_clk_per * pll->pll_ref_div * 4 / par->mclk_per;	/* actually 8*q */
+	/* FIXME: use the VTB/GTB /3 post divider if it's better suited.
+	 *        Actually 8*q
+         */
+	q = par->ref_clk_per * pll->pll_ref_div * 4 / par->mclk_per;
+
 	if (q < 16 * 8 || q > 255 * 8)
-		FAIL("mclk out of range");
+		printk(KERN_DEBUG "atyfb: mclk out of range");
 	else if (q < 32 * 8)
 		pll->mclk_post_div_real = 8;
 	else if (q < 64 * 8)
@@ -133,11 +145,44 @@
 	else
 		pll->mclk_post_div_real = 1;
 	pll->mclk_fb_div = q * pll->mclk_post_div_real / 8;
+	pll->sclk_fb_div = q*pll->mclk_post_div_real/8;
+	
+#ifdef DEBUG
+	pllsclk = (1000000 * 2 * pll->sclk_fb_div) /
+			(par->ref_clk_per * pll->pll_ref_div);
+	printk(__FUNCTION__ ": pllsclk=%d MHz, mclk=%d MHz\n",
+		pllsclk, pllsclk / pll->mclk_post_div_real);
+#endif
+
+	pll->mclk_fb_mult = M64_HAS(MFB_TIMES_4) ? 4 : 2;
+
+	/* actually 8*q */
+	q = par->ref_clk_per * pll->pll_ref_div * 8 /
+		(pll->mclk_fb_mult * par->xclk_per);
+
+	if (q < 16*8 || q > 255*8)
+		printk(KERN_DEBUG "mclk out of range");
+	else if (q < 32*8)
+		pll->xclk_post_div_real = 8;
+	else if (q < 64*8)
+		pll->xclk_post_div_real = 4;
+	else if (q < 128*8)
+		pll->xclk_post_div_real = 2;
+	else
+		pll->xclk_post_div_real = 1;
+	pll->mclk_fb_div = q*pll->xclk_post_div_real/8;
+
+#ifdef DEBUG
+	pllmclk = (1000000 * pll->mclk_fb_mult * pll->mclk_fb_div) /
+			(par->ref_clk_per * pll->pll_ref_div);
+	printk(__FUNCTION__ ": pllmclk=%d MHz, xclk=%d MHz\n",
+			pllmclk, pllmclk / pll->xclk_post_div_real);
+#endif
 
 	/* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */
 	q = par->ref_clk_per * pll->pll_ref_div * 4 / vclk_per;	/* actually 8*q */
 	if (q < 16 * 8 || q > 255 * 8)
-		FAIL("vclk out of range");
+		printk(KERN_DEBUG "vclk out of range");
 	else if (q < 32 * 8)
 		pll->vclk_post_div_real = 8;
 	else if (q < 64 * 8)
@@ -153,13 +198,14 @@
 void aty_calc_pll_ct(const struct fb_info *info, struct pll_ct *pll)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	u8 xpostdiv = 0;
 	u8 mpostdiv = 0;
 	u8 vpostdiv = 0;
 
 	if (M64_HAS(SDRAM_MAGIC_PLL) && (par->ram_type >= SDRAM))
-		pll->pll_gen_cntl = 0x04;
+		pll->pll_gen_cntl = 0x64;	/* mclk = sclk */
 	else
-		pll->pll_gen_cntl = 0x84;
+		pll->pll_gen_cntl = 0xe4;	/* mclk = sclk */
 
 	switch (pll->mclk_post_div_real) {
 	case 1:
@@ -168,9 +214,6 @@
 	case 2:
 		mpostdiv = 1;
 		break;
-	case 3:
-		mpostdiv = 4;
-		break;
 	case 4:
 		mpostdiv = 2;
 		break;
@@ -178,12 +221,33 @@
 		mpostdiv = 3;
 		break;
 	}
-	pll->pll_gen_cntl |= mpostdiv << 4;	/* mclk */
+	pll->spll_cntl2 = mpostdiv << 4; /* sclk == pllsclk / mpostdiv */	
+
+	switch (pll->xclk_post_div_real) {
+		case 1:
+			xpostdiv = 0;
+			break;
+		case 2:
+			xpostdiv = 1;
+			break;
+		case 3:
+			xpostdiv = 4;
+			break;
+		case 4:
+			xpostdiv = 2;
+			break;
+		case 8:
+			xpostdiv = 3;
+			break;
+	}
 
 	if (M64_HAS(MAGIC_POSTDIV))
 		pll->pll_ext_cntl = 0;
 	else
-		pll->pll_ext_cntl = mpostdiv;	/* xclk == mclk */
+		pll->pll_ext_cntl = mpostdiv;	/* xclk == pllmclk / xpostdiv */
+
+	if (pll->mclk_fb_mult == 4)
+		pll->pll_ext_cntl |= 0x08;
 
 	switch (pll->vclk_post_div_real) {
 	case 2:
@@ -241,25 +305,53 @@
 		    const union aty_pll *pll)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
-
+#ifdef DEBUG
+	printk(__FUNCTION__ ": about to program:\n"
+		"refdiv=%d, extcntl=0x%02x, mfbdiv=%d\n"
+		"spllcntl2=0x%02x, sfbdiv=%d, gencntl=0x%02x\n"
+		"vclkcntl=0x%02x, vpostdiv=0x%02x, vfbdiv=%d\n"
+		"clocksel=%d\n",
+		pll->ct.pll_ref_div, pll->ct.pll_ext_cntl,
+		pll->ct.mclk_fb_div, pll->ct.spll_cntl2,
+		pll->ct.sclk_fb_div, pll->ct.pll_gen_cntl,
+		pll->ct.pll_vclk_cntl, pll->ct.vclk_post_div,
+		pll->ct.vclk_fb_div, aty_ld_le32(CLOCK_CNTL, info) & 0x03);
+#endif
 	aty_st_pll(PLL_REF_DIV, pll->ct.pll_ref_div, par);
+
+	aty_st_pll(PLL_EXT_CNTL, pll->ct.pll_ext_cntl, par);
+	aty_st_pll(MCLK_FB_DIV, pll->ct.mclk_fb_div, par); // for XCLK
+
+	aty_st_pll(SPLL_CNTL2, pll->ct.spll_cntl2, par);
+	aty_st_pll(SCLK_FB_DIV, pll->ct.sclk_fb_div, par); // for MCLK
+
 	aty_st_pll(PLL_GEN_CNTL, pll->ct.pll_gen_cntl, par);
-	aty_st_pll(MCLK_FB_DIV, pll->ct.mclk_fb_div, par);
+	
+	aty_st_pll(EXT_VPLL_CNTL, 0, par);
 	aty_st_pll(PLL_VCLK_CNTL, pll->ct.pll_vclk_cntl, par);
 	aty_st_pll(VCLK_POST_DIV, pll->ct.vclk_post_div, par);
 	aty_st_pll(VCLK0_FB_DIV, pll->ct.vclk_fb_div, par);
-	aty_st_pll(PLL_EXT_CNTL, pll->ct.pll_ext_cntl, par);
 
 	if (M64_HAS(GTB_DSP)) {
+		u8 dll_cntl;
+
 		if (M64_HAS(XL_DLL))
-			aty_st_pll(DLL_CNTL, 0x80, par);
+			dll_cntl = 0x80;
 		else if (par->ram_type >= SDRAM)
-			aty_st_pll(DLL_CNTL, 0xa6, par);
+			dll_cntl = 0xa6;
 		else
-			aty_st_pll(DLL_CNTL, 0xa0, par);
+			dll_cntl = 0xa0;
+		aty_st_pll(DLL_CNTL, dll_cntl, par);
 		aty_st_pll(VFC_CNTL, 0x1b, par);
 		aty_st_le32(DSP_CONFIG, pll->ct.dsp_config, par);
 		aty_st_le32(DSP_ON_OFF, pll->ct.dsp_on_off, par);
+
+		mdelay(10);
+		aty_st_pll(DLL_CNTL, dll_cntl, par);
+		mdelay(10);
+		aty_st_pll(DLL_CNTL, dll_cntl | 0x40, par);
+		mdelay(10);
+		aty_st_pll(DLL_CNTL, dll_cntl & ~0x40, par);
 	}
 }
 
diff -Nru a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
--- a/drivers/video/aty/mach64_cursor.c	Sat Nov 23 11:49:51 2002
+++ b/drivers/video/aty/mach64_cursor.c	Sun Feb  9 15:55:58 2003
@@ -135,6 +135,10 @@
 			yoff = 0;
 		}
 
+		/* In doublescan mode, the cursor location also needs to be
+		   doubled. */
+                if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
+			y<<=1;
 		wait_for_fifo(4, par);
 		aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1),
 			    par);
diff -Nru a/drivers/video/aty/mach64_gx.c b/drivers/video/aty/mach64_gx.c
--- a/drivers/video/aty/mach64_gx.c	Sat Oct 12 12:51:46 2002
+++ b/drivers/video/aty/mach64_gx.c	Sun Feb  9 15:55:58 2003
@@ -1,11 +1,9 @@
-
 /*
  *  ATI Mach64 GX Support
  */
 
 #include <linux/delay.h>
 #include <linux/fb.h>
-#include <linux/sched.h>
 
 #include <asm/io.h>
 
@@ -121,7 +119,7 @@
 }
 
 static int aty_var_to_pll_514(const struct fb_info *info, u32 vclk_per,
-			      u8 bpp, union aty_pll *pll)
+			      u32 bpp, u32 width, union aty_pll *pll)
 {
 	/*
 	 *  FIXME: use real calculations instead of using fixed values from the old
@@ -339,8 +337,8 @@
      *  ATI 18818 / ICS 2595 Clock Chip
      */
 
-static int aty_var_to_pll_18818(const struct fb_info *info,
-				u32 vclk_per, u8 bpp, union aty_pll *pll)
+static int aty_var_to_pll_18818(const struct fb_info *info, u32 vclk_per,
+				u32 bpp, u32 width, union aty_pll *pll)
 {
 	u32 MHz100;		/* in 0.01 MHz */
 	u32 program_bits;
@@ -495,8 +493,8 @@
      *  STG 1703 Clock Chip
      */
 
-static int aty_var_to_pll_1703(const struct fb_info *info,
-			       u32 vclk_per, u8 bpp, union aty_pll *pll)
+static int aty_var_to_pll_1703(const struct fb_info *info, u32 vclk_per,
+			       u32 bpp, u32 width, union aty_pll *pll)
 {
 	u32 mhz100;		/* in 0.01 MHz */
 	u32 program_bits;
@@ -611,8 +609,8 @@
      *  Chrontel 8398 Clock Chip
      */
 
-static int aty_var_to_pll_8398(const struct fb_info *info,
-			       u32 vclk_per, u8 bpp, union aty_pll *pll)
+static int aty_var_to_pll_8398(const struct fb_info *info, u32 vclk_per,
+			       u32 bpp, u32 width, union aty_pll *pll)
 {
 	u32 tempA, tempB, fOut, longMHz100, diff, preDiff;
 
@@ -736,7 +734,7 @@
      */
 
 static int aty_var_to_pll_408(const struct fb_info *info, u32 vclk_per,
-			      u8 bpp, union aty_pll *pll)
+			      u32 bpp, u32 width, union aty_pll *pll)
 {
 	u32 mhz100;		/* in 0.01 MHz */
 	u32 program_bits;
diff -Nru a/drivers/video/aty/xlinit.c b/drivers/video/aty/xlinit.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/aty/xlinit.c	Thu Feb 27 17:17:33 2003
@@ -0,0 +1,367 @@
+/*
+ *  ATI Rage XL Initialization. Support for Xpert98 and Victoria
+ *  PCI cards.
+ *
+ *  Copyright (C) 2002 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.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h> 
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <video/mach64.h>
+#include "atyfb.h"
+
+#define MPLL_GAIN       0xad
+#define VPLL_GAIN       0xd5
+
+enum {
+	VICTORIA = 0,
+	XPERT98,
+	NUM_XL_CARDS
+};
+
+extern const struct aty_pll_ops aty_pll_ct;
+
+#define DEFAULT_CARD XPERT98
+static int xl_card = DEFAULT_CARD;
+
+static const struct xl_card_cfg_t {
+	int ref_crystal; // 10^4 Hz
+	int mem_type;
+	int mem_size;
+	u32 mem_cntl;
+	u32 ext_mem_cntl;
+	u32 mem_addr_config;
+	u32 bus_cntl;
+	u32 dac_cntl;
+	u32 hw_debug;
+	u32 custom_macro_cntl;
+	u8  dll2_cntl;
+	u8  pll_yclk_cntl;
+} card_cfg[NUM_XL_CARDS] = {
+	// VICTORIA
+	{	2700, SDRAM, 0x800000,
+		0x10757A3B, 0x64000C81, 0x00110202, 0x7b33A040,
+		0x82010102, 0x48803800, 0x005E0179,
+		0x50, 0x25
+	},
+	// XPERT98
+	{	1432,  WRAM, 0x800000,
+		0x00165A2B, 0xE0000CF1, 0x00200213, 0x7333A001,
+		0x8000000A, 0x48833800, 0x007F0779,
+		0x10, 0x19
+	}
+};
+	  
+typedef struct {
+	u8 lcd_reg;
+	u32 val;
+} lcd_tbl_t;
+
+static const lcd_tbl_t lcd_tbl[] = {
+	{ 0x01,	0x000520C0 },
+	{ 0x08,	0x02000408 },
+	{ 0x03,	0x00000F00 },
+	{ 0x00,	0x00000000 },
+	{ 0x02,	0x00000000 },
+	{ 0x04,	0x00000000 },
+	{ 0x05,	0x00000000 },
+	{ 0x06,	0x00000000 },
+	{ 0x33,	0x00000000 },
+	{ 0x34,	0x00000000 },
+	{ 0x35,	0x00000000 },
+	{ 0x36,	0x00000000 },
+	{ 0x37,	0x00000000 }
+};
+
+static inline u32 aty_ld_lcd(u8 lcd_reg, struct atyfb_par *par)
+{
+	aty_st_8(LCD_INDEX, lcd_reg, par);
+	return aty_ld_le32(LCD_DATA, par);
+}
+
+static inline void aty_st_lcd(u8 lcd_reg, u32 val,
+			      struct atyfb_par *par)
+{
+	aty_st_8(LCD_INDEX, lcd_reg, par);
+	aty_st_le32(LCD_DATA, val, par);
+}
+
+static void reset_gui(struct atyfb_par *par)
+{
+	aty_st_8(GEN_TEST_CNTL+1, 0x01, par);
+	aty_st_8(GEN_TEST_CNTL+1, 0x00, par);
+	aty_st_8(GEN_TEST_CNTL+1, 0x02, par);
+	mdelay(5);
+}
+
+static void reset_sdram(struct atyfb_par *par)
+{
+	u8 temp;
+
+	temp = aty_ld_8(EXT_MEM_CNTL, par);
+	temp |= 0x02;
+	aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_SDRAM_RESET = 1b
+	temp |= 0x08;
+	aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST    = 10b
+	temp |= 0x0c;
+	aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST    = 11b
+	mdelay(5);
+	temp &= 0xf3;
+	aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST    = 00b
+	temp &= 0xfd;
+	aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_SDRAM_REST  = 0b
+	mdelay(5);
+}
+
+static void init_dll(struct atyfb_par *par)
+{
+	// enable DLL
+	aty_st_pll(PLL_GEN_CNTL,
+		   aty_ld_pll(PLL_GEN_CNTL, par) & 0x7f,
+		   par);
+
+	// reset DLL
+	aty_st_pll(DLL_CNTL, 0x82, par);
+	aty_st_pll(DLL_CNTL, 0xE2, par);
+	mdelay(5);
+	aty_st_pll(DLL_CNTL, 0x82, par);
+	mdelay(6);
+}
+
+static void reset_clocks(struct atyfb_par *par, struct pll_ct *pll,
+			 int hsync_enb)
+{
+	reset_gui(par);
+	aty_st_pll(MCLK_FB_DIV, pll->mclk_fb_div, par);
+	aty_st_pll(SCLK_FB_DIV, pll->sclk_fb_div, par);
+
+	mdelay(15);
+	init_dll(par);
+	aty_st_8(GEN_TEST_CNTL+1, 0x00, par);
+	mdelay(5);
+	aty_st_8(CRTC_GEN_CNTL+3, 0x04, par);
+	mdelay(6);
+	reset_sdram(par);
+	aty_st_8(CRTC_GEN_CNTL+3,
+		 hsync_enb ? 0x00 : 0x04, par);
+
+	aty_st_pll(SPLL_CNTL2, pll->spll_cntl2, par);
+	aty_st_pll(PLL_GEN_CNTL, pll->pll_gen_cntl, par);
+	aty_st_pll(PLL_VCLK_CNTL, pll->pll_vclk_cntl, par);
+}
+
+int atyfb_xl_init(struct fb_info *info)
+{
+	const struct xl_card_cfg_t * card = &card_cfg[xl_card];
+	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	union aty_pll pll;
+	int i, err;
+	u32 temp;
+	
+	aty_st_8(CONFIG_STAT0, 0x85, par);
+	mdelay(10);
+
+	/*
+	 * The following needs to be set before the call
+	 * to var_to_pll() below. They'll be re-set again
+	 * to the same values in aty_init().
+	 */
+	par->ref_clk_per = 100000000UL/card->ref_crystal;
+	par->ram_type = card->mem_type;
+	info->fix.smem_len = card->mem_size;
+	if (xl_card == VICTORIA) {
+		// the MCLK, XCLK are 120MHz on victoria card
+		par->mclk_per = 1000000/120;
+		par->xclk_per = 1000000/120;
+		par->features &= ~M64F_MFB_TIMES_4;
+	}
+	
+	/*
+	 * Calculate mclk and xclk dividers, etc. The passed
+	 * pixclock and bpp values don't matter yet, the vclk
+	 * isn't programmed until later.
+	 */
+	if ((err = aty_pll_ct.var_to_pll(info, 39726, 8, &pll)))
+		return err;
+
+	aty_st_pll(LVDS_CNTL0, 0x00, par);
+	aty_st_pll(DLL2_CNTL, card->dll2_cntl, par);
+	aty_st_pll(V2PLL_CNTL, 0x10, par);
+	aty_st_pll(MPLL_CNTL, MPLL_GAIN, par);
+	aty_st_pll(VPLL_CNTL, VPLL_GAIN, par);
+	aty_st_pll(PLL_VCLK_CNTL, 0x00, par);
+	aty_st_pll(VFC_CNTL, 0x1B, par);
+	aty_st_pll(PLL_REF_DIV, pll.ct.pll_ref_div, par);
+	aty_st_pll(PLL_EXT_CNTL, pll.ct.pll_ext_cntl, par);
+	aty_st_pll(SPLL_CNTL2, 0x03, par);
+	aty_st_pll(PLL_GEN_CNTL, 0x44, par);
+
+	reset_clocks(par, &pll.ct, 0);
+	mdelay(10);
+
+	aty_st_pll(VCLK_POST_DIV, 0x03, par);
+	aty_st_pll(VCLK0_FB_DIV, 0xDA, par);
+	aty_st_pll(VCLK_POST_DIV, 0x0F, par);
+	aty_st_pll(VCLK1_FB_DIV, 0xF5, par);
+	aty_st_pll(VCLK_POST_DIV, 0x3F, par);
+	aty_st_pll(PLL_EXT_CNTL, 0x40 | pll.ct.pll_ext_cntl, par);
+	aty_st_pll(VCLK2_FB_DIV, 0x00, par);
+	aty_st_pll(VCLK_POST_DIV, 0xFF, par);
+	aty_st_pll(PLL_EXT_CNTL, 0xC0 | pll.ct.pll_ext_cntl, par);
+	aty_st_pll(VCLK3_FB_DIV, 0x00, par);
+
+	aty_st_8(BUS_CNTL, 0x01, par);
+	aty_st_le32(BUS_CNTL, card->bus_cntl | 0x08000000, par);
+
+	aty_st_le32(CRTC_GEN_CNTL, 0x04000200, par);
+	aty_st_le16(CONFIG_STAT0, 0x0020, par);
+	aty_st_le32(MEM_CNTL, 0x10151A33, par);
+	aty_st_le32(EXT_MEM_CNTL, 0xE0000C01, par);
+	aty_st_le16(CRTC_GEN_CNTL+2, 0x0000, par);
+	aty_st_le32(DAC_CNTL, card->dac_cntl, par);
+	aty_st_le16(GEN_TEST_CNTL, 0x0100, par);
+	aty_st_le32(CUSTOM_MACRO_CNTL, 0x003C0171, par);
+	aty_st_le32(MEM_BUF_CNTL, 0x00382848, par);
+
+	aty_st_le32(HW_DEBUG, card->hw_debug, par);
+	aty_st_le16(MEM_ADDR_CONFIG, 0x0000, par);
+	aty_st_le16(GP_IO+2, 0x0000, par);
+	aty_st_le16(GEN_TEST_CNTL, 0x0000, par);
+	aty_st_le16(EXT_DAC_REGS+2, 0x0000, par);
+	aty_st_le32(CRTC_INT_CNTL, 0x00000000, par);
+	aty_st_le32(TIMER_CONFIG, 0x00000000, par);
+	aty_st_le32(0xEC, 0x00000000, par);
+	aty_st_le32(0xFC, 0x00000000, par);
+
+	for (i=0; i<sizeof(lcd_tbl)/sizeof(lcd_tbl_t); i++) {
+		aty_st_lcd(lcd_tbl[i].lcd_reg, lcd_tbl[i].val, par);
+	}
+
+	aty_st_le16(CONFIG_STAT0, 0x00A4, par);
+	mdelay(10);
+
+	aty_st_8(BUS_CNTL+1, 0xA0, par);
+	mdelay(10);
+	
+	reset_clocks(par, &pll.ct, 1);
+	mdelay(10);
+
+	// something about power management
+	aty_st_8(LCD_INDEX, 0x08, par);
+	aty_st_8(LCD_DATA, 0x0A, par);
+	aty_st_8(LCD_INDEX, 0x08, par);
+	aty_st_8(LCD_DATA+3, 0x02, par);
+	aty_st_8(LCD_INDEX, 0x08, par);
+	aty_st_8(LCD_DATA, 0x0B, par);
+	mdelay(2);
+	
+	// enable display requests, enable CRTC
+	aty_st_8(CRTC_GEN_CNTL+3, 0x02, par);
+	// disable display
+	aty_st_8(CRTC_GEN_CNTL, 0x40, par);
+	// disable display requests, disable CRTC
+	aty_st_8(CRTC_GEN_CNTL+3, 0x04, par);
+	mdelay(10);
+
+	aty_st_pll(PLL_YCLK_CNTL, 0x25, par);
+
+	aty_st_le16(CUSTOM_MACRO_CNTL, 0x0179, par);
+	aty_st_le16(CUSTOM_MACRO_CNTL+2, 0x005E, par);
+	aty_st_le16(CUSTOM_MACRO_CNTL+2, card->custom_macro_cntl>>16, par);
+	aty_st_8(CUSTOM_MACRO_CNTL+1,
+		 (card->custom_macro_cntl>>8) & 0xff, par);
+
+	aty_st_le32(MEM_ADDR_CONFIG, card->mem_addr_config, par);
+	aty_st_le32(MEM_CNTL, card->mem_cntl, par);
+	aty_st_le32(EXT_MEM_CNTL, card->ext_mem_cntl, par);
+
+	aty_st_8(CONFIG_STAT0, 0xA0 | card->mem_type, par);
+
+	aty_st_pll(PLL_YCLK_CNTL, 0x01, par);
+	mdelay(15);
+	aty_st_pll(PLL_YCLK_CNTL, card->pll_yclk_cntl, par);
+	mdelay(1);
+	
+	reset_clocks(par, &pll.ct, 0);
+	mdelay(50);
+	reset_clocks(par, &pll.ct, 0);
+	mdelay(50);
+
+	// enable extended register block
+	aty_st_8(BUS_CNTL+3, 0x7B, par);
+	mdelay(1);
+	// disable extended register block
+	aty_st_8(BUS_CNTL+3, 0x73, par);
+
+	aty_st_8(CONFIG_STAT0, 0x80 | card->mem_type, par);
+
+	// disable display requests, disable CRTC
+	aty_st_8(CRTC_GEN_CNTL+3, 0x04, par);
+	// disable mapping registers in VGA aperture
+	aty_st_8(CONFIG_CNTL, aty_ld_8(CONFIG_CNTL, par) & ~0x04, par);
+	mdelay(50);
+	// enable display requests, enable CRTC
+	aty_st_8(CRTC_GEN_CNTL+3, 0x02, par);
+
+	// make GPIO's 14,15,16 all inputs
+	aty_st_8(LCD_INDEX, 0x07, par);
+	aty_st_8(LCD_DATA+3, 0x00, par);
+
+	// enable the display
+	aty_st_8(CRTC_GEN_CNTL, 0x00, par);
+	mdelay(17);
+	// reset the memory controller
+	aty_st_8(GEN_TEST_CNTL+1, 0x02, par);
+	mdelay(15);
+	aty_st_8(GEN_TEST_CNTL+1, 0x00, par);
+	mdelay(30);
+
+	// enable extended register block
+	aty_st_8(BUS_CNTL+3,
+		 (u8)(aty_ld_8(BUS_CNTL+3, par) | 0x08),
+		 par);
+	// set FIFO size to 512 (PIO)
+	aty_st_le32(GUI_CNTL,
+		    aty_ld_le32(GUI_CNTL, par) & ~0x3,
+		    par);
+
+	// enable CRT and disable lcd
+	aty_st_8(LCD_INDEX, 0x01, par);
+	temp = aty_ld_le32(LCD_DATA, par);
+	temp = (temp | 0x01) & ~0x02;
+	aty_st_le32(LCD_DATA, temp, par);
+	return 0;
+}
+
diff -Nru a/drivers/video/aty128fb.c b/drivers/video/aty128fb.c
--- a/drivers/video/aty128fb.c	Tue Dec 31 17:25:03 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,2363 +0,0 @@
-/* $Id: aty128fb.c,v 1.1.1.1.36.1 1999/12/11 09:03:05 Exp $
- *  linux/drivers/video/aty128fb.c -- Frame buffer device for ATI Rage128
- *
- *  Copyright (C) 1999-2000, Brad Douglas <brad@neruo.com>
- *  Copyright (C) 1999, Anthony Tong <atong@uiuc.edu>
- *
- *                Ani Joshi / Jeff Garzik
- *                      - Code cleanup
- *
- *                Michel Dänzer <michdaen@iiic.ethz.ch>
- *                      - 15/16 bit cleanup
- *                      - fix panning
- *
- *                Benjamin Herrenschmidt
- *                      - pmac-specific PM stuff
- *
- *                Andreas Hundt <andi@convergence.de>
- *                      - FB_ACTIVATE fixes
- *
- *		  Paul Mackerras <paulus@samba.org>
- *			- Convert to new framebuffer API,
- *			  fix colormap setting at 16 bits/pixel (565)
- *
- *		  Paul Mundt 
- *		  	- PCI hotplug
- *
- *  Based off of Geert's atyfb.c and vfb.c.
- *
- *  TODO:
- *		- monitor sensing (DDC)
- *              - virtual display
- *		- other platform support (only ppc/x86 supported)
- *		- hardware cursor support
- *		- ioctl()'s
- *
- *    Please cc: your patches to brad@neruo.com.
- */
-
-/*
- * A special note of gratitude to ATI's devrel for providing documentation,
- * example code and hardware. Thanks Nitya.	-atong and brad
- */
-
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <asm/uaccess.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_ALL_PPC
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include "macmodes.h"
-#endif
-
-#ifdef CONFIG_ADB_PMU
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#endif
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-#include <asm/backlight.h>
-#endif
-
-#ifdef CONFIG_BOOTX_TEXT
-#include <asm/btext.h>
-#endif /* CONFIG_BOOTX_TEXT */
-
-#ifdef CONFIG_MTRR
-#include <asm/mtrr.h>
-#endif
-
-#include <video/aty128.h>
-
-/* Debug flag */
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(fmt, args...)		printk(KERN_DEBUG "aty128fb: %s " fmt, __FUNCTION__, ##args);
-#else
-#define DBG(fmt, args...)
-#endif
-
-#ifndef CONFIG_ALL_PPC
-/* default mode */
-static struct fb_var_screeninfo default_var __initdata = {
-	/* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
-	640, 480, 640, 480, 0, 0, 8, 0,
-	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
-	0, FB_VMODE_NONINTERLACED
-};
-
-#else /* CONFIG_ALL_PPC */
-/* default to 1024x768 at 75Hz on PPC - this will work
- * on the iMac, the usual 640x480 @ 60Hz doesn't. */
-static struct fb_var_screeninfo default_var = {
-	/* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
-	1024, 768, 1024, 768, 0, 0, 8, 0,
-	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-	0, 0, -1, -1, 0, 12699, 160, 32, 28, 1, 96, 3,
-	FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-};
-#endif /* CONFIG_ALL_PPC */
-
-/* default modedb mode */
-/* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
-static struct fb_videomode defaultmode __initdata = {
-	.refresh =	60,
-	.xres =		640,
-	.yres =		480,
-	.pixclock =	39722,
-	.left_margin =	48,
-	.right_margin =	16,
-	.upper_margin =	33,
-	.lower_margin =	10,
-	.hsync_len =	96,
-	.vsync_len =	2,
-	.sync =		0,
-	.vmode =	FB_VMODE_NONINTERLACED
-};
-
-/* Chip generations */
-enum {
-	rage_128,
-	rage_128_pro,
-	rage_M3
-};
-
-/*
- * PCI driver prototypes
- */
-static int aty128_probe(struct pci_dev *pdev,
-                               const struct pci_device_id *ent);
-static void aty128_remove(struct pci_dev *pdev);
-
-/* supported Rage128 chipsets */
-static struct pci_device_id aty128_pci_tbl[] __devinitdata = {
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RE,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RF,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RK,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RL,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PF,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PR,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_U3,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_U1,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LE,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LF,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, aty128_pci_tbl);
-
-static struct pci_driver aty128fb_driver = {
-	name:		"aty128fb",
-	id_table:	aty128_pci_tbl,
-	probe:		aty128_probe,
-	remove:		__devexit_p(aty128_remove),
-};
-
-/* packed BIOS settings */
-#ifndef CONFIG_PPC
-typedef struct {
-	u8 clock_chip_type;
-	u8 struct_size;
-	u8 accelerator_entry;
-	u8 VGA_entry;
-	u16 VGA_table_offset;
-	u16 POST_table_offset;
-	u16 XCLK;
-	u16 MCLK;
-	u8 num_PLL_blocks;
-	u8 size_PLL_blocks;
-	u16 PCLK_ref_freq;
-	u16 PCLK_ref_divider;
-	u32 PCLK_min_freq;
-	u32 PCLK_max_freq;
-	u16 MCLK_ref_freq;
-	u16 MCLK_ref_divider;
-	u32 MCLK_min_freq;
-	u32 MCLK_max_freq;
-	u16 XCLK_ref_freq;
-	u16 XCLK_ref_divider;
-	u32 XCLK_min_freq;
-	u32 XCLK_max_freq;
-} __attribute__ ((packed)) PLL_BLOCK;
-#endif /* !CONFIG_PPC */
-
-/* onboard memory information */
-struct aty128_meminfo {
-	u8 ML;
-	u8 MB;
-	u8 Trcd;
-	u8 Trp;
-	u8 Twr;
-	u8 CL;
-	u8 Tr2w;
-	u8 LoopLatency;
-	u8 DspOn;
-	u8 Rloop;
-	const char *name;
-};
-
-/* various memory configurations */
-static const struct aty128_meminfo sdr_128   =
-	{ 4, 4, 3, 3, 1, 3, 1, 16, 30, 16, "128-bit SDR SGRAM (1:1)" };
-static const struct aty128_meminfo sdr_64    =
-	{ 4, 8, 3, 3, 1, 3, 1, 17, 46, 17, "64-bit SDR SGRAM (1:1)" };
-static const struct aty128_meminfo sdr_sgram =
-	{ 4, 4, 1, 2, 1, 2, 1, 16, 24, 16, "64-bit SDR SGRAM (2:1)" };
-static const struct aty128_meminfo ddr_sgram =
-	{ 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" };
-
-static struct fb_fix_screeninfo aty128fb_fix __initdata = {
-	.id		= "ATY Rage128",
-	.type		= FB_TYPE_PACKED_PIXELS,
-	.visual		= FB_VISUAL_PSEUDOCOLOR,
-	.xpanstep	= 8,
-	.ypanstep	= 1,
-	.mmio_len	= 0x2000,
-	.accel		= FB_ACCEL_ATI_RAGE128,
-};
-
-#ifdef MODULE
-static char *mode __initdata = NULL;
-#ifdef CONFIG_MTRR
-static int  nomtrr __initdata = 0;
-#endif /* CONFIG_MTRR */
-#endif /* MODULE */
-
-static char *mode_option __initdata = NULL;
-
-#ifdef CONFIG_ALL_PPC
-static int default_vmode __initdata = VMODE_1024_768_60;
-static int default_cmode __initdata = CMODE_8;
-#endif
-
-#ifdef CONFIG_PMAC_PBOOK
-static int default_crt_on __initdata = 0;
-static int default_lcd_on __initdata = 1;
-#endif
-
-#ifdef CONFIG_MTRR
-static int mtrr = 1;
-#endif
-
-/* PLL constants */
-struct aty128_constants {
-	u32 dotclock;
-	u32 ppll_min;
-	u32 ppll_max;
-	u32 ref_divider;
-	u32 xclk;
-	u32 fifo_width;
-	u32 fifo_depth;
-};
-
-struct aty128_crtc {
-	u32 gen_cntl;
-	u32 h_total, h_sync_strt_wid;
-	u32 v_total, v_sync_strt_wid;
-	u32 pitch;
-	u32 offset, offset_cntl;
-	u32 xoffset, yoffset;
-	u32 vxres, vyres;
-	u32 depth, bpp;
-};
-
-struct aty128_pll {
-	u32 post_divider;
-	u32 feedback_divider;
-	u32 vclk;
-};
-
-struct aty128_ddafifo {
-	u32 dda_config;
-	u32 dda_on_off;
-};
-
-/* register values for a specific mode */
-struct aty128fb_par {
-	struct aty128_crtc crtc;
-	struct aty128_pll pll;
-	struct aty128_ddafifo fifo_reg;
-	u32 accel_flags;
-	struct aty128_constants constants;  /* PLL and others      */
-	void *regbase;                      /* remapped mmio       */
-	u32 vram_size;                      /* onboard video ram   */
-	int chip_gen;
-	const struct aty128_meminfo *mem;   /* onboard mem info    */
-#ifdef CONFIG_MTRR
-	struct { int vram; int vram_valid; } mtrr;
-#endif
-	int blitter_may_be_busy;
-	int fifo_slots;                 /* free slots in FIFO (64 max) */
-#ifdef CONFIG_PMAC_PBOOK
-	unsigned char *save_framebuffer;
-	int	pm_reg;
-	int crt_on, lcd_on;
-	struct pci_dev *pdev;
-	struct fb_info *next;
-#endif
-	u8	red[32];		/* see aty128fb_setcolreg */
-	u8	green[64];
-	u8	blue[32];
-	u32	pseudo_palette[16];	/* used for TRUECOLOR */
-};
-
-#ifdef CONFIG_PMAC_PBOOK
-int aty128_sleep_notify(struct pmu_sleep_notifier *self, int when);
-static struct pmu_sleep_notifier aty128_sleep_notifier = {
-	aty128_sleep_notify, SLEEP_LEVEL_VIDEO,
-};
-static struct fb_info *aty128_fb = NULL;
-#endif
-
-#define round_div(n, d) ((n+(d/2))/d)
-
-    /*
-     *  Interface used by the world
-     */
-int aty128fb_init(void);
-int aty128fb_setup(char *options);
-
-static int aty128fb_check_var(struct fb_var_screeninfo *var,
-			      struct fb_info *info);
-static int aty128fb_set_par(struct fb_info *info);
-static int aty128fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			      u_int transp, struct fb_info *info);
-static int aty128fb_pan_display(struct fb_var_screeninfo *var,
-			   struct fb_info *fb);
-static int aty128fb_blank(int blank, struct fb_info *fb);
-static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-			  u_long arg, struct fb_info *info);
-static int aty128fb_sync(struct fb_info *info);
-
-    /*
-     *  Internal routines
-     */
-
-static int aty128_encode_var(struct fb_var_screeninfo *var,
-                             const struct aty128fb_par *par);
-static int aty128_decode_var(struct fb_var_screeninfo *var,
-                             struct aty128fb_par *par);
-#if !defined(CONFIG_PPC) && !defined(__sparc__)
-static void __init aty128_get_pllinfo(struct aty128fb_par *par,
-				      char *bios_seg);
-static char __init *aty128find_ROM(void);
-#endif
-static void aty128_timings(struct aty128fb_par *par);
-static void aty128_init_engine(struct aty128fb_par *par);
-static void aty128_reset_engine(const struct aty128fb_par *par);
-static void aty128_flush_pixel_cache(const struct aty128fb_par *par);
-static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par);
-static void wait_for_fifo(u16 entries, struct aty128fb_par *par);
-static void wait_for_idle(struct aty128fb_par *par);
-static u32 depth_to_dst(u32 depth);
-
-static struct fb_ops aty128fb_ops = {
-	.owner		= THIS_MODULE,
-	.fb_check_var	= aty128fb_check_var,
-	.fb_set_par	= aty128fb_set_par,
-	.fb_setcolreg	= aty128fb_setcolreg,
-	.fb_pan_display = aty128fb_pan_display,
-	.fb_blank	= aty128fb_blank,
-	.fb_ioctl	= aty128fb_ioctl,
-	.fb_sync	= aty128fb_sync,
-#if 0
-	.fb_fillrect	= aty128fb_fillrect,
-	.fb_copyarea	= aty128fb_copyarea,
-	.fb_imageblit	= aty128fb_imageblit,
-#else
-	.fb_fillrect	= cfb_fillrect,
-	.fb_copyarea	= cfb_copyarea,
-	.fb_imageblit	= cfb_imageblit,
-#endif
-	.fb_cursor	= soft_cursor,
-};
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-static int aty128_set_backlight_enable(int on, int level, void* data);
-static int aty128_set_backlight_level(int level, void* data);
-
-static struct backlight_controller aty128_backlight_controller = {
-	aty128_set_backlight_enable,
-	aty128_set_backlight_level
-};
-#endif /* CONFIG_PMAC_BACKLIGHT */
-
-    /*
-     * Functions to read from/write to the mmio registers
-     *	- endian conversions may possibly be avoided by
-     *    using the other register aperture. TODO.
-     */
-static inline u32
-_aty_ld_le32(volatile unsigned int regindex, const struct aty128fb_par *par)
-{
-	u32 val;
-
-#if defined(__powerpc__)
-	asm("lwbrx %0,%1,%2;eieio" : "=r"(val) : "b"(regindex), "r"(par->regbase));
-#else
-	val = readl (par->regbase + regindex);
-#endif
-
-	return val;
-}
-
-static inline void
-_aty_st_le32(volatile unsigned int regindex, u32 val, 
-                               const struct aty128fb_par *par)
-{
-#if defined(__powerpc__)
-	asm("stwbrx %0,%1,%2;eieio" : : "r"(val), "b"(regindex),
-	    "r"(par->regbase) : "memory");
-#else
-	writel (val, par->regbase + regindex);
-#endif
-}
-
-static inline u8
-_aty_ld_8(unsigned int regindex, const struct aty128fb_par *par)
-{
-	return readb (par->regbase + regindex);
-}
-
-static inline void
-_aty_st_8(unsigned int regindex, u8 val, const struct aty128fb_par *par)
-{
-	writeb (val, par->regbase + regindex);
-}
-
-#define aty_ld_le32(regindex)		_aty_ld_le32(regindex, par)
-#define aty_st_le32(regindex, val)	_aty_st_le32(regindex, val, par)
-#define aty_ld_8(regindex)		_aty_ld_8(regindex, par)
-#define aty_st_8(regindex, val)		_aty_st_8(regindex, val, par)
-
-    /*
-     * Functions to read from/write to the pll registers
-     */
-
-#define aty_ld_pll(pll_index)		_aty_ld_pll(pll_index, par)
-#define aty_st_pll(pll_index, val)	_aty_st_pll(pll_index, val, par)
-
-
-static u32
-_aty_ld_pll(unsigned int pll_index,
-			const struct aty128fb_par *par)
-{       
-	aty_st_8(CLOCK_CNTL_INDEX, pll_index & 0x3F);
-	return aty_ld_le32(CLOCK_CNTL_DATA);
-}
-
-    
-static void
-_aty_st_pll(unsigned int pll_index, u32 val,
-			const struct aty128fb_par *par)
-{
-	aty_st_8(CLOCK_CNTL_INDEX, (pll_index & 0x3F) | PLL_WR_EN);
-	aty_st_le32(CLOCK_CNTL_DATA, val);
-}
-
-
-/* return true when the PLL has completed an atomic update */
-static int
-aty_pll_readupdate(const struct aty128fb_par *par)
-{
-	return !(aty_ld_pll(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R);
-}
-
-
-static void
-aty_pll_wait_readupdate(const struct aty128fb_par *par)
-{
-	unsigned long timeout = jiffies + HZ/100; // should be more than enough
-	int reset = 1;
-
-	while (time_before(jiffies, timeout))
-		if (aty_pll_readupdate(par)) {
-			reset = 0;
-			break;
-		}
-
-	if (reset)	/* reset engine?? */
-		printk(KERN_DEBUG "aty128fb: PLL write timeout!\n");
-}
-
-
-/* tell PLL to update */
-static void
-aty_pll_writeupdate(const struct aty128fb_par *par)
-{
-	aty_pll_wait_readupdate(par);
-
-	aty_st_pll(PPLL_REF_DIV,
-		   aty_ld_pll(PPLL_REF_DIV) | PPLL_ATOMIC_UPDATE_W);
-}
-
-
-/* write to the scratch register to test r/w functionality */
-static int __init
-register_test(const struct aty128fb_par *par)
-{
-	u32 val;
-	int flag = 0;
-
-	val = aty_ld_le32(BIOS_0_SCRATCH);
-
-	aty_st_le32(BIOS_0_SCRATCH, 0x55555555);
-	if (aty_ld_le32(BIOS_0_SCRATCH) == 0x55555555) {
-		aty_st_le32(BIOS_0_SCRATCH, 0xAAAAAAAA);
-
-		if (aty_ld_le32(BIOS_0_SCRATCH) == 0xAAAAAAAA)
-			flag = 1; 
-	}
-
-	aty_st_le32(BIOS_0_SCRATCH, val);	// restore value
-	return flag;
-}
-
-
-/*
- * Accelerator engine functions
- */
-static void
-do_wait_for_fifo(u16 entries, struct aty128fb_par *par)
-{
-	int i;
-
-	for (;;) {
-		for (i = 0; i < 2000000; i++) {
-			par->fifo_slots = aty_ld_le32(GUI_STAT) & 0x0fff;
-			if (par->fifo_slots >= entries)
-				return;
-		}
-		aty128_reset_engine(par);
-	}
-}
-
-
-static void
-wait_for_idle(struct aty128fb_par *par)
-{
-	int i;
-
-	do_wait_for_fifo(64, par);
-
-	for (;;) {
-		for (i = 0; i < 2000000; i++) {
-			if (!(aty_ld_le32(GUI_STAT) & (1 << 31))) {
-				aty128_flush_pixel_cache(par);
-				par->blitter_may_be_busy = 0;
-				return;
-			}
-		}
-		aty128_reset_engine(par);
-	}
-}
-
-
-static void
-wait_for_fifo(u16 entries, struct aty128fb_par *par)
-{
-	if (par->fifo_slots < entries)
-		do_wait_for_fifo(64, par);
-	par->fifo_slots -= entries;
-}
-
-
-static void
-aty128_flush_pixel_cache(const struct aty128fb_par *par)
-{
-	int i;
-	u32 tmp;
-
-	tmp = aty_ld_le32(PC_NGUI_CTLSTAT);
-	tmp &= ~(0x00ff);
-	tmp |= 0x00ff;
-	aty_st_le32(PC_NGUI_CTLSTAT, tmp);
-
-	for (i = 0; i < 2000000; i++)
-		if (!(aty_ld_le32(PC_NGUI_CTLSTAT) & PC_BUSY))
-			break;
-}
-
-
-static void
-aty128_reset_engine(const struct aty128fb_par *par)
-{
-	u32 gen_reset_cntl, clock_cntl_index, mclk_cntl;
-
-	aty128_flush_pixel_cache(par);
-
-	clock_cntl_index = aty_ld_le32(CLOCK_CNTL_INDEX);
-	mclk_cntl = aty_ld_pll(MCLK_CNTL);
-
-	aty_st_pll(MCLK_CNTL, mclk_cntl | 0x00030000);
-
-	gen_reset_cntl = aty_ld_le32(GEN_RESET_CNTL);
-	aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl | SOFT_RESET_GUI);
-	aty_ld_le32(GEN_RESET_CNTL);
-	aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl & ~(SOFT_RESET_GUI));
-	aty_ld_le32(GEN_RESET_CNTL);
-
-	aty_st_pll(MCLK_CNTL, mclk_cntl);
-	aty_st_le32(CLOCK_CNTL_INDEX, clock_cntl_index);
-	aty_st_le32(GEN_RESET_CNTL, gen_reset_cntl);
-
-	/* use old pio mode */
-	aty_st_le32(PM4_BUFFER_CNTL, PM4_BUFFER_CNTL_NONPM4);
-
-	DBG("engine reset");
-}
-
-
-static void
-aty128_init_engine(struct aty128fb_par *par)
-{
-	u32 pitch_value;
-
-	wait_for_idle(par);
-
-	/* 3D scaler not spoken here */
-	wait_for_fifo(1, par);
-	aty_st_le32(SCALE_3D_CNTL, 0x00000000);
-
-	aty128_reset_engine(par);
-
-	pitch_value = par->crtc.pitch;
-	if (par->crtc.bpp == 24) {
-		pitch_value = pitch_value * 3;
-	}
-
-	wait_for_fifo(4, par);
-	/* setup engine offset registers */
-	aty_st_le32(DEFAULT_OFFSET, 0x00000000);
-
-	/* setup engine pitch registers */
-	aty_st_le32(DEFAULT_PITCH, pitch_value);
-
-	/* set the default scissor register to max dimensions */
-	aty_st_le32(DEFAULT_SC_BOTTOM_RIGHT, (0x1FFF << 16) | 0x1FFF);
-
-	/* set the drawing controls registers */
-	aty_st_le32(DP_GUI_MASTER_CNTL,
-		    GMC_SRC_PITCH_OFFSET_DEFAULT		|
-		    GMC_DST_PITCH_OFFSET_DEFAULT		|
-		    GMC_SRC_CLIP_DEFAULT			|
-		    GMC_DST_CLIP_DEFAULT			|
-		    GMC_BRUSH_SOLIDCOLOR			|
-		    (depth_to_dst(par->crtc.depth) << 8)	|
-		    GMC_SRC_DSTCOLOR			|
-		    GMC_BYTE_ORDER_MSB_TO_LSB		|
-		    GMC_DP_CONVERSION_TEMP_6500		|
-		    ROP3_PATCOPY				|
-		    GMC_DP_SRC_RECT				|
-		    GMC_3D_FCN_EN_CLR			|
-		    GMC_DST_CLR_CMP_FCN_CLEAR		|
-		    GMC_AUX_CLIP_CLEAR			|
-		    GMC_WRITE_MASK_SET);
-
-	wait_for_fifo(8, par);
-	/* clear the line drawing registers */
-	aty_st_le32(DST_BRES_ERR, 0);
-	aty_st_le32(DST_BRES_INC, 0);
-	aty_st_le32(DST_BRES_DEC, 0);
-
-	/* set brush color registers */
-	aty_st_le32(DP_BRUSH_FRGD_CLR, 0xFFFFFFFF); /* white */
-	aty_st_le32(DP_BRUSH_BKGD_CLR, 0x00000000); /* black */
-
-	/* set source color registers */
-	aty_st_le32(DP_SRC_FRGD_CLR, 0xFFFFFFFF);   /* white */
-	aty_st_le32(DP_SRC_BKGD_CLR, 0x00000000);   /* black */
-
-	/* default write mask */
-	aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF);
-
-	/* Wait for all the writes to be completed before returning */
-	wait_for_idle(par);
-}
-
-
-/* convert depth values to their register representation */
-static u32
-depth_to_dst(u32 depth)
-{
-	if (depth <= 8)
-		return DST_8BPP;
-	else if (depth <= 15)
-		return DST_15BPP;
-	else if (depth == 16)
-		return DST_16BPP;
-	else if (depth <= 24)
-		return DST_24BPP;
-	else if (depth <= 32)
-		return DST_32BPP;
-
-	return -EINVAL;
-}
-
-
-/*
-     * CRTC programming
-     */
-
-/* Program the CRTC registers */
-static void
-aty128_set_crtc(const struct aty128_crtc *crtc,
-		const struct aty128fb_par *par)
-{
-	aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl);
-	aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_total);
-	aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid);
-	aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_total);
-	aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid);
-	aty_st_le32(CRTC_PITCH, crtc->pitch);
-	aty_st_le32(CRTC_OFFSET, crtc->offset);
-	aty_st_le32(CRTC_OFFSET_CNTL, crtc->offset_cntl);
-	/* Disable ATOMIC updating.  Is this the right place? */
-	aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~(0x00030000));
-}
-
-
-static int
-aty128_var_to_crtc(const struct fb_var_screeninfo *var,
-		   struct aty128_crtc *crtc,
-		   const struct aty128fb_par *par)
-{
-	u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp, dst;
-	u32 left, right, upper, lower, hslen, vslen, sync, vmode;
-	u32 h_total, h_disp, h_sync_strt, h_sync_wid, h_sync_pol;
-	u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
-	u32 depth, bytpp;
-	u8 mode_bytpp[7] = { 0, 0, 1, 2, 2, 3, 4 };
-
-	/* input */
-	xres = var->xres;
-	yres = var->yres;
-	vxres   = var->xres_virtual;
-	vyres   = var->yres_virtual;
-	xoffset = var->xoffset;
-	yoffset = var->yoffset;
-	bpp   = var->bits_per_pixel;
-	left  = var->left_margin;
-	right = var->right_margin;
-	upper = var->upper_margin;
-	lower = var->lower_margin;
-	hslen = var->hsync_len;
-	vslen = var->vsync_len;
-	sync  = var->sync;
-	vmode = var->vmode;
-
-	if (bpp != 16)
-		depth = bpp;
-	else
-		depth = (var->green.length == 6) ? 16 : 15;
-
-	/* check for mode eligibility
-	 * accept only non interlaced modes */
-	if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
-		return -EINVAL;
-
-	/* convert (and round up) and validate */
-	xres = (xres + 7) & ~7;
-	xoffset = (xoffset + 7) & ~7;
-
-	if (vxres < xres + xoffset)
-		vxres = xres + xoffset;
-
-	if (vyres < yres + yoffset)
-		vyres = yres + yoffset;
-
-	/* convert depth into ATI register depth */
-	dst = depth_to_dst(depth);
-
-	if (dst == -EINVAL) {
-		printk(KERN_ERR "aty128fb: Invalid depth or RGBA\n");
-		return -EINVAL;
-	}
-
-	/* convert register depth to bytes per pixel */
-	bytpp = mode_bytpp[dst];
-
-	/* make sure there is enough video ram for the mode */
-	if ((u32)(vxres * vyres * bytpp) > par->vram_size) {
-		printk(KERN_ERR "aty128fb: Not enough memory for mode\n");
-		return -EINVAL;
-	}
-
-	h_disp = (xres >> 3) - 1;
-	h_total = (((xres + right + hslen + left) >> 3) - 1) & 0xFFFFL;
-
-	v_disp = yres - 1;
-	v_total = (yres + upper + vslen + lower - 1) & 0xFFFFL;
-
-	/* check to make sure h_total and v_total are in range */
-	if (((h_total >> 3) - 1) > 0x1ff || (v_total - 1) > 0x7FF) {
-		printk(KERN_ERR "aty128fb: invalid width ranges\n");
-		return -EINVAL;
-	}
-
-	h_sync_wid = (hslen + 7) >> 3;
-	if (h_sync_wid == 0)
-		h_sync_wid = 1;
-	else if (h_sync_wid > 0x3f)        /* 0x3f = max hwidth */
-		h_sync_wid = 0x3f;
-
-	h_sync_strt = (h_disp << 3) + right;
-
-	v_sync_wid = vslen;
-	if (v_sync_wid == 0)
-		v_sync_wid = 1;
-	else if (v_sync_wid > 0x1f)        /* 0x1f = max vwidth */
-		v_sync_wid = 0x1f;
-    
-	v_sync_strt = v_disp + lower;
-
-	h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
-	v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
-    
-	c_sync = sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
-
-	crtc->gen_cntl = 0x3000000L | c_sync | (dst << 8);
-
-	crtc->h_total = h_total | (h_disp << 16);
-	crtc->v_total = v_total | (v_disp << 16);
-
-	crtc->h_sync_strt_wid = h_sync_strt | (h_sync_wid << 16) |
-	        (h_sync_pol << 23);
-	crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid << 16) |
-                (v_sync_pol << 23);
-
-	crtc->pitch = vxres >> 3;
-
-	crtc->offset = 0;
-
-	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
-		crtc->offset_cntl = 0x00010000;
-	else
-		crtc->offset_cntl = 0;
-
-	crtc->vxres = vxres;
-	crtc->vyres = vyres;
-	crtc->xoffset = xoffset;
-	crtc->yoffset = yoffset;
-	crtc->depth = depth;
-	crtc->bpp = bpp;
-
-	return 0;
-}
-
-
-static int
-aty128_pix_width_to_var(int pix_width, struct fb_var_screeninfo *var)
-{
-
-	/* fill in pixel info */
-	var->red.msb_right = 0;
-	var->green.msb_right = 0;
-	var->blue.offset = 0;
-	var->blue.msb_right = 0;
-	var->transp.offset = 0;
-	var->transp.length = 0;
-	var->transp.msb_right = 0;
-	switch (pix_width) {
-	case CRTC_PIX_WIDTH_8BPP:
-		var->bits_per_pixel = 8;
-		var->red.offset = 0;
-		var->red.length = 8;
-		var->green.offset = 0;
-		var->green.length = 8;
-		var->blue.length = 8;
-		break;
-	case CRTC_PIX_WIDTH_15BPP:
-		var->bits_per_pixel = 16;
-		var->red.offset = 10;
-		var->red.length = 5;
-		var->green.offset = 5;
-		var->green.length = 5;
-		var->blue.length = 5;
-		break;
-	case CRTC_PIX_WIDTH_16BPP:
-		var->bits_per_pixel = 16;
-		var->red.offset = 11;
-		var->red.length = 5;
-		var->green.offset = 5;
-		var->green.length = 6;
-		var->blue.length = 5;
-		break;
-	case CRTC_PIX_WIDTH_24BPP:
-		var->bits_per_pixel = 24;
-		var->red.offset = 16;
-		var->red.length = 8;
-		var->green.offset = 8;
-		var->green.length = 8;
-		var->blue.length = 8;
-		break;
-	case CRTC_PIX_WIDTH_32BPP:
-		var->bits_per_pixel = 32;
-		var->red.offset = 16;
-		var->red.length = 8;
-		var->green.offset = 8;
-		var->green.length = 8;
-		var->blue.length = 8;
-		var->transp.offset = 24;
-		var->transp.length = 8;
-		break;
-	default:
-		printk(KERN_ERR "aty128fb: Invalid pixel width\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-
-static int
-aty128_crtc_to_var(const struct aty128_crtc *crtc,
-		   struct fb_var_screeninfo *var)
-{
-	u32 xres, yres, left, right, upper, lower, hslen, vslen, sync;
-	u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
-	u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol, c_sync;
-	u32 pix_width;
-
-	/* fun with masking */
-	h_total     = crtc->h_total & 0x1ff;
-	h_disp      = (crtc->h_total >> 16) & 0xff;
-	h_sync_strt = (crtc->h_sync_strt_wid >> 3) & 0x1ff;
-	h_sync_dly  = crtc->h_sync_strt_wid & 0x7;
-	h_sync_wid  = (crtc->h_sync_strt_wid >> 16) & 0x3f;
-	h_sync_pol  = (crtc->h_sync_strt_wid >> 23) & 0x1;
-	v_total     = crtc->v_total & 0x7ff;
-	v_disp      = (crtc->v_total >> 16) & 0x7ff;
-	v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
-	v_sync_wid  = (crtc->v_sync_strt_wid >> 16) & 0x1f;
-	v_sync_pol  = (crtc->v_sync_strt_wid >> 23) & 0x1;
-	c_sync      = crtc->gen_cntl & CRTC_CSYNC_EN ? 1 : 0;
-	pix_width   = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
-
-	/* do conversions */
-	xres  = (h_disp + 1) << 3;
-	yres  = v_disp + 1;
-	left  = ((h_total - h_sync_strt - h_sync_wid) << 3) - h_sync_dly;
-	right = ((h_sync_strt - h_disp) << 3) + h_sync_dly;
-	hslen = h_sync_wid << 3;
-	upper = v_total - v_sync_strt - v_sync_wid;
-	lower = v_sync_strt - v_disp;
-	vslen = v_sync_wid;
-	sync  = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
-		(v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT) |
-		(c_sync ? FB_SYNC_COMP_HIGH_ACT : 0);
-
-	aty128_pix_width_to_var(pix_width, var);
-
-	var->xres = xres;
-	var->yres = yres;
-	var->xres_virtual = crtc->vxres;
-	var->yres_virtual = crtc->vyres;
-	var->xoffset = crtc->xoffset;
-	var->yoffset = crtc->yoffset;
-	var->left_margin  = left;
-	var->right_margin = right;
-	var->upper_margin = upper;
-	var->lower_margin = lower;
-	var->hsync_len = hslen;
-	var->vsync_len = vslen;
-	var->sync  = sync;
-	var->vmode = FB_VMODE_NONINTERLACED;
-
-	return 0;
-}
-
-#ifdef CONFIG_PMAC_PBOOK
-static void
-aty128_set_crt_enable(struct aty128fb_par *par, int on)
-{
-	if (on) {
-		aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) | CRT_CRTC_ON);
-		aty_st_le32(DAC_CNTL, (aty_ld_le32(DAC_CNTL) | DAC_PALETTE2_SNOOP_EN));
-	} else
-		aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) & ~CRT_CRTC_ON);
-}
-
-static void
-aty128_set_lcd_enable(struct aty128fb_par *par, int on)
-{
-	u32 reg;
-
-	if (on) {
-		reg = aty_ld_le32(LVDS_GEN_CNTL);
-		reg |= LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION;
-		reg &= ~LVDS_DISPLAY_DIS;
-		aty_st_le32(LVDS_GEN_CNTL, reg);
-#ifdef CONFIG_PMAC_BACKLIGHT
-		aty128_set_backlight_enable(get_backlight_enable(),
-					    get_backlight_level(), par);
-#endif	
-	} else {
-#ifdef CONFIG_PMAC_BACKLIGHT
-		aty128_set_backlight_enable(0, 0, par);
-#endif	
-		reg = aty_ld_le32(LVDS_GEN_CNTL);
-		reg |= LVDS_DISPLAY_DIS;
-		aty_st_le32(LVDS_GEN_CNTL, reg);
-		mdelay(100);
-		reg &= ~(LVDS_ON /*| LVDS_EN*/);
-		aty_st_le32(LVDS_GEN_CNTL, reg);
-	}
-}
-#endif
-
-static void
-aty128_set_pll(struct aty128_pll *pll, const struct aty128fb_par *par)
-{
-	u32 div3;
-
-	unsigned char post_conv[] =	/* register values for post dividers */
-        { 2, 0, 1, 4, 2, 2, 6, 2, 3, 2, 2, 2, 7 };
-
-	/* select PPLL_DIV_3 */
-	aty_st_le32(CLOCK_CNTL_INDEX, aty_ld_le32(CLOCK_CNTL_INDEX) | (3 << 8));
-
-	/* reset PLL */
-	aty_st_pll(PPLL_CNTL,
-		   aty_ld_pll(PPLL_CNTL) | PPLL_RESET | PPLL_ATOMIC_UPDATE_EN);
-
-	/* write the reference divider */
-	aty_pll_wait_readupdate(par);
-	aty_st_pll(PPLL_REF_DIV, par->constants.ref_divider & 0x3ff);
-	aty_pll_writeupdate(par);
-
-	div3 = aty_ld_pll(PPLL_DIV_3);
-	div3 &= ~PPLL_FB3_DIV_MASK;
-	div3 |= pll->feedback_divider;
-	div3 &= ~PPLL_POST3_DIV_MASK;
-	div3 |= post_conv[pll->post_divider] << 16;
-
-	/* write feedback and post dividers */
-	aty_pll_wait_readupdate(par);
-	aty_st_pll(PPLL_DIV_3, div3);
-	aty_pll_writeupdate(par);
-
-	aty_pll_wait_readupdate(par);
-	aty_st_pll(HTOTAL_CNTL, 0);	/* no horiz crtc adjustment */
-	aty_pll_writeupdate(par);
-
-	/* clear the reset, just in case */
-	aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~PPLL_RESET);
-}
-
-
-static int
-aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
-		  const struct aty128fb_par *par)
-{
-	const struct aty128_constants c = par->constants;
-	unsigned char post_dividers[] = {1,2,4,8,3,6,12};
-	u32 output_freq;
-	u32 vclk;        /* in .01 MHz */
-	int i;
-	u32 n, d;
-
-	vclk = 100000000 / period_in_ps;	/* convert units to 10 kHz */
-
-	/* adjust pixel clock if necessary */
-	if (vclk > c.ppll_max)
-		vclk = c.ppll_max;
-	if (vclk * 12 < c.ppll_min)
-		vclk = c.ppll_min/12;
-
-	/* now, find an acceptable divider */
-	for (i = 0; i < sizeof(post_dividers); i++) {
-		output_freq = post_dividers[i] * vclk;
-		if (output_freq >= c.ppll_min && output_freq <= c.ppll_max)
-			break;
-	}
-
-	/* calculate feedback divider */
-	n = c.ref_divider * output_freq;
-	d = c.dotclock;
-
-	pll->post_divider = post_dividers[i];
-	pll->feedback_divider = round_div(n, d);
-	pll->vclk = vclk;
-
-	DBG("post %d feedback %d vlck %d output %d ref_divider %d "
-	    "vclk_per: %d\n", pll->post_divider,
-	    pll->feedback_divider, vclk, output_freq,
-	    c.ref_divider, period_in_ps);
-
-	return 0;
-}
-
-
-static int
-aty128_pll_to_var(const struct aty128_pll *pll, struct fb_var_screeninfo *var)
-{
-	var->pixclock = 100000000 / pll->vclk;
-
-	return 0;
-}
-
-
-static void
-aty128_set_fifo(const struct aty128_ddafifo *dsp,
-		const struct aty128fb_par *par)
-{
-	aty_st_le32(DDA_CONFIG, dsp->dda_config);
-	aty_st_le32(DDA_ON_OFF, dsp->dda_on_off);
-}
-
-
-static int
-aty128_ddafifo(struct aty128_ddafifo *dsp,
-	       const struct aty128_pll *pll,
-	       u32 depth,
-	       const struct aty128fb_par *par)
-{
-	const struct aty128_meminfo *m = par->mem;
-	u32 xclk = par->constants.xclk;
-	u32 fifo_width = par->constants.fifo_width;
-	u32 fifo_depth = par->constants.fifo_depth;
-	s32 x, b, p, ron, roff;
-	u32 n, d, bpp;
-
-	/* round up to multiple of 8 */
-	bpp = (depth+7) & ~7;
-
-	n = xclk * fifo_width;
-	d = pll->vclk * bpp;
-	x = round_div(n, d);
-
-	ron = 4 * m->MB +
-		3 * ((m->Trcd - 2 > 0) ? m->Trcd - 2 : 0) +
-		2 * m->Trp +
-		m->Twr +
-		m->CL +
-		m->Tr2w +
-		x;
-
-	DBG("x %x\n", x);
-
-	b = 0;
-	while (x) {
-		x >>= 1;
-		b++;
-	}
-	p = b + 1;
-
-	ron <<= (11 - p);
-
-	n <<= (11 - p);
-	x = round_div(n, d);
-	roff = x * (fifo_depth - 4);
-
-	if ((ron + m->Rloop) >= roff) {
-		printk(KERN_ERR "aty128fb: Mode out of range!\n");
-		return -EINVAL;
-	}
-
-	DBG("p: %x rloop: %x x: %x ron: %x roff: %x\n",
-	    p, m->Rloop, x, ron, roff);
-
-	dsp->dda_config = p << 16 | m->Rloop << 20 | x;
-	dsp->dda_on_off = ron << 16 | roff;
-
-	return 0;
-}
-
-
-/*
- * This actually sets the video mode.
- */
-static int
-aty128fb_set_par(struct fb_info *info)
-{ 
-	struct aty128fb_par *par = info->par;
-	u32 config;
-	int err;
-
-	if ((err = aty128_decode_var(&info->var, par)) != 0)
-		return err;
-
-	if (par->blitter_may_be_busy)
-		wait_for_idle(par);
-
-	/* clear all registers that may interfere with mode setting */
-	aty_st_le32(OVR_CLR, 0);
-	aty_st_le32(OVR_WID_LEFT_RIGHT, 0);
-	aty_st_le32(OVR_WID_TOP_BOTTOM, 0);
-	aty_st_le32(OV0_SCALE_CNTL, 0);
-	aty_st_le32(MPP_TB_CONFIG, 0);
-	aty_st_le32(MPP_GP_CONFIG, 0);
-	aty_st_le32(SUBPIC_CNTL, 0);
-	aty_st_le32(VIPH_CONTROL, 0);
-	aty_st_le32(I2C_CNTL_1, 0);         /* turn off i2c */
-	aty_st_le32(GEN_INT_CNTL, 0);	/* turn off interrupts */
-	aty_st_le32(CAP0_TRIG_CNTL, 0);
-	aty_st_le32(CAP1_TRIG_CNTL, 0);
-
-	aty_st_8(CRTC_EXT_CNTL + 1, 4);	/* turn video off */
-
-	aty128_set_crtc(&par->crtc, par);
-	aty128_set_pll(&par->pll, par);
-	aty128_set_fifo(&par->fifo_reg, par);
-
-	config = aty_ld_le32(CONFIG_CNTL) & ~3;
-
-#if defined(__BIG_ENDIAN)
-	if (par->crtc.bpp == 32)
-		config |= 2;	/* make aperture do 32 bit swapping */
-	else if (par->crtc.bpp == 16)
-		config |= 1;	/* make aperture do 16 bit swapping */
-#endif
-
-	aty_st_le32(CONFIG_CNTL, config);
-	aty_st_8(CRTC_EXT_CNTL + 1, 0);	/* turn the video back on */
-
-	info->fix.line_length = (par->crtc.vxres * par->crtc.bpp) >> 3;
-	info->fix.visual = par->crtc.bpp == 8 ? FB_VISUAL_PSEUDOCOLOR
-		: FB_VISUAL_DIRECTCOLOR;
-
-#ifdef CONFIG_PMAC_PBOOK
-	if (par->chip_gen == rage_M3) {
-		aty128_set_crt_enable(par, par->crt_on);
-		aty128_set_lcd_enable(par, par->lcd_on);
-	}
-#endif
-	if (par->accel_flags & FB_ACCELF_TEXT)
-		aty128_init_engine(par);
-
-#ifdef CONFIG_BOOTX_TEXT
-	btext_update_display(info->fix.smem_start,
-			     (((par->crtc.h_total>>16) & 0xff)+1)*8,
-			     ((par->crtc.v_total>>16) & 0x7ff)+1,
-			     par->crtc.bpp,
-			     par->crtc.vxres*par->crtc.bpp/8);
-#endif /* CONFIG_BOOTX_TEXT */
-
-	return 0;
-}
-
-/*
- *  encode/decode the User Defined Part of the Display
- */
-
-static int
-aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par)
-{
-	int err;
-	struct aty128_crtc crtc;
-	struct aty128_pll pll;
-	struct aty128_ddafifo fifo_reg;
-
-	if ((err = aty128_var_to_crtc(var, &crtc, par)))
-		return err;
-
-	if ((err = aty128_var_to_pll(var->pixclock, &pll, par)))
-		return err;
-
-	if ((err = aty128_ddafifo(&fifo_reg, &pll, crtc.depth, par)))
-		return err;
-
-	par->crtc = crtc;
-	par->pll = pll;
-	par->fifo_reg = fifo_reg;
-	par->accel_flags = var->accel_flags;
-
-	return 0;
-}
-
-
-static int
-aty128_encode_var(struct fb_var_screeninfo *var,
-		  const struct aty128fb_par *par)
-{
-	int err;
-
-	if ((err = aty128_crtc_to_var(&par->crtc, var)))
-		return err;
-
-	if ((err = aty128_pll_to_var(&par->pll, var)))
-		return err;
-
-	var->nonstd = 0;
-	var->activate = 0;
-
-	var->height = -1;
-	var->width = -1;
-	var->accel_flags = par->accel_flags;
-
-	return 0;
-}           
-
-
-static int
-aty128fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	struct aty128fb_par par;
-	int err;
-
-	par = *(struct aty128fb_par *)info->par;
-	if ((err = aty128_decode_var(var, &par)) != 0)
-		return err;
-	aty128_encode_var(var, &par);
-	return 0;
-}
-
-
-/*
- *  Pan or Wrap the Display
- */
-static int
-aty128fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fb) 
-{
-	struct aty128fb_par *par = fb->par;
-	u32 xoffset, yoffset;
-	u32 offset;
-	u32 xres, yres;
-
-	xres = (((par->crtc.h_total >> 16) & 0xff) + 1) << 3;
-	yres = ((par->crtc.v_total >> 16) & 0x7ff) + 1;
-
-	xoffset = (var->xoffset +7) & ~7;
-	yoffset = var->yoffset;
-
-	if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
-		return -EINVAL;
-
-	par->crtc.xoffset = xoffset;
-	par->crtc.yoffset = yoffset;
-
-	offset = ((yoffset * par->crtc.vxres + xoffset)*(par->crtc.bpp >> 3)) & ~7;
-
-	if (par->crtc.bpp == 24)
-		offset += 8 * (offset % 3); /* Must be multiple of 8 and 3 */
-
-	aty_st_le32(CRTC_OFFSET, offset);
-
-	return 0;
-}
-
-
-/*
- *  Helper function to store a single palette register
- */
-static void
-aty128_st_pal(u_int regno, u_int red, u_int green, u_int blue,
-	      struct aty128fb_par *par)
-{
-	if (par->chip_gen == rage_M3) {
-#if 0
-		/* Note: For now, on M3, we set palette on both heads, which may
-		 * be useless. Can someone with a M3 check this ?
-		 * 
-		 * This code would still be useful if using the second CRTC to 
-		 * do mirroring
-		 */
-
-		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
-		aty_st_8(PALETTE_INDEX, regno);
-		aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue);
-#endif
-		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
-	}
-
-	aty_st_8(PALETTE_INDEX, regno);
-	aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue);
-}
-
-static int
-aty128fb_sync(struct fb_info *info)
-{
-	struct aty128fb_par *par = info->par;
-
-	if (par->blitter_may_be_busy)
-		wait_for_idle(par);
-	return 0;
-}
-
-int __init
-aty128fb_setup(char *options)
-{
-	char *this_opt;
-
-	if (!options || !*options)
-		return 0;
-
-	while ((this_opt = strsep(&options, ",")) != NULL) {
-#ifdef CONFIG_PMAC_PBOOK
-		if (!strncmp(this_opt, "lcd:", 4)) {
-			default_lcd_on = simple_strtoul(this_opt+4, NULL, 0);
-		} else if (!strncmp(this_opt, "crt:", 4)) {
-			default_crt_on = simple_strtoul(this_opt+4, NULL, 0);
-		}
-#endif
-#ifdef CONFIG_MTRR
-		if(!strncmp(this_opt, "nomtrr", 6)) {
-			mtrr = 0;
-		}
-#endif
-#ifdef CONFIG_ALL_PPC
-		/* vmode and cmode deprecated */
-		if (!strncmp(this_opt, "vmode:", 6)) {
-			unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
-			if (vmode > 0 && vmode <= VMODE_MAX)
-				default_vmode = vmode;
-		} else if (!strncmp(this_opt, "cmode:", 6)) {
-			unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
-			switch (cmode) {
-			case 0:
-			case 8:
-				default_cmode = CMODE_8;
-				break;
-			case 15:
-			case 16:
-				default_cmode = CMODE_16;
-				break;
-			case 24:
-			case 32:
-				default_cmode = CMODE_32;
-				break;
-			}
-		}
-#endif /* CONFIG_ALL_PPC */
-		else
-			mode_option = this_opt;
-	}
-	return 0;
-}
-
-
-/*
- *  Initialisation
- */
-
-static int __init
-aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	struct fb_info *info = pci_get_drvdata(pdev);
-	struct aty128fb_par *par = info->par;
-	struct fb_var_screeninfo var;
-	char video_card[25];
-	u8 chip_rev;
-	u32 dac;
-
-	if (!par->vram_size)	/* may have already been probed */
-		par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
-
-	/* Get the chip revision */
-	chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
-
-	switch (pdev->device) {
-		case PCI_DEVICE_ID_ATI_RAGE128_RE:
-			strcpy(video_card, "Rage128 RE (PCI)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_RF:
-			strcpy(video_card, "Rage128 RF (AGP)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_RK:
-			strcpy(video_card, "Rage128 RK (PCI)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_RL:
-			strcpy(video_card, "Rage128 RL (AGP)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_PF:
-			strcpy(video_card, "Rage128 Pro PF (AGP)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_PR:
-			strcpy(video_card, "Rage128 Pro PR (PCI)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_U3:
-			strcpy(video_card, "Rage128 Pro TR (AGP)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_U1:
-			strcpy(video_card, "Rage128 Pro TF (AGP)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_LE:
-			strcpy(video_card, "Rage Mobility M3 (PCI)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_LF:
-			strcpy(video_card, "Rage Mobility M3 (AGP)");
-			break;
-		default:
-			return -ENODEV;
-	}
-
-	printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);
-
-	if (par->vram_size % (1024 * 1024) == 0)
-		printk("%dM %s\n", par->vram_size / (1024*1024), par->mem->name);
-	else
-		printk("%dk %s\n", par->vram_size / 1024, par->mem->name);
-
-	par->chip_gen = ent->driver_data;
-
-	/* fill in info */
-	info->node  = NODEV;
-	info->fbops = &aty128fb_ops;
-	info->flags = FBINFO_FLAG_DEFAULT;
-
-#ifdef CONFIG_PMAC_PBOOK
-	par->lcd_on = default_lcd_on;
-	par->crt_on = default_crt_on;
-#endif
-
-	var = default_var;
-#ifdef CONFIG_ALL_PPC
-	if (_machine == _MACH_Pmac) {
-		if (mode_option) {
-			if (!mac_find_mode(&var, info, mode_option, 8))
-				var = default_var;
-		} else {
-			if (default_vmode <= 0 || default_vmode > VMODE_MAX)
-				default_vmode = VMODE_1024_768_60;
-
-			/* iMacs need that resolution
-			 * PowerMac2,1 first r128 iMacs
-			 * PowerMac2,2 summer 2000 iMacs
-			 * PowerMac4,1 january 2001 iMacs "flower power"
-			 */
-			if (machine_is_compatible("PowerMac2,1") ||
-			    machine_is_compatible("PowerMac2,2") ||
-			    machine_is_compatible("PowerMac4,1"))
-				default_vmode = VMODE_1024_768_75;
-
-			/* iBook SE */
-			if (machine_is_compatible("PowerBook2,2"))
-				default_vmode = VMODE_800_600_60;
-
-			/* PowerBook Firewire (Pismo), iBook Dual USB */
-			if (machine_is_compatible("PowerBook3,1") ||
-			    machine_is_compatible("PowerBook4,1"))
-				default_vmode = VMODE_1024_768_60;
-
-			/* PowerBook Titanium */
-			if (machine_is_compatible("PowerBook3,2"))
-				default_vmode = VMODE_1152_768_60;
-	
-			if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
-				default_cmode = CMODE_8;
-
-			if (mac_vmode_to_var(default_vmode, default_cmode, &var))
-				var = default_var;
-		}
-	} else
-#endif /* CONFIG_ALL_PPC */
-	{
-		if (fb_find_mode(&var, info, mode_option, NULL, 0,
-				 &defaultmode, 8) == 0)
-			var = default_var;
-	}
-
-	var.accel_flags &= ~FB_ACCELF_TEXT;
-//	var.accel_flags |= FB_ACCELF_TEXT;/* FIXME Will add accel later */
-
-	if (aty128fb_check_var(&var, info)) {
-		printk(KERN_ERR "aty128fb: Cannot set default mode.\n");
-		return 0;
-	}
-
-	/* setup the DAC the way we like it */
-	dac = aty_ld_le32(DAC_CNTL);
-	dac |= (DAC_8BIT_EN | DAC_RANGE_CNTL);
-	dac |= DAC_MASK;
-	if (par->chip_gen == rage_M3)
-		dac |= DAC_PALETTE2_SNOOP_EN;
-	aty_st_le32(DAC_CNTL, dac);
-
-	/* turn off bus mastering, just in case */
-	aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_MASTER_DIS);
-
-	info->var = var;
-	fb_alloc_cmap(&info->cmap, 256, 0);
-
-	var.activate = FB_ACTIVATE_NOW;
-
-	aty128_init_engine(par);
-
-	if (register_framebuffer(info) < 0)
-		return 0;
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-	/* Could be extended to Rage128Pro LVDS output too */
-	if (par->chip_gen == rage_M3)
-		register_backlight_controller(&aty128_backlight_controller, par, "ati");
-#endif /* CONFIG_PMAC_BACKLIGHT */
-#ifdef CONFIG_PMAC_PBOOK
-	par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
-	if (aty128_fb == NULL) {
-		/* XXX can only put one chip to sleep */
-		aty128_fb = info;
-	} else
-		printk(KERN_WARNING "aty128fb: can only sleep one Rage 128\n");
-	par->pdev = pdev;
-#endif
-
-	printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
-	       minor(info->node), info->fix.id, video_card);
-
-	return 1;	/* success! */
-}
-
-#ifdef CONFIG_PCI
-/* register a card    ++ajoshi */
-static int __init
-aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	unsigned long fb_addr, reg_addr;
-	struct aty128fb_par *par;
-	struct fb_info *info;
-	int err, size;
-#if !defined(CONFIG_PPC) && !defined(__sparc__)
-	char *bios_seg = NULL;
-#endif
-
-	/* Enable device in PCI config */
-	if ((err = pci_enable_device(pdev))) {
-		printk(KERN_ERR "aty128fb: Cannot enable PCI device: %d\n",
-				err);
-		return -ENODEV;
-	}
-
-	fb_addr = pci_resource_start(pdev, 0);
-	if (!request_mem_region(fb_addr, pci_resource_len(pdev, 0),
-				"aty128fb FB")) {
-		printk(KERN_ERR "aty128fb: cannot reserve frame "
-				"buffer memory\n");
-		goto err_free_fb;
-	}
-
-	reg_addr = pci_resource_start(pdev, 2);
-	if (!request_mem_region(reg_addr, pci_resource_len(pdev, 2),
-				"aty128fb MMIO")) {
-		printk(KERN_ERR "aty128fb: cannot reserve MMIO region\n");
-		goto err_free_mmio;
-	}
-
-	/* We have the resources. Now virtualize them */
-	size = sizeof(struct fb_info) + sizeof(struct aty128fb_par);
-	if (!(info = kmalloc(size, GFP_ATOMIC))) {
-		printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n");
-		goto err_unmap_out;
-	}
-	memset(info, 0, size);
-
-	par = (struct aty128fb_par *)(info + 1);
-	info->pseudo_palette = par->pseudo_palette;
-
-	info->par = par;
-	info->fix = aty128fb_fix;
-
-	/* Virtualize mmio region */
-	info->fix.mmio_start = reg_addr;
-	par->regbase = ioremap(reg_addr, 0x2000);
-	if (!par->regbase)
-		goto err_free_info;
-
-	/* Grab memory size from the card */
-	par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
-
-	/* Virtualize the framebuffer */
-	info->screen_base = ioremap(fb_addr, par->vram_size);
-	if (!info->screen_base) {
-		iounmap(par->regbase);
-		goto err_free_info;
-	}
-
-	/* Set up info->fix */
-	info->fix = aty128fb_fix;
-	info->fix.smem_start = fb_addr;
-	info->fix.smem_len = par->vram_size;
-	info->fix.mmio_start = reg_addr;
-
-	/* If we can't test scratch registers, something is seriously wrong */
-	if (!register_test(par)) {
-		printk(KERN_ERR "aty128fb: Can't write to video register!\n");
-		goto err_out;
-	}
-
-#if !defined(CONFIG_PPC) && !defined(__sparc__)
-	if (!(bios_seg = aty128find_ROM()))
-		printk(KERN_INFO "aty128fb: Rage128 BIOS not located. "
-					"Guessing...\n");
-	else {
-		printk(KERN_INFO "aty128fb: Rage128 BIOS located at "
-				"segment %4.4X\n", (unsigned int)bios_seg);
-		aty128_get_pllinfo(par, bios_seg);
-	}
-#endif
-	aty128_timings(par);
-	pci_set_drvdata(pdev, info);
-
-	if (!aty128_init(pdev, ent))
-		goto err_out;
-
-#ifdef CONFIG_MTRR
-	if (mtrr) {
-		par->mtrr.vram = mtrr_add(info->fix.smem_start,
-				par->vram_size, MTRR_TYPE_WRCOMB, 1);
-		par->mtrr.vram_valid = 1;
-		/* let there be speed */
-		printk(KERN_INFO "aty128fb: Rage128 MTRR set to ON\n");
-	}
-#endif /* CONFIG_MTRR */
-	return 0;
-
-err_out:
-	iounmap(info->screen_base);
-	iounmap(par->regbase);
-err_free_info:
-	kfree(info);
-err_unmap_out:
-	release_mem_region(pci_resource_start(pdev, 2),
-			pci_resource_len(pdev, 2));
-err_free_mmio:
-	release_mem_region(pci_resource_start(pdev, 0),
-			pci_resource_len(pdev, 0));
-err_free_fb:
-	release_mem_region(pci_resource_start(pdev, 1),
-			pci_resource_len(pdev, 1));
-	return -ENODEV;
-}
-
-static void __devexit aty128_remove(struct pci_dev *pdev)
-{
-	struct fb_info *info = pci_get_drvdata(pdev);
-	struct aty128fb_par *par = info->par;
-
-	if (!info)
-		return;
-
-	unregister_framebuffer(info);
-#ifdef CONFIG_MTRR
-	if (par->mtrr.vram_valid)
-		mtrr_del(par->mtrr.vram, info->fix.smem_start,
-			 par->vram_size);
-#endif /* CONFIG_MTRR */
-	iounmap(par->regbase);
-	iounmap(info->screen_base);
-
-	release_mem_region(pci_resource_start(pdev, 0),
-			   pci_resource_len(pdev, 0));
-	release_mem_region(pci_resource_start(pdev, 1),
-			   pci_resource_len(pdev, 1));
-	release_mem_region(pci_resource_start(pdev, 2),
-			   pci_resource_len(pdev, 2));
-#ifdef CONFIG_PMAC_PBOOK
-	if (info == aty128_fb)
-		aty128_fb = NULL;
-#endif
-	kfree(info);
-}
-#endif /* CONFIG_PCI */
-
-/* PPC and Sparc cannot read video ROM */
-#if !defined(CONFIG_PPC) && !defined(__sparc__)
-static char * __init aty128find_ROM(void)
-{
-	u32  segstart;
-	char *rom_base;
-	char *rom;
-	int  stage;
-	int  i, j;
-	char aty_rom_sig[] = "761295520";   /* ATI ROM Signature      */
-	char *R128_sig[] = {
-		"R128",		/* Rage128 ROM identifier */
-		"128b"
-	};
-
-	for (segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
-        	stage = 1;
-
-		rom_base = (char *)ioremap(segstart, 0x1000);
-
-		if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))
-			stage = 2;
-
-		if (stage != 2) {
-			iounmap(rom_base);
-			continue;
-		}
-		rom = rom_base;
-
-		for (i = 0; (i < 128 - strlen(aty_rom_sig)) && (stage != 3); i++) {
-			if (aty_rom_sig[0] == *rom)
-				if (strncmp(aty_rom_sig, rom,
-						strlen(aty_rom_sig)) == 0)
-					stage = 3;
-			rom++;
-		}
-		if (stage != 3) {
-			iounmap(rom_base);
-			continue;
-		}
-		rom = rom_base;
-
-		/* ATI signature found.  Let's see if it's a Rage128 */
-		for (i = 0; (i < 512) && (stage != 4); i++) {
-			for (j = 0; j < sizeof(R128_sig)/sizeof(char *);j++) {
-				if (R128_sig[j][0] == *rom)
-					if (strncmp(R128_sig[j], rom, 
-					    strlen(R128_sig[j])) == 0) {
-						stage = 4;
-						break;
-					}
-			}
-			rom++;
-		}
-		if (stage != 4) {
-			iounmap(rom_base);
-			continue;
-		}
-		return rom_base;
-	}
-	return NULL;
-}
-
-
-static void __init
-aty128_get_pllinfo(struct aty128fb_par *par, char *bios_seg)
-{
-	void *bios_header;
-	void *header_ptr;
-	u16 bios_header_offset, pll_info_offset;
-	PLL_BLOCK pll;
-
-	bios_header = bios_seg + 0x48L;
-	header_ptr  = bios_header;
-
-	bios_header_offset = readw(header_ptr);
-	bios_header = bios_seg + bios_header_offset;
-	bios_header += 0x30;
-
-	header_ptr = bios_header;
-	pll_info_offset = readw(header_ptr);
-	header_ptr = bios_seg + pll_info_offset;
-
-	memcpy_fromio(&pll, header_ptr, 50);
-
-	par->constants.ppll_max = pll.PCLK_max_freq;
-	par->constants.ppll_min = pll.PCLK_min_freq;
-	par->constants.xclk = (u32)pll.XCLK;
-	par->constants.ref_divider = (u32)pll.PCLK_ref_divider;
-	par->constants.dotclock = (u32)pll.PCLK_ref_freq;
-
-	DBG("ppll_max %d ppll_min %d xclk %d ref_divider %d dotclock %d\n",
-			par->constants.ppll_max, par->constants.ppll_min,
-			par->constants.xclk, par->constants.ref_divider,
-			par->constants.dotclock);
-
-}           
-#endif /* !CONFIG_PPC */
-
-
-/* fill in known card constants if pll_block is not available */
-static void __init
-aty128_timings(struct aty128fb_par *par)
-{
-#ifdef CONFIG_ALL_PPC
-	/* instead of a table lookup, assume OF has properly
-	 * setup the PLL registers and use their values
-	 * to set the XCLK values and reference divider values */
-
-	u32 x_mpll_ref_fb_div;
-	u32 xclk_cntl;
-	u32 Nx, M;
-	unsigned PostDivSet[] = { 0, 1, 2, 4, 8, 3, 6, 12 };
-#endif
-
-	if (!par->constants.dotclock)
-		par->constants.dotclock = 2950;
-
-#ifdef CONFIG_ALL_PPC
-	x_mpll_ref_fb_div = aty_ld_pll(X_MPLL_REF_FB_DIV);
-	xclk_cntl = aty_ld_pll(XCLK_CNTL) & 0x7;
-	Nx = (x_mpll_ref_fb_div & 0x00ff00) >> 8;
-	M  = x_mpll_ref_fb_div & 0x0000ff;
-
-	par->constants.xclk = round_div((2 * Nx * par->constants.dotclock),
-					(M * PostDivSet[xclk_cntl]));
-
-	par->constants.ref_divider =
-		aty_ld_pll(PPLL_REF_DIV) & PPLL_REF_DIV_MASK;
-#endif
-
-	if (!par->constants.ref_divider) {
-		par->constants.ref_divider = 0x3b;
-
-		aty_st_pll(X_MPLL_REF_FB_DIV, 0x004c4c1e);
-		aty_pll_writeupdate(par);
-	}
-	aty_st_pll(PPLL_REF_DIV, par->constants.ref_divider);
-	aty_pll_writeupdate(par);
-
-	/* from documentation */
-	if (!par->constants.ppll_min)
-		par->constants.ppll_min = 12500;
-	if (!par->constants.ppll_max)
-		par->constants.ppll_max = 25000;    /* 23000 on some cards? */
-	if (!par->constants.xclk)
-		par->constants.xclk = 0x1d4d;	     /* same as mclk */
-
-	par->constants.fifo_width = 128;
-	par->constants.fifo_depth = 32;
-
-	switch (aty_ld_le32(MEM_CNTL) & 0x3) {
-	case 0:
-		par->mem = &sdr_128;
-		break;
-	case 1:
-		par->mem = &sdr_sgram;
-		break;
-	case 2:
-		par->mem = &ddr_sgram;
-		break;
-	default:
-		par->mem = &sdr_sgram;
-	}
-}
-
-
-    /*
-     *  Blank the display.
-     */
-static int
-aty128fb_blank(int blank, struct fb_info *fb)
-{
-	struct aty128fb_par *par = fb->par;
-	u8 state = 0;
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-	if ((_machine == _MACH_Pmac) && blank)
-		set_backlight_enable(0);
-#endif /* CONFIG_PMAC_BACKLIGHT */
-
-	if (blank & VESA_VSYNC_SUSPEND)
-		state |= 2;
-	if (blank & VESA_HSYNC_SUSPEND)
-		state |= 1;
-	if (blank & VESA_POWERDOWN)
-		state |= 4;
-
-	aty_st_8(CRTC_EXT_CNTL+1, state);
-
-#ifdef CONFIG_PMAC_PBOOK
-	if (par->chip_gen == rage_M3) {
-		aty128_set_crt_enable(par, par->crt_on && !blank);
-		aty128_set_lcd_enable(par, par->lcd_on && !blank);
-	}
-#endif	
-#ifdef CONFIG_PMAC_BACKLIGHT
-	if ((_machine == _MACH_Pmac) && !blank)
-		set_backlight_enable(1);
-#endif /* CONFIG_PMAC_BACKLIGHT */
-	return 0;
-}
-
-/*
- *  Set a single color register. The values supplied are already
- *  rounded down to the hardware's capabilities (according to the
- *  entries in the var structure). Return != 0 for invalid regno.
- */
-static int
-aty128fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp, struct fb_info *info)
-{
-	struct aty128fb_par *par = info->par;
-
-	if (regno > 255
-	    || (par->crtc.depth == 16 && regno > 63)
-	    || (par->crtc.depth == 15 && regno > 31))
-		return 1;
-
-	red >>= 8;
-	green >>= 8;
-	blue >>= 8;
-
-	if (regno < 16) {
-		int i;
-		switch (par->crtc.depth) {
-		case 15:
-			((u16 *) (info->pseudo_palette))[regno] =
-			    (regno << 10) | (regno << 5) | regno;
-			break;
-		case 16:
-			((u16 *) (info->pseudo_palette))[regno] =
-			    (regno << 11) | (regno << 6) | regno;
-			break;
-		case 24:
-			((u32 *) (info->pseudo_palette))[regno] =
-			    (regno << 16) | (regno << 8) | regno;
-			break;
-		case 32:
-			i = (regno << 8) | regno;
-			((u32 *) (info->pseudo_palette))[regno] =
-			    (i << 16) | i;
-			break;
-		}
-	}
-
-	if (par->crtc.depth == 16 && regno > 0) {
-		/*
-		 * With the 5-6-5 split of bits for RGB at 16 bits/pixel, we
-		 * have 32 slots for R and B values but 64 slots for G values.
-		 * Thus the R and B values go in one slot but the G value
-		 * goes in a different slot, and we have to avoid disturbing
-		 * the other fields in the slots we touch.
-		 */
-		par->green[regno] = green;
-		if (regno < 32) {
-			par->red[regno] = red;
-			par->blue[regno] = blue;
-			aty128_st_pal(regno * 8, red, par->green[regno*2],
-				      blue, par);
-		}
-		red = par->red[regno/2];
-		blue = par->blue[regno/2];
-		regno <<= 2;
-	} else if (par->crtc.bpp == 16)
-		regno <<= 3;
-	aty128_st_pal(regno, red, green, blue, par);
-
-	return 0;
-}
-
-#define ATY_MIRROR_LCD_ON	0x00000001
-#define ATY_MIRROR_CRT_ON	0x00000002
-
-/* out param: u32*	backlight value: 0 to 15 */
-#define FBIO_ATY128_GET_MIRROR	_IOR('@', 1, sizeof(__u32*))
-/* in param: u32*	backlight value: 0 to 15 */
-#define FBIO_ATY128_SET_MIRROR	_IOW('@', 2, sizeof(__u32*))
-
-static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-			  u_long arg, struct fb_info *info)
-{
-#ifdef CONFIG_PMAC_PBOOK
-	struct aty128fb_par *par = info->par;
-	u32 value;
-	int rc;
-    
-	switch (cmd) {
-	case FBIO_ATY128_SET_MIRROR:
-		if (par->chip_gen != rage_M3)
-			return -EINVAL;
-		rc = get_user(value, (__u32*)arg);
-		if (rc)
-			return rc;
-		par->lcd_on = (value & 0x01) != 0;
-		par->crt_on = (value & 0x02) != 0;
-		if (!par->crt_on && !par->lcd_on)
-			par->lcd_on = 1;
-		aty128_set_crt_enable(par, par->crt_on);	
-		aty128_set_lcd_enable(par, par->lcd_on);	
-		return 0;
-	case FBIO_ATY128_GET_MIRROR:
-		if (par->chip_gen != rage_M3)
-			return -EINVAL;
-		value = (par->crt_on << 1) | par->lcd_on;
-		return put_user(value, (__u32*)arg);
-	}
-#endif
-	return -EINVAL;
-}
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-static int backlight_conv[] = {
-	0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
-	0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
-};
-
-/* We turn off the LCD completely instead of just dimming the backlight.
- * This provides greater power saving and the display is useless without
- * backlight anyway
- */
-#define BACKLIGHT_LVDS_OFF
-/* That one prevents proper CRT output with LCD off */
-#undef BACKLIGHT_DAC_OFF
-
-static int
-aty128_set_backlight_enable(int on, int level, void *data)
-{
-	struct aty128fb_par *par = data;
-	unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
-
-	if (!par->lcd_on)
-		on = 0;
-	reg |= LVDS_BL_MOD_EN | LVDS_BLON;
-	if (on && level > BACKLIGHT_OFF) {
-		reg |= LVDS_DIGION;
-		if (!reg & LVDS_ON) {
-			reg &= ~LVDS_BLON;
-			aty_st_le32(LVDS_GEN_CNTL, reg);
-			(void)aty_ld_le32(LVDS_GEN_CNTL);
-			mdelay(10);
-			reg |= LVDS_BLON;
-			aty_st_le32(LVDS_GEN_CNTL, reg);
-		}
-		reg &= ~LVDS_BL_MOD_LEVEL_MASK;
-		reg |= (backlight_conv[level] << LVDS_BL_MOD_LEVEL_SHIFT);
-#ifdef BACKLIGHT_LVDS_OFF
-		reg |= LVDS_ON | LVDS_EN;
-		reg &= ~LVDS_DISPLAY_DIS;
-#endif
-		aty_st_le32(LVDS_GEN_CNTL, reg);
-#ifdef BACKLIGHT_DAC_OFF
-		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & (~DAC_PDWN));
-#endif		
-	} else {
-		reg &= ~LVDS_BL_MOD_LEVEL_MASK;
-		reg |= (backlight_conv[0] << LVDS_BL_MOD_LEVEL_SHIFT);
-#ifdef BACKLIGHT_LVDS_OFF
-		reg |= LVDS_DISPLAY_DIS;
-		aty_st_le32(LVDS_GEN_CNTL, reg);
-		(void)aty_ld_le32(LVDS_GEN_CNTL);
-		udelay(10);
-		reg &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGION);
-#endif		
-		aty_st_le32(LVDS_GEN_CNTL, reg);
-#ifdef BACKLIGHT_DAC_OFF
-		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PDWN);
-#endif		
-	}
-
-	return 0;
-}
-
-static int
-aty128_set_backlight_level(int level, void* data)
-{
-	return aty128_set_backlight_enable(1, level, data);
-}
-#endif /* CONFIG_PMAC_BACKLIGHT */
-
-#if 0
-    /*
-     *  Accelerated functions
-     */
-
-static inline void
-aty128_rectcopy(int srcx, int srcy, int dstx, int dsty,
-		u_int width, u_int height,
-		struct fb_info_aty128 *par)
-{
-    u32 save_dp_datatype, save_dp_cntl, dstval;
-
-    if (!width || !height)
-        return;
-
-    dstval = depth_to_dst(par->current_par.crtc.depth);
-    if (dstval == DST_24BPP) {
-        srcx *= 3;
-        dstx *= 3;
-        width *= 3;
-    } else if (dstval == -EINVAL) {
-        printk("aty128fb: invalid depth or RGBA\n");
-        return;
-    }
-
-    wait_for_fifo(2, par);
-    save_dp_datatype = aty_ld_le32(DP_DATATYPE);
-    save_dp_cntl     = aty_ld_le32(DP_CNTL);
-
-    wait_for_fifo(6, par);
-    aty_st_le32(SRC_Y_X, (srcy << 16) | srcx);
-    aty_st_le32(DP_MIX, ROP3_SRCCOPY | DP_SRC_RECT);
-    aty_st_le32(DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
-    aty_st_le32(DP_DATATYPE, save_dp_datatype | dstval | SRC_DSTCOLOR);
-
-    aty_st_le32(DST_Y_X, (dsty << 16) | dstx);
-    aty_st_le32(DST_HEIGHT_WIDTH, (height << 16) | width);
-
-    par->blitter_may_be_busy = 1;
-
-    wait_for_fifo(2, par);
-    aty_st_le32(DP_DATATYPE, save_dp_datatype);
-    aty_st_le32(DP_CNTL, save_dp_cntl); 
-}
-
-
-    /*
-     * Text mode accelerated functions
-     */
-
-static void
-fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			int height, int width)
-{
-    sx     *= fontwidth(p);
-    sy     *= fontheight(p);
-    dx     *= fontwidth(p);
-    dy     *= fontheight(p);
-    width  *= fontwidth(p);
-    height *= fontheight(p);
-
-    aty128_rectcopy(sx, sy, dx, dy, width, height,
-			(struct fb_info_aty128 *)p->fb_info);
-}
-#endif /* 0 */
-
-#ifdef CONFIG_PMAC_PBOOK
-static void
-aty128_set_suspend(struct aty128fb_par *par, int suspend)
-{
-	u32	pmgt;
-	u16	pwr_command;
-	struct pci_dev *pdev = par->pdev;
-
-	if (!par->pm_reg)
-		return;
-		
-	/* Set the chip into the appropriate suspend mode (we use D2,
-	 * D3 would require a complete re-initialisation of the chip,
-	 * including PCI config registers, clocks, AGP configuration, ...)
-	 */
-	if (suspend) {
-		/* Make sure CRTC2 is reset. Remove that the day we decide to
-		 * actually use CRTC2 and replace it with real code for disabling
-		 * the CRTC2 output during sleep
-		 */
-		aty_st_le32(CRTC2_GEN_CNTL, aty_ld_le32(CRTC2_GEN_CNTL) &
-			~(CRTC2_EN));
-
-		/* Set the power management mode to be PCI based */
-		/* Use this magic value for now */
-		pmgt = 0x0c005407;
-		aty_st_pll(POWER_MANAGEMENT, pmgt);
-		(void)aty_ld_pll(POWER_MANAGEMENT);
-		aty_st_le32(BUS_CNTL1, 0x00000010);
-		aty_st_le32(MEM_POWER_MISC, 0x0c830000);
-		mdelay(100);
-		pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
-		/* Switch PCI power management to D2 */
-		pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL,
-			(pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2);
-		pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
-	} else {
-		/* Switch back PCI power management to D0 */
-		mdelay(100);
-		pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 0);
-		pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
-		mdelay(100);
-	}
-}
-
-/*
- * Save the contents of the frame buffer when we go to sleep,
- * and restore it when we wake up again.
- */
-int
-aty128_sleep_notify(struct pmu_sleep_notifier *self, int when)
-{
- 	int nb;
-	struct fb_info *info = aty128_fb;
-	struct aty128fb_par *par;
-
-	if (info == NULL)
-		return PBOOK_SLEEP_OK;
-	par = info->par;
-	nb = info->var.yres * info->fix.line_length;
-
-	switch (when) {
-	case PBOOK_SLEEP_REQUEST:
-		par->save_framebuffer = vmalloc(nb);
-		if (par->save_framebuffer == NULL)
-			return PBOOK_SLEEP_REFUSE;
-		break;
-	case PBOOK_SLEEP_REJECT:
-		if (par->save_framebuffer) {
-			vfree(par->save_framebuffer);
-			par->save_framebuffer = 0;
-		}
-		break;
-	case PBOOK_SLEEP_NOW:
-		wait_for_idle(par);
-		aty128_reset_engine(par);
-		wait_for_idle(par);
-
-		/* Backup fb content */	
-		if (par->save_framebuffer)
-			memcpy_fromio(par->save_framebuffer,
-			       info->screen_base, nb);
-
-		/* Blank display and LCD */
-		aty128fb_blank(VESA_POWERDOWN, info);
-			
-		/* Sleep the chip */
-		aty128_set_suspend(par, 1);
-
-		break;
-	case PBOOK_WAKE:
-		/* Wake the chip */
-		aty128_set_suspend(par, 0);
-		
-		aty128_reset_engine(par);
-		wait_for_idle(par);
-
-		/* Restore fb content */			
-		if (par->save_framebuffer) {
-			memcpy_toio(info->screen_base,
-			       par->save_framebuffer, nb);
-			vfree(par->save_framebuffer);
-			par->save_framebuffer = 0;
-		}
-		aty128fb_blank(0, info);
-		break;
-	}
-	return PBOOK_SLEEP_OK;
-}
-#endif /* CONFIG_PMAC_PBOOK */
-
-int __init aty128fb_init(void)
-{
-#ifdef CONFIG_PMAC_PBOOK
-	pmu_register_sleep_notifier(&aty128_sleep_notifier);
-#endif
-	return pci_module_init(&aty128fb_driver);
-}
-
-static void __exit aty128fb_exit(void)
-{
-#ifdef CONFIG_PMAC_PBOOK
-	pmu_unregister_sleep_notifier(&aty128_sleep_notifier);
-#endif
-	pci_unregister_driver(&aty128fb_driver);
-}
-
-MODULE_AUTHOR("(c)1999-2000 Brad Douglas <brad@neruo.com>");
-MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards");
-MODULE_LICENSE("GPL");
-MODULE_PARM(mode, "s");
-MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
-#ifdef CONFIG_MTRR
-MODULE_PARM(nomtrr, "i");
-MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
-#endif
-
diff -Nru a/drivers/video/c2p.c b/drivers/video/c2p.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/c2p.c	Fri Jan 24 10:23:15 2003
@@ -0,0 +1,229 @@
+/*
+ *  Fast C2P (Chunky-to-Planar) Conversion
+ *
+ *  Copyright (C) 2003 Geert Uytterhoeven
+ *
+ *  NOTES:
+ *    - This code was inspired by Scout's C2P tutorial
+ *    - It assumes to run on a big endian system
+ *
+ *  This file is subject to 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/string.h>
+#include "c2p.h"
+
+
+    /*
+     *  Basic transpose step
+     */
+
+#define _transp(d, i1, i2, shift, mask)			\
+    do {						\
+	u32 t = (d[i1] ^ (d[i2] >> shift)) & mask;	\
+	d[i1] ^= t;					\
+	d[i2] ^= t << shift;				\
+    } while (0)
+
+static inline u32 get_mask(int n)
+{
+    switch (n) {
+	case 1:
+	    return 0x55555555;
+	    break;
+
+	case 2:
+	    return 0x33333333;
+	    break;
+
+	case 4:
+	    return 0x0f0f0f0f;
+	    break;
+
+	case 8:
+	    return 0x00ff00ff;
+	    break;
+
+	case 16:
+	    return 0x0000ffff;
+	    break;
+    }
+    return 0;
+}
+
+#define transp_nx1(d, n)				\
+    do {						\
+	u32 mask = get_mask(n);				\
+	/* First block */				\
+	_transp(d, 0, 1, n, mask);			\
+	/* Second block */				\
+	_transp(d, 2, 3, n, mask);			\
+	/* Third block */				\
+	_transp(d, 4, 5, n, mask);			\
+	/* Fourth block */				\
+	_transp(d, 6, 7, n, mask);			\
+    } while (0)
+
+#define transp_nx2(d, n)				\
+    do {						\
+	u32 mask = get_mask(n);				\
+	/* First block */				\
+	_transp(d, 0, 2, n, mask);			\
+	_transp(d, 1, 3, n, mask);			\
+	/* Second block */				\
+	_transp(d, 4, 6, n, mask);			\
+	_transp(d, 5, 7, n, mask);			\
+    } while (0)
+
+#define transp_nx4(d, n)				\
+    do {						\
+	u32 mask = get_mask(n);				\
+	_transp(d, 0, 4, n, mask);			\
+	_transp(d, 1, 5, n, mask);			\
+	_transp(d, 2, 6, n, mask);			\
+	_transp(d, 3, 7, n, mask);			\
+    } while (0)
+
+#define transp(d, n, m)	transp_nx ## m(d, n)
+
+
+    /*
+     *  Perform a full C2P step on 32 8-bit pixels, stored in 8 32-bit words
+     *  containing
+     *    - 32 8-bit chunky pixels on input
+     *    - permuted planar data on output
+     */
+
+static void c2p_8bpp(u32 d[8])
+{
+    transp(d, 16, 4);
+    transp(d, 8, 2);
+    transp(d, 4, 1);
+    transp(d, 2, 4);
+    transp(d, 1, 2);
+}
+
+
+    /*
+     *  Array containing the permution indices of the planar data after c2p
+     */
+
+static const int perm_c2p_8bpp[8] = { 7, 5, 3, 1, 6, 4, 2, 0 };
+
+
+    /*
+     *  Compose two values, using a bitmask as decision value
+     *  This is equivalent to (a & mask) | (b & ~mask)
+     */
+
+static inline unsigned long comp(unsigned long a, unsigned long b,
+				 unsigned long mask)
+{
+	return ((a ^ b) & mask) ^ b;
+}
+
+
+    /*
+     *  Store a full block of planar data after c2p conversion
+     */
+
+static inline void store_planar(char *dst, u32 dst_inc, u32 bpp, u32 d[8])
+{
+    int i;
+
+    for (i = 0; i < bpp; i++, dst += dst_inc)
+	*(u32 *)dst = d[perm_c2p_8bpp[i]];
+}
+
+
+    /*
+     *  Store a partial block of planar data after c2p conversion
+     */
+
+static inline void store_planar_masked(char *dst, u32 dst_inc, u32 bpp,
+				       u32 d[8], u32 mask)
+{
+    int i;
+
+    for (i = 0; i < bpp; i++, dst += dst_inc)
+	*(u32 *)dst = comp(d[perm_c2p_8bpp[i]], *(u32 *)dst, mask);
+}
+
+
+    /*
+     *  c2p - Copy 8-bit chunky image data to a planar frame buffer
+     *  @dst: Starting address of the planar frame buffer
+     *  @dx: Horizontal destination offset (in pixels)
+     *  @dy: Vertical destination offset (in pixels)
+     *  @width: Image width (in pixels)
+     *  @height: Image height (in pixels)
+     *  @dst_nextline: Frame buffer offset to the next line (in bytes)
+     *  @dst_nextplane: Frame buffer offset to the next plane (in bytes)
+     *  @src_nextline: Image offset to the next line (in bytes)
+     *  @bpp: Bits per pixel of the planar frame buffer (1-8)
+     */
+
+void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height,
+	 u32 dst_nextline, u32 dst_nextplane, u32 src_nextline, u32 bpp)
+{
+    int dst_idx;
+    u32 d[8], first, last, w;
+    const u8 *c;
+    u8 *p;
+
+    dst += dy*dst_nextline+(dx & ~31);
+    dst_idx = dx % 32;
+    first = ~0UL >> dst_idx;
+    last = ~(~0UL >> ((dst_idx+width) % 32));
+    while (height--) {
+	c = src;
+	p = dst;
+	w = width;
+	if (dst_idx+width <= 32) {
+	    /* Single destination word */
+	    first &= last;
+	    memset(d, 0, sizeof(d));
+	    memcpy((u8 *)d+dst_idx, c, width);
+	    c += width;
+	    c2p_8bpp(d);
+	    store_planar_masked(p, dst_nextplane, bpp, d, first);
+	    p += 4;
+	} else {
+	    /* Multiple destination words */
+	    w = width;
+	    /* Leading bits */
+	    if (dst_idx) {
+		w = 32 - dst_idx;
+		memset(d, 0, dst_idx);
+		memcpy((u8 *)d+dst_idx, c, w);
+		c += w;
+		c2p_8bpp(d);
+		store_planar_masked(p, dst_nextplane, bpp, d, first);
+		p += 4;
+		w = width-w;
+	    }
+	    /* Main chunk */
+	    while (w >= 32) {
+		memcpy(d, c, 32);
+		c += 32;
+		c2p_8bpp(d);
+		store_planar(p, dst_nextplane, bpp, d);
+		p += 4;
+		w -= 32;
+	    }
+	    /* Trailing bits */
+	    w %= 32;
+	    if (w > 0) {
+		memcpy(d, c, w);
+		memset((u8 *)d+w, 0, 32-w);
+		c2p_8bpp(d);
+		store_planar_masked(p, dst_nextplane, bpp, d, last);
+	    }
+	}
+	src += src_nextline;
+	dst += dst_nextline;
+    }
+}
+
diff -Nru a/drivers/video/c2p.h b/drivers/video/c2p.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/c2p.h	Fri Jan 24 10:23:04 2003
@@ -0,0 +1,16 @@
+/*
+ *  Fast C2P (Chunky-to-Planar) Conversion
+ *
+ *  Copyright (C) 2003 Geert Uytterhoeven
+ *
+ *  This file is subject to 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/types.h>
+
+extern void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height,
+		u32 dst_nextline, u32 dst_nextplane, u32 src_nextline,
+		u32 bpp);
+
diff -Nru a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
--- a/drivers/video/cfbcopyarea.c	Thu Feb 27 04:00:40 2003
+++ b/drivers/video/cfbcopyarea.c	Mon Mar  3 14:02:00 2003
@@ -65,15 +65,14 @@
 			// Single word
 			if (last)
 				first &= last;
-			FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & ~first),
-				  dst);
+			FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & ~first), dst);
 		} else {
 			// Multiple destination words
 			// Leading bits
 			if (first) {
 				
-				FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & 
-							    ~first), dst);
+				FB_WRITEL((FB_READL(src) & first) | 
+					  (FB_READL(dst) & ~first), dst);
 				dst++;
 				src++;
 				n -= BITS_PER_LONG-dst_idx;
@@ -96,8 +95,7 @@
 				FB_WRITEL(FB_READL(src++), dst++);
 			// Trailing bits
 			if (last)
-				FB_WRITEL((FB_READL(src) & last) | (FB_READL(dst) & 
-							   ~last), dst);
+				FB_WRITEL((FB_READL(src) & last) | (FB_READL(dst) & ~last), dst);
 		}
 	} else {
 		// Different alignment for source and dest
@@ -220,14 +218,12 @@
 			// Single word
 			if (last)
 				first &= last;
-			FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & ~first), 
-				  dst);
+			FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & ~first), dst); 
 		} else {
 			// Multiple destination words
 			// Leading bits
 			if (first) {
-				FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & 
-							    ~first), dst);
+				FB_WRITEL((FB_READL(src) & first) | (FB_READL(dst) & ~first), dst); 
 				dst--;
 				src--;
 				n -= dst_idx+1;
@@ -251,8 +247,7 @@
 			
 			// Trailing bits
 			if (last)
-				FB_WRITEL((FB_READL(src) & last) | (FB_READL(dst) & 
-							   ~last), dst);
+				FB_WRITEL((FB_READL(src) & last) | (FB_READL(dst) & ~last), dst);
 		}
 	} else {
 		// Different alignment for source and dest
@@ -342,8 +337,10 @@
 	}
 }
 
-void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
+void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
 {
+	u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
+	u32 height = area->height, width = area->width;
 	int x2, y2, old_dx, old_dy, vxres, vyres;
 	unsigned long next_line = p->fix.line_length;
 	int dst_idx = 0, src_idx = 0, rev_copy = 0;
@@ -370,59 +367,57 @@
 	 */
 	x2 = area->dx + area->width;
 	y2 = area->dy + area->height;
-	area->dx = area->dx > 0 ? area->dx : 0;
-	area->dy = area->dy > 0 ? area->dy : 0;
+	dx = area->dx > 0 ? area->dx : 0;
+	dy = area->dy > 0 ? area->dy : 0;
 	x2 = x2 < vxres ? x2 : vxres;
 	y2 = y2 < vyres ? y2 : vyres;
-	area->width = x2 - area->dx;
-	area->height = y2 - area->dy;
+	width = x2 - dx;
+	height = y2 - dy;
 
 	/* update sx1,sy1 */
-	area->sx += (area->dx - old_dx);
-	area->sy += (area->dy - old_dy);
+	sx += (dx - old_dx);
+	sy += (dy - old_dy);
 
 	/* the source must be completely inside the virtual screen */
-	if (area->sx < 0 || area->sy < 0 ||
-	    (area->sx + area->width) > vxres ||
-	    (area->sy + area->height) > vyres)
+	if (sx < 0 || sy < 0 ||
+	    (sx + width) > vxres ||
+	    (sy + height) > vyres)
 		return;
 
-	if ((area->dy == area->sy && area->dx > area->sx) ||	
-	    (area->dy > area->sy)) { 
-		area->dy += area->height;
-		area->sy += area->height;
+	if ((dy == sy && dx > sx) ||	
+	    (dy > sy)) { 
+		dy += height;
+		sy += height;
 		rev_copy = 1;
 	}
 
 	dst = src = (unsigned long *)((unsigned long)p->screen_base & 
 				      ~(BYTES_PER_LONG-1));
 	dst_idx = src_idx = (unsigned long)p->screen_base & (BYTES_PER_LONG-1);
-	dst_idx += area->dy*next_line*8 + area->dx*p->var.bits_per_pixel;
-	src_idx += area->sy*next_line*8 + area->sx*p->var.bits_per_pixel;
+	dst_idx += dy*next_line*8 + dx*p->var.bits_per_pixel;
+	src_idx += sy*next_line*8 + sx*p->var.bits_per_pixel;
 	
 	if (p->fbops->fb_sync)
 		p->fbops->fb_sync(p);
 	if (rev_copy) {
-		while (area->height--) {
+		while (height--) {
 			dst_idx -= next_line*8;
 			src_idx -= next_line*8;
 			dst += dst_idx >> SHIFT_PER_LONG;
 			dst_idx &= (BYTES_PER_LONG-1);
 			src += src_idx >> SHIFT_PER_LONG;
 			src_idx &= (BYTES_PER_LONG-1);
-			bitcpy_rev(dst, dst_idx,
-				   src, src_idx, 
-				   area->width*p->var.bits_per_pixel);
+			bitcpy_rev(dst, dst_idx, src, src_idx, 
+				   width*p->var.bits_per_pixel);
 		}	
 	} else {
-		while (area->height--) {
+		while (height--) {
 			dst += dst_idx >> SHIFT_PER_LONG;
 			dst_idx &= (BYTES_PER_LONG-1);
 			src += src_idx >> SHIFT_PER_LONG;
 			src_idx &= (BYTES_PER_LONG-1);
-			bitcpy(dst, dst_idx, 
-			       src, src_idx, 
-			       area->width*p->var.bits_per_pixel);
+			bitcpy(dst, dst_idx, src, src_idx, 
+			       width*p->var.bits_per_pixel);
 			dst_idx += next_line*8;
 			src_idx += next_line*8;
 		}	
diff -Nru a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
--- a/drivers/video/cfbfillrect.c	Tue Jan 14 14:48:29 2003
+++ b/drivers/video/cfbfillrect.c	Sun Jan 26 14:03:25 2003
@@ -359,13 +359,13 @@
 	}
 }
 
-void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
+void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
 {
-	unsigned long height, fg;
+	u32 bpp = p->var.bits_per_pixel;
 	unsigned long x2, y2, vxres, vyres;
+	unsigned long height, width, fg;
 	unsigned long *dst;
 	int dst_idx, left;
-	u32 bpp = p->var.bits_per_pixel;
 
 	/* We want rotation but lack hardware to do it for us. */
 	if (!p->fbops->fb_rotate && p->var.rotate) {
@@ -385,7 +385,7 @@
 	y2 = rect->dy + rect->height;
 	x2 = x2 < vxres ? x2 : vxres;
 	y2 = y2 < vyres ? y2 : vyres;
-	rect->width = x2 - rect->dx;
+	width = x2 - rect->dx;
 	height = y2 - rect->dy;
 	
 	if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
@@ -419,7 +419,7 @@
 		while (height--) {
 			dst += dst_idx >> SHIFT_PER_LONG;
 			dst_idx &= (BITS_PER_LONG-1);
-			fill_op32(dst, dst_idx, pat, rect->width*bpp);
+			fill_op32(dst, dst_idx, pat, width*bpp);
 			dst_idx += p->fix.line_length*8;
 		}
 	} else {
@@ -443,7 +443,7 @@
 			dst += dst_idx >> SHIFT_PER_LONG;
 			dst_idx &= (BITS_PER_LONG-1);
 			fill_op(dst, dst_idx, pat, left, right, 
-				rect->width*bpp);
+				width*bpp);
 			r = (p->fix.line_length*8) % bpp;
 			pat = pat << (bpp-r) | pat >> r;
 			dst_idx += p->fix.line_length*8;
diff -Nru a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
--- a/drivers/video/cfbimgblt.c	Thu Feb 27 03:52:51 2003
+++ b/drivers/video/cfbimgblt.c	Sun Mar 23 00:20:38 2003
@@ -73,41 +73,57 @@
 	0x00000000, 0xffffffff
 };
 
-#define FB_WRITEL fb_writel
-#define FB_READL  fb_readl
-
 #if defined (__BIG_ENDIAN)
-#define LEFT_POS(bpp)          (32 - bpp)
-#define NEXT_POS(pos, bpp)     ((pos) -= (bpp))
+#define LEFT_POS(bpp)          (BITS_PER_LONG - bpp)
 #define SHIFT_HIGH(val, bits)  ((val) >> (bits))
 #define SHIFT_LOW(val, bits)   ((val) << (bits))
 #else
 #define LEFT_POS(bpp)          (0)
-#define NEXT_POS(pos, bpp)     ((pos) += (bpp))
 #define SHIFT_HIGH(val, bits)  ((val) << (bits))
 #define SHIFT_LOW(val, bits)   ((val) >> (bits))
 #endif
 
-static inline void color_imageblit(struct fb_image *image, struct fb_info *p, 
-				   u8 *dst1, u32 start_index,
-				   u32 pitch_index)
+#if BITS_PER_LONG == 32
+#define FB_WRITEL	fb_writel
+#define FB_READL	fb_readl
+#define INIT_FASTPATH	{}
+#define FASTPATH	fb_writel((end_mask & eorx)^bgx, dst++)
+#else
+#define FB_WRITEL	fb_writeq
+#define FB_READL	fb_readq
+#define INIT_FASTPATH	unsigned long val = 0, bpl = 0
+#define FASTPATH {					\
+	val |= SHIFT_HIGH((end_mask & eorx)^bgx, bpl);	\
+	bpl += 32;					\
+	bpl &= BITS_PER_LONG - 1;			\
+	if (!bpl) {					\
+		FB_WRITEL(val, dst++);			\
+		val = 0;				\
+	}						\
+}
+#endif
+
+static inline void color_imageblit(const struct fb_image *image, 
+				   struct fb_info *p, u8 *dst1, 
+				   unsigned long start_index,
+				   unsigned long pitch_index)
 {
 	/* Draw the penguin */
-	u32 *dst, *dst2, color = 0, val, shift;
+	unsigned long *dst, *dst2, color = 0, val, shift;
 	int i, n, bpp = p->var.bits_per_pixel;
-	u32 null_bits = 32 - bpp;
+	unsigned long null_bits = BITS_PER_LONG - bpp;
 	u32 *palette = (u32 *) p->pseudo_palette;
-	u8 *src = image->data;
+	u8 *src = (u8 *) image->data;
 
-	dst2 = (u32 *) dst1;
+	dst2 = (unsigned long *) dst1;
 	for (i = image->height; i--; ) {
+		dst = (unsigned long *) dst1;
 		n = image->width;
-		dst = (u32 *) dst1;
-		shift = 0;
-		val = 0;
+		shift = val = 0;
 		
 		if (start_index) {
-			u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index));
+			unsigned long start_mask = ~(SHIFT_HIGH(~0UL,
+								start_index));
 			val = FB_READL(dst) & start_mask;
 			shift = start_index;
 		}
@@ -123,14 +139,14 @@
 				FB_WRITEL(val, dst++);
 	
 				val = (shift == null_bits) ? 0 : 
-					SHIFT_LOW(color, 32 - shift);
+					SHIFT_LOW(color,BITS_PER_LONG - shift);
 			}
 			shift += bpp;
-			shift &= (32 - 1);
+			shift &= (BITS_PER_LONG - 1);
 			src++;
 		}
 		if (shift) {
-			u32 end_mask = SHIFT_HIGH(~(u32)0, shift);
+			unsigned long  end_mask = SHIFT_HIGH(~0UL, shift);
 
 			FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
 		}
@@ -138,39 +154,41 @@
 		if (pitch_index) {
 			dst2 += p->fix.line_length;
 			dst1 = (char *) dst2;
-			(unsigned long) dst1 &= ~(sizeof(u32) - 1);
+			(unsigned long) dst1 &= ~(sizeof(unsigned long) - 1);
 
 			start_index += pitch_index;
-			start_index &= 32 - 1;
+			start_index &= BITS_PER_LONG - 1;
 		}
 	}
 }
 
-static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, 
-				  u8 *dst1, u32 fgcolor,
-				  u32 bgcolor, 
-				  u32 start_index,
-				  u32 pitch_index)
+static inline void slow_imageblit(const struct fb_image *image, 
+				  struct fb_info *p, u8 *dst1, 
+				  unsigned long fgcolor,
+				  unsigned long bgcolor, 
+				  unsigned long start_index,
+				  unsigned long pitch_index)
 {
-	u32 shift, color = 0, bpp = p->var.bits_per_pixel;
-	u32 *dst, *dst2, val, pitch = p->fix.line_length;
-	u32 null_bits = 32 - bpp;
-	u32 spitch = (image->width+7)/8;
-	u8 *src = image->data, *s;
-	u32 i, j, l;
+	unsigned long shift, color = 0, bpp = p->var.bits_per_pixel;
+	unsigned long *dst, *dst2, val, pitch = p->fix.line_length;
+	unsigned long null_bits = BITS_PER_LONG - bpp;
+	unsigned long spitch = (image->width+7)/8;
+	const char *src = image->data, *s;
+	unsigned long i, j, l;
 	
-	dst2 = (u32 *) dst1;
+	dst2 = (unsigned long *) dst1;
 
 	for (i = image->height; i--; ) {
-		shift = val = 0;
-		l = 8;
+		dst = (unsigned long *) dst1;
 		j = image->width;
-		dst = (u32 *) dst1;
+		shift = val = 0;
 		s = src;
+		l = 8;
 
 		/* write leading bits */
 		if (start_index) {
-			u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index));
+			unsigned long start_mask = ~(SHIFT_HIGH(~0UL,
+								start_index));
 			val = FB_READL(dst) & start_mask;
 			shift = start_index;
 		}
@@ -185,16 +203,16 @@
 			if (shift >= null_bits) {
 				FB_WRITEL(val, dst++);
 				val = (shift == null_bits) ? 0 :
-					 SHIFT_LOW(color,32 - shift);
+					 SHIFT_LOW(color,BITS_PER_LONG - shift);
 			}
 			shift += bpp;
-			shift &= (32 - 1);
+			shift &= (BITS_PER_LONG - 1);
 			if (!l) { l = 8; s++; };
 		}
 
 		/* write trailing bits */
  		if (shift) {
-			u32 end_mask = SHIFT_HIGH(~(u32)0, shift);
+			unsigned long end_mask = SHIFT_HIGH(~0UL, shift);
 
 			FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
 		}
@@ -204,10 +222,10 @@
 		if (pitch_index) {
 			dst2 += pitch;
 			dst1 = (char *) dst2;
-			(unsigned long) dst1 &= ~(sizeof(u32) - 1);
+			(unsigned long) dst1 &= ~(sizeof(unsigned long) - 1);
 
 			start_index += pitch_index;
-			start_index &= 32 - 1;
+			start_index &= BITS_PER_LONG - 1;
 		}
 		
 	}
@@ -221,15 +239,15 @@
  *           fix->line_legth is divisible by 4;
  *           beginning and end of a scanline is dword aligned
  */
-static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, 
-				  u8 *dst1, u32 fgcolor, 
-				  u32 bgcolor) 
+static inline void fast_imageblit(const struct fb_image *image, 
+				  struct fb_info *p, u8 *dst1, 
+				  u32 fgcolor, u32 bgcolor) 
 {
 	u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
-	u32 ppw = 32/bpp, spitch = (image->width + 7)/8;
+	u32 ppw = BITS_PER_LONG/bpp, spitch = (image->width + 7)/8;
 	u32 bit_mask, end_mask, eorx, shift;
-	char *s = image->data, *src;
-	u32 *dst;
+	const char *s = image->data, *src;
+	unsigned long *dst;
 	u32 *tab = NULL;
 	int i, j, k;
 		
@@ -257,12 +275,14 @@
 	k = image->width/ppw;
 
 	for (i = image->height; i--; ) {
-		dst = (u32 *) dst1, shift = 8; src = s;
-		
+		INIT_FASTPATH;
+
+		dst = (unsigned long *) dst1, shift = 8; src = s;
+	
 		for (j = k; j--; ) {
 			shift -= ppw;
 			end_mask = tab[(*src >> shift) & bit_mask];
-			FB_WRITEL((end_mask & eorx)^bgx, dst++);
+			FASTPATH;
 			if (!shift) { shift = 8; src++; }		
 		}
 		dst1 += p->fix.line_length;
@@ -270,10 +290,12 @@
 	}
 }	
 	
-void cfb_imageblit(struct fb_info *p, struct fb_image *image)
+void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
 {
-	u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
-	u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
+	unsigned long fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
+	unsigned long bpl = sizeof(unsigned long), bpp = p->var.bits_per_pixel;
+	u32 width = image->width, height = image->height; 
+	u32 dx = image->dx, dy = image->dy;
 	int x2, y2, vxres, vyres;
 	u8 *dst1;
 
@@ -289,15 +311,15 @@
 
 	x2 = image->dx + image->width;
 	y2 = image->dy + image->height;
-	image->dx = image->dx > 0 ? image->dx : 0;
-	image->dy = image->dy > 0 ? image->dy : 0;
+	dx = image->dx > 0 ? image->dx : 0;
+	dy = image->dy > 0 ? image->dy : 0;
 	x2 = x2 < vxres ? x2 : vxres;
 	y2 = y2 < vyres ? y2 : vyres;
-	image->width  = x2 - image->dx;
-	image->height = y2 - image->dy;
+	width  = x2 - dx;
+	height = y2 - dy;
 
-	bitstart = (image->dy * p->fix.line_length * 8) + (image->dx * bpp);
-	start_index = bitstart & (32 - 1);
+	bitstart = (dy * p->fix.line_length * 8) + (dx * bpp);
+	start_index = bitstart & (BITS_PER_LONG - 1);
 	pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
 
 	bitstart /= 8;
@@ -307,7 +329,7 @@
 	if (p->fbops->fb_sync)
 		p->fbops->fb_sync(p);
 
-	if (image->depth == 1) {
+	if (image->depth == 0) {
 		if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
 		    p->fix.visual == FB_VISUAL_DIRECTCOLOR) {
 			fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color];
@@ -317,14 +339,14 @@
 			bgcolor = image->bg_color;
 		}	
 		
-		if (32 % bpp == 0 && !start_index && !pitch_index && 
-		    ((image->width & (32/bpp-1)) == 0) &&
+		if (BITS_PER_LONG % bpp == 0 && !start_index && !pitch_index && 
+		    ((width & (BITS_PER_LONG/bpp-1)) == 0) &&
 		    bpp >= 8 && bpp <= 32) 			
 			fast_imageblit(image, p, dst1, fgcolor, bgcolor);
 		else 
-			slow_imageblit(image, p, dst1, fgcolor, bgcolor, start_index, pitch_index);
-	}
-	else if (image->depth == bpp) 
+			slow_imageblit(image, p, dst1, fgcolor, bgcolor,
+					start_index, pitch_index);
+	} else if (image->depth == bpp) 
 		color_imageblit(image, p, dst1, start_index, pitch_index);
 }
 
diff -Nru a/drivers/video/cg6.c b/drivers/video/cg6.c
--- a/drivers/video/cg6.c	Tue Mar  4 09:55:26 2003
+++ b/drivers/video/cg6.c	Sun Mar 23 00:28:04 2003
@@ -33,8 +33,8 @@
 			 unsigned, struct fb_info *);
 static int cg6_blank(int, struct fb_info *);
 
-static void cg6_imageblit(struct fb_info *, struct fb_image *);
-static void cg6_fillrect(struct fb_info *, struct fb_fillrect *);
+static void cg6_imageblit(struct fb_info *, const struct fb_image *);
+static void cg6_fillrect(struct fb_info *, const struct fb_fillrect *);
 static int cg6_sync(struct fb_info *);
 static int cg6_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
 static int cg6_ioctl(struct inode *, struct file *, unsigned int,
@@ -289,7 +289,7 @@
  *      @info: frame buffer structure that represents a single frame buffer
  *      @rect: structure defining the rectagle and operation.
  */
-static void cg6_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+static void cg6_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
 	struct cg6_par *par = (struct cg6_par *) info->par;
 	struct cg6_fbc *fbc = par->fbc;
@@ -324,11 +324,11 @@
  *      @info: frame buffer structure that represents a single frame buffer
  *      @image: structure defining the image.
  */
-static void cg6_imageblit(struct fb_info *info, struct fb_image *image)
+static void cg6_imageblit(struct fb_info *info, const struct fb_image *image)
 {
 	struct cg6_par *par = (struct cg6_par *) info->par;
 	struct cg6_fbc *fbc = par->fbc;
-	u8 *data = image->data;
+	const u8 *data = image->data;
 	unsigned long flags;
 	u32 x, y;
 	int i, width;
diff -Nru a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/cirrusfb.c	Tue Mar  4 05:33:23 2003
@@ -0,0 +1,3546 @@
+/*
+ * drivers/video/clgenfb.c - driver for Cirrus Logic chipsets
+ *
+ * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com>
+ *
+ * Contributors (thanks, all!)
+ *
+ *      Jeff Rugen:
+ *      Major contributions;  Motorola PowerStack (PPC and PCI) support,
+ *      GD54xx, 1280x1024 mode support, change MCLK based on VCLK.
+ *
+ *	Geert Uytterhoeven:
+ *	Excellent code review.
+ *
+ *	Lars Hecking:
+ *	Amiga updates and testing.
+ *
+ * Original clgenfb author:  Frank Neumann
+ *
+ * Based on retz3fb.c and clgen.c:
+ *      Copyright (C) 1997 Jes Sorensen
+ *      Copyright (C) 1996 Frank Neumann
+ *
+ ***************************************************************
+ *
+ * Format this code with GNU indent '-kr -i8 -pcs' options.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#define CLGEN_VERSION "1.9.9.1"
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/selection.h>
+#include <asm/pgtable.h>
+
+#ifdef CONFIG_ZORRO
+#include <linux/zorro.h>
+#endif
+#ifdef CONFIG_PCI
+#include <linux/pci.h>
+#endif
+#ifdef CONFIG_AMIGA
+#include <asm/amigahw.h>
+#endif
+#ifdef CONFIG_ALL_PPC
+#include <asm/processor.h>
+#define isPReP (_machine == _MACH_prep)
+#else
+#define isPReP 0
+#endif
+
+#include <video/fbcon.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
+
+#include "clgenfb.h"
+#include "vga.h"
+
+
+/*****************************************************************
+ *
+ * debugging and utility macros
+ *
+ */
+
+/* enable debug output? */
+/* #define CLGEN_DEBUG 1 */
+
+/* disable runtime assertions? */
+/* #define CLGEN_NDEBUG */
+
+/* debug output */
+#ifdef CLGEN_DEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+/* debugging assertions */
+#ifndef CLGEN_NDEBUG
+#define assert(expr) \
+        if(!(expr)) { \
+        printk( "Assertion failed! %s,%s,%s,line=%d\n",\
+        #expr,__FILE__,__FUNCTION__,__LINE__); \
+        }
+#else
+#define assert(expr)
+#endif
+
+#ifdef TRUE
+#undef TRUE
+#endif
+#ifdef FALSE
+#undef FALSE
+#endif
+#define TRUE  1
+#define FALSE 0
+
+#define MB_ (1024*1024)
+#define KB_ (1024)
+
+#define MAX_NUM_BOARDS 7
+
+
+/*****************************************************************
+ *
+ * chipset information
+ *
+ */
+
+/* board types */
+typedef enum {
+	BT_NONE = 0,
+	BT_SD64,
+	BT_PICCOLO,
+	BT_PICASSO,
+	BT_SPECTRUM,
+	BT_PICASSO4,	/* GD5446 */
+	BT_ALPINE,	/* GD543x/4x */
+	BT_GD5480,
+	BT_LAGUNA,	/* GD546x */
+} clgen_board_t;
+
+
+/*
+ * per-board-type information, used for enumerating and abstracting
+ * chip-specific information
+ * NOTE: MUST be in the same order as clgen_board_t in order to
+ * use direct indexing on this array
+ * NOTE: '__initdata' cannot be used as some of this info
+ * is required at runtime.  Maybe separate into an init-only and
+ * a run-time table?
+ */
+static const struct clgen_board_info_rec {
+	clgen_board_t btype;	/* chipset enum, not strictly necessary, as
+				 * clgen_board_info[] is directly indexed
+				 * by this value */
+	char *name;		/* ASCII name of chipset */
+	long maxclock;		/* maximum video clock */
+	unsigned init_sr07 : 1;	/* init SR07 during init_vgachip() */
+	unsigned init_sr1f : 1; /* write SR1F during init_vgachip() */
+	unsigned scrn_start_bit19 : 1; /* construct bit 19 of screen start address */
+
+	/* initial SR07 value, then for each mode */
+	unsigned char sr07;
+	unsigned char sr07_1bpp;
+	unsigned char sr07_1bpp_mux;
+	unsigned char sr07_8bpp;
+	unsigned char sr07_8bpp_mux;
+
+	unsigned char sr1f;	/* SR1F VGA initial register value */
+} clgen_board_info[] = {
+	{ BT_NONE, }, /* dummy record */
+	{ BT_SD64,
+		"CL SD64",
+		140000,		/* the SD64/P4 have a higher max. videoclock */
+		TRUE,
+		TRUE,
+		TRUE,
+		0xF0,
+		0xF0,
+		0,		/* unused, does not multiplex */
+		0xF1,
+		0,		/* unused, does not multiplex */
+		0x20 },
+	{ BT_PICCOLO,
+		"CL Piccolo",
+		90000,
+		TRUE,
+		TRUE,
+		FALSE,
+		0x80,
+		0x80,
+		0,		/* unused, does not multiplex */
+		0x81,
+		0,		/* unused, does not multiplex */
+		0x22 },
+	{ BT_PICASSO,
+		"CL Picasso",
+		90000,
+		TRUE,
+		TRUE,
+		FALSE,
+		0x20,
+		0x20,
+		0,		/* unused, does not multiplex */
+		0x21,
+		0,		/* unused, does not multiplex */
+		0x22 },
+	{ BT_SPECTRUM,
+		"CL Spectrum",
+		90000,
+		TRUE,
+		TRUE,
+		FALSE,
+		0x80,
+		0x80,
+		0,		/* unused, does not multiplex */
+		0x81,
+		0,		/* unused, does not multiplex */
+		0x22 },
+	{ BT_PICASSO4,
+		"CL Picasso4",
+		140000,		/* the SD64/P4 have a higher max. videoclock */
+		TRUE,
+		FALSE,
+		TRUE,
+		0x20,
+		0x20,
+		0,		/* unused, does not multiplex */
+		0x21,
+		0,		/* unused, does not multiplex */
+		0 },
+	{ BT_ALPINE,
+		"CL Alpine",
+		110000,		/* 135100 for some, 85500 for others */
+		TRUE,
+		TRUE,
+		TRUE,
+		0xA0,
+		0xA1,
+		0xA7,
+		0xA1,
+		0xA7,
+		0x1C },
+	{ BT_GD5480,
+		"CL GD5480",
+		90000,
+		TRUE,
+		TRUE,
+		TRUE,
+		0x10,
+		0x11,
+		0,		/* unused, does not multiplex */
+		0x11,
+		0,		/* unused, does not multiplex */
+		0x1C },
+	{ BT_LAGUNA,
+		"CL Laguna",
+		135100,
+		FALSE,
+		FALSE,
+		TRUE,
+		0,		/* unused */
+		0,		/* unused */
+		0,		/* unused */
+		0,		/* unused */
+		0,		/* unused */
+		0 },		/* unused */
+};
+
+
+#ifdef CONFIG_PCI
+/* the list of PCI devices for which we probe, and the
+ * order in which we do it */
+static const struct {
+	clgen_board_t btype;
+	const char *nameOverride; /* XXX unused... for now */
+	unsigned short device;
+} clgen_pci_probe_list[] __initdata = {
+	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5436 },
+	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5434_8 },
+	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5434_4 },
+	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5430 }, /* GD-5440 has identical id */
+	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_7543 },
+	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_7548 },
+	{ BT_GD5480, NULL, PCI_DEVICE_ID_CIRRUS_5480 }, /* MacPicasso probably */
+	{ BT_PICASSO4, NULL, PCI_DEVICE_ID_CIRRUS_5446 }, /* Picasso 4 is a GD5446 */
+	{ BT_LAGUNA, "CL Laguna", PCI_DEVICE_ID_CIRRUS_5462 },
+	{ BT_LAGUNA, "CL Laguna 3D", PCI_DEVICE_ID_CIRRUS_5464 },
+	{ BT_LAGUNA, "CL Laguna 3DA", PCI_DEVICE_ID_CIRRUS_5465 },
+};
+#endif /* CONFIG_PCI */
+
+
+#ifdef CONFIG_ZORRO
+static const struct {
+	clgen_board_t btype;
+	zorro_id id, id2;
+	unsigned long size;
+} clgen_zorro_probe_list[] __initdata = {
+	{ BT_SD64,
+		ZORRO_PROD_HELFRICH_SD64_RAM,
+		ZORRO_PROD_HELFRICH_SD64_REG,
+		0x400000 },
+	{ BT_PICCOLO,
+		ZORRO_PROD_HELFRICH_PICCOLO_RAM,
+		ZORRO_PROD_HELFRICH_PICCOLO_REG,
+		0x200000 },
+	{ BT_PICASSO,
+		ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
+		ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
+		0x200000 },
+	{ BT_SPECTRUM,
+		ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
+		ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
+		0x200000 },
+	{ BT_PICASSO4,
+		ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
+		0,
+		0x400000 },
+};
+#endif /* CONFIG_ZORRO */
+
+
+
+struct clgenfb_par {
+	struct fb_var_screeninfo var;
+
+	__u32 line_length;	/* in BYTES! */
+	__u32 visual;
+	__u32 type;
+
+	long freq;
+	long nom;
+	long den;
+	long div;
+	long multiplexing;
+	long mclk;
+	long divMCLK;
+
+	long HorizRes;		/* The x resolution in pixel */
+	long HorizTotal;
+	long HorizDispEnd;
+	long HorizBlankStart;
+	long HorizBlankEnd;
+	long HorizSyncStart;
+	long HorizSyncEnd;
+
+	long VertRes;		/* the physical y resolution in scanlines */
+	long VertTotal;
+	long VertDispEnd;
+	long VertSyncStart;
+	long VertSyncEnd;
+	long VertBlankStart;
+	long VertBlankEnd;
+};
+
+
+
+#ifdef CLGEN_DEBUG
+typedef enum {
+        CRT,
+        SEQ
+} clgen_dbg_reg_class_t;
+#endif                          /* CLGEN_DEBUG */
+
+
+
+
+/* info about board */
+struct clgenfb_info {
+	struct fb_info_gen gen;
+
+	caddr_t fbmem;
+	caddr_t regs;
+	caddr_t mem;
+	unsigned long size;
+	clgen_board_t btype;
+	int smallboard;
+	unsigned char SFR;	/* Shadow of special function register */
+
+	unsigned long fbmem_phys;
+	unsigned long fbregs_phys;
+
+	struct clgenfb_par currentmode;
+
+	struct { u8 red, green, blue, pad; } palette[256];
+
+	union {
+#ifdef FBCON_HAS_CFB16
+		u16 cfb16[16];
+#endif
+#ifdef FBCON_HAS_CFB24
+		u32 cfb24[16];
+#endif
+#ifdef FBCON_HAS_CFB32
+		u32 cfb32[16];
+#endif
+	} fbcon_cmap;
+
+#ifdef CONFIG_ZORRO
+	unsigned long board_addr,
+		      board_size;
+#endif
+
+#ifdef CONFIG_PCI
+	struct pci_dev *pdev;
+#endif
+};
+
+
+
+
+static struct display disp;
+
+static struct clgenfb_info boards[MAX_NUM_BOARDS];	/* the boards */
+
+static unsigned clgen_def_mode = 1;
+static int noaccel = 0;
+
+
+
+/*
+ *    Predefined Video Modes
+ */
+
+static const struct {
+	const char *name;
+	struct fb_var_screeninfo var;
+} clgenfb_predefined[] __initdata =
+
+{
+	{"Autodetect",		/* autodetect mode */
+	 {0}
+	},
+
+	{"640x480",		/* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */
+	 {
+		 640, 480, 640, 480, 0, 0, 8, 0,
+		 {0, 8, 0},
+		 {0, 8, 0},
+		 {0, 8, 0},
+		 {0, 0, 0},
+	       0, 0, -1, -1, FB_ACCEL_NONE, 40000, 48, 16, 32, 8, 96, 4,
+     FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+	 }
+	},
+
+	{"800x600",		/* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */
+	 {
+		 800, 600, 800, 600, 0, 0, 8, 0,
+		 {0, 8, 0},
+		 {0, 8, 0},
+		 {0, 8, 0},
+		 {0, 0, 0},
+	       0, 0, -1, -1, FB_ACCEL_NONE, 20000, 128, 16, 24, 2, 96, 6,
+     0, FB_VMODE_NONINTERLACED
+	 }
+	},
+
+	/*
+	   Modeline from XF86Config:
+	   Mode "1024x768" 80  1024 1136 1340 1432  768 770 774 805
+	 */
+	{"1024x768",		/* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */
+		{
+			1024, 768, 1024, 768, 0, 0, 8, 0,
+			{0, 8, 0},
+			{0, 8, 0},
+			{0, 8, 0},
+			{0, 0, 0},
+	      0, 0, -1, -1, FB_ACCEL_NONE, 12500, 144, 32, 30, 2, 192, 6,
+     0, FB_VMODE_NONINTERLACED
+		}
+	}
+};
+
+#define NUM_TOTAL_MODES    ARRAY_SIZE(clgenfb_predefined)
+static struct fb_var_screeninfo clgenfb_default;
+
+/*
+ *    Frame Buffer Name
+ */
+
+static const char *clgenfb_name = "CLgen";
+
+/****************************************************************************/
+/**** BEGIN PROTOTYPES ******************************************************/
+
+
+/*--- Interface used by the world ------------------------------------------*/
+int clgenfb_init (void);
+int clgenfb_setup (char *options);
+
+static int clgenfb_open (struct fb_info *info, int user);
+static int clgenfb_release (struct fb_info *info, int user);
+
+static int clgenfb_setcolreg (unsigned regno, unsigned red, unsigned green,
+			      unsigned blue, unsigned transp,
+			      struct fb_info *info);
+
+/* function table of the above functions */
+static struct fb_ops clgenfb_ops = {
+	.owner =	THIS_MODULE,
+	.fb_open =	clgenfb_open,
+	.fb_release =	clgenfb_release,
+	.fb_get_fix =	fbgen_get_fix,
+	.fb_get_var =	fbgen_get_var,
+	.fb_set_var =	fbgen_set_var,
+	.fb_get_cmap =	fbgen_get_cmap,
+	.fb_set_cmap =	gen_set_cmap,
+	.fb_setcolreg =	clgenfb_setcolreg,
+	.fb_pan_display =fbgen_pan_display,
+	.fb_blank =	fbgen_blank,
+};
+
+/*--- Hardware Specific Routines -------------------------------------------*/
+static void clgen_detect (void);
+static int clgen_encode_fix (struct fb_fix_screeninfo *fix, const void *par,
+			     struct fb_info_gen *info);
+static int clgen_decode_var (const struct fb_var_screeninfo *var, void *par,
+			     struct fb_info_gen *info);
+static int clgen_encode_var (struct fb_var_screeninfo *var, const void *par,
+			     struct fb_info_gen *info);
+static void clgen_get_par (void *par, struct fb_info_gen *info);
+static void clgen_set_par (const void *par, struct fb_info_gen *info);
+static int clgen_getcolreg (unsigned regno, unsigned *red, unsigned *green,
+			    unsigned *blue, unsigned *transp,
+			    struct fb_info *info);
+static int clgen_pan_display (const struct fb_var_screeninfo *var,
+			      struct fb_info_gen *info);
+static int clgen_blank (int blank_mode, struct fb_info_gen *info);
+
+static void clgen_set_disp (const void *par, struct display *disp,
+			    struct fb_info_gen *info);
+
+/* function table of the above functions */
+static struct fbgen_hwswitch clgen_hwswitch =
+{
+	clgen_detect,
+	clgen_encode_fix,
+	clgen_decode_var,
+	clgen_encode_var,
+	clgen_get_par,
+	clgen_set_par,
+	clgen_getcolreg,
+	clgen_pan_display,
+	clgen_blank,
+	clgen_set_disp
+};
+
+/* Text console acceleration */
+
+#ifdef FBCON_HAS_CFB8
+static void fbcon_clgen8_bmove (struct display *p, int sy, int sx,
+				int dy, int dx, int height, int width);
+static void fbcon_clgen8_clear (struct vc_data *conp, struct display *p,
+				int sy, int sx, int height, int width);
+
+static struct display_switch fbcon_clgen_8 = {
+	.setup =	fbcon_cfb8_setup,
+	.bmove =	fbcon_clgen8_bmove,
+	.clear =	fbcon_clgen8_clear,
+	.putc =		fbcon_cfb8_putc,
+	.putcs =	fbcon_cfb8_putcs,
+	.revc =		fbcon_cfb8_revc,
+	.clear_margins =fbcon_cfb8_clear_margins,
+	.fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
+};
+#endif
+#ifdef FBCON_HAS_CFB16
+static void fbcon_clgen16_bmove (struct display *p, int sy, int sx,
+				 int dy, int dx, int height, int width);
+static void fbcon_clgen16_clear (struct vc_data *conp, struct display *p,
+				 int sy, int sx, int height, int width);
+static struct display_switch fbcon_clgen_16 = {
+	.setup =	fbcon_cfb16_setup,
+	.bmove =	fbcon_clgen16_bmove,
+	.clear =	fbcon_clgen16_clear,
+	.putc =		fbcon_cfb16_putc,
+	.putcs =	fbcon_cfb16_putcs,
+	.revc =		fbcon_cfb16_revc,
+	.clear_margins =fbcon_cfb16_clear_margins,
+	.fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
+};
+#endif
+#ifdef FBCON_HAS_CFB32
+static void fbcon_clgen32_bmove (struct display *p, int sy, int sx,
+				 int dy, int dx, int height, int width);
+static void fbcon_clgen32_clear (struct vc_data *conp, struct display *p,
+				 int sy, int sx, int height, int width);
+static struct display_switch fbcon_clgen_32 = {
+	.setup =	fbcon_cfb32_setup,
+	.bmove =	fbcon_clgen32_bmove,
+	.clear =	fbcon_clgen32_clear,
+	.putc =		fbcon_cfb32_putc,
+	.putcs =	fbcon_cfb32_putcs,
+	.revc =		fbcon_cfb32_revc,
+	.clear_margins =fbcon_cfb32_clear_margins,
+	.fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
+};
+#endif
+
+
+
+/*--- Internal routines ----------------------------------------------------*/
+static void init_vgachip (struct clgenfb_info *fb_info);
+static void switch_monitor (struct clgenfb_info *fb_info, int on);
+static void WGen (const struct clgenfb_info *fb_info,
+		  int regnum, unsigned char val);
+static unsigned char RGen (const struct clgenfb_info *fb_info, int regnum);
+static void AttrOn (const struct clgenfb_info *fb_info);
+static void WHDR (const struct clgenfb_info *fb_info, unsigned char val);
+static void WSFR (struct clgenfb_info *fb_info, unsigned char val);
+static void WSFR2 (struct clgenfb_info *fb_info, unsigned char val);
+static void WClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char red,
+		   unsigned char green,
+		   unsigned char blue);
+#if 0
+static void RClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char *red,
+		   unsigned char *green,
+		   unsigned char *blue);
+#endif
+static void clgen_WaitBLT (caddr_t regbase);
+static void clgen_BitBLT (caddr_t regbase, u_short curx, u_short cury,
+			  u_short destx, u_short desty,
+			  u_short width, u_short height,
+			  u_short line_length);
+static void clgen_RectFill (struct clgenfb_info *fb_info, u_short x, u_short y,
+			    u_short width, u_short height,
+			    u_char color, u_short line_length);
+
+static void bestclock (long freq, long *best,
+		       long *nom, long *den,
+		       long *div, long maxfreq);
+
+#ifdef CLGEN_DEBUG
+static void clgen_dump (void);
+static void clgen_dbg_reg_dump (caddr_t regbase);
+static void clgen_dbg_print_regs (caddr_t regbase, clgen_dbg_reg_class_t reg_class,...);
+static void clgen_dbg_print_byte (const char *name, unsigned char val);
+#endif /* CLGEN_DEBUG */
+
+/*** END   PROTOTYPES ********************************************************/
+/*****************************************************************************/
+/*** BEGIN Interface Used by the World ***************************************/
+
+static int opencount = 0;
+
+/*--- Open /dev/fbx ---------------------------------------------------------*/
+static int clgenfb_open (struct fb_info *info, int user)
+{
+	if (opencount++ == 0)
+		switch_monitor ((struct clgenfb_info *) info, 1);
+	return 0;
+}
+
+/*--- Close /dev/fbx --------------------------------------------------------*/
+static int clgenfb_release (struct fb_info *info, int user)
+{
+	if (--opencount == 0)
+		switch_monitor ((struct clgenfb_info *) info, 0);
+	return 0;
+}
+
+/**** END   Interface used by the World *************************************/
+/****************************************************************************/
+/**** BEGIN Hardware specific Routines **************************************/
+
+static void clgen_detect (void)
+{
+	DPRINTK ("ENTER\n");
+	DPRINTK ("EXIT\n");
+}
+
+static int clgen_encode_fix (struct fb_fix_screeninfo *fix, const void *par,
+			     struct fb_info_gen *info)
+{
+	struct clgenfb_par *_par = (struct clgenfb_par *) par;
+	struct clgenfb_info *_info = (struct clgenfb_info *) info;
+
+	DPRINTK ("ENTER\n");
+
+	memset (fix, 0, sizeof (struct fb_fix_screeninfo));
+	strcpy (fix->id, clgenfb_name);
+
+	if (_info->btype == BT_GD5480) {
+		/* Select proper byte-swapping aperture */
+		switch (_par->var.bits_per_pixel) {
+		case 1:
+		case 8:
+			fix->smem_start = _info->fbmem_phys;
+			break;
+		case 16:
+			fix->smem_start = _info->fbmem_phys + 1 * MB_;
+			break;
+		case 24:
+		case 32:
+			fix->smem_start = _info->fbmem_phys + 2 * MB_;
+			break;
+		}
+	} else {
+		fix->smem_start = _info->fbmem_phys;
+	}
+
+	/* monochrome: only 1 memory plane */
+	/* 8 bit and above: Use whole memory area */
+	fix->smem_len = _par->var.bits_per_pixel == 1 ? _info->size / 4
+	    : _info->size;
+	fix->type = _par->type;
+	fix->type_aux = 0;
+	fix->visual = _par->visual;
+	fix->xpanstep = 1;
+	fix->ypanstep = 1;
+	fix->ywrapstep = 0;
+	fix->line_length = _par->line_length;
+
+	/* FIXME: map region at 0xB8000 if available, fill in here */
+	fix->mmio_start = 0;
+	fix->mmio_len = 0;
+	fix->accel = FB_ACCEL_NONE;
+
+	DPRINTK ("EXIT\n");
+	return 0;
+}
+
+
+
+/* Get a good MCLK value */
+static long clgen_get_mclk (long freq, int bpp, long *div)
+{
+	long mclk;
+
+	assert (div != NULL);
+
+	/* Calculate MCLK, in case VCLK is high enough to require > 50MHz.
+	 * Assume a 64-bit data path for now.  The formula is:
+	 * ((B * PCLK * 2)/W) * 1.2
+	 * B = bytes per pixel, PCLK = pixclock, W = data width in bytes */
+	mclk = ((bpp / 8) * freq * 2) / 4;
+	mclk = (mclk * 12) / 10;
+	if (mclk < 50000)
+		mclk = 50000;
+	DPRINTK ("Use MCLK of %ld kHz\n", mclk);
+
+	/* Calculate value for SR1F.  Multiply by 2 so we can round up. */
+	mclk = ((mclk * 16) / 14318);
+	mclk = (mclk + 1) / 2;
+	DPRINTK ("Set SR1F[5:0] to 0x%lx\n", mclk);
+
+	/* Determine if we should use MCLK instead of VCLK, and if so, what we
+	   * should divide it by to get VCLK */
+	switch (freq) {
+	case 24751 ... 25249:
+		*div = 2;
+		DPRINTK ("Using VCLK = MCLK/2\n");
+		break;
+	case 49501 ... 50499:
+		*div = 1;
+		DPRINTK ("Using VCLK = MCLK\n");
+		break;
+	default:
+		*div = 0;
+		break;
+	}
+
+	return mclk;
+}
+
+static int clgen_decode_var (const struct fb_var_screeninfo *var, void *par,
+			     struct fb_info_gen *info)
+{
+	long freq;
+	long maxclock;
+	int xres, hfront, hsync, hback;
+	int yres, vfront, vsync, vback;
+	int nom, den;		/* translyting from pixels->bytes */
+	int i;
+	static struct {
+		int xres, yres;
+	} modes[] = { {
+			1600, 1280
+	}, {
+		1280, 1024
+	}, {
+		1024, 768
+	},
+	{
+		800, 600
+	}, {
+		640, 480
+	}, {
+		-1, -1
+	}
+	};
+
+	struct clgenfb_par *_par = (struct clgenfb_par *) par;
+	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
+
+	assert (var != NULL);
+	assert (par != NULL);
+	assert (info != NULL);
+
+	DPRINTK ("ENTER\n");
+
+	DPRINTK ("Requested: %dx%dx%d\n", var->xres, var->yres, var->bits_per_pixel);
+	DPRINTK ("  virtual: %dx%d\n", var->xres_virtual, var->yres_virtual);
+	DPRINTK ("   offset: (%d,%d)\n", var->xoffset, var->yoffset);
+	DPRINTK ("grayscale: %d\n", var->grayscale);
+
+	memset (par, 0, sizeof (struct clgenfb_par));
+
+	_par->var = *var;
+
+	switch (var->bits_per_pixel) {
+	case 1:
+		nom = 4;
+		den = 8;
+		break;		/* 8 pixel per byte, only 1/4th of mem usable */
+	case 2 ... 8:
+		_par->var.bits_per_pixel = 8;
+		nom = 1;
+		den = 1;
+		break;		/* 1 pixel == 1 byte */
+	case 9 ... 16:
+		_par->var.bits_per_pixel = 16;
+		nom = 2;
+		den = 1;
+		break;		/* 2 bytes per pixel */
+	case 17 ... 24:
+		_par->var.bits_per_pixel = 24;
+		nom = 3;
+		den = 1;
+		break;		/* 3 bytes per pixel */
+	case 25 ... 32:
+		_par->var.bits_per_pixel = 32;
+		nom = 4;
+		den = 1;
+		break;		/* 4 bytes per pixel */
+	default:
+		printk ("clgen: mode %dx%dx%d rejected...color depth not supported.\n",
+			var->xres, var->yres, var->bits_per_pixel);
+		DPRINTK ("EXIT - EINVAL error\n");
+		return -EINVAL;
+	}
+
+	if (_par->var.xres * nom / den * _par->var.yres > fb_info->size) {
+		printk ("clgen: mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
+			var->xres, var->yres, var->bits_per_pixel);
+		DPRINTK ("EXIT - EINVAL error\n");
+		return -EINVAL;
+	}
+	/* use highest possible virtual resolution */
+	if (_par->var.xres_virtual == -1 &&
+	    _par->var.yres_virtual == -1) {
+		printk ("clgen: using maximum available virtual resolution\n");
+		for (i = 0; modes[i].xres != -1; i++) {
+			if (modes[i].xres * nom / den * modes[i].yres < fb_info->size / 2)
+				break;
+		}
+		if (modes[i].xres == -1) {
+			printk ("clgen: could not find a virtual resolution that fits into video memory!!\n");
+			DPRINTK ("EXIT - EINVAL error\n");
+			return -EINVAL;
+		}
+		_par->var.xres_virtual = modes[i].xres;
+		_par->var.yres_virtual = modes[i].yres;
+
+		printk ("clgen: virtual resolution set to maximum of %dx%d\n",
+			_par->var.xres_virtual, _par->var.yres_virtual);
+	} else if (_par->var.xres_virtual == -1) {
+		/* FIXME: maximize X virtual resolution only */
+	} else if (_par->var.yres_virtual == -1) {
+		/* FIXME: maximize Y virtual resolution only */
+	}
+	if (_par->var.xoffset < 0)
+		_par->var.xoffset = 0;
+	if (_par->var.yoffset < 0)
+		_par->var.yoffset = 0;
+
+	/* truncate xoffset and yoffset to maximum if too high */
+	if (_par->var.xoffset > _par->var.xres_virtual - _par->var.xres)
+		_par->var.xoffset = _par->var.xres_virtual - _par->var.xres - 1;
+
+	if (_par->var.yoffset > _par->var.yres_virtual - _par->var.yres)
+		_par->var.yoffset = _par->var.yres_virtual - _par->var.yres - 1;
+
+	switch (_par->var.bits_per_pixel) {
+	case 1:
+		_par->line_length = _par->var.xres_virtual / 8;
+		_par->visual = FB_VISUAL_MONO10;
+		break;
+
+	case 8:
+		_par->line_length = _par->var.xres_virtual;
+		_par->visual = FB_VISUAL_PSEUDOCOLOR;
+		_par->var.red.offset = 0;
+		_par->var.red.length = 6;
+		_par->var.green.offset = 0;
+		_par->var.green.length = 6;
+		_par->var.blue.offset = 0;
+		_par->var.blue.length = 6;
+		break;
+
+	case 16:
+		_par->line_length = _par->var.xres_virtual * 2;
+		_par->visual = FB_VISUAL_DIRECTCOLOR;
+		if(isPReP) {
+			_par->var.red.offset = 2;
+			_par->var.green.offset = -3;
+			_par->var.blue.offset = 8;
+		} else {
+			_par->var.red.offset = 10;
+			_par->var.green.offset = 5;
+			_par->var.blue.offset = 0;
+		}
+		_par->var.red.length = 5;
+		_par->var.green.length = 5;
+		_par->var.blue.length = 5;
+		break;
+
+	case 24:
+		_par->line_length = _par->var.xres_virtual * 3;
+		_par->visual = FB_VISUAL_DIRECTCOLOR;
+		if(isPReP) {
+			_par->var.red.offset = 8;
+			_par->var.green.offset = 16;
+			_par->var.blue.offset = 24;
+		} else {
+			_par->var.red.offset = 16;
+			_par->var.green.offset = 8;
+			_par->var.blue.offset = 0;
+		}
+		_par->var.red.length = 8;
+		_par->var.green.length = 8;
+		_par->var.blue.length = 8;
+		break;
+
+	case 32:
+		_par->line_length = _par->var.xres_virtual * 4;
+		_par->visual = FB_VISUAL_DIRECTCOLOR;
+		if(isPReP) {
+			_par->var.red.offset = 8;
+			_par->var.green.offset = 16;
+			_par->var.blue.offset = 24;
+		} else {
+			_par->var.red.offset = 16;
+			_par->var.green.offset = 8;
+			_par->var.blue.offset = 0;
+		}
+		_par->var.red.length = 8;
+		_par->var.green.length = 8;
+		_par->var.blue.length = 8;
+		break;
+
+	default:
+		DPRINTK("Unsupported bpp size: %d\n", _par->var.bits_per_pixel);
+		assert (FALSE);
+		/* should never occur */
+		break;
+	}
+
+	_par->var.red.msb_right =
+	    _par->var.green.msb_right =
+	    _par->var.blue.msb_right =
+	    _par->var.transp.offset =
+	    _par->var.transp.length =
+	    _par->var.transp.msb_right = 0;
+
+	_par->type = FB_TYPE_PACKED_PIXELS;
+
+	/* convert from ps to kHz */
+	freq = 1000000000 / var->pixclock;
+
+	DPRINTK ("desired pixclock: %ld kHz\n", freq);
+
+	maxclock = clgen_board_info[fb_info->btype].maxclock;
+	_par->multiplexing = 0;
+
+	/* If the frequency is greater than we can support, we might be able
+	 * to use multiplexing for the video mode */
+	if (freq > maxclock) {
+		switch (fb_info->btype) {
+		case BT_ALPINE:
+		case BT_GD5480:
+			_par->multiplexing = 1;
+			break;
+
+		default:
+			printk (KERN_WARNING "clgen: ERROR: Frequency greater than maxclock (%ld kHz)\n", maxclock);
+			DPRINTK ("EXIT - return -EINVAL\n");
+			return -EINVAL;
+		}
+	}
+#if 0
+	/* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where
+	 * the VCLK is double the pixel clock. */
+	switch (var->bits_per_pixel) {
+	case 16:
+	case 32:
+		if (_par->HorizRes <= 800)
+			freq /= 2;	/* Xbh has this type of clock for 32-bit */
+		break;
+	}
+#endif
+
+	bestclock (freq, &_par->freq, &_par->nom, &_par->den, &_par->div,
+		   maxclock);
+	_par->mclk = clgen_get_mclk (freq, _par->var.bits_per_pixel, &_par->divMCLK);
+
+	xres = _par->var.xres;
+	hfront = _par->var.right_margin;
+	hsync = _par->var.hsync_len;
+	hback = _par->var.left_margin;
+
+	yres = _par->var.yres;
+	vfront = _par->var.lower_margin;
+	vsync = _par->var.vsync_len;
+	vback = _par->var.upper_margin;
+
+	if (_par->var.vmode & FB_VMODE_DOUBLE) {
+		yres *= 2;
+		vfront *= 2;
+		vsync *= 2;
+		vback *= 2;
+	} else if (_par->var.vmode & FB_VMODE_INTERLACED) {
+		yres = (yres + 1) / 2;
+		vfront = (vfront + 1) / 2;
+		vsync = (vsync + 1) / 2;
+		vback = (vback + 1) / 2;
+	}
+	_par->HorizRes = xres;
+	_par->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5;
+	_par->HorizDispEnd = xres / 8 - 1;
+	_par->HorizBlankStart = xres / 8;
+	_par->HorizBlankEnd = _par->HorizTotal + 5;	/* does not count with "-5" */
+	_par->HorizSyncStart = (xres + hfront) / 8 + 1;
+	_par->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1;
+
+	_par->VertRes = yres;
+	_par->VertTotal = yres + vfront + vsync + vback - 2;
+	_par->VertDispEnd = yres - 1;
+	_par->VertBlankStart = yres;
+	_par->VertBlankEnd = _par->VertTotal;
+	_par->VertSyncStart = yres + vfront - 1;
+	_par->VertSyncEnd = yres + vfront + vsync - 1;
+
+	if (_par->VertRes >= 1024) {
+		_par->VertTotal /= 2;
+		_par->VertSyncStart /= 2;
+		_par->VertSyncEnd /= 2;
+		_par->VertDispEnd /= 2;
+	}
+	if (_par->multiplexing) {
+		_par->HorizTotal /= 2;
+		_par->HorizSyncStart /= 2;
+		_par->HorizSyncEnd /= 2;
+		_par->HorizDispEnd /= 2;
+	}
+	if (_par->VertRes >= 1280) {
+		printk (KERN_WARNING "clgen: ERROR: VerticalTotal >= 1280; special treatment required! (TODO)\n");
+		DPRINTK ("EXIT - EINVAL error\n");
+		return -EINVAL;
+	}
+	DPRINTK ("EXIT\n");
+	return 0;
+}
+
+
+static int clgen_encode_var (struct fb_var_screeninfo *var, const void *par,
+			     struct fb_info_gen *info)
+{
+	DPRINTK ("ENTER\n");
+
+	*var = ((struct clgenfb_par *) par)->var;
+
+	DPRINTK ("EXIT\n");
+	return 0;
+}
+
+/* get current video mode */
+static void clgen_get_par (void *par, struct fb_info_gen *info)
+{
+	struct clgenfb_par *_par = (struct clgenfb_par *) par;
+	struct clgenfb_info *_info = (struct clgenfb_info *) info;
+
+	DPRINTK ("ENTER\n");
+
+	*_par = _info->currentmode;
+
+	DPRINTK ("EXIT\n");
+}
+
+static void clgen_set_mclk (const struct clgenfb_info *fb_info, int val, int div)
+{
+	assert (fb_info != NULL);
+
+	if (div == 2) {
+		/* VCLK = MCLK/2 */
+		unsigned char old = vga_rseq (fb_info->regs, CL_SEQR1E);
+		vga_wseq (fb_info->regs, CL_SEQR1E, old | 0x1);
+		vga_wseq (fb_info->regs, CL_SEQR1F, 0x40 | (val & 0x3f));
+	} else if (div == 1) {
+		/* VCLK = MCLK */
+		unsigned char old = vga_rseq (fb_info->regs, CL_SEQR1E);
+		vga_wseq (fb_info->regs, CL_SEQR1E, old & ~0x1);
+		vga_wseq (fb_info->regs, CL_SEQR1F, 0x40 | (val & 0x3f));
+	} else {
+		vga_wseq (fb_info->regs, CL_SEQR1F, val & 0x3f);
+	}
+}
+
+/*************************************************************************
+	clgen_set_par()
+
+	actually writes the values for a new video mode into the hardware,
+**************************************************************************/
+static void clgen_set_par (const void *par, struct fb_info_gen *info)
+{
+	unsigned char tmp;
+	int offset = 0;
+	struct clgenfb_par *_par = (struct clgenfb_par *) par;
+	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
+	const struct clgen_board_info_rec *bi;
+
+	DPRINTK ("ENTER\n");
+	DPRINTK ("Requested mode: %dx%dx%d\n",
+	       _par->var.xres, _par->var.yres, _par->var.bits_per_pixel);
+	DPRINTK ("pixclock: %d\n", _par->var.pixclock);
+
+	bi = &clgen_board_info[fb_info->btype];
+
+
+	/* unlock register VGA_CRTC_H_TOTAL..CRT7 */
+	vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, 0x20);	/* previously: 0x00) */
+
+	/* if debugging is enabled, all parameters get output before writing */
+	DPRINTK ("CRT0: %ld\n", _par->HorizTotal);
+	vga_wcrt (fb_info->regs, VGA_CRTC_H_TOTAL, _par->HorizTotal);
+
+	DPRINTK ("CRT1: %ld\n", _par->HorizDispEnd);
+	vga_wcrt (fb_info->regs, VGA_CRTC_H_DISP, _par->HorizDispEnd);
+
+	DPRINTK ("CRT2: %ld\n", _par->HorizBlankStart);
+	vga_wcrt (fb_info->regs, VGA_CRTC_H_BLANK_START, _par->HorizBlankStart);
+
+	DPRINTK ("CRT3: 128+%ld\n", _par->HorizBlankEnd % 32);	/*  + 128: Compatible read */
+	vga_wcrt (fb_info->regs, VGA_CRTC_H_BLANK_END, 128 + (_par->HorizBlankEnd % 32));
+
+	DPRINTK ("CRT4: %ld\n", _par->HorizSyncStart);
+	vga_wcrt (fb_info->regs, VGA_CRTC_H_SYNC_START, _par->HorizSyncStart);
+
+	tmp = _par->HorizSyncEnd % 32;
+	if (_par->HorizBlankEnd & 32)
+		tmp += 128;
+	DPRINTK ("CRT5: %d\n", tmp);
+	vga_wcrt (fb_info->regs, VGA_CRTC_H_SYNC_END, tmp);
+
+	DPRINTK ("CRT6: %ld\n", _par->VertTotal & 0xff);
+	vga_wcrt (fb_info->regs, VGA_CRTC_V_TOTAL, (_par->VertTotal & 0xff));
+
+	tmp = 16;		/* LineCompare bit #9 */
+	if (_par->VertTotal & 256)
+		tmp |= 1;
+	if (_par->VertDispEnd & 256)
+		tmp |= 2;
+	if (_par->VertSyncStart & 256)
+		tmp |= 4;
+	if (_par->VertBlankStart & 256)
+		tmp |= 8;
+	if (_par->VertTotal & 512)
+		tmp |= 32;
+	if (_par->VertDispEnd & 512)
+		tmp |= 64;
+	if (_par->VertSyncStart & 512)
+		tmp |= 128;
+	DPRINTK ("CRT7: %d\n", tmp);
+	vga_wcrt (fb_info->regs, VGA_CRTC_OVERFLOW, tmp);
+
+	tmp = 0x40;		/* LineCompare bit #8 */
+	if (_par->VertBlankStart & 512)
+		tmp |= 0x20;
+	if (_par->var.vmode & FB_VMODE_DOUBLE)
+		tmp |= 0x80;
+	DPRINTK ("CRT9: %d\n", tmp);
+	vga_wcrt (fb_info->regs, VGA_CRTC_MAX_SCAN, tmp);
+
+	DPRINTK ("CRT10: %ld\n", _par->VertSyncStart & 0xff);
+	vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_START, (_par->VertSyncStart & 0xff));
+
+	DPRINTK ("CRT11: 64+32+%ld\n", _par->VertSyncEnd % 16);
+	vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, (_par->VertSyncEnd % 16 + 64 + 32));
+
+	DPRINTK ("CRT12: %ld\n", _par->VertDispEnd & 0xff);
+	vga_wcrt (fb_info->regs, VGA_CRTC_V_DISP_END, (_par->VertDispEnd & 0xff));
+
+	DPRINTK ("CRT15: %ld\n", _par->VertBlankStart & 0xff);
+	vga_wcrt (fb_info->regs, VGA_CRTC_V_BLANK_START, (_par->VertBlankStart & 0xff));
+
+	DPRINTK ("CRT16: %ld\n", _par->VertBlankEnd & 0xff);
+	vga_wcrt (fb_info->regs, VGA_CRTC_V_BLANK_END, (_par->VertBlankEnd & 0xff));
+
+	DPRINTK ("CRT18: 0xff\n");
+	vga_wcrt (fb_info->regs, VGA_CRTC_LINE_COMPARE, 0xff);
+
+	tmp = 0;
+	if (_par->var.vmode & FB_VMODE_INTERLACED)
+		tmp |= 1;
+	if (_par->HorizBlankEnd & 64)
+		tmp |= 16;
+	if (_par->HorizBlankEnd & 128)
+		tmp |= 32;
+	if (_par->VertBlankEnd & 256)
+		tmp |= 64;
+	if (_par->VertBlankEnd & 512)
+		tmp |= 128;
+
+	DPRINTK ("CRT1a: %d\n", tmp);
+	vga_wcrt (fb_info->regs, CL_CRT1A, tmp);
+
+	/* set VCLK0 */
+	/* hardware RefClock: 14.31818 MHz */
+	/* formula: VClk = (OSC * N) / (D * (1+P)) */
+	/* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
+
+	vga_wseq (fb_info->regs, CL_SEQRB, _par->nom);
+	tmp = _par->den << 1;
+	if (_par->div != 0)
+		tmp |= 1;
+
+	if ((fb_info->btype == BT_SD64) ||
+	    (fb_info->btype == BT_ALPINE) ||
+	    (fb_info->btype == BT_GD5480))
+		tmp |= 0x80;	/* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
+
+	DPRINTK ("CL_SEQR1B: %ld\n", (long) tmp);
+	vga_wseq (fb_info->regs, CL_SEQR1B, tmp);
+
+	if (_par->VertRes >= 1024)
+		/* 1280x1024 */
+		vga_wcrt (fb_info->regs, VGA_CRTC_MODE, 0xc7);
+	else
+		/* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
+		 * address wrap, no compat. */
+		vga_wcrt (fb_info->regs, VGA_CRTC_MODE, 0xc3);
+
+/* HAEH?        vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, 0x20);  * previously: 0x00  unlock VGA_CRTC_H_TOTAL..CRT7 */
+
+	/* don't know if it would hurt to also program this if no interlaced */
+	/* mode is used, but I feel better this way.. :-) */
+	if (_par->var.vmode & FB_VMODE_INTERLACED)
+		vga_wcrt (fb_info->regs, VGA_CRTC_REGS, _par->HorizTotal / 2);
+	else
+		vga_wcrt (fb_info->regs, VGA_CRTC_REGS, 0x00);	/* interlace control */
+
+	vga_wseq (fb_info->regs, VGA_SEQ_CHARACTER_MAP, 0);
+
+	/* adjust horizontal/vertical sync type (low/high) */
+	tmp = 0x03;		/* enable display memory & CRTC I/O address for color mode */
+	if (_par->var.sync & FB_SYNC_HOR_HIGH_ACT)
+		tmp |= 0x40;
+	if (_par->var.sync & FB_SYNC_VERT_HIGH_ACT)
+		tmp |= 0x80;
+	WGen (fb_info, VGA_MIS_W, tmp);
+
+	vga_wcrt (fb_info->regs, VGA_CRTC_PRESET_ROW, 0);	/* Screen A Preset Row-Scan register */
+	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_START, 0);	/* text cursor on and start line */
+	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_END, 31);	/* text cursor end line */
+
+	/******************************************************
+	 *
+	 * 1 bpp
+	 *
+	 */
+
+	/* programming for different color depths */
+	if (_par->var.bits_per_pixel == 1) {
+		DPRINTK ("clgen: preparing for 1 bit deep display\n");
+		vga_wgfx (fb_info->regs, VGA_GFX_MODE, 0);	/* mode register */
+
+		/* SR07 */
+		switch (fb_info->btype) {
+		case BT_SD64:
+		case BT_PICCOLO:
+		case BT_PICASSO:
+		case BT_SPECTRUM:
+		case BT_PICASSO4:
+		case BT_ALPINE:
+		case BT_GD5480:
+			DPRINTK (" (for GD54xx)\n");
+			vga_wseq (fb_info->regs, CL_SEQR7,
+				  _par->multiplexing ?
+				  	bi->sr07_1bpp_mux : bi->sr07_1bpp);
+			break;
+
+		case BT_LAGUNA:
+			DPRINTK (" (for GD546x)\n");
+			vga_wseq (fb_info->regs, CL_SEQR7,
+				vga_rseq (fb_info->regs, CL_SEQR7) & ~0x01);
+			break;
+
+		default:
+			printk (KERN_WARNING "clgen: unknown Board\n");
+			break;
+		}
+
+		/* Extended Sequencer Mode */
+		switch (fb_info->btype) {
+		case BT_SD64:
+			/* setting the SEQRF on SD64 is not necessary (only during init) */
+			DPRINTK ("(for SD64)\n");
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x1a);		/*  MCLK select */
+			break;
+
+		case BT_PICCOLO:
+			DPRINTK ("(for Piccolo)\n");
+/* ### ueberall 0x22? */
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ##vorher 1c MCLK select */
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* evtl d0 bei 1 bit? avoid FIFO underruns..? */
+			break;
+
+		case BT_PICASSO:
+			DPRINTK ("(for Picasso)\n");
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ##vorher 22 MCLK select */
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xd0);	/* ## vorher d0 avoid FIFO underruns..? */
+			break;
+
+		case BT_SPECTRUM:
+			DPRINTK ("(for Spectrum)\n");
+/* ### ueberall 0x22? */
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ##vorher 1c MCLK select */
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* evtl d0? avoid FIFO underruns..? */
+			break;
+
+		case BT_PICASSO4:
+		case BT_ALPINE:
+		case BT_GD5480:
+		case BT_LAGUNA:
+			DPRINTK (" (for GD54xx)\n");
+			/* do nothing */
+			break;
+
+		default:
+			printk (KERN_WARNING "clgen: unknown Board\n");
+			break;
+		}
+
+		WGen (fb_info, VGA_PEL_MSK, 0x01);	/* pixel mask: pass-through for first plane */
+		if (_par->multiplexing)
+			WHDR (fb_info, 0x4a);	/* hidden dac reg: 1280x1024 */
+		else
+			WHDR (fb_info, 0);	/* hidden dac: nothing */
+		vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x06);	/* memory mode: odd/even, ext. memory */
+		vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0x01);	/* plane mask: only write to first plane */
+		offset = _par->var.xres_virtual / 16;
+	}
+
+	/******************************************************
+	 *
+	 * 8 bpp
+	 *
+	 */
+
+	else if (_par->var.bits_per_pixel == 8) {
+		DPRINTK ("clgen: preparing for 8 bit deep display\n");
+		switch (fb_info->btype) {
+		case BT_SD64:
+		case BT_PICCOLO:
+		case BT_PICASSO:
+		case BT_SPECTRUM:
+		case BT_PICASSO4:
+		case BT_ALPINE:
+		case BT_GD5480:
+			DPRINTK (" (for GD54xx)\n");
+			vga_wseq (fb_info->regs, CL_SEQR7,
+				  _par->multiplexing ?
+				  	bi->sr07_8bpp_mux : bi->sr07_8bpp);
+			break;
+
+		case BT_LAGUNA:
+			DPRINTK (" (for GD546x)\n");
+			vga_wseq (fb_info->regs, CL_SEQR7,
+				vga_rseq (fb_info->regs, CL_SEQR7) | 0x01);
+			break;
+
+		default:
+			printk (KERN_WARNING "clgen: unknown Board\n");
+			break;
+		}
+
+		switch (fb_info->btype) {
+		case BT_SD64:
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x1d);		/* MCLK select */
+			break;
+
+		case BT_PICCOLO:
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ### vorher 1c MCLK select */
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
+			break;
+
+		case BT_PICASSO:
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ### vorher 1c MCLK select */
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
+			break;
+
+		case BT_SPECTRUM:
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ### vorher 1c MCLK select */
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
+			break;
+
+		case BT_PICASSO4:
+#ifdef CONFIG_ZORRO
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb8);	/* ### INCOMPLETE!! */
+#endif
+/*          vga_wseq (fb_info->regs, CL_SEQR1F, 0x1c); */
+			break;
+
+		case BT_ALPINE:
+			DPRINTK (" (for GD543x)\n");
+			clgen_set_mclk (fb_info, _par->mclk, _par->divMCLK);
+			/* We already set SRF and SR1F */
+			break;
+
+		case BT_GD5480:
+		case BT_LAGUNA:
+			DPRINTK (" (for GD54xx)\n");
+			/* do nothing */
+			break;
+
+		default:
+			printk (KERN_WARNING "clgen: unknown Board\n");
+			break;
+		}
+
+		vga_wgfx (fb_info->regs, VGA_GFX_MODE, 64);	/* mode register: 256 color mode */
+		WGen (fb_info, VGA_PEL_MSK, 0xff);	/* pixel mask: pass-through all planes */
+		if (_par->multiplexing)
+			WHDR (fb_info, 0x4a);	/* hidden dac reg: 1280x1024 */
+		else
+			WHDR (fb_info, 0);	/* hidden dac: nothing */
+		vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x0a);	/* memory mode: chain4, ext. memory */
+		vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0xff);	/* plane mask: enable writing to all 4 planes */
+		offset = _par->var.xres_virtual / 8;
+	}
+
+	/******************************************************
+	 *
+	 * 16 bpp
+	 *
+	 */
+
+	else if (_par->var.bits_per_pixel == 16) {
+		DPRINTK ("clgen: preparing for 16 bit deep display\n");
+		switch (fb_info->btype) {
+		case BT_SD64:
+			vga_wseq (fb_info->regs, CL_SEQR7, 0xf7);	/* Extended Sequencer Mode: 256c col. mode */
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x1e);		/* MCLK select */
+			break;
+
+		case BT_PICCOLO:
+			vga_wseq (fb_info->regs, CL_SEQR7, 0x87);
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* MCLK select */
+			break;
+
+		case BT_PICASSO:
+			vga_wseq (fb_info->regs, CL_SEQR7, 0x27);
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* MCLK select */
+			break;
+
+		case BT_SPECTRUM:
+			vga_wseq (fb_info->regs, CL_SEQR7, 0x87);
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* MCLK select */
+			break;
+
+		case BT_PICASSO4:
+			vga_wseq (fb_info->regs, CL_SEQR7, 0x27);
+/*          vga_wseq (fb_info->regs, CL_SEQR1F, 0x1c);  */
+			break;
+
+		case BT_ALPINE:
+			DPRINTK (" (for GD543x)\n");
+			if (_par->HorizRes >= 1024)
+				vga_wseq (fb_info->regs, CL_SEQR7, 0xa7);
+			else
+				vga_wseq (fb_info->regs, CL_SEQR7, 0xa3);
+			clgen_set_mclk (fb_info, _par->mclk, _par->divMCLK);
+			break;
+
+		case BT_GD5480:
+			DPRINTK (" (for GD5480)\n");
+			vga_wseq (fb_info->regs, CL_SEQR7, 0x17);
+			/* We already set SRF and SR1F */
+			break;
+
+		case BT_LAGUNA:
+			DPRINTK (" (for GD546x)\n");
+			vga_wseq (fb_info->regs, CL_SEQR7,
+				vga_rseq (fb_info->regs, CL_SEQR7) & ~0x01);
+			break;
+
+		default:
+			printk (KERN_WARNING "CLGEN: unknown Board\n");
+			break;
+		}
+
+		vga_wgfx (fb_info->regs, VGA_GFX_MODE, 64);	/* mode register: 256 color mode */
+		WGen (fb_info, VGA_PEL_MSK, 0xff);	/* pixel mask: pass-through all planes */
+#ifdef CONFIG_PCI
+		WHDR (fb_info, 0xc0);	/* Copy Xbh */
+#elif defined(CONFIG_ZORRO)
+		/* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
+		WHDR (fb_info, 0xa0);	/* hidden dac reg: nothing special */
+#endif
+		vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x0a);	/* memory mode: chain4, ext. memory */
+		vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0xff);	/* plane mask: enable writing to all 4 planes */
+		offset = _par->var.xres_virtual / 4;
+	}
+
+	/******************************************************
+	 *
+	 * 32 bpp
+	 *
+	 */
+
+	else if (_par->var.bits_per_pixel == 32) {
+		DPRINTK ("clgen: preparing for 24/32 bit deep display\n");
+		switch (fb_info->btype) {
+		case BT_SD64:
+			vga_wseq (fb_info->regs, CL_SEQR7, 0xf9);	/* Extended Sequencer Mode: 256c col. mode */
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x1e);		/* MCLK select */
+			break;
+
+		case BT_PICCOLO:
+			vga_wseq (fb_info->regs, CL_SEQR7, 0x85);
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* MCLK select */
+			break;
+
+		case BT_PICASSO:
+			vga_wseq (fb_info->regs, CL_SEQR7, 0x25);
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* MCLK select */
+			break;
+
+		case BT_SPECTRUM:
+			vga_wseq (fb_info->regs, CL_SEQR7, 0x85);
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
+			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* MCLK select */
+			break;
+
+		case BT_PICASSO4:
+			vga_wseq (fb_info->regs, CL_SEQR7, 0x25);
+/*          vga_wseq (fb_info->regs, CL_SEQR1F, 0x1c);  */
+			break;
+
+		case BT_ALPINE:
+			DPRINTK (" (for GD543x)\n");
+			vga_wseq (fb_info->regs, CL_SEQR7, 0xa9);
+			clgen_set_mclk (fb_info, _par->mclk, _par->divMCLK);
+			break;
+
+		case BT_GD5480:
+			DPRINTK (" (for GD5480)\n");
+			vga_wseq (fb_info->regs, CL_SEQR7, 0x19);
+			/* We already set SRF and SR1F */
+			break;
+
+		case BT_LAGUNA:
+			DPRINTK (" (for GD546x)\n");
+			vga_wseq (fb_info->regs, CL_SEQR7,
+				vga_rseq (fb_info->regs, CL_SEQR7) & ~0x01);
+			break;
+
+		default:
+			printk (KERN_WARNING "clgen: unknown Board\n");
+			break;
+		}
+
+		vga_wgfx (fb_info->regs, VGA_GFX_MODE, 64);	/* mode register: 256 color mode */
+		WGen (fb_info, VGA_PEL_MSK, 0xff);	/* pixel mask: pass-through all planes */
+		WHDR (fb_info, 0xc5);	/* hidden dac reg: 8-8-8 mode (24 or 32) */
+		vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x0a);	/* memory mode: chain4, ext. memory */
+		vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0xff);	/* plane mask: enable writing to all 4 planes */
+		offset = _par->var.xres_virtual / 4;
+	}
+
+	/******************************************************
+	 *
+	 * unknown/unsupported bpp
+	 *
+	 */
+
+	else {
+		printk (KERN_ERR "clgen: What's this?? requested color depth == %d.\n",
+			_par->var.bits_per_pixel);
+	}
+
+	vga_wcrt (fb_info->regs, VGA_CRTC_OFFSET, offset & 0xff);
+	tmp = 0x22;
+	if (offset & 0x100)
+		tmp |= 0x10;	/* offset overflow bit */
+
+	vga_wcrt (fb_info->regs, CL_CRT1B, tmp);	/* screen start addr #16-18, fastpagemode cycles */
+
+	if (fb_info->btype == BT_SD64 ||
+	    fb_info->btype == BT_PICASSO4 ||
+	    fb_info->btype == BT_ALPINE ||
+	    fb_info->btype == BT_GD5480)
+		vga_wcrt (fb_info->regs, CL_CRT1D, 0x00);	/* screen start address bit 19 */
+
+	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_HI, 0);	/* text cursor location high */
+	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_LO, 0);	/* text cursor location low */
+	vga_wcrt (fb_info->regs, VGA_CRTC_UNDERLINE, 0);	/* underline row scanline = at very bottom */
+
+	vga_wattr (fb_info->regs, VGA_ATC_MODE, 1);	/* controller mode */
+	vga_wattr (fb_info->regs, VGA_ATC_OVERSCAN, 0);		/* overscan (border) color */
+	vga_wattr (fb_info->regs, VGA_ATC_PLANE_ENABLE, 15);	/* color plane enable */
+	vga_wattr (fb_info->regs, CL_AR33, 0);	/* pixel panning */
+	vga_wattr (fb_info->regs, VGA_ATC_COLOR_PAGE, 0);	/* color select */
+
+	/* [ EGS: SetOffset(); ] */
+	/* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
+	AttrOn (fb_info);
+
+	vga_wgfx (fb_info->regs, VGA_GFX_SR_VALUE, 0);	/* set/reset register */
+	vga_wgfx (fb_info->regs, VGA_GFX_SR_ENABLE, 0);		/* set/reset enable */
+	vga_wgfx (fb_info->regs, VGA_GFX_COMPARE_VALUE, 0);	/* color compare */
+	vga_wgfx (fb_info->regs, VGA_GFX_DATA_ROTATE, 0);	/* data rotate */
+	vga_wgfx (fb_info->regs, VGA_GFX_PLANE_READ, 0);	/* read map select */
+	vga_wgfx (fb_info->regs, VGA_GFX_MISC, 1);	/* miscellaneous register */
+	vga_wgfx (fb_info->regs, VGA_GFX_COMPARE_MASK, 15);	/* color don't care */
+	vga_wgfx (fb_info->regs, VGA_GFX_BIT_MASK, 255);	/* bit mask */
+
+	vga_wseq (fb_info->regs, CL_SEQR12, 0x0);	/* graphics cursor attributes: nothing special */
+
+	/* finally, turn on everything - turn off "FullBandwidth" bit */
+	/* also, set "DotClock%2" bit where requested */
+	tmp = 0x01;
+
+/*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ?
+    if (var->vmode & FB_VMODE_CLOCK_HALVE)
+	tmp |= 0x08;
+*/
+
+	vga_wseq (fb_info->regs, VGA_SEQ_CLOCK_MODE, tmp);
+	DPRINTK ("CL_SEQR1: %d\n", tmp);
+
+	fb_info->currentmode = *_par;
+
+	DPRINTK ("virtual offset: (%d,%d)\n", _par->var.xoffset, _par->var.yoffset);
+	/* pan to requested offset */
+	clgen_pan_display (&fb_info->currentmode.var, (struct fb_info_gen *) fb_info);
+
+#ifdef CLGEN_DEBUG
+	clgen_dump ();
+#endif
+
+	DPRINTK ("EXIT\n");
+	return;
+}
+
+
+static int clgen_getcolreg (unsigned regno, unsigned *red, unsigned *green,
+			    unsigned *blue, unsigned *transp,
+			    struct fb_info *info)
+{
+    struct clgenfb_info *fb_info = (struct clgenfb_info *)info;
+
+    if (regno > 255)
+	return 1;
+    *red = fb_info->palette[regno].red;
+    *green = fb_info->palette[regno].green;
+    *blue = fb_info->palette[regno].blue;
+    *transp = 0;
+    return 0;
+}
+
+
+static int clgenfb_setcolreg (unsigned regno, unsigned red, unsigned green,
+			      unsigned blue, unsigned transp,
+			      struct fb_info *info)
+{
+	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
+
+	if (regno > 255)
+		return -EINVAL;
+
+#ifdef FBCON_HAS_CFB8
+	switch (fb_info->currentmode.var.bits_per_pixel) {
+	case 8:
+		/* "transparent" stuff is completely ignored. */
+		WClut (fb_info, regno, red >> 10, green >> 10, blue >> 10);
+		break;
+	default:
+		/* do nothing */
+		break;
+	}
+#endif	/* FBCON_HAS_CFB8 */
+
+	fb_info->palette[regno].red = red;
+	fb_info->palette[regno].green = green;
+	fb_info->palette[regno].blue = blue;
+
+	if (regno >= 16)
+		return 0;
+
+	switch (fb_info->currentmode.var.bits_per_pixel) {
+
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		assert (regno < 16);
+		if(isPReP) {
+			fb_info->fbcon_cmap.cfb16[regno] =
+			    ((red & 0xf800) >> 9) |
+			    ((green & 0xf800) >> 14) |
+			    ((green & 0xf800) << 2) |
+			    ((blue & 0xf800) >> 3);
+		} else {
+			fb_info->fbcon_cmap.cfb16[regno] =
+			    ((red & 0xf800) >> 1) |
+			    ((green & 0xf800) >> 6) |
+			    ((blue & 0xf800) >> 11);
+		}
+#endif /* FBCON_HAS_CFB16 */
+
+#ifdef FBCON_HAS_CFB24
+	case 24:
+		assert (regno < 16);
+		fb_info->fbcon_cmap.cfb24[regno] =
+			(red   << fb_info->currentmode.var.red.offset)   |
+			(green << fb_info->currentmode.var.green.offset) |
+			(blue  << fb_info->currentmode.var.blue.offset);
+		break;
+#endif /* FBCON_HAS_CFB24 */
+
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		assert (regno < 16);
+		if(isPReP) {
+			fb_info->fbcon_cmap.cfb32[regno] =
+			    ((red & 0xff00)) |
+			    ((green & 0xff00) << 8) |
+			    ((blue & 0xff00) << 16);
+		} else {
+			fb_info->fbcon_cmap.cfb32[regno] =
+			    ((red & 0xff00) << 8) |
+			    ((green & 0xff00)) |
+			    ((blue & 0xff00) >> 8);
+		}
+		break;
+#endif /* FBCON_HAS_CFB32 */
+	default:
+		/* do nothing */
+		break;
+	}
+
+	return 0;
+}
+
+/*************************************************************************
+	clgen_pan_display()
+
+	performs display panning - provided hardware permits this
+**************************************************************************/
+static int clgen_pan_display (const struct fb_var_screeninfo *var,
+			      struct fb_info_gen *info)
+{
+	int xoffset = 0;
+	int yoffset = 0;
+	unsigned long base;
+	unsigned char tmp = 0, tmp2 = 0, xpix;
+	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
+
+	DPRINTK ("ENTER\n");
+
+	/* no range checks for xoffset and yoffset,   */
+	/* as fbgen_pan_display has already done this */
+
+	fb_info->currentmode.var.xoffset = var->xoffset;
+	fb_info->currentmode.var.yoffset = var->yoffset;
+
+	xoffset = var->xoffset * fb_info->currentmode.var.bits_per_pixel / 8;
+	yoffset = var->yoffset;
+
+	base = yoffset * fb_info->currentmode.line_length + xoffset;
+
+	if (fb_info->currentmode.var.bits_per_pixel == 1) {
+		/* base is already correct */
+		xpix = (unsigned char) (var->xoffset % 8);
+	} else {
+		base /= 4;
+		xpix = (unsigned char) ((xoffset % 4) * 2);
+	}
+
+	/* lower 8 + 8 bits of screen start address */
+	vga_wcrt (fb_info->regs, VGA_CRTC_START_LO, (unsigned char) (base & 0xff));
+	vga_wcrt (fb_info->regs, VGA_CRTC_START_HI, (unsigned char) (base >> 8));
+
+	/* construct bits 16, 17 and 18 of screen start address */
+	if (base & 0x10000)
+		tmp |= 0x01;
+	if (base & 0x20000)
+		tmp |= 0x04;
+	if (base & 0x40000)
+		tmp |= 0x08;
+
+	tmp2 = (vga_rcrt (fb_info->regs, CL_CRT1B) & 0xf2) | tmp;	/* 0xf2 is %11110010, exclude tmp bits */
+	vga_wcrt (fb_info->regs, CL_CRT1B, tmp2);
+
+	/* construct bit 19 of screen start address */
+	if (clgen_board_info[fb_info->btype].scrn_start_bit19) {
+		tmp2 = 0;
+		if (base & 0x80000)
+			tmp2 = 0x80;
+		vga_wcrt (fb_info->regs, CL_CRT1D, tmp2);
+	}
+
+	/* write pixel panning value to AR33; this does not quite work in 8bpp */
+	/* ### Piccolo..? Will this work? */
+	if (fb_info->currentmode.var.bits_per_pixel == 1)
+		vga_wattr (fb_info->regs, CL_AR33, xpix);
+
+
+	DPRINTK ("EXIT\n");
+	return (0);
+}
+
+
+static int clgen_blank (int blank_mode, struct fb_info_gen *info)
+{
+	/*
+	 *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL
+	 *  then the caller blanks by setting the CLUT (Color Look Up Table) to all
+	 *  black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
+	 *  to e.g. a video mode which doesn't support it. Implements VESA suspend
+	 *  and powerdown modes on hardware that supports disabling hsync/vsync:
+	 *    blank_mode == 2: suspend vsync
+	 *    blank_mode == 3: suspend hsync
+	 *    blank_mode == 4: powerdown
+	 */
+	unsigned char val;
+	static int current_mode = 0;
+	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
+
+	DPRINTK ("ENTER, blank mode = %d\n", blank_mode);
+
+	if (current_mode == blank_mode) {
+		DPRINTK ("EXIT, returning 0\n");
+		return 0;
+	}
+
+	/* Undo current */
+	switch (current_mode) {
+	case 0:		/* Screen is normal */
+		break;
+	case 1:		/* Screen is blanked */
+		val = vga_rseq (fb_info->regs, VGA_SEQ_CLOCK_MODE);
+		vga_wseq (fb_info->regs, VGA_SEQ_CLOCK_MODE, val & 0xdf);	/* clear "FullBandwidth" bit */
+		break;
+	case 2:		/* vsync suspended */
+	case 3:		/* hsync suspended */
+	case 4:		/* sceen is powered down */
+		vga_wgfx (fb_info->regs, CL_GRE, 0x00);
+		break;
+	default:
+		DPRINTK ("EXIT, returning 1\n");
+		return 1;
+	}
+
+	/* set new */
+	switch (blank_mode) {
+	case 0:		/* Unblank screen */
+		break;
+	case 1:		/* Blank screen */
+		val = vga_rseq (fb_info->regs, VGA_SEQ_CLOCK_MODE);
+		vga_wseq (fb_info->regs, VGA_SEQ_CLOCK_MODE, val | 0x20);	/* set "FullBandwidth" bit */
+		break;
+	case 2:		/* suspend vsync */
+		vga_wgfx (fb_info->regs, CL_GRE, 0x04);
+		break;
+	case 3:		/* suspend hsync */
+		vga_wgfx (fb_info->regs, CL_GRE, 0x02);
+		break;
+	case 4:		/* powerdown */
+		vga_wgfx (fb_info->regs, CL_GRE, 0x06);
+		break;
+	default:
+		DPRINTK ("EXIT, returning 1\n");
+		return 1;
+	}
+
+	current_mode = blank_mode;
+	DPRINTK ("EXIT, returning 0\n");
+	return 0;
+}
+/**** END   Hardware specific Routines **************************************/
+/****************************************************************************/
+/**** BEGIN Internal Routines ***********************************************/
+
+static void __init init_vgachip (struct clgenfb_info *fb_info)
+{
+	const struct clgen_board_info_rec *bi;
+
+	DPRINTK ("ENTER\n");
+
+	assert (fb_info != NULL);
+
+	bi = &clgen_board_info[fb_info->btype];
+
+	/* reset board globally */
+	switch (fb_info->btype) {
+	case BT_PICCOLO:
+		WSFR (fb_info, 0x01);
+		udelay (500);
+		WSFR (fb_info, 0x51);
+		udelay (500);
+		break;
+	case BT_PICASSO:
+		WSFR2 (fb_info, 0xff);
+		udelay (500);
+		break;
+	case BT_SD64:
+	case BT_SPECTRUM:
+		WSFR (fb_info, 0x1f);
+		udelay (500);
+		WSFR (fb_info, 0x4f);
+		udelay (500);
+		break;
+	case BT_PICASSO4:
+		vga_wcrt (fb_info->regs, CL_CRT51, 0x00);	/* disable flickerfixer */
+		mdelay (100);
+		vga_wgfx (fb_info->regs, CL_GR2F, 0x00);	/* from Klaus' NetBSD driver: */
+		vga_wgfx (fb_info->regs, CL_GR33, 0x00);	/* put blitter into 542x compat */
+		vga_wgfx (fb_info->regs, CL_GR31, 0x00);	/* mode */
+		break;
+
+	case BT_GD5480:
+		vga_wgfx (fb_info->regs, CL_GR2F, 0x00);	/* from Klaus' NetBSD driver: */
+		break;
+
+	case BT_ALPINE:
+		/* Nothing to do to reset the board. */
+		break;
+
+	default:
+		printk (KERN_ERR "clgen: Warning: Unknown board type\n");
+		break;
+	}
+
+	assert (fb_info->size > 0); /* make sure RAM size set by this point */
+
+	/* assume it's a "large memory" board (2/4 MB) */
+	fb_info->smallboard = FALSE;
+
+	/* the P4 is not fully initialized here; I rely on it having been */
+	/* inited under AmigaOS already, which seems to work just fine    */
+	/* (Klaus advised to do it this way)                              */
+
+	if (fb_info->btype != BT_PICASSO4) {
+		WGen (fb_info, CL_VSSM, 0x10);	/* EGS: 0x16 */
+		WGen (fb_info, CL_POS102, 0x01);
+		WGen (fb_info, CL_VSSM, 0x08);	/* EGS: 0x0e */
+
+		if (fb_info->btype != BT_SD64)
+			WGen (fb_info, CL_VSSM2, 0x01);
+
+		vga_wseq (fb_info->regs, CL_SEQR0, 0x03);	/* reset sequencer logic */
+
+		vga_wseq (fb_info->regs, VGA_SEQ_CLOCK_MODE, 0x21);	/* FullBandwidth (video off) and 8/9 dot clock */
+		WGen (fb_info, VGA_MIS_W, 0xc1);	/* polarity (-/-), disable access to display memory, VGA_CRTC_START_HI base address: color */
+
+/*      vga_wgfx (fb_info->regs, CL_GRA, 0xce);    "magic cookie" - doesn't make any sense to me.. */
+		vga_wseq (fb_info->regs, CL_SEQR6, 0x12);	/* unlock all extension registers */
+
+		vga_wgfx (fb_info->regs, CL_GR31, 0x04);	/* reset blitter */
+
+		switch (fb_info->btype) {
+		case BT_GD5480:
+			vga_wseq (fb_info->regs, CL_SEQRF, 0x98);
+			break;
+		case BT_ALPINE:
+			break;
+		case BT_SD64:
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb8);
+			break;
+		default:
+			vga_wseq (fb_info->regs, CL_SEQR16, 0x0f);
+			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);
+			break;
+		}
+	}
+	vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0xff);	/* plane mask: nothing */
+	vga_wseq (fb_info->regs, VGA_SEQ_CHARACTER_MAP, 0x00);	/* character map select: doesn't even matter in gx mode */
+	vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x0e);	/* memory mode: chain-4, no odd/even, ext. memory */
+
+	/* controller-internal base address of video memory */
+	if (bi->init_sr07)
+		vga_wseq (fb_info->regs, CL_SEQR7, bi->sr07);
+
+	/*  vga_wseq (fb_info->regs, CL_SEQR8, 0x00); *//* EEPROM control: shouldn't be necessary to write to this at all.. */
+
+	vga_wseq (fb_info->regs, CL_SEQR10, 0x00);		/* graphics cursor X position (incomplete; position gives rem. 3 bits */
+	vga_wseq (fb_info->regs, CL_SEQR11, 0x00);		/* graphics cursor Y position (..."... ) */
+	vga_wseq (fb_info->regs, CL_SEQR12, 0x00);		/* graphics cursor attributes */
+	vga_wseq (fb_info->regs, CL_SEQR13, 0x00);		/* graphics cursor pattern address */
+
+	/* writing these on a P4 might give problems..  */
+	if (fb_info->btype != BT_PICASSO4) {
+		vga_wseq (fb_info->regs, CL_SEQR17, 0x00);		/* configuration readback and ext. color */
+		vga_wseq (fb_info->regs, CL_SEQR18, 0x02);		/* signature generator */
+	}
+
+	/* MCLK select etc. */
+	if (bi->init_sr1f)
+		vga_wseq (fb_info->regs, CL_SEQR1F, bi->sr1f);
+
+	vga_wcrt (fb_info->regs, VGA_CRTC_PRESET_ROW, 0x00);	/* Screen A preset row scan: none */
+	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_START, 0x20);	/* Text cursor start: disable text cursor */
+	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_END, 0x00);	/* Text cursor end: - */
+	vga_wcrt (fb_info->regs, VGA_CRTC_START_HI, 0x00);	/* Screen start address high: 0 */
+	vga_wcrt (fb_info->regs, VGA_CRTC_START_LO, 0x00);	/* Screen start address low: 0 */
+	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_HI, 0x00);	/* text cursor location high: 0 */
+	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_LO, 0x00);	/* text cursor location low: 0 */
+
+	vga_wcrt (fb_info->regs, VGA_CRTC_UNDERLINE, 0x00);	/* Underline Row scanline: - */
+	vga_wcrt (fb_info->regs, VGA_CRTC_MODE, 0xc3);	/* mode control: timing enable, byte mode, no compat modes */
+	vga_wcrt (fb_info->regs, VGA_CRTC_LINE_COMPARE, 0x00);	/* Line Compare: not needed */
+	/* ### add 0x40 for text modes with > 30 MHz pixclock */
+	vga_wcrt (fb_info->regs, CL_CRT1B, 0x02);	/* ext. display controls: ext.adr. wrap */
+
+	vga_wgfx (fb_info->regs, VGA_GFX_SR_VALUE, 0x00);	/* Set/Reset registes: - */
+	vga_wgfx (fb_info->regs, VGA_GFX_SR_ENABLE, 0x00);	/* Set/Reset enable: - */
+	vga_wgfx (fb_info->regs, VGA_GFX_COMPARE_VALUE, 0x00);	/* Color Compare: - */
+	vga_wgfx (fb_info->regs, VGA_GFX_DATA_ROTATE, 0x00);	/* Data Rotate: - */
+	vga_wgfx (fb_info->regs, VGA_GFX_PLANE_READ, 0x00);	/* Read Map Select: - */
+	vga_wgfx (fb_info->regs, VGA_GFX_MODE, 0x00);	/* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
+	vga_wgfx (fb_info->regs, VGA_GFX_MISC, 0x01);	/* Miscellaneous: memory map base address, graphics mode */
+	vga_wgfx (fb_info->regs, VGA_GFX_COMPARE_MASK, 0x0f);	/* Color Don't care: involve all planes */
+	vga_wgfx (fb_info->regs, VGA_GFX_BIT_MASK, 0xff);	/* Bit Mask: no mask at all */
+	if (fb_info->btype == BT_ALPINE)
+		vga_wgfx (fb_info->regs, CL_GRB, 0x20);	/* (5434 can't have bit 3 set for bitblt) */
+	else
+		vga_wgfx (fb_info->regs, CL_GRB, 0x28);	/* Graphics controller mode extensions: finer granularity, 8byte data latches */
+
+	vga_wgfx (fb_info->regs, CL_GRC, 0xff);	/* Color Key compare: - */
+	vga_wgfx (fb_info->regs, CL_GRD, 0x00);	/* Color Key compare mask: - */
+	vga_wgfx (fb_info->regs, CL_GRE, 0x00);	/* Miscellaneous control: - */
+	/*  vga_wgfx (fb_info->regs, CL_GR10, 0x00); *//* Background color byte 1: - */
+/*  vga_wgfx (fb_info->regs, CL_GR11, 0x00); */
+
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTE0, 0x00);	/* Attribute Controller palette registers: "identity mapping" */
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTE1, 0x01);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTE2, 0x02);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTE3, 0x03);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTE4, 0x04);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTE5, 0x05);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTE6, 0x06);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTE7, 0x07);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTE8, 0x08);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTE9, 0x09);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTEA, 0x0a);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTEB, 0x0b);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTEC, 0x0c);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTED, 0x0d);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTEE, 0x0e);
+	vga_wattr (fb_info->regs, VGA_ATC_PALETTEF, 0x0f);
+
+	vga_wattr (fb_info->regs, VGA_ATC_MODE, 0x01);	/* Attribute Controller mode: graphics mode */
+	vga_wattr (fb_info->regs, VGA_ATC_OVERSCAN, 0x00);	/* Overscan color reg.: reg. 0 */
+	vga_wattr (fb_info->regs, VGA_ATC_PLANE_ENABLE, 0x0f);	/* Color Plane enable: Enable all 4 planes */
+/* ###  vga_wattr (fb_info->regs, CL_AR33, 0x00); * Pixel Panning: - */
+	vga_wattr (fb_info->regs, VGA_ATC_COLOR_PAGE, 0x00);	/* Color Select: - */
+
+	WGen (fb_info, VGA_PEL_MSK, 0xff);	/* Pixel mask: no mask */
+
+	if (fb_info->btype != BT_ALPINE && fb_info->btype != BT_GD5480)
+		WGen (fb_info, VGA_MIS_W, 0xc3);	/* polarity (-/-), enable display mem, VGA_CRTC_START_HI i/o base = color */
+
+	vga_wgfx (fb_info->regs, CL_GR31, 0x04);	/* BLT Start/status: Blitter reset */
+	vga_wgfx (fb_info->regs, CL_GR31, 0x00);	/* - " -           : "end-of-reset" */
+
+	/* CLUT setup */
+	WClut (fb_info, 0, 0x00, 0x00, 0x00);	/* background: black */
+	WClut (fb_info, 1, 0x3f, 0x3f, 0x3f);	/* foreground: white */
+	WClut (fb_info, 2, 0x00, 0x20, 0x00);
+	WClut (fb_info, 3, 0x00, 0x20, 0x20);
+	WClut (fb_info, 4, 0x20, 0x00, 0x00);
+	WClut (fb_info, 5, 0x20, 0x00, 0x20);
+	WClut (fb_info, 6, 0x20, 0x10, 0x00);
+	WClut (fb_info, 7, 0x20, 0x20, 0x20);
+	WClut (fb_info, 8, 0x10, 0x10, 0x10);
+	WClut (fb_info, 9, 0x10, 0x10, 0x30);
+	WClut (fb_info, 10, 0x10, 0x30, 0x10);
+	WClut (fb_info, 11, 0x10, 0x30, 0x30);
+	WClut (fb_info, 12, 0x30, 0x10, 0x10);
+	WClut (fb_info, 13, 0x30, 0x10, 0x30);
+	WClut (fb_info, 14, 0x30, 0x30, 0x10);
+	WClut (fb_info, 15, 0x30, 0x30, 0x30);
+
+	/* the rest a grey ramp */
+	{
+		int i;
+
+		for (i = 16; i < 256; i++)
+			WClut (fb_info, i, i >> 2, i >> 2, i >> 2);
+	}
+
+
+	/* misc... */
+	WHDR (fb_info, 0);	/* Hidden DAC register: - */
+
+	printk (KERN_INFO "clgen: This board has %ld bytes of DRAM memory\n", fb_info->size);
+	DPRINTK ("EXIT\n");
+	return;
+}
+
+static void switch_monitor (struct clgenfb_info *fb_info, int on)
+{
+#ifdef CONFIG_ZORRO /* only works on Zorro boards */
+	static int IsOn = 0;	/* XXX not ok for multiple boards */
+
+	DPRINTK ("ENTER\n");
+
+	if (fb_info->btype == BT_PICASSO4)
+		return;		/* nothing to switch */
+	if (fb_info->btype == BT_ALPINE)
+		return;		/* nothing to switch */
+	if (fb_info->btype == BT_GD5480)
+		return;		/* nothing to switch */
+	if (fb_info->btype == BT_PICASSO) {
+		if ((on && !IsOn) || (!on && IsOn))
+			WSFR (fb_info, 0xff);
+
+		DPRINTK ("EXIT\n");
+		return;
+	}
+	if (on) {
+		switch (fb_info->btype) {
+		case BT_SD64:
+			WSFR (fb_info, fb_info->SFR | 0x21);
+			break;
+		case BT_PICCOLO:
+			WSFR (fb_info, fb_info->SFR | 0x28);
+			break;
+		case BT_SPECTRUM:
+			WSFR (fb_info, 0x6f);
+			break;
+		default: /* do nothing */ break;
+		}
+	} else {
+		switch (fb_info->btype) {
+		case BT_SD64:
+			WSFR (fb_info, fb_info->SFR & 0xde);
+			break;
+		case BT_PICCOLO:
+			WSFR (fb_info, fb_info->SFR & 0xd7);
+			break;
+		case BT_SPECTRUM:
+			WSFR (fb_info, 0x4f);
+			break;
+		default: /* do nothing */ break;
+		}
+	}
+
+	DPRINTK ("EXIT\n");
+#endif /* CONFIG_ZORRO */
+}
+
+static void clgen_set_disp (const void *par, struct display *disp,
+			    struct fb_info_gen *info)
+{
+	struct clgenfb_par *_par = (struct clgenfb_par *) par;
+	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
+	int accel_text;
+
+	DPRINTK ("ENTER\n");
+
+	assert (_par != NULL);
+	assert (fb_info != NULL);
+
+	accel_text = _par->var.accel_flags & FB_ACCELF_TEXT;
+
+	printk ("Cirrus Logic video mode: ");
+	info->info.screen_base = (char *) fb_info->fbmem;
+	switch (_par->var.bits_per_pixel) {
+#ifdef FBCON_HAS_MFB
+	case 1:
+		printk ("monochrome\n");
+		if (fb_info->btype == BT_GD5480)
+			info->info.screen_base = (char *) fb_info->fbmem;
+		disp->dispsw = &fbcon_mfb;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		printk ("8 bit color depth\n");
+		if (fb_info->btype == BT_GD5480)
+			info->info.screen_base = (char *) fb_info->fbmem;
+		if (accel_text)
+			disp->dispsw = &fbcon_clgen_8;
+		else
+			disp->dispsw = &fbcon_cfb8;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		printk ("16 bit color depth\n");
+		if (accel_text)
+			disp->dispsw = &fbcon_clgen_16;
+		else
+			disp->dispsw = &fbcon_cfb16;
+		if (fb_info->btype == BT_GD5480)
+			info->info.screen_base = (char *) fb_info->fbmem + 1 * MB_;
+		disp->dispsw_data = fb_info->fbcon_cmap.cfb16;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB24
+	case 24:
+		printk ("24 bit color depth\n");
+		disp->dispsw = &fbcon_cfb24;
+		if (fb_info->btype == BT_GD5480)
+			info->info.screen_base = (char *) fb_info->fbmem + 2 * MB_;
+		disp->dispsw_data = fb_info->fbcon_cmap.cfb24;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		printk ("32 bit color depth\n");
+		if (accel_text)
+			disp->dispsw = &fbcon_clgen_32;
+		else
+			disp->dispsw = &fbcon_cfb32;
+		if (fb_info->btype == BT_GD5480)
+			info->info.screen_base = (char *) fb_info->fbmem + 2 * MB_;
+		disp->dispsw_data = fb_info->fbcon_cmap.cfb32;
+		break;
+#endif
+
+	default:
+		printk ("unsupported color depth\n");
+		disp->dispsw = &fbcon_dummy;
+		disp->dispsw_data = NULL;
+		break;
+	}
+
+	DPRINTK ("EXIT\n");
+}
+
+#ifdef FBCON_HAS_CFB8
+static void fbcon_clgen8_bmove (struct display *p, int sy, int sx,
+				int dy, int dx, int height, int width)
+{
+	struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
+
+	DPRINTK ("ENTER\n");
+
+	sx *= fontwidth (p);
+	sy *= fontheight (p);
+	dx *= fontwidth (p);
+	dy *= fontheight (p);
+	width *= fontwidth (p);
+	height *= fontheight (p);
+
+	clgen_BitBLT (fb_info->regs, (unsigned short) sx, (unsigned short) sy,
+		      (unsigned short) dx, (unsigned short) dy,
+		      (unsigned short) width, (unsigned short) height,
+		      fb_info->currentmode.line_length);
+
+	DPRINTK ("EXIT\n");
+}
+
+static void fbcon_clgen8_clear (struct vc_data *conp, struct display *p,
+				int sy, int sx, int height, int width)
+{
+	struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
+	unsigned short col;
+
+	DPRINTK ("ENTER\n");
+
+	sx *= fontwidth (p);
+	sy *= fontheight (p);
+	width *= fontwidth (p);
+	height *= fontheight (p);
+
+	col = attr_bgcol_ec (p, conp);
+	col &= 0xff;
+
+	clgen_RectFill (fb_info, (unsigned short) sx, (unsigned short) sy,
+			(unsigned short) width, (unsigned short) height,
+			col, fb_info->currentmode.line_length);
+
+	DPRINTK ("EXIT\n");
+}
+
+#endif
+
+#ifdef FBCON_HAS_CFB16
+static void fbcon_clgen16_bmove (struct display *p, int sy, int sx,
+				 int dy, int dx, int height, int width)
+{
+	struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
+
+	DPRINTK ("ENTER\n");
+
+	sx *= fontwidth (p) * 2;	/* 2 bytes/pixel */
+	sy *= fontheight (p);
+	dx *= fontwidth (p) * 2;	/* 2 bytes/pixel */
+	dy *= fontheight (p);
+	width *= fontwidth (p) * 2;	/* 2 bytes/pixel */
+	height *= fontheight (p);
+
+	clgen_BitBLT (fb_info->regs, (unsigned short) sx, (unsigned short) sy,
+		      (unsigned short) dx, (unsigned short) dy,
+		      (unsigned short) width, (unsigned short) height,
+		      fb_info->currentmode.line_length);
+
+	DPRINTK ("EXIT\n");
+}
+
+static void fbcon_clgen16_clear (struct vc_data *conp, struct display *p,
+				 int sy, int sx, int height, int width)
+{
+	struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
+	unsigned short col;
+
+	DPRINTK ("ENTER\n");
+
+	sx *= fontwidth (p) * 2;	/* 2 bytes/pixel */
+	sy *= fontheight (p);
+	width *= fontwidth (p) * 2;	/* 2 bytes/pixel? */
+	height *= fontheight (p);
+
+	col = attr_bgcol_ec (p, conp);
+	col &= 0xff;
+
+	clgen_RectFill (fb_info, (unsigned short) sx, (unsigned short) sy,
+			(unsigned short) width, (unsigned short) height,
+			col, fb_info->currentmode.line_length);
+
+	DPRINTK ("EXIT\n");
+}
+
+#endif
+
+#ifdef FBCON_HAS_CFB32
+static void fbcon_clgen32_bmove (struct display *p, int sy, int sx,
+				 int dy, int dx, int height, int width)
+{
+	struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
+
+	DPRINTK ("ENTER\n");
+
+	sx *= fontwidth (p) * 4;	/* 4 bytes/pixel */
+	sy *= fontheight (p);
+	dx *= fontwidth (p) * 4;	/* 4 bytes/pixel */
+	dy *= fontheight (p);
+	width *= fontwidth (p) * 4;	/* 4 bytes/pixel */
+	height *= fontheight (p);
+
+	clgen_BitBLT (fb_info->regs, (unsigned short) sx, (unsigned short) sy,
+		      (unsigned short) dx, (unsigned short) dy,
+		      (unsigned short) width, (unsigned short) height,
+		      fb_info->currentmode.line_length);
+
+	DPRINTK ("EXIT\n");
+}
+
+static void fbcon_clgen32_clear (struct vc_data *conp, struct display *p,
+				 int sy, int sx, int height, int width)
+{
+	struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
+
+	unsigned short col;
+
+	DPRINTK ("ENTER\n");
+
+	sx *= fontwidth (p) * 4;	/* 4 bytes/pixel */
+	sy *= fontheight (p);
+	width *= fontwidth (p) * 4;	/* 4 bytes/pixel? */
+	height *= fontheight (p);
+
+	col = attr_bgcol_ec (p, conp);
+	col &= 0xff;
+
+	clgen_RectFill (fb_info, (unsigned short) sx, (unsigned short) sy,
+			(unsigned short) width, (unsigned short) height,
+			col, fb_info->currentmode.line_length);
+
+	DPRINTK ("EXIT\n");
+}
+
+#endif				/* FBCON_HAS_CFB32 */
+
+
+
+
+#ifdef CONFIG_ALL_PPC
+#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
+#define PREP_IO_BASE    ((volatile unsigned char *) 0x80000000)
+static void __init get_prep_addrs (unsigned long *display, unsigned long *registers)
+{
+	DPRINTK ("ENTER\n");
+
+	*display = PREP_VIDEO_BASE;
+	*registers = (unsigned long) PREP_IO_BASE;
+
+	DPRINTK ("EXIT\n");
+}
+
+#endif				/* CONFIG_ALL_PPC */
+
+
+
+
+#ifdef CONFIG_PCI
+static int release_io_ports = 0;
+
+/* Pulled the logic from XFree86 Cirrus driver to get the memory size,
+ * based on the DRAM bandwidth bit and DRAM bank switching bit.  This
+ * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
+ * seem to have. */
+static unsigned int __init clgen_get_memsize (caddr_t regbase)
+{
+	unsigned long mem;
+	unsigned char SRF;
+
+	DPRINTK ("ENTER\n");
+
+	SRF = vga_rseq (regbase, CL_SEQRF);
+	switch ((SRF & 0x18)) {
+	    case 0x08: mem = 512 * 1024; break;
+	    case 0x10: mem = 1024 * 1024; break;
+		/* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory
+		   * on the 5430. */
+	    case 0x18: mem = 2048 * 1024; break;
+	    default: printk ("CLgenfb: Unknown memory size!\n");
+		mem = 1024 * 1024;
+	}
+	if (SRF & 0x80) {
+		/* If DRAM bank switching is enabled, there must be twice as much
+		   * memory installed. (4MB on the 5434) */
+		mem *= 2;
+	}
+	/* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
+	return mem;
+
+	DPRINTK ("EXIT\n");
+}
+
+
+
+static struct pci_dev * __init clgen_pci_dev_get (clgen_board_t *btype)
+{
+	struct pci_dev *pdev;
+	int i;
+
+	DPRINTK ("ENTER\n");
+
+	for (i = 0; i < ARRAY_SIZE(clgen_pci_probe_list); i++) {
+		pdev = NULL;
+		while ((pdev = pci_find_device (PCI_VENDOR_ID_CIRRUS,
+				clgen_pci_probe_list[i].device, pdev)) != NULL) {
+			if (pci_enable_device(pdev) == 0) {
+				*btype = clgen_pci_probe_list[i].btype;
+				DPRINTK ("EXIT, returning pdev=%p\n", pdev);
+				return pdev;
+			}
+		}
+	}
+
+	DPRINTK ("EXIT, returning NULL\n");
+	return NULL;
+}
+
+
+
+
+static void __init get_pci_addrs (const struct pci_dev *pdev,
+			   unsigned long *display, unsigned long *registers)
+{
+	assert (pdev != NULL);
+	assert (display != NULL);
+	assert (registers != NULL);
+
+	DPRINTK ("ENTER\n");
+
+	*display = 0;
+	*registers = 0;
+
+	/* This is a best-guess for now */
+
+	if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
+		*display = pci_resource_start(pdev, 1);
+		*registers = pci_resource_start(pdev, 0);
+	} else {
+		*display = pci_resource_start(pdev, 0);
+		*registers = pci_resource_start(pdev, 1);
+	}
+
+	assert (*display != 0);
+
+	DPRINTK ("EXIT\n");
+}
+
+
+static void __exit clgen_pci_unmap (struct clgenfb_info *info)
+{
+	iounmap (info->fbmem);
+	release_mem_region(info->fbmem_phys, info->size);
+
+#if 0 /* if system didn't claim this region, we would... */
+	release_mem_region(0xA0000, 65535);
+#endif
+
+	if (release_io_ports)
+		release_region(0x3C0, 32);
+}
+
+
+static int __init clgen_pci_setup (struct clgenfb_info *info,
+				   clgen_board_t *btype)
+{
+	struct pci_dev *pdev;
+	unsigned long board_addr, board_size;
+
+	DPRINTK ("ENTER\n");
+
+	pdev = clgen_pci_dev_get (btype);
+	if (!pdev) {
+		printk (KERN_ERR " Couldn't find PCI device\n");
+		DPRINTK ("EXIT, returning 1\n");
+		return 1;
+	}
+	DPRINTK (" Found PCI device, base address 0 is 0x%lx, btype set to %d\n",
+		 pdev->resource[0].start, *btype);
+	DPRINTK (" base address 1 is 0x%lx\n", pdev->resource[1].start);
+
+	info->pdev = pdev;
+
+	if(isPReP) {
+		/* Xbh does this, though 0 seems to be the init value */
+		pcibios_write_config_dword (0, pdev->devfn, PCI_BASE_ADDRESS_0,
+			0x00000000);
+
+#ifdef CONFIG_ALL_PPC
+		get_prep_addrs (&board_addr, &info->fbregs_phys);
+#endif
+	} else {
+		DPRINTK ("Attempt to get PCI info for Cirrus Graphics Card\n");
+		get_pci_addrs (pdev, &board_addr, &info->fbregs_phys);
+	}
+
+	DPRINTK ("Board address: 0x%lx, register address: 0x%lx\n", board_addr, info->fbregs_phys);
+
+	if(isPReP) {
+		/* PReP dies if we ioremap the IO registers, but it works w/out... */
+		info->regs = (char *) info->fbregs_phys;
+	} else
+		info->regs = 0;		/* FIXME: this forces VGA.  alternatives? */
+
+	if (*btype == BT_GD5480) {
+		board_size = 32 * MB_;
+	} else {
+		board_size = clgen_get_memsize (info->regs);
+	}
+
+	if (!request_mem_region(board_addr, board_size, "clgenfb")) {
+		printk(KERN_ERR "clgen: cannot reserve region 0x%lx, abort\n",
+		       board_addr);
+		return -1;
+	}
+#if 0 /* if the system didn't claim this region, we would... */
+	if (!request_mem_region(0xA0000, 65535, "clgenfb")) {
+		printk(KERN_ERR "clgen: cannot reserve region 0x%lx, abort\n",
+		       0xA0000L);
+		release_mem_region(board_addr, board_size);
+		return -1;
+	}
+#endif
+	if (request_region(0x3C0, 32, "clgenfb"))
+		release_io_ports = 1;
+
+	info->fbmem = ioremap (board_addr, board_size);
+	info->fbmem_phys = board_addr;
+	info->size = board_size;
+
+	printk (" RAM (%lu kB) at 0x%lx, ", info->size / KB_, board_addr);
+
+	printk ("Cirrus Logic chipset on PCI bus\n");
+
+	DPRINTK ("EXIT, returning 0\n");
+	return 0;
+}
+#endif				/* CONFIG_PCI */
+
+
+
+
+#ifdef CONFIG_ZORRO
+static int __init clgen_zorro_find (struct zorro_dev **z_o,
+				    struct zorro_dev **z2_o,
+				    clgen_board_t *btype, unsigned long *size)
+{
+	struct zorro_dev *z = NULL;
+	int i;
+
+	assert (z_o != NULL);
+	assert (btype != NULL);
+
+	for (i = 0; i < ARRAY_SIZE(clgen_zorro_probe_list); i++)
+		if ((z = zorro_find_device(clgen_zorro_probe_list[i].id, NULL)))
+			break;
+
+	if (z) {
+		*z_o = z;
+		if (clgen_zorro_probe_list[i].id2)
+			*z2_o = zorro_find_device(clgen_zorro_probe_list[i].id2, NULL);
+		else
+			*z2_o = NULL;
+
+		*btype = clgen_zorro_probe_list[i].btype;
+		*size = clgen_zorro_probe_list[i].size;
+
+		printk (KERN_INFO "clgen: %s board detected; ",
+			clgen_board_info[*btype].name);
+
+		return 0;
+	}
+
+	printk (KERN_NOTICE "clgen: no supported board found.\n");
+	return -1;
+}
+
+
+static void __exit clgen_zorro_unmap (struct clgenfb_info *info)
+{
+	release_mem_region(info->board_addr, info->board_size);
+
+	if (info->btype == BT_PICASSO4) {
+		iounmap ((void *)info->board_addr);
+		iounmap ((void *)info->fbmem_phys);
+	} else {
+		if (info->board_addr > 0x01000000)
+			iounmap ((void *)info->board_addr);
+	}
+}
+
+
+static int __init clgen_zorro_setup (struct clgenfb_info *info,
+				     clgen_board_t *btype)
+{
+	struct zorro_dev *z = NULL, *z2 = NULL;
+	unsigned long board_addr, board_size, size;
+
+	assert (info != NULL);
+	assert (btype != NULL);
+
+	if (clgen_zorro_find (&z, &z2, btype, &size))
+		return -1;
+
+	assert (z > 0);
+	assert (z2 >= 0);
+	assert (*btype != BT_NONE);
+
+	info->board_addr = board_addr = z->resource.start;
+	info->board_size = board_size = z->resource.end-z->resource.start+1;
+	info->size = size;
+
+	if (!request_mem_region(board_addr, board_size, "clgenfb")) {
+		printk(KERN_ERR "clgen: cannot reserve region 0x%lx, abort\n",
+		       board_addr);
+		return -1;
+	}
+
+	printk (" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr);
+
+	if (*btype == BT_PICASSO4) {
+		printk (" REG at $%lx\n", board_addr + 0x600000);
+
+		/* To be precise, for the P4 this is not the */
+		/* begin of the board, but the begin of RAM. */
+		/* for P4, map in its address space in 2 chunks (### TEST! ) */
+		/* (note the ugly hardcoded 16M number) */
+		info->regs = ioremap (board_addr, 16777216);
+		DPRINTK ("clgen: Virtual address for board set to: $%p\n", info->regs);
+		info->regs += 0x600000;
+		info->fbregs_phys = board_addr + 0x600000;
+
+		info->fbmem_phys = board_addr + 16777216;
+		info->fbmem = ioremap (info->fbmem_phys, 16777216);
+	} else {
+		printk (" REG at $%lx\n", (unsigned long) z2->resource.start);
+
+		info->fbmem_phys = board_addr;
+		if (board_addr > 0x01000000)
+			info->fbmem = ioremap (board_addr, board_size);
+		else
+			info->fbmem = (caddr_t) ZTWO_VADDR (board_addr);
+
+		/* set address for REG area of board */
+		info->regs = (caddr_t) ZTWO_VADDR (z2->resource.start);
+		info->fbregs_phys = z2->resource.start;
+
+		DPRINTK ("clgen: Virtual address for board set to: $%p\n", info->regs);
+	}
+
+	printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
+
+	return 0;
+}
+#endif /* CONFIG_ZORRO */
+
+
+
+/********************************************************************/
+/* clgenfb_init() - master initialization function                  */
+/********************************************************************/
+int __init clgenfb_init(void)
+{
+	int err, j, k;
+
+	clgen_board_t btype = BT_NONE;
+	struct clgenfb_info *fb_info = NULL;
+
+	DPRINTK ("ENTER\n");
+
+	printk (KERN_INFO "clgen: Driver for Cirrus Logic based graphic boards, v" CLGEN_VERSION "\n");
+
+	fb_info = &boards[0];	/* FIXME support multiple boards ... */
+
+#ifdef CONFIG_PCI
+	if (clgen_pci_setup (fb_info, &btype)) { /* Also does OF setup */
+		DPRINTK ("EXIT, returning -ENXIO\n");
+		return -ENXIO;
+	}
+
+#elif defined(CONFIG_ZORRO)
+	/* FIXME: CONFIG_PCI and CONFIG_ZORRO may both be defined */
+	if (clgen_zorro_setup (fb_info, &btype)) {
+		DPRINTK ("EXIT, returning -ENXIO\n");
+		return -ENXIO;
+	}
+
+#else
+#error This driver requires Zorro or PCI bus.
+#endif				/* !CONFIG_PCI, !CONFIG_ZORRO */
+
+	/* sanity checks */
+	assert (btype != BT_NONE);
+	assert (btype == clgen_board_info[btype].btype);
+
+	fb_info->btype = btype;
+
+	DPRINTK ("clgen: (RAM start set to: 0x%p)\n", fb_info->fbmem);
+
+	if (noaccel)
+	{
+		printk("clgen: disabling text acceleration support\n");
+#ifdef FBCON_HAS_CFB8
+		fbcon_clgen_8.bmove = fbcon_cfb8_bmove;
+		fbcon_clgen_8.clear = fbcon_cfb8_clear;
+#endif
+#ifdef FBCON_HAS_CFB16
+		fbcon_clgen_16.bmove = fbcon_cfb16_bmove;
+		fbcon_clgen_16.clear = fbcon_cfb16_clear;
+#endif
+#ifdef FBCON_HAS_CFB32
+		fbcon_clgen_32.bmove = fbcon_cfb32_bmove;
+		fbcon_clgen_32.clear = fbcon_cfb32_clear;
+#endif
+	}
+
+	init_vgachip (fb_info);
+
+	/* set up a few more things, register framebuffer driver etc */
+	fb_info->gen.parsize = sizeof (struct clgenfb_par);
+	fb_info->gen.fbhw = &clgen_hwswitch;
+
+	strncpy (fb_info->gen.info.modename, clgen_board_info[btype].name,
+		 sizeof (fb_info->gen.info.modename));
+	fb_info->gen.info.modename [sizeof (fb_info->gen.info.modename) - 1] = 0;
+
+	fb_info->gen.info.node = NODEV;
+	fb_info->gen.info.fbops = &clgenfb_ops;
+	fb_info->gen.info.disp = &disp;
+	fb_info->gen.info.currcon = -1;
+	fb_info->gen.info.changevar = NULL;
+	fb_info->gen.info.switch_con = &fbgen_switch;
+	fb_info->gen.info.updatevar = &fbgen_update_var;
+	fb_info->gen.info.flags = FBINFO_FLAG_DEFAULT;
+
+	for (j = 0; j < 256; j++) {
+		if (j < 16) {
+			k = color_table[j];
+			fb_info->palette[j].red = default_red[k];
+			fb_info->palette[j].green = default_grn[k];
+			fb_info->palette[j].blue = default_blu[k];
+		} else {
+			fb_info->palette[j].red =
+			fb_info->palette[j].green =
+			fb_info->palette[j].blue = j;
+		}
+	}
+
+	/* now that we know the board has been registered n' stuff, we */
+	/* can finally initialize it to a default mode */
+	clgenfb_default = clgenfb_predefined[clgen_def_mode].var;
+	clgenfb_default.activate = FB_ACTIVATE_NOW;
+	clgenfb_default.yres_virtual = 480 * 3;		/* for fast scrolling (YPAN-Mode) */
+	err = fbgen_do_set_var (&clgenfb_default, 1, &fb_info->gen);
+
+	if (err) {
+		DPRINTK ("EXIT, returning -EINVAL\n");
+		return -EINVAL;
+	}
+
+	disp.var = clgenfb_default;
+	fbgen_set_disp (-1, &fb_info->gen);
+	do_install_cmap (0, &fb_info->gen.info);
+
+	err = register_framebuffer (&fb_info->gen.info);
+	if (err) {
+		printk (KERN_ERR "clgen: ERROR - could not register fb device; err = %d!\n", err);
+		DPRINTK ("EXIT, returning -EINVAL\n");
+		return -EINVAL;
+	}
+	DPRINTK ("EXIT, returning 0\n");
+	return 0;
+}
+
+
+
+    /*
+     *  Cleanup (only needed for module)
+     */
+static void __exit clgenfb_cleanup (struct clgenfb_info *info)
+{
+	DPRINTK ("ENTER\n");
+
+#ifdef CONFIG_ZORRO
+	switch_monitor (info, 0);
+
+	clgen_zorro_unmap (info);
+#else
+	clgen_pci_unmap (info);
+#endif				/* CONFIG_ZORRO */
+
+	unregister_framebuffer ((struct fb_info *) info);
+	printk ("Framebuffer unregistered\n");
+
+	DPRINTK ("EXIT\n");
+}
+
+
+#ifndef MODULE
+int __init clgenfb_setup(char *options) {
+	char *this_opt, s[32];
+	int i;
+
+	DPRINTK ("ENTER\n");
+
+	if (!options || !*options)
+		return 0;
+
+	while ((this_opt = strsep (&options, ",")) != NULL) {	
+		if (!*this_opt) continue;
+
+		DPRINTK("clgenfb_setup: option '%s'\n", this_opt);
+
+		for (i = 0; i < NUM_TOTAL_MODES; i++) {
+			sprintf (s, "mode:%s", clgenfb_predefined[i].name);
+			if (strcmp (this_opt, s) == 0)
+				clgen_def_mode = i;
+		}
+		if (!strcmp(this_opt, "noaccel"))
+			noaccel = 1;
+	}
+	return 0;
+}
+#endif
+
+
+    /*
+     *  Modularization
+     */
+
+MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
+MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
+MODULE_LICENSE("GPL");
+
+static void __exit clgenfb_exit (void)
+{
+	DPRINTK ("ENTER\n");
+
+	clgenfb_cleanup (&boards[0]);	/* FIXME: support multiple boards */
+
+	DPRINTK ("EXIT\n");
+}
+
+#ifdef MODULE
+module_init(clgenfb_init);
+#endif
+module_exit(clgenfb_exit);
+
+
+/**********************************************************************/
+/* about the following functions - I have used the same names for the */
+/* functions as Markus Wild did in his Retina driver for NetBSD as    */
+/* they just made sense for this purpose. Apart from that, I wrote    */
+/* these functions myself.                                            */
+/**********************************************************************/
+
+/*** WGen() - write into one of the external/general registers ***/
+static void WGen (const struct clgenfb_info *fb_info,
+		  int regnum, unsigned char val)
+{
+	unsigned long regofs = 0;
+
+	if (fb_info->btype == BT_PICASSO) {
+		/* Picasso II specific hack */
+/*              if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || regnum == CL_VSSM2) */
+		if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
+			regofs = 0xfff;
+	}
+
+	vga_w (fb_info->regs, regofs + regnum, val);
+}
+
+/*** RGen() - read out one of the external/general registers ***/
+static unsigned char RGen (const struct clgenfb_info *fb_info, int regnum)
+{
+	unsigned long regofs = 0;
+
+	if (fb_info->btype == BT_PICASSO) {
+		/* Picasso II specific hack */
+/*              if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || regnum == CL_VSSM2) */
+		if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
+			regofs = 0xfff;
+	}
+
+	return vga_r (fb_info->regs, regofs + regnum);
+}
+
+/*** AttrOn() - turn on VideoEnable for Attribute controller ***/
+static void AttrOn (const struct clgenfb_info *fb_info)
+{
+	assert (fb_info != NULL);
+
+	DPRINTK ("ENTER\n");
+
+	if (vga_rcrt (fb_info->regs, CL_CRT24) & 0x80) {
+		/* if we're just in "write value" mode, write back the */
+		/* same value as before to not modify anything */
+		vga_w (fb_info->regs, VGA_ATT_IW,
+		       vga_r (fb_info->regs, VGA_ATT_R));
+	}
+	/* turn on video bit */
+/*      vga_w (fb_info->regs, VGA_ATT_IW, 0x20); */
+	vga_w (fb_info->regs, VGA_ATT_IW, 0x33);
+
+	/* dummy write on Reg0 to be on "write index" mode next time */
+	vga_w (fb_info->regs, VGA_ATT_IW, 0x00);
+
+	DPRINTK ("EXIT\n");
+}
+
+/*** WHDR() - write into the Hidden DAC register ***/
+/* as the HDR is the only extension register that requires special treatment
+ * (the other extension registers are accessible just like the "ordinary"
+ * registers of their functional group) here is a specialized routine for
+ * accessing the HDR
+ */
+static void WHDR (const struct clgenfb_info *fb_info, unsigned char val)
+{
+	unsigned char dummy;
+
+	if (fb_info->btype == BT_PICASSO) {
+		/* Klaus' hint for correct access to HDR on some boards */
+		/* first write 0 to pixel mask (3c6) */
+		WGen (fb_info, VGA_PEL_MSK, 0x00);
+		udelay (200);
+		/* next read dummy from pixel address (3c8) */
+		dummy = RGen (fb_info, VGA_PEL_IW);
+		udelay (200);
+	}
+	/* now do the usual stuff to access the HDR */
+
+	dummy = RGen (fb_info, VGA_PEL_MSK);
+	udelay (200);
+	dummy = RGen (fb_info, VGA_PEL_MSK);
+	udelay (200);
+	dummy = RGen (fb_info, VGA_PEL_MSK);
+	udelay (200);
+	dummy = RGen (fb_info, VGA_PEL_MSK);
+	udelay (200);
+
+	WGen (fb_info, VGA_PEL_MSK, val);
+	udelay (200);
+
+	if (fb_info->btype == BT_PICASSO) {
+		/* now first reset HDR access counter */
+		dummy = RGen (fb_info, VGA_PEL_IW);
+		udelay (200);
+
+		/* and at the end, restore the mask value */
+		/* ## is this mask always 0xff? */
+		WGen (fb_info, VGA_PEL_MSK, 0xff);
+		udelay (200);
+	}
+}
+
+
+/*** WSFR() - write to the "special function register" (SFR) ***/
+static void WSFR (struct clgenfb_info *fb_info, unsigned char val)
+{
+#ifdef CONFIG_ZORRO
+	assert (fb_info->regs != NULL);
+	fb_info->SFR = val;
+	z_writeb (val, fb_info->regs + 0x8000);
+#endif
+}
+
+/* The Picasso has a second register for switching the monitor bit */
+static void WSFR2 (struct clgenfb_info *fb_info, unsigned char val)
+{
+#ifdef CONFIG_ZORRO
+	/* writing an arbitrary value to this one causes the monitor switcher */
+	/* to flip to Amiga display */
+	assert (fb_info->regs != NULL);
+	fb_info->SFR = val;
+	z_writeb (val, fb_info->regs + 0x9000);
+#endif
+}
+
+
+/*** WClut - set CLUT entry (range: 0..63) ***/
+static void WClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char red,
+	    unsigned char green, unsigned char blue)
+{
+	unsigned int data = VGA_PEL_D;
+
+	/* address write mode register is not translated.. */
+	vga_w (fb_info->regs, VGA_PEL_IW, regnum);
+
+	if (fb_info->btype == BT_PICASSO || fb_info->btype == BT_PICASSO4 ||
+	    fb_info->btype == BT_ALPINE || fb_info->btype == BT_GD5480) {
+		/* but DAC data register IS, at least for Picasso II */
+		if (fb_info->btype == BT_PICASSO)
+			data += 0xfff;
+		vga_w (fb_info->regs, data, red);
+		vga_w (fb_info->regs, data, green);
+		vga_w (fb_info->regs, data, blue);
+	} else {
+		vga_w (fb_info->regs, data, blue);
+		vga_w (fb_info->regs, data, green);
+		vga_w (fb_info->regs, data, red);
+	}
+}
+
+
+#if 0
+/*** RClut - read CLUT entry (range 0..63) ***/
+static void RClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char *red,
+	    unsigned char *green, unsigned char *blue)
+{
+	unsigned int data = VGA_PEL_D;
+
+	vga_w (fb_info->regs, VGA_PEL_IR, regnum);
+
+	if (fb_info->btype == BT_PICASSO || fb_info->btype == BT_PICASSO4 ||
+	    fb_info->btype == BT_ALPINE || fb_info->btype == BT_GD5480) {
+		if (fb_info->btype == BT_PICASSO)
+			data += 0xfff;
+		*red = vga_r (fb_info->regs, data);
+		*green = vga_r (fb_info->regs, data);
+		*blue = vga_r (fb_info->regs, data);
+	} else {
+		*blue = vga_r (fb_info->regs, data);
+		*green = vga_r (fb_info->regs, data);
+		*red = vga_r (fb_info->regs, data);
+	}
+}
+#endif
+
+
+/*******************************************************************
+	clgen_WaitBLT()
+
+	Wait for the BitBLT engine to complete a possible earlier job
+*********************************************************************/
+
+/* FIXME: use interrupts instead */
+extern inline void clgen_WaitBLT (caddr_t regbase)
+{
+	/* now busy-wait until we're done */
+	while (vga_rgfx (regbase, CL_GR31) & 0x08)
+		/* do nothing */ ;
+}
+
+/*******************************************************************
+	clgen_BitBLT()
+
+	perform accelerated "scrolling"
+********************************************************************/
+
+static void clgen_BitBLT (caddr_t regbase, u_short curx, u_short cury, u_short destx, u_short desty,
+		   u_short width, u_short height, u_short line_length)
+{
+	u_short nwidth, nheight;
+	u_long nsrc, ndest;
+	u_char bltmode;
+
+	DPRINTK ("ENTER\n");
+
+	nwidth = width - 1;
+	nheight = height - 1;
+
+	bltmode = 0x00;
+	/* if source adr < dest addr, do the Blt backwards */
+	if (cury <= desty) {
+		if (cury == desty) {
+			/* if src and dest are on the same line, check x */
+			if (curx < destx)
+				bltmode |= 0x01;
+		} else
+			bltmode |= 0x01;
+	}
+	if (!bltmode) {
+		/* standard case: forward blitting */
+		nsrc = (cury * line_length) + curx;
+		ndest = (desty * line_length) + destx;
+	} else {
+		/* this means start addresses are at the end, counting backwards */
+		nsrc = cury * line_length + curx + nheight * line_length + nwidth;
+		ndest = desty * line_length + destx + nheight * line_length + nwidth;
+	}
+
+        clgen_WaitBLT(regbase);
+
+	/*
+	   run-down of registers to be programmed:
+	   destination pitch
+	   source pitch
+	   BLT width/height
+	   source start
+	   destination start
+	   BLT mode
+	   BLT ROP
+	   VGA_GFX_SR_VALUE / VGA_GFX_SR_ENABLE: "fill color"
+	   start/stop
+	 */
+
+	/* pitch: set to line_length */
+	vga_wgfx (regbase, CL_GR24, line_length & 0xff);	/* dest pitch low */
+	vga_wgfx (regbase, CL_GR25, (line_length >> 8));	/* dest pitch hi */
+	vga_wgfx (regbase, CL_GR26, line_length & 0xff);	/* source pitch low */
+	vga_wgfx (regbase, CL_GR27, (line_length >> 8));	/* source pitch hi */
+
+	/* BLT width: actual number of pixels - 1 */
+	vga_wgfx (regbase, CL_GR20, nwidth & 0xff);	/* BLT width low */
+	vga_wgfx (regbase, CL_GR21, (nwidth >> 8));	/* BLT width hi */
+
+	/* BLT height: actual number of lines -1 */
+	vga_wgfx (regbase, CL_GR22, nheight & 0xff);	/* BLT height low */
+	vga_wgfx (regbase, CL_GR23, (nheight >> 8));	/* BLT width hi */
+
+	/* BLT destination */
+	vga_wgfx (regbase, CL_GR28, (u_char) (ndest & 0xff));	/* BLT dest low */
+	vga_wgfx (regbase, CL_GR29, (u_char) (ndest >> 8));	/* BLT dest mid */
+	vga_wgfx (regbase, CL_GR2A, (u_char) (ndest >> 16));	/* BLT dest hi */
+
+	/* BLT source */
+	vga_wgfx (regbase, CL_GR2C, (u_char) (nsrc & 0xff));	/* BLT src low */
+	vga_wgfx (regbase, CL_GR2D, (u_char) (nsrc >> 8));		/* BLT src mid */
+	vga_wgfx (regbase, CL_GR2E, (u_char) (nsrc >> 16));	/* BLT src hi */
+
+	/* BLT mode */
+	vga_wgfx (regbase, CL_GR30, bltmode);	/* BLT mode */
+
+	/* BLT ROP: SrcCopy */
+	vga_wgfx (regbase, CL_GR32, 0x0d);		/* BLT ROP */
+
+	/* and finally: GO! */
+	vga_wgfx (regbase, CL_GR31, 0x02);		/* BLT Start/status */
+
+	DPRINTK ("EXIT\n");
+}
+
+
+/*******************************************************************
+	clgen_RectFill()
+
+	perform accelerated rectangle fill
+********************************************************************/
+
+static void clgen_RectFill (struct clgenfb_info *fb_info,
+		     u_short x, u_short y, u_short width, u_short height,
+		     u_char color, u_short line_length)
+{
+	u_short nwidth, nheight;
+	u_long ndest;
+	u_char op;
+
+	DPRINTK ("ENTER\n");
+
+	nwidth = width - 1;
+	nheight = height - 1;
+
+	ndest = (y * line_length) + x;
+
+        clgen_WaitBLT(fb_info->regs);
+
+	/* pitch: set to line_length */
+	vga_wgfx (fb_info->regs, CL_GR24, line_length & 0xff);	/* dest pitch low */
+	vga_wgfx (fb_info->regs, CL_GR25, (line_length >> 8));	/* dest pitch hi */
+	vga_wgfx (fb_info->regs, CL_GR26, line_length & 0xff);	/* source pitch low */
+	vga_wgfx (fb_info->regs, CL_GR27, (line_length >> 8));	/* source pitch hi */
+
+	/* BLT width: actual number of pixels - 1 */
+	vga_wgfx (fb_info->regs, CL_GR20, nwidth & 0xff);	/* BLT width low */
+	vga_wgfx (fb_info->regs, CL_GR21, (nwidth >> 8));	/* BLT width hi */
+
+	/* BLT height: actual number of lines -1 */
+	vga_wgfx (fb_info->regs, CL_GR22, nheight & 0xff);		/* BLT height low */
+	vga_wgfx (fb_info->regs, CL_GR23, (nheight >> 8));		/* BLT width hi */
+
+	/* BLT destination */
+	vga_wgfx (fb_info->regs, CL_GR28, (u_char) (ndest & 0xff));	/* BLT dest low */
+	vga_wgfx (fb_info->regs, CL_GR29, (u_char) (ndest >> 8));	/* BLT dest mid */
+	vga_wgfx (fb_info->regs, CL_GR2A, (u_char) (ndest >> 16));		/* BLT dest hi */
+
+	/* BLT source: set to 0 (is a dummy here anyway) */
+	vga_wgfx (fb_info->regs, CL_GR2C, 0x00);	/* BLT src low */
+	vga_wgfx (fb_info->regs, CL_GR2D, 0x00);	/* BLT src mid */
+	vga_wgfx (fb_info->regs, CL_GR2E, 0x00);	/* BLT src hi */
+
+	/* This is a ColorExpand Blt, using the */
+	/* same color for foreground and background */
+	vga_wgfx (fb_info->regs, VGA_GFX_SR_VALUE, color);	/* foreground color */
+	vga_wgfx (fb_info->regs, VGA_GFX_SR_ENABLE, color);	/* background color */
+
+	op = 0xc0;
+	if (fb_info->currentmode.var.bits_per_pixel == 16) {
+		vga_wgfx (fb_info->regs, CL_GR10, color);	/* foreground color */
+		vga_wgfx (fb_info->regs, CL_GR11, color);	/* background color */
+		op = 0x50;
+		op = 0xd0;
+	} else if (fb_info->currentmode.var.bits_per_pixel == 32) {
+		vga_wgfx (fb_info->regs, CL_GR10, color);	/* foreground color */
+		vga_wgfx (fb_info->regs, CL_GR11, color);	/* background color */
+		vga_wgfx (fb_info->regs, CL_GR12, color);	/* foreground color */
+		vga_wgfx (fb_info->regs, CL_GR13, color);	/* background color */
+		vga_wgfx (fb_info->regs, CL_GR14, 0);	/* foreground color */
+		vga_wgfx (fb_info->regs, CL_GR15, 0);	/* background color */
+		op = 0x50;
+		op = 0xf0;
+	}
+	/* BLT mode: color expand, Enable 8x8 copy (faster?) */
+	vga_wgfx (fb_info->regs, CL_GR30, op);	/* BLT mode */
+
+	/* BLT ROP: SrcCopy */
+	vga_wgfx (fb_info->regs, CL_GR32, 0x0d);	/* BLT ROP */
+
+	/* and finally: GO! */
+	vga_wgfx (fb_info->regs, CL_GR31, 0x02);	/* BLT Start/status */
+
+	DPRINTK ("EXIT\n");
+}
+
+
+/**************************************************************************
+ * bestclock() - determine closest possible clock lower(?) than the
+ * desired pixel clock
+ **************************************************************************/
+static void bestclock (long freq, long *best, long *nom,
+		       long *den, long *div, long maxfreq)
+{
+	long n, h, d, f;
+
+	assert (best != NULL);
+	assert (nom != NULL);
+	assert (den != NULL);
+	assert (div != NULL);
+	assert (maxfreq > 0);
+
+	*nom = 0;
+	*den = 0;
+	*div = 0;
+
+	DPRINTK ("ENTER\n");
+
+	if (freq < 8000)
+		freq = 8000;
+
+	if (freq > maxfreq)
+		freq = maxfreq;
+
+	*best = 0;
+	f = freq * 10;
+
+	for (n = 32; n < 128; n++) {
+		d = (143181 * n) / f;
+		if ((d >= 7) && (d <= 63)) {
+			if (d > 31)
+				d = (d / 2) * 2;
+			h = (14318 * n) / d;
+			if (abs (h - freq) < abs (*best - freq)) {
+				*best = h;
+				*nom = n;
+				if (d < 32) {
+					*den = d;
+					*div = 0;
+				} else {
+					*den = d / 2;
+					*div = 1;
+				}
+			}
+		}
+		d = ((143181 * n) + f - 1) / f;
+		if ((d >= 7) && (d <= 63)) {
+			if (d > 31)
+				d = (d / 2) * 2;
+			h = (14318 * n) / d;
+			if (abs (h - freq) < abs (*best - freq)) {
+				*best = h;
+				*nom = n;
+				if (d < 32) {
+					*den = d;
+					*div = 0;
+				} else {
+					*den = d / 2;
+					*div = 1;
+				}
+			}
+		}
+	}
+
+	DPRINTK ("Best possible values for given frequency:\n");
+	DPRINTK ("        best: %ld kHz  nom: %ld  den: %ld  div: %ld\n",
+		 freq, *nom, *den, *div);
+
+	DPRINTK ("EXIT\n");
+}
+
+
+/* -------------------------------------------------------------------------
+ *
+ * debugging functions
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifdef CLGEN_DEBUG
+
+/**
+ * clgen_dbg_print_byte
+ * @name: name associated with byte value to be displayed
+ * @val: byte value to be displayed
+ *
+ * DESCRIPTION:
+ * Display an indented string, along with a hexidecimal byte value, and
+ * its decoded bits.  Bits 7 through 0 are listed in left-to-right
+ * order.
+ */
+
+static
+void clgen_dbg_print_byte (const char *name, unsigned char val)
+{
+	DPRINTK ("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n",
+		 name, val,
+		 val & 0x80 ? '1' : '0',
+		 val & 0x40 ? '1' : '0',
+		 val & 0x20 ? '1' : '0',
+		 val & 0x10 ? '1' : '0',
+		 val & 0x08 ? '1' : '0',
+		 val & 0x04 ? '1' : '0',
+		 val & 0x02 ? '1' : '0',
+		 val & 0x01 ? '1' : '0');
+}
+
+
+/**
+ * clgen_dbg_print_regs
+ * @base: If using newmmio, the newmmio base address, otherwise %NULL
+ * @reg_class: type of registers to read: %CRT, or %SEQ
+ *
+ * DESCRIPTION:
+ * Dumps the given list of VGA CRTC registers.  If @base is %NULL,
+ * old-style I/O ports are queried for information, otherwise MMIO is
+ * used at the given @base address to query the information.
+ */
+
+static
+void clgen_dbg_print_regs (caddr_t regbase, clgen_dbg_reg_class_t reg_class,...)
+{
+	va_list list;
+	unsigned char val = 0;
+	unsigned reg;
+	char *name;
+
+	va_start (list, reg_class);
+
+	name = va_arg (list, char *);
+	while (name != NULL) {
+		reg = va_arg (list, int);
+
+		switch (reg_class) {
+		case CRT:
+			val = vga_rcrt (regbase, (unsigned char) reg);
+			break;
+		case SEQ:
+			val = vga_rseq (regbase, (unsigned char) reg);
+			break;
+		default:
+			/* should never occur */
+			assert (FALSE);
+			break;
+		}
+
+		clgen_dbg_print_byte (name, val);
+
+		name = va_arg (list, char *);
+	}
+
+	va_end (list);
+}
+
+
+/**
+ * clgen_dump
+ * @clgeninfo:
+ *
+ * DESCRIPTION:
+ */
+
+static
+void clgen_dump (void)
+{
+	clgen_dbg_reg_dump (NULL);
+}
+
+
+/**
+ * clgen_dbg_reg_dump
+ * @base: If using newmmio, the newmmio base address, otherwise %NULL
+ *
+ * DESCRIPTION:
+ * Dumps a list of interesting VGA and CLGEN registers.  If @base is %NULL,
+ * old-style I/O ports are queried for information, otherwise MMIO is
+ * used at the given @base address to query the information.
+ */
+
+static
+void clgen_dbg_reg_dump (caddr_t regbase)
+{
+	DPRINTK ("CLGEN VGA CRTC register dump:\n");
+
+	clgen_dbg_print_regs (regbase, CRT,
+			   "CR00", 0x00,
+			   "CR01", 0x01,
+			   "CR02", 0x02,
+			   "CR03", 0x03,
+			   "CR04", 0x04,
+			   "CR05", 0x05,
+			   "CR06", 0x06,
+			   "CR07", 0x07,
+			   "CR08", 0x08,
+			   "CR09", 0x09,
+			   "CR0A", 0x0A,
+			   "CR0B", 0x0B,
+			   "CR0C", 0x0C,
+			   "CR0D", 0x0D,
+			   "CR0E", 0x0E,
+			   "CR0F", 0x0F,
+			   "CR10", 0x10,
+			   "CR11", 0x11,
+			   "CR12", 0x12,
+			   "CR13", 0x13,
+			   "CR14", 0x14,
+			   "CR15", 0x15,
+			   "CR16", 0x16,
+			   "CR17", 0x17,
+			   "CR18", 0x18,
+			   "CR22", 0x22,
+			   "CR24", 0x24,
+			   "CR26", 0x26,
+			   "CR2D", 0x2D,
+			   "CR2E", 0x2E,
+			   "CR2F", 0x2F,
+			   "CR30", 0x30,
+			   "CR31", 0x31,
+			   "CR32", 0x32,
+			   "CR33", 0x33,
+			   "CR34", 0x34,
+			   "CR35", 0x35,
+			   "CR36", 0x36,
+			   "CR37", 0x37,
+			   "CR38", 0x38,
+			   "CR39", 0x39,
+			   "CR3A", 0x3A,
+			   "CR3B", 0x3B,
+			   "CR3C", 0x3C,
+			   "CR3D", 0x3D,
+			   "CR3E", 0x3E,
+			   "CR3F", 0x3F,
+			   NULL);
+
+	DPRINTK ("\n");
+
+	DPRINTK ("CLGEN VGA SEQ register dump:\n");
+
+	clgen_dbg_print_regs (regbase, SEQ,
+			   "SR00", 0x00,
+			   "SR01", 0x01,
+			   "SR02", 0x02,
+			   "SR03", 0x03,
+			   "SR04", 0x04,
+			   "SR08", 0x08,
+			   "SR09", 0x09,
+			   "SR0A", 0x0A,
+			   "SR0B", 0x0B,
+			   "SR0D", 0x0D,
+			   "SR10", 0x10,
+			   "SR11", 0x11,
+			   "SR12", 0x12,
+			   "SR13", 0x13,
+			   "SR14", 0x14,
+			   "SR15", 0x15,
+			   "SR16", 0x16,
+			   "SR17", 0x17,
+			   "SR18", 0x18,
+			   "SR19", 0x19,
+			   "SR1A", 0x1A,
+			   "SR1B", 0x1B,
+			   "SR1C", 0x1C,
+			   "SR1D", 0x1D,
+			   "SR1E", 0x1E,
+			   "SR1F", 0x1F,
+			   NULL);
+
+	DPRINTK ("\n");
+}
+
+#endif				/* CLGEN_DEBUG */
+
diff -Nru a/drivers/video/clgenfb.c b/drivers/video/clgenfb.c
--- a/drivers/video/clgenfb.c	Mon Oct 28 21:14:42 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,3546 +0,0 @@
-/*
- * drivers/video/clgenfb.c - driver for Cirrus Logic chipsets
- *
- * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com>
- *
- * Contributors (thanks, all!)
- *
- *      Jeff Rugen:
- *      Major contributions;  Motorola PowerStack (PPC and PCI) support,
- *      GD54xx, 1280x1024 mode support, change MCLK based on VCLK.
- *
- *	Geert Uytterhoeven:
- *	Excellent code review.
- *
- *	Lars Hecking:
- *	Amiga updates and testing.
- *
- * Original clgenfb author:  Frank Neumann
- *
- * Based on retz3fb.c and clgen.c:
- *      Copyright (C) 1997 Jes Sorensen
- *      Copyright (C) 1996 Frank Neumann
- *
- ***************************************************************
- *
- * Format this code with GNU indent '-kr -i8 -pcs' options.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive
- * for more details.
- *
- */
-
-#define CLGEN_VERSION "1.9.9.1"
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/selection.h>
-#include <asm/pgtable.h>
-
-#ifdef CONFIG_ZORRO
-#include <linux/zorro.h>
-#endif
-#ifdef CONFIG_PCI
-#include <linux/pci.h>
-#endif
-#ifdef CONFIG_AMIGA
-#include <asm/amigahw.h>
-#endif
-#ifdef CONFIG_ALL_PPC
-#include <asm/processor.h>
-#define isPReP (_machine == _MACH_prep)
-#else
-#define isPReP 0
-#endif
-
-#include <video/fbcon.h>
-#include <video/fbcon-mfb.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-
-#include "clgenfb.h"
-#include "vga.h"
-
-
-/*****************************************************************
- *
- * debugging and utility macros
- *
- */
-
-/* enable debug output? */
-/* #define CLGEN_DEBUG 1 */
-
-/* disable runtime assertions? */
-/* #define CLGEN_NDEBUG */
-
-/* debug output */
-#ifdef CLGEN_DEBUG
-#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
-#else
-#define DPRINTK(fmt, args...)
-#endif
-
-/* debugging assertions */
-#ifndef CLGEN_NDEBUG
-#define assert(expr) \
-        if(!(expr)) { \
-        printk( "Assertion failed! %s,%s,%s,line=%d\n",\
-        #expr,__FILE__,__FUNCTION__,__LINE__); \
-        }
-#else
-#define assert(expr)
-#endif
-
-#ifdef TRUE
-#undef TRUE
-#endif
-#ifdef FALSE
-#undef FALSE
-#endif
-#define TRUE  1
-#define FALSE 0
-
-#define MB_ (1024*1024)
-#define KB_ (1024)
-
-#define MAX_NUM_BOARDS 7
-
-
-/*****************************************************************
- *
- * chipset information
- *
- */
-
-/* board types */
-typedef enum {
-	BT_NONE = 0,
-	BT_SD64,
-	BT_PICCOLO,
-	BT_PICASSO,
-	BT_SPECTRUM,
-	BT_PICASSO4,	/* GD5446 */
-	BT_ALPINE,	/* GD543x/4x */
-	BT_GD5480,
-	BT_LAGUNA,	/* GD546x */
-} clgen_board_t;
-
-
-/*
- * per-board-type information, used for enumerating and abstracting
- * chip-specific information
- * NOTE: MUST be in the same order as clgen_board_t in order to
- * use direct indexing on this array
- * NOTE: '__initdata' cannot be used as some of this info
- * is required at runtime.  Maybe separate into an init-only and
- * a run-time table?
- */
-static const struct clgen_board_info_rec {
-	clgen_board_t btype;	/* chipset enum, not strictly necessary, as
-				 * clgen_board_info[] is directly indexed
-				 * by this value */
-	char *name;		/* ASCII name of chipset */
-	long maxclock;		/* maximum video clock */
-	unsigned init_sr07 : 1;	/* init SR07 during init_vgachip() */
-	unsigned init_sr1f : 1; /* write SR1F during init_vgachip() */
-	unsigned scrn_start_bit19 : 1; /* construct bit 19 of screen start address */
-
-	/* initial SR07 value, then for each mode */
-	unsigned char sr07;
-	unsigned char sr07_1bpp;
-	unsigned char sr07_1bpp_mux;
-	unsigned char sr07_8bpp;
-	unsigned char sr07_8bpp_mux;
-
-	unsigned char sr1f;	/* SR1F VGA initial register value */
-} clgen_board_info[] = {
-	{ BT_NONE, }, /* dummy record */
-	{ BT_SD64,
-		"CL SD64",
-		140000,		/* the SD64/P4 have a higher max. videoclock */
-		TRUE,
-		TRUE,
-		TRUE,
-		0xF0,
-		0xF0,
-		0,		/* unused, does not multiplex */
-		0xF1,
-		0,		/* unused, does not multiplex */
-		0x20 },
-	{ BT_PICCOLO,
-		"CL Piccolo",
-		90000,
-		TRUE,
-		TRUE,
-		FALSE,
-		0x80,
-		0x80,
-		0,		/* unused, does not multiplex */
-		0x81,
-		0,		/* unused, does not multiplex */
-		0x22 },
-	{ BT_PICASSO,
-		"CL Picasso",
-		90000,
-		TRUE,
-		TRUE,
-		FALSE,
-		0x20,
-		0x20,
-		0,		/* unused, does not multiplex */
-		0x21,
-		0,		/* unused, does not multiplex */
-		0x22 },
-	{ BT_SPECTRUM,
-		"CL Spectrum",
-		90000,
-		TRUE,
-		TRUE,
-		FALSE,
-		0x80,
-		0x80,
-		0,		/* unused, does not multiplex */
-		0x81,
-		0,		/* unused, does not multiplex */
-		0x22 },
-	{ BT_PICASSO4,
-		"CL Picasso4",
-		140000,		/* the SD64/P4 have a higher max. videoclock */
-		TRUE,
-		FALSE,
-		TRUE,
-		0x20,
-		0x20,
-		0,		/* unused, does not multiplex */
-		0x21,
-		0,		/* unused, does not multiplex */
-		0 },
-	{ BT_ALPINE,
-		"CL Alpine",
-		110000,		/* 135100 for some, 85500 for others */
-		TRUE,
-		TRUE,
-		TRUE,
-		0xA0,
-		0xA1,
-		0xA7,
-		0xA1,
-		0xA7,
-		0x1C },
-	{ BT_GD5480,
-		"CL GD5480",
-		90000,
-		TRUE,
-		TRUE,
-		TRUE,
-		0x10,
-		0x11,
-		0,		/* unused, does not multiplex */
-		0x11,
-		0,		/* unused, does not multiplex */
-		0x1C },
-	{ BT_LAGUNA,
-		"CL Laguna",
-		135100,
-		FALSE,
-		FALSE,
-		TRUE,
-		0,		/* unused */
-		0,		/* unused */
-		0,		/* unused */
-		0,		/* unused */
-		0,		/* unused */
-		0 },		/* unused */
-};
-
-
-#ifdef CONFIG_PCI
-/* the list of PCI devices for which we probe, and the
- * order in which we do it */
-static const struct {
-	clgen_board_t btype;
-	const char *nameOverride; /* XXX unused... for now */
-	unsigned short device;
-} clgen_pci_probe_list[] __initdata = {
-	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5436 },
-	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5434_8 },
-	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5434_4 },
-	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5430 }, /* GD-5440 has identical id */
-	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_7543 },
-	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_7548 },
-	{ BT_GD5480, NULL, PCI_DEVICE_ID_CIRRUS_5480 }, /* MacPicasso probably */
-	{ BT_PICASSO4, NULL, PCI_DEVICE_ID_CIRRUS_5446 }, /* Picasso 4 is a GD5446 */
-	{ BT_LAGUNA, "CL Laguna", PCI_DEVICE_ID_CIRRUS_5462 },
-	{ BT_LAGUNA, "CL Laguna 3D", PCI_DEVICE_ID_CIRRUS_5464 },
-	{ BT_LAGUNA, "CL Laguna 3DA", PCI_DEVICE_ID_CIRRUS_5465 },
-};
-#endif /* CONFIG_PCI */
-
-
-#ifdef CONFIG_ZORRO
-static const struct {
-	clgen_board_t btype;
-	zorro_id id, id2;
-	unsigned long size;
-} clgen_zorro_probe_list[] __initdata = {
-	{ BT_SD64,
-		ZORRO_PROD_HELFRICH_SD64_RAM,
-		ZORRO_PROD_HELFRICH_SD64_REG,
-		0x400000 },
-	{ BT_PICCOLO,
-		ZORRO_PROD_HELFRICH_PICCOLO_RAM,
-		ZORRO_PROD_HELFRICH_PICCOLO_REG,
-		0x200000 },
-	{ BT_PICASSO,
-		ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
-		ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
-		0x200000 },
-	{ BT_SPECTRUM,
-		ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
-		ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
-		0x200000 },
-	{ BT_PICASSO4,
-		ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
-		0,
-		0x400000 },
-};
-#endif /* CONFIG_ZORRO */
-
-
-
-struct clgenfb_par {
-	struct fb_var_screeninfo var;
-
-	__u32 line_length;	/* in BYTES! */
-	__u32 visual;
-	__u32 type;
-
-	long freq;
-	long nom;
-	long den;
-	long div;
-	long multiplexing;
-	long mclk;
-	long divMCLK;
-
-	long HorizRes;		/* The x resolution in pixel */
-	long HorizTotal;
-	long HorizDispEnd;
-	long HorizBlankStart;
-	long HorizBlankEnd;
-	long HorizSyncStart;
-	long HorizSyncEnd;
-
-	long VertRes;		/* the physical y resolution in scanlines */
-	long VertTotal;
-	long VertDispEnd;
-	long VertSyncStart;
-	long VertSyncEnd;
-	long VertBlankStart;
-	long VertBlankEnd;
-};
-
-
-
-#ifdef CLGEN_DEBUG
-typedef enum {
-        CRT,
-        SEQ
-} clgen_dbg_reg_class_t;
-#endif                          /* CLGEN_DEBUG */
-
-
-
-
-/* info about board */
-struct clgenfb_info {
-	struct fb_info_gen gen;
-
-	caddr_t fbmem;
-	caddr_t regs;
-	caddr_t mem;
-	unsigned long size;
-	clgen_board_t btype;
-	int smallboard;
-	unsigned char SFR;	/* Shadow of special function register */
-
-	unsigned long fbmem_phys;
-	unsigned long fbregs_phys;
-
-	struct clgenfb_par currentmode;
-
-	struct { u8 red, green, blue, pad; } palette[256];
-
-	union {
-#ifdef FBCON_HAS_CFB16
-		u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB24
-		u32 cfb24[16];
-#endif
-#ifdef FBCON_HAS_CFB32
-		u32 cfb32[16];
-#endif
-	} fbcon_cmap;
-
-#ifdef CONFIG_ZORRO
-	unsigned long board_addr,
-		      board_size;
-#endif
-
-#ifdef CONFIG_PCI
-	struct pci_dev *pdev;
-#endif
-};
-
-
-
-
-static struct display disp;
-
-static struct clgenfb_info boards[MAX_NUM_BOARDS];	/* the boards */
-
-static unsigned clgen_def_mode = 1;
-static int noaccel = 0;
-
-
-
-/*
- *    Predefined Video Modes
- */
-
-static const struct {
-	const char *name;
-	struct fb_var_screeninfo var;
-} clgenfb_predefined[] __initdata =
-
-{
-	{"Autodetect",		/* autodetect mode */
-	 {0}
-	},
-
-	{"640x480",		/* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */
-	 {
-		 640, 480, 640, 480, 0, 0, 8, 0,
-		 {0, 8, 0},
-		 {0, 8, 0},
-		 {0, 8, 0},
-		 {0, 0, 0},
-	       0, 0, -1, -1, FB_ACCEL_NONE, 40000, 48, 16, 32, 8, 96, 4,
-     FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-	 }
-	},
-
-	{"800x600",		/* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */
-	 {
-		 800, 600, 800, 600, 0, 0, 8, 0,
-		 {0, 8, 0},
-		 {0, 8, 0},
-		 {0, 8, 0},
-		 {0, 0, 0},
-	       0, 0, -1, -1, FB_ACCEL_NONE, 20000, 128, 16, 24, 2, 96, 6,
-     0, FB_VMODE_NONINTERLACED
-	 }
-	},
-
-	/*
-	   Modeline from XF86Config:
-	   Mode "1024x768" 80  1024 1136 1340 1432  768 770 774 805
-	 */
-	{"1024x768",		/* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */
-		{
-			1024, 768, 1024, 768, 0, 0, 8, 0,
-			{0, 8, 0},
-			{0, 8, 0},
-			{0, 8, 0},
-			{0, 0, 0},
-	      0, 0, -1, -1, FB_ACCEL_NONE, 12500, 144, 32, 30, 2, 192, 6,
-     0, FB_VMODE_NONINTERLACED
-		}
-	}
-};
-
-#define NUM_TOTAL_MODES    ARRAY_SIZE(clgenfb_predefined)
-static struct fb_var_screeninfo clgenfb_default;
-
-/*
- *    Frame Buffer Name
- */
-
-static const char *clgenfb_name = "CLgen";
-
-/****************************************************************************/
-/**** BEGIN PROTOTYPES ******************************************************/
-
-
-/*--- Interface used by the world ------------------------------------------*/
-int clgenfb_init (void);
-int clgenfb_setup (char *options);
-
-static int clgenfb_open (struct fb_info *info, int user);
-static int clgenfb_release (struct fb_info *info, int user);
-
-static int clgenfb_setcolreg (unsigned regno, unsigned red, unsigned green,
-			      unsigned blue, unsigned transp,
-			      struct fb_info *info);
-
-/* function table of the above functions */
-static struct fb_ops clgenfb_ops = {
-	.owner =	THIS_MODULE,
-	.fb_open =	clgenfb_open,
-	.fb_release =	clgenfb_release,
-	.fb_get_fix =	fbgen_get_fix,
-	.fb_get_var =	fbgen_get_var,
-	.fb_set_var =	fbgen_set_var,
-	.fb_get_cmap =	fbgen_get_cmap,
-	.fb_set_cmap =	gen_set_cmap,
-	.fb_setcolreg =	clgenfb_setcolreg,
-	.fb_pan_display =fbgen_pan_display,
-	.fb_blank =	fbgen_blank,
-};
-
-/*--- Hardware Specific Routines -------------------------------------------*/
-static void clgen_detect (void);
-static int clgen_encode_fix (struct fb_fix_screeninfo *fix, const void *par,
-			     struct fb_info_gen *info);
-static int clgen_decode_var (const struct fb_var_screeninfo *var, void *par,
-			     struct fb_info_gen *info);
-static int clgen_encode_var (struct fb_var_screeninfo *var, const void *par,
-			     struct fb_info_gen *info);
-static void clgen_get_par (void *par, struct fb_info_gen *info);
-static void clgen_set_par (const void *par, struct fb_info_gen *info);
-static int clgen_getcolreg (unsigned regno, unsigned *red, unsigned *green,
-			    unsigned *blue, unsigned *transp,
-			    struct fb_info *info);
-static int clgen_pan_display (const struct fb_var_screeninfo *var,
-			      struct fb_info_gen *info);
-static int clgen_blank (int blank_mode, struct fb_info_gen *info);
-
-static void clgen_set_disp (const void *par, struct display *disp,
-			    struct fb_info_gen *info);
-
-/* function table of the above functions */
-static struct fbgen_hwswitch clgen_hwswitch =
-{
-	clgen_detect,
-	clgen_encode_fix,
-	clgen_decode_var,
-	clgen_encode_var,
-	clgen_get_par,
-	clgen_set_par,
-	clgen_getcolreg,
-	clgen_pan_display,
-	clgen_blank,
-	clgen_set_disp
-};
-
-/* Text console acceleration */
-
-#ifdef FBCON_HAS_CFB8
-static void fbcon_clgen8_bmove (struct display *p, int sy, int sx,
-				int dy, int dx, int height, int width);
-static void fbcon_clgen8_clear (struct vc_data *conp, struct display *p,
-				int sy, int sx, int height, int width);
-
-static struct display_switch fbcon_clgen_8 = {
-	.setup =	fbcon_cfb8_setup,
-	.bmove =	fbcon_clgen8_bmove,
-	.clear =	fbcon_clgen8_clear,
-	.putc =		fbcon_cfb8_putc,
-	.putcs =	fbcon_cfb8_putcs,
-	.revc =		fbcon_cfb8_revc,
-	.clear_margins =fbcon_cfb8_clear_margins,
-	.fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
-};
-#endif
-#ifdef FBCON_HAS_CFB16
-static void fbcon_clgen16_bmove (struct display *p, int sy, int sx,
-				 int dy, int dx, int height, int width);
-static void fbcon_clgen16_clear (struct vc_data *conp, struct display *p,
-				 int sy, int sx, int height, int width);
-static struct display_switch fbcon_clgen_16 = {
-	.setup =	fbcon_cfb16_setup,
-	.bmove =	fbcon_clgen16_bmove,
-	.clear =	fbcon_clgen16_clear,
-	.putc =		fbcon_cfb16_putc,
-	.putcs =	fbcon_cfb16_putcs,
-	.revc =		fbcon_cfb16_revc,
-	.clear_margins =fbcon_cfb16_clear_margins,
-	.fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
-};
-#endif
-#ifdef FBCON_HAS_CFB32
-static void fbcon_clgen32_bmove (struct display *p, int sy, int sx,
-				 int dy, int dx, int height, int width);
-static void fbcon_clgen32_clear (struct vc_data *conp, struct display *p,
-				 int sy, int sx, int height, int width);
-static struct display_switch fbcon_clgen_32 = {
-	.setup =	fbcon_cfb32_setup,
-	.bmove =	fbcon_clgen32_bmove,
-	.clear =	fbcon_clgen32_clear,
-	.putc =		fbcon_cfb32_putc,
-	.putcs =	fbcon_cfb32_putcs,
-	.revc =		fbcon_cfb32_revc,
-	.clear_margins =fbcon_cfb32_clear_margins,
-	.fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
-};
-#endif
-
-
-
-/*--- Internal routines ----------------------------------------------------*/
-static void init_vgachip (struct clgenfb_info *fb_info);
-static void switch_monitor (struct clgenfb_info *fb_info, int on);
-static void WGen (const struct clgenfb_info *fb_info,
-		  int regnum, unsigned char val);
-static unsigned char RGen (const struct clgenfb_info *fb_info, int regnum);
-static void AttrOn (const struct clgenfb_info *fb_info);
-static void WHDR (const struct clgenfb_info *fb_info, unsigned char val);
-static void WSFR (struct clgenfb_info *fb_info, unsigned char val);
-static void WSFR2 (struct clgenfb_info *fb_info, unsigned char val);
-static void WClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char red,
-		   unsigned char green,
-		   unsigned char blue);
-#if 0
-static void RClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char *red,
-		   unsigned char *green,
-		   unsigned char *blue);
-#endif
-static void clgen_WaitBLT (caddr_t regbase);
-static void clgen_BitBLT (caddr_t regbase, u_short curx, u_short cury,
-			  u_short destx, u_short desty,
-			  u_short width, u_short height,
-			  u_short line_length);
-static void clgen_RectFill (struct clgenfb_info *fb_info, u_short x, u_short y,
-			    u_short width, u_short height,
-			    u_char color, u_short line_length);
-
-static void bestclock (long freq, long *best,
-		       long *nom, long *den,
-		       long *div, long maxfreq);
-
-#ifdef CLGEN_DEBUG
-static void clgen_dump (void);
-static void clgen_dbg_reg_dump (caddr_t regbase);
-static void clgen_dbg_print_regs (caddr_t regbase, clgen_dbg_reg_class_t reg_class,...);
-static void clgen_dbg_print_byte (const char *name, unsigned char val);
-#endif /* CLGEN_DEBUG */
-
-/*** END   PROTOTYPES ********************************************************/
-/*****************************************************************************/
-/*** BEGIN Interface Used by the World ***************************************/
-
-static int opencount = 0;
-
-/*--- Open /dev/fbx ---------------------------------------------------------*/
-static int clgenfb_open (struct fb_info *info, int user)
-{
-	if (opencount++ == 0)
-		switch_monitor ((struct clgenfb_info *) info, 1);
-	return 0;
-}
-
-/*--- Close /dev/fbx --------------------------------------------------------*/
-static int clgenfb_release (struct fb_info *info, int user)
-{
-	if (--opencount == 0)
-		switch_monitor ((struct clgenfb_info *) info, 0);
-	return 0;
-}
-
-/**** END   Interface used by the World *************************************/
-/****************************************************************************/
-/**** BEGIN Hardware specific Routines **************************************/
-
-static void clgen_detect (void)
-{
-	DPRINTK ("ENTER\n");
-	DPRINTK ("EXIT\n");
-}
-
-static int clgen_encode_fix (struct fb_fix_screeninfo *fix, const void *par,
-			     struct fb_info_gen *info)
-{
-	struct clgenfb_par *_par = (struct clgenfb_par *) par;
-	struct clgenfb_info *_info = (struct clgenfb_info *) info;
-
-	DPRINTK ("ENTER\n");
-
-	memset (fix, 0, sizeof (struct fb_fix_screeninfo));
-	strcpy (fix->id, clgenfb_name);
-
-	if (_info->btype == BT_GD5480) {
-		/* Select proper byte-swapping aperture */
-		switch (_par->var.bits_per_pixel) {
-		case 1:
-		case 8:
-			fix->smem_start = _info->fbmem_phys;
-			break;
-		case 16:
-			fix->smem_start = _info->fbmem_phys + 1 * MB_;
-			break;
-		case 24:
-		case 32:
-			fix->smem_start = _info->fbmem_phys + 2 * MB_;
-			break;
-		}
-	} else {
-		fix->smem_start = _info->fbmem_phys;
-	}
-
-	/* monochrome: only 1 memory plane */
-	/* 8 bit and above: Use whole memory area */
-	fix->smem_len = _par->var.bits_per_pixel == 1 ? _info->size / 4
-	    : _info->size;
-	fix->type = _par->type;
-	fix->type_aux = 0;
-	fix->visual = _par->visual;
-	fix->xpanstep = 1;
-	fix->ypanstep = 1;
-	fix->ywrapstep = 0;
-	fix->line_length = _par->line_length;
-
-	/* FIXME: map region at 0xB8000 if available, fill in here */
-	fix->mmio_start = 0;
-	fix->mmio_len = 0;
-	fix->accel = FB_ACCEL_NONE;
-
-	DPRINTK ("EXIT\n");
-	return 0;
-}
-
-
-
-/* Get a good MCLK value */
-static long clgen_get_mclk (long freq, int bpp, long *div)
-{
-	long mclk;
-
-	assert (div != NULL);
-
-	/* Calculate MCLK, in case VCLK is high enough to require > 50MHz.
-	 * Assume a 64-bit data path for now.  The formula is:
-	 * ((B * PCLK * 2)/W) * 1.2
-	 * B = bytes per pixel, PCLK = pixclock, W = data width in bytes */
-	mclk = ((bpp / 8) * freq * 2) / 4;
-	mclk = (mclk * 12) / 10;
-	if (mclk < 50000)
-		mclk = 50000;
-	DPRINTK ("Use MCLK of %ld kHz\n", mclk);
-
-	/* Calculate value for SR1F.  Multiply by 2 so we can round up. */
-	mclk = ((mclk * 16) / 14318);
-	mclk = (mclk + 1) / 2;
-	DPRINTK ("Set SR1F[5:0] to 0x%lx\n", mclk);
-
-	/* Determine if we should use MCLK instead of VCLK, and if so, what we
-	   * should divide it by to get VCLK */
-	switch (freq) {
-	case 24751 ... 25249:
-		*div = 2;
-		DPRINTK ("Using VCLK = MCLK/2\n");
-		break;
-	case 49501 ... 50499:
-		*div = 1;
-		DPRINTK ("Using VCLK = MCLK\n");
-		break;
-	default:
-		*div = 0;
-		break;
-	}
-
-	return mclk;
-}
-
-static int clgen_decode_var (const struct fb_var_screeninfo *var, void *par,
-			     struct fb_info_gen *info)
-{
-	long freq;
-	long maxclock;
-	int xres, hfront, hsync, hback;
-	int yres, vfront, vsync, vback;
-	int nom, den;		/* translyting from pixels->bytes */
-	int i;
-	static struct {
-		int xres, yres;
-	} modes[] = { {
-			1600, 1280
-	}, {
-		1280, 1024
-	}, {
-		1024, 768
-	},
-	{
-		800, 600
-	}, {
-		640, 480
-	}, {
-		-1, -1
-	}
-	};
-
-	struct clgenfb_par *_par = (struct clgenfb_par *) par;
-	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
-
-	assert (var != NULL);
-	assert (par != NULL);
-	assert (info != NULL);
-
-	DPRINTK ("ENTER\n");
-
-	DPRINTK ("Requested: %dx%dx%d\n", var->xres, var->yres, var->bits_per_pixel);
-	DPRINTK ("  virtual: %dx%d\n", var->xres_virtual, var->yres_virtual);
-	DPRINTK ("   offset: (%d,%d)\n", var->xoffset, var->yoffset);
-	DPRINTK ("grayscale: %d\n", var->grayscale);
-
-	memset (par, 0, sizeof (struct clgenfb_par));
-
-	_par->var = *var;
-
-	switch (var->bits_per_pixel) {
-	case 1:
-		nom = 4;
-		den = 8;
-		break;		/* 8 pixel per byte, only 1/4th of mem usable */
-	case 2 ... 8:
-		_par->var.bits_per_pixel = 8;
-		nom = 1;
-		den = 1;
-		break;		/* 1 pixel == 1 byte */
-	case 9 ... 16:
-		_par->var.bits_per_pixel = 16;
-		nom = 2;
-		den = 1;
-		break;		/* 2 bytes per pixel */
-	case 17 ... 24:
-		_par->var.bits_per_pixel = 24;
-		nom = 3;
-		den = 1;
-		break;		/* 3 bytes per pixel */
-	case 25 ... 32:
-		_par->var.bits_per_pixel = 32;
-		nom = 4;
-		den = 1;
-		break;		/* 4 bytes per pixel */
-	default:
-		printk ("clgen: mode %dx%dx%d rejected...color depth not supported.\n",
-			var->xres, var->yres, var->bits_per_pixel);
-		DPRINTK ("EXIT - EINVAL error\n");
-		return -EINVAL;
-	}
-
-	if (_par->var.xres * nom / den * _par->var.yres > fb_info->size) {
-		printk ("clgen: mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
-			var->xres, var->yres, var->bits_per_pixel);
-		DPRINTK ("EXIT - EINVAL error\n");
-		return -EINVAL;
-	}
-	/* use highest possible virtual resolution */
-	if (_par->var.xres_virtual == -1 &&
-	    _par->var.yres_virtual == -1) {
-		printk ("clgen: using maximum available virtual resolution\n");
-		for (i = 0; modes[i].xres != -1; i++) {
-			if (modes[i].xres * nom / den * modes[i].yres < fb_info->size / 2)
-				break;
-		}
-		if (modes[i].xres == -1) {
-			printk ("clgen: could not find a virtual resolution that fits into video memory!!\n");
-			DPRINTK ("EXIT - EINVAL error\n");
-			return -EINVAL;
-		}
-		_par->var.xres_virtual = modes[i].xres;
-		_par->var.yres_virtual = modes[i].yres;
-
-		printk ("clgen: virtual resolution set to maximum of %dx%d\n",
-			_par->var.xres_virtual, _par->var.yres_virtual);
-	} else if (_par->var.xres_virtual == -1) {
-		/* FIXME: maximize X virtual resolution only */
-	} else if (_par->var.yres_virtual == -1) {
-		/* FIXME: maximize Y virtual resolution only */
-	}
-	if (_par->var.xoffset < 0)
-		_par->var.xoffset = 0;
-	if (_par->var.yoffset < 0)
-		_par->var.yoffset = 0;
-
-	/* truncate xoffset and yoffset to maximum if too high */
-	if (_par->var.xoffset > _par->var.xres_virtual - _par->var.xres)
-		_par->var.xoffset = _par->var.xres_virtual - _par->var.xres - 1;
-
-	if (_par->var.yoffset > _par->var.yres_virtual - _par->var.yres)
-		_par->var.yoffset = _par->var.yres_virtual - _par->var.yres - 1;
-
-	switch (_par->var.bits_per_pixel) {
-	case 1:
-		_par->line_length = _par->var.xres_virtual / 8;
-		_par->visual = FB_VISUAL_MONO10;
-		break;
-
-	case 8:
-		_par->line_length = _par->var.xres_virtual;
-		_par->visual = FB_VISUAL_PSEUDOCOLOR;
-		_par->var.red.offset = 0;
-		_par->var.red.length = 6;
-		_par->var.green.offset = 0;
-		_par->var.green.length = 6;
-		_par->var.blue.offset = 0;
-		_par->var.blue.length = 6;
-		break;
-
-	case 16:
-		_par->line_length = _par->var.xres_virtual * 2;
-		_par->visual = FB_VISUAL_DIRECTCOLOR;
-		if(isPReP) {
-			_par->var.red.offset = 2;
-			_par->var.green.offset = -3;
-			_par->var.blue.offset = 8;
-		} else {
-			_par->var.red.offset = 10;
-			_par->var.green.offset = 5;
-			_par->var.blue.offset = 0;
-		}
-		_par->var.red.length = 5;
-		_par->var.green.length = 5;
-		_par->var.blue.length = 5;
-		break;
-
-	case 24:
-		_par->line_length = _par->var.xres_virtual * 3;
-		_par->visual = FB_VISUAL_DIRECTCOLOR;
-		if(isPReP) {
-			_par->var.red.offset = 8;
-			_par->var.green.offset = 16;
-			_par->var.blue.offset = 24;
-		} else {
-			_par->var.red.offset = 16;
-			_par->var.green.offset = 8;
-			_par->var.blue.offset = 0;
-		}
-		_par->var.red.length = 8;
-		_par->var.green.length = 8;
-		_par->var.blue.length = 8;
-		break;
-
-	case 32:
-		_par->line_length = _par->var.xres_virtual * 4;
-		_par->visual = FB_VISUAL_DIRECTCOLOR;
-		if(isPReP) {
-			_par->var.red.offset = 8;
-			_par->var.green.offset = 16;
-			_par->var.blue.offset = 24;
-		} else {
-			_par->var.red.offset = 16;
-			_par->var.green.offset = 8;
-			_par->var.blue.offset = 0;
-		}
-		_par->var.red.length = 8;
-		_par->var.green.length = 8;
-		_par->var.blue.length = 8;
-		break;
-
-	default:
-		DPRINTK("Unsupported bpp size: %d\n", _par->var.bits_per_pixel);
-		assert (FALSE);
-		/* should never occur */
-		break;
-	}
-
-	_par->var.red.msb_right =
-	    _par->var.green.msb_right =
-	    _par->var.blue.msb_right =
-	    _par->var.transp.offset =
-	    _par->var.transp.length =
-	    _par->var.transp.msb_right = 0;
-
-	_par->type = FB_TYPE_PACKED_PIXELS;
-
-	/* convert from ps to kHz */
-	freq = 1000000000 / var->pixclock;
-
-	DPRINTK ("desired pixclock: %ld kHz\n", freq);
-
-	maxclock = clgen_board_info[fb_info->btype].maxclock;
-	_par->multiplexing = 0;
-
-	/* If the frequency is greater than we can support, we might be able
-	 * to use multiplexing for the video mode */
-	if (freq > maxclock) {
-		switch (fb_info->btype) {
-		case BT_ALPINE:
-		case BT_GD5480:
-			_par->multiplexing = 1;
-			break;
-
-		default:
-			printk (KERN_WARNING "clgen: ERROR: Frequency greater than maxclock (%ld kHz)\n", maxclock);
-			DPRINTK ("EXIT - return -EINVAL\n");
-			return -EINVAL;
-		}
-	}
-#if 0
-	/* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where
-	 * the VCLK is double the pixel clock. */
-	switch (var->bits_per_pixel) {
-	case 16:
-	case 32:
-		if (_par->HorizRes <= 800)
-			freq /= 2;	/* Xbh has this type of clock for 32-bit */
-		break;
-	}
-#endif
-
-	bestclock (freq, &_par->freq, &_par->nom, &_par->den, &_par->div,
-		   maxclock);
-	_par->mclk = clgen_get_mclk (freq, _par->var.bits_per_pixel, &_par->divMCLK);
-
-	xres = _par->var.xres;
-	hfront = _par->var.right_margin;
-	hsync = _par->var.hsync_len;
-	hback = _par->var.left_margin;
-
-	yres = _par->var.yres;
-	vfront = _par->var.lower_margin;
-	vsync = _par->var.vsync_len;
-	vback = _par->var.upper_margin;
-
-	if (_par->var.vmode & FB_VMODE_DOUBLE) {
-		yres *= 2;
-		vfront *= 2;
-		vsync *= 2;
-		vback *= 2;
-	} else if (_par->var.vmode & FB_VMODE_INTERLACED) {
-		yres = (yres + 1) / 2;
-		vfront = (vfront + 1) / 2;
-		vsync = (vsync + 1) / 2;
-		vback = (vback + 1) / 2;
-	}
-	_par->HorizRes = xres;
-	_par->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5;
-	_par->HorizDispEnd = xres / 8 - 1;
-	_par->HorizBlankStart = xres / 8;
-	_par->HorizBlankEnd = _par->HorizTotal + 5;	/* does not count with "-5" */
-	_par->HorizSyncStart = (xres + hfront) / 8 + 1;
-	_par->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1;
-
-	_par->VertRes = yres;
-	_par->VertTotal = yres + vfront + vsync + vback - 2;
-	_par->VertDispEnd = yres - 1;
-	_par->VertBlankStart = yres;
-	_par->VertBlankEnd = _par->VertTotal;
-	_par->VertSyncStart = yres + vfront - 1;
-	_par->VertSyncEnd = yres + vfront + vsync - 1;
-
-	if (_par->VertRes >= 1024) {
-		_par->VertTotal /= 2;
-		_par->VertSyncStart /= 2;
-		_par->VertSyncEnd /= 2;
-		_par->VertDispEnd /= 2;
-	}
-	if (_par->multiplexing) {
-		_par->HorizTotal /= 2;
-		_par->HorizSyncStart /= 2;
-		_par->HorizSyncEnd /= 2;
-		_par->HorizDispEnd /= 2;
-	}
-	if (_par->VertRes >= 1280) {
-		printk (KERN_WARNING "clgen: ERROR: VerticalTotal >= 1280; special treatment required! (TODO)\n");
-		DPRINTK ("EXIT - EINVAL error\n");
-		return -EINVAL;
-	}
-	DPRINTK ("EXIT\n");
-	return 0;
-}
-
-
-static int clgen_encode_var (struct fb_var_screeninfo *var, const void *par,
-			     struct fb_info_gen *info)
-{
-	DPRINTK ("ENTER\n");
-
-	*var = ((struct clgenfb_par *) par)->var;
-
-	DPRINTK ("EXIT\n");
-	return 0;
-}
-
-/* get current video mode */
-static void clgen_get_par (void *par, struct fb_info_gen *info)
-{
-	struct clgenfb_par *_par = (struct clgenfb_par *) par;
-	struct clgenfb_info *_info = (struct clgenfb_info *) info;
-
-	DPRINTK ("ENTER\n");
-
-	*_par = _info->currentmode;
-
-	DPRINTK ("EXIT\n");
-}
-
-static void clgen_set_mclk (const struct clgenfb_info *fb_info, int val, int div)
-{
-	assert (fb_info != NULL);
-
-	if (div == 2) {
-		/* VCLK = MCLK/2 */
-		unsigned char old = vga_rseq (fb_info->regs, CL_SEQR1E);
-		vga_wseq (fb_info->regs, CL_SEQR1E, old | 0x1);
-		vga_wseq (fb_info->regs, CL_SEQR1F, 0x40 | (val & 0x3f));
-	} else if (div == 1) {
-		/* VCLK = MCLK */
-		unsigned char old = vga_rseq (fb_info->regs, CL_SEQR1E);
-		vga_wseq (fb_info->regs, CL_SEQR1E, old & ~0x1);
-		vga_wseq (fb_info->regs, CL_SEQR1F, 0x40 | (val & 0x3f));
-	} else {
-		vga_wseq (fb_info->regs, CL_SEQR1F, val & 0x3f);
-	}
-}
-
-/*************************************************************************
-	clgen_set_par()
-
-	actually writes the values for a new video mode into the hardware,
-**************************************************************************/
-static void clgen_set_par (const void *par, struct fb_info_gen *info)
-{
-	unsigned char tmp;
-	int offset = 0;
-	struct clgenfb_par *_par = (struct clgenfb_par *) par;
-	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
-	const struct clgen_board_info_rec *bi;
-
-	DPRINTK ("ENTER\n");
-	DPRINTK ("Requested mode: %dx%dx%d\n",
-	       _par->var.xres, _par->var.yres, _par->var.bits_per_pixel);
-	DPRINTK ("pixclock: %d\n", _par->var.pixclock);
-
-	bi = &clgen_board_info[fb_info->btype];
-
-
-	/* unlock register VGA_CRTC_H_TOTAL..CRT7 */
-	vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, 0x20);	/* previously: 0x00) */
-
-	/* if debugging is enabled, all parameters get output before writing */
-	DPRINTK ("CRT0: %ld\n", _par->HorizTotal);
-	vga_wcrt (fb_info->regs, VGA_CRTC_H_TOTAL, _par->HorizTotal);
-
-	DPRINTK ("CRT1: %ld\n", _par->HorizDispEnd);
-	vga_wcrt (fb_info->regs, VGA_CRTC_H_DISP, _par->HorizDispEnd);
-
-	DPRINTK ("CRT2: %ld\n", _par->HorizBlankStart);
-	vga_wcrt (fb_info->regs, VGA_CRTC_H_BLANK_START, _par->HorizBlankStart);
-
-	DPRINTK ("CRT3: 128+%ld\n", _par->HorizBlankEnd % 32);	/*  + 128: Compatible read */
-	vga_wcrt (fb_info->regs, VGA_CRTC_H_BLANK_END, 128 + (_par->HorizBlankEnd % 32));
-
-	DPRINTK ("CRT4: %ld\n", _par->HorizSyncStart);
-	vga_wcrt (fb_info->regs, VGA_CRTC_H_SYNC_START, _par->HorizSyncStart);
-
-	tmp = _par->HorizSyncEnd % 32;
-	if (_par->HorizBlankEnd & 32)
-		tmp += 128;
-	DPRINTK ("CRT5: %d\n", tmp);
-	vga_wcrt (fb_info->regs, VGA_CRTC_H_SYNC_END, tmp);
-
-	DPRINTK ("CRT6: %ld\n", _par->VertTotal & 0xff);
-	vga_wcrt (fb_info->regs, VGA_CRTC_V_TOTAL, (_par->VertTotal & 0xff));
-
-	tmp = 16;		/* LineCompare bit #9 */
-	if (_par->VertTotal & 256)
-		tmp |= 1;
-	if (_par->VertDispEnd & 256)
-		tmp |= 2;
-	if (_par->VertSyncStart & 256)
-		tmp |= 4;
-	if (_par->VertBlankStart & 256)
-		tmp |= 8;
-	if (_par->VertTotal & 512)
-		tmp |= 32;
-	if (_par->VertDispEnd & 512)
-		tmp |= 64;
-	if (_par->VertSyncStart & 512)
-		tmp |= 128;
-	DPRINTK ("CRT7: %d\n", tmp);
-	vga_wcrt (fb_info->regs, VGA_CRTC_OVERFLOW, tmp);
-
-	tmp = 0x40;		/* LineCompare bit #8 */
-	if (_par->VertBlankStart & 512)
-		tmp |= 0x20;
-	if (_par->var.vmode & FB_VMODE_DOUBLE)
-		tmp |= 0x80;
-	DPRINTK ("CRT9: %d\n", tmp);
-	vga_wcrt (fb_info->regs, VGA_CRTC_MAX_SCAN, tmp);
-
-	DPRINTK ("CRT10: %ld\n", _par->VertSyncStart & 0xff);
-	vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_START, (_par->VertSyncStart & 0xff));
-
-	DPRINTK ("CRT11: 64+32+%ld\n", _par->VertSyncEnd % 16);
-	vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, (_par->VertSyncEnd % 16 + 64 + 32));
-
-	DPRINTK ("CRT12: %ld\n", _par->VertDispEnd & 0xff);
-	vga_wcrt (fb_info->regs, VGA_CRTC_V_DISP_END, (_par->VertDispEnd & 0xff));
-
-	DPRINTK ("CRT15: %ld\n", _par->VertBlankStart & 0xff);
-	vga_wcrt (fb_info->regs, VGA_CRTC_V_BLANK_START, (_par->VertBlankStart & 0xff));
-
-	DPRINTK ("CRT16: %ld\n", _par->VertBlankEnd & 0xff);
-	vga_wcrt (fb_info->regs, VGA_CRTC_V_BLANK_END, (_par->VertBlankEnd & 0xff));
-
-	DPRINTK ("CRT18: 0xff\n");
-	vga_wcrt (fb_info->regs, VGA_CRTC_LINE_COMPARE, 0xff);
-
-	tmp = 0;
-	if (_par->var.vmode & FB_VMODE_INTERLACED)
-		tmp |= 1;
-	if (_par->HorizBlankEnd & 64)
-		tmp |= 16;
-	if (_par->HorizBlankEnd & 128)
-		tmp |= 32;
-	if (_par->VertBlankEnd & 256)
-		tmp |= 64;
-	if (_par->VertBlankEnd & 512)
-		tmp |= 128;
-
-	DPRINTK ("CRT1a: %d\n", tmp);
-	vga_wcrt (fb_info->regs, CL_CRT1A, tmp);
-
-	/* set VCLK0 */
-	/* hardware RefClock: 14.31818 MHz */
-	/* formula: VClk = (OSC * N) / (D * (1+P)) */
-	/* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
-
-	vga_wseq (fb_info->regs, CL_SEQRB, _par->nom);
-	tmp = _par->den << 1;
-	if (_par->div != 0)
-		tmp |= 1;
-
-	if ((fb_info->btype == BT_SD64) ||
-	    (fb_info->btype == BT_ALPINE) ||
-	    (fb_info->btype == BT_GD5480))
-		tmp |= 0x80;	/* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
-
-	DPRINTK ("CL_SEQR1B: %ld\n", (long) tmp);
-	vga_wseq (fb_info->regs, CL_SEQR1B, tmp);
-
-	if (_par->VertRes >= 1024)
-		/* 1280x1024 */
-		vga_wcrt (fb_info->regs, VGA_CRTC_MODE, 0xc7);
-	else
-		/* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
-		 * address wrap, no compat. */
-		vga_wcrt (fb_info->regs, VGA_CRTC_MODE, 0xc3);
-
-/* HAEH?        vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, 0x20);  * previously: 0x00  unlock VGA_CRTC_H_TOTAL..CRT7 */
-
-	/* don't know if it would hurt to also program this if no interlaced */
-	/* mode is used, but I feel better this way.. :-) */
-	if (_par->var.vmode & FB_VMODE_INTERLACED)
-		vga_wcrt (fb_info->regs, VGA_CRTC_REGS, _par->HorizTotal / 2);
-	else
-		vga_wcrt (fb_info->regs, VGA_CRTC_REGS, 0x00);	/* interlace control */
-
-	vga_wseq (fb_info->regs, VGA_SEQ_CHARACTER_MAP, 0);
-
-	/* adjust horizontal/vertical sync type (low/high) */
-	tmp = 0x03;		/* enable display memory & CRTC I/O address for color mode */
-	if (_par->var.sync & FB_SYNC_HOR_HIGH_ACT)
-		tmp |= 0x40;
-	if (_par->var.sync & FB_SYNC_VERT_HIGH_ACT)
-		tmp |= 0x80;
-	WGen (fb_info, VGA_MIS_W, tmp);
-
-	vga_wcrt (fb_info->regs, VGA_CRTC_PRESET_ROW, 0);	/* Screen A Preset Row-Scan register */
-	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_START, 0);	/* text cursor on and start line */
-	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_END, 31);	/* text cursor end line */
-
-	/******************************************************
-	 *
-	 * 1 bpp
-	 *
-	 */
-
-	/* programming for different color depths */
-	if (_par->var.bits_per_pixel == 1) {
-		DPRINTK ("clgen: preparing for 1 bit deep display\n");
-		vga_wgfx (fb_info->regs, VGA_GFX_MODE, 0);	/* mode register */
-
-		/* SR07 */
-		switch (fb_info->btype) {
-		case BT_SD64:
-		case BT_PICCOLO:
-		case BT_PICASSO:
-		case BT_SPECTRUM:
-		case BT_PICASSO4:
-		case BT_ALPINE:
-		case BT_GD5480:
-			DPRINTK (" (for GD54xx)\n");
-			vga_wseq (fb_info->regs, CL_SEQR7,
-				  _par->multiplexing ?
-				  	bi->sr07_1bpp_mux : bi->sr07_1bpp);
-			break;
-
-		case BT_LAGUNA:
-			DPRINTK (" (for GD546x)\n");
-			vga_wseq (fb_info->regs, CL_SEQR7,
-				vga_rseq (fb_info->regs, CL_SEQR7) & ~0x01);
-			break;
-
-		default:
-			printk (KERN_WARNING "clgen: unknown Board\n");
-			break;
-		}
-
-		/* Extended Sequencer Mode */
-		switch (fb_info->btype) {
-		case BT_SD64:
-			/* setting the SEQRF on SD64 is not necessary (only during init) */
-			DPRINTK ("(for SD64)\n");
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x1a);		/*  MCLK select */
-			break;
-
-		case BT_PICCOLO:
-			DPRINTK ("(for Piccolo)\n");
-/* ### ueberall 0x22? */
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ##vorher 1c MCLK select */
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* evtl d0 bei 1 bit? avoid FIFO underruns..? */
-			break;
-
-		case BT_PICASSO:
-			DPRINTK ("(for Picasso)\n");
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ##vorher 22 MCLK select */
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xd0);	/* ## vorher d0 avoid FIFO underruns..? */
-			break;
-
-		case BT_SPECTRUM:
-			DPRINTK ("(for Spectrum)\n");
-/* ### ueberall 0x22? */
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ##vorher 1c MCLK select */
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* evtl d0? avoid FIFO underruns..? */
-			break;
-
-		case BT_PICASSO4:
-		case BT_ALPINE:
-		case BT_GD5480:
-		case BT_LAGUNA:
-			DPRINTK (" (for GD54xx)\n");
-			/* do nothing */
-			break;
-
-		default:
-			printk (KERN_WARNING "clgen: unknown Board\n");
-			break;
-		}
-
-		WGen (fb_info, VGA_PEL_MSK, 0x01);	/* pixel mask: pass-through for first plane */
-		if (_par->multiplexing)
-			WHDR (fb_info, 0x4a);	/* hidden dac reg: 1280x1024 */
-		else
-			WHDR (fb_info, 0);	/* hidden dac: nothing */
-		vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x06);	/* memory mode: odd/even, ext. memory */
-		vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0x01);	/* plane mask: only write to first plane */
-		offset = _par->var.xres_virtual / 16;
-	}
-
-	/******************************************************
-	 *
-	 * 8 bpp
-	 *
-	 */
-
-	else if (_par->var.bits_per_pixel == 8) {
-		DPRINTK ("clgen: preparing for 8 bit deep display\n");
-		switch (fb_info->btype) {
-		case BT_SD64:
-		case BT_PICCOLO:
-		case BT_PICASSO:
-		case BT_SPECTRUM:
-		case BT_PICASSO4:
-		case BT_ALPINE:
-		case BT_GD5480:
-			DPRINTK (" (for GD54xx)\n");
-			vga_wseq (fb_info->regs, CL_SEQR7,
-				  _par->multiplexing ?
-				  	bi->sr07_8bpp_mux : bi->sr07_8bpp);
-			break;
-
-		case BT_LAGUNA:
-			DPRINTK (" (for GD546x)\n");
-			vga_wseq (fb_info->regs, CL_SEQR7,
-				vga_rseq (fb_info->regs, CL_SEQR7) | 0x01);
-			break;
-
-		default:
-			printk (KERN_WARNING "clgen: unknown Board\n");
-			break;
-		}
-
-		switch (fb_info->btype) {
-		case BT_SD64:
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x1d);		/* MCLK select */
-			break;
-
-		case BT_PICCOLO:
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ### vorher 1c MCLK select */
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
-			break;
-
-		case BT_PICASSO:
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ### vorher 1c MCLK select */
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
-			break;
-
-		case BT_SPECTRUM:
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* ### vorher 1c MCLK select */
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
-			break;
-
-		case BT_PICASSO4:
-#ifdef CONFIG_ZORRO
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb8);	/* ### INCOMPLETE!! */
-#endif
-/*          vga_wseq (fb_info->regs, CL_SEQR1F, 0x1c); */
-			break;
-
-		case BT_ALPINE:
-			DPRINTK (" (for GD543x)\n");
-			clgen_set_mclk (fb_info, _par->mclk, _par->divMCLK);
-			/* We already set SRF and SR1F */
-			break;
-
-		case BT_GD5480:
-		case BT_LAGUNA:
-			DPRINTK (" (for GD54xx)\n");
-			/* do nothing */
-			break;
-
-		default:
-			printk (KERN_WARNING "clgen: unknown Board\n");
-			break;
-		}
-
-		vga_wgfx (fb_info->regs, VGA_GFX_MODE, 64);	/* mode register: 256 color mode */
-		WGen (fb_info, VGA_PEL_MSK, 0xff);	/* pixel mask: pass-through all planes */
-		if (_par->multiplexing)
-			WHDR (fb_info, 0x4a);	/* hidden dac reg: 1280x1024 */
-		else
-			WHDR (fb_info, 0);	/* hidden dac: nothing */
-		vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x0a);	/* memory mode: chain4, ext. memory */
-		vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0xff);	/* plane mask: enable writing to all 4 planes */
-		offset = _par->var.xres_virtual / 8;
-	}
-
-	/******************************************************
-	 *
-	 * 16 bpp
-	 *
-	 */
-
-	else if (_par->var.bits_per_pixel == 16) {
-		DPRINTK ("clgen: preparing for 16 bit deep display\n");
-		switch (fb_info->btype) {
-		case BT_SD64:
-			vga_wseq (fb_info->regs, CL_SEQR7, 0xf7);	/* Extended Sequencer Mode: 256c col. mode */
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x1e);		/* MCLK select */
-			break;
-
-		case BT_PICCOLO:
-			vga_wseq (fb_info->regs, CL_SEQR7, 0x87);
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* MCLK select */
-			break;
-
-		case BT_PICASSO:
-			vga_wseq (fb_info->regs, CL_SEQR7, 0x27);
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* MCLK select */
-			break;
-
-		case BT_SPECTRUM:
-			vga_wseq (fb_info->regs, CL_SEQR7, 0x87);
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* MCLK select */
-			break;
-
-		case BT_PICASSO4:
-			vga_wseq (fb_info->regs, CL_SEQR7, 0x27);
-/*          vga_wseq (fb_info->regs, CL_SEQR1F, 0x1c);  */
-			break;
-
-		case BT_ALPINE:
-			DPRINTK (" (for GD543x)\n");
-			if (_par->HorizRes >= 1024)
-				vga_wseq (fb_info->regs, CL_SEQR7, 0xa7);
-			else
-				vga_wseq (fb_info->regs, CL_SEQR7, 0xa3);
-			clgen_set_mclk (fb_info, _par->mclk, _par->divMCLK);
-			break;
-
-		case BT_GD5480:
-			DPRINTK (" (for GD5480)\n");
-			vga_wseq (fb_info->regs, CL_SEQR7, 0x17);
-			/* We already set SRF and SR1F */
-			break;
-
-		case BT_LAGUNA:
-			DPRINTK (" (for GD546x)\n");
-			vga_wseq (fb_info->regs, CL_SEQR7,
-				vga_rseq (fb_info->regs, CL_SEQR7) & ~0x01);
-			break;
-
-		default:
-			printk (KERN_WARNING "CLGEN: unknown Board\n");
-			break;
-		}
-
-		vga_wgfx (fb_info->regs, VGA_GFX_MODE, 64);	/* mode register: 256 color mode */
-		WGen (fb_info, VGA_PEL_MSK, 0xff);	/* pixel mask: pass-through all planes */
-#ifdef CONFIG_PCI
-		WHDR (fb_info, 0xc0);	/* Copy Xbh */
-#elif defined(CONFIG_ZORRO)
-		/* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
-		WHDR (fb_info, 0xa0);	/* hidden dac reg: nothing special */
-#endif
-		vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x0a);	/* memory mode: chain4, ext. memory */
-		vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0xff);	/* plane mask: enable writing to all 4 planes */
-		offset = _par->var.xres_virtual / 4;
-	}
-
-	/******************************************************
-	 *
-	 * 32 bpp
-	 *
-	 */
-
-	else if (_par->var.bits_per_pixel == 32) {
-		DPRINTK ("clgen: preparing for 24/32 bit deep display\n");
-		switch (fb_info->btype) {
-		case BT_SD64:
-			vga_wseq (fb_info->regs, CL_SEQR7, 0xf9);	/* Extended Sequencer Mode: 256c col. mode */
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x1e);		/* MCLK select */
-			break;
-
-		case BT_PICCOLO:
-			vga_wseq (fb_info->regs, CL_SEQR7, 0x85);
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* MCLK select */
-			break;
-
-		case BT_PICASSO:
-			vga_wseq (fb_info->regs, CL_SEQR7, 0x25);
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* MCLK select */
-			break;
-
-		case BT_SPECTRUM:
-			vga_wseq (fb_info->regs, CL_SEQR7, 0x85);
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);	/* Fast Page-Mode writes */
-			vga_wseq (fb_info->regs, CL_SEQR1F, 0x22);		/* MCLK select */
-			break;
-
-		case BT_PICASSO4:
-			vga_wseq (fb_info->regs, CL_SEQR7, 0x25);
-/*          vga_wseq (fb_info->regs, CL_SEQR1F, 0x1c);  */
-			break;
-
-		case BT_ALPINE:
-			DPRINTK (" (for GD543x)\n");
-			vga_wseq (fb_info->regs, CL_SEQR7, 0xa9);
-			clgen_set_mclk (fb_info, _par->mclk, _par->divMCLK);
-			break;
-
-		case BT_GD5480:
-			DPRINTK (" (for GD5480)\n");
-			vga_wseq (fb_info->regs, CL_SEQR7, 0x19);
-			/* We already set SRF and SR1F */
-			break;
-
-		case BT_LAGUNA:
-			DPRINTK (" (for GD546x)\n");
-			vga_wseq (fb_info->regs, CL_SEQR7,
-				vga_rseq (fb_info->regs, CL_SEQR7) & ~0x01);
-			break;
-
-		default:
-			printk (KERN_WARNING "clgen: unknown Board\n");
-			break;
-		}
-
-		vga_wgfx (fb_info->regs, VGA_GFX_MODE, 64);	/* mode register: 256 color mode */
-		WGen (fb_info, VGA_PEL_MSK, 0xff);	/* pixel mask: pass-through all planes */
-		WHDR (fb_info, 0xc5);	/* hidden dac reg: 8-8-8 mode (24 or 32) */
-		vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x0a);	/* memory mode: chain4, ext. memory */
-		vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0xff);	/* plane mask: enable writing to all 4 planes */
-		offset = _par->var.xres_virtual / 4;
-	}
-
-	/******************************************************
-	 *
-	 * unknown/unsupported bpp
-	 *
-	 */
-
-	else {
-		printk (KERN_ERR "clgen: What's this?? requested color depth == %d.\n",
-			_par->var.bits_per_pixel);
-	}
-
-	vga_wcrt (fb_info->regs, VGA_CRTC_OFFSET, offset & 0xff);
-	tmp = 0x22;
-	if (offset & 0x100)
-		tmp |= 0x10;	/* offset overflow bit */
-
-	vga_wcrt (fb_info->regs, CL_CRT1B, tmp);	/* screen start addr #16-18, fastpagemode cycles */
-
-	if (fb_info->btype == BT_SD64 ||
-	    fb_info->btype == BT_PICASSO4 ||
-	    fb_info->btype == BT_ALPINE ||
-	    fb_info->btype == BT_GD5480)
-		vga_wcrt (fb_info->regs, CL_CRT1D, 0x00);	/* screen start address bit 19 */
-
-	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_HI, 0);	/* text cursor location high */
-	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_LO, 0);	/* text cursor location low */
-	vga_wcrt (fb_info->regs, VGA_CRTC_UNDERLINE, 0);	/* underline row scanline = at very bottom */
-
-	vga_wattr (fb_info->regs, VGA_ATC_MODE, 1);	/* controller mode */
-	vga_wattr (fb_info->regs, VGA_ATC_OVERSCAN, 0);		/* overscan (border) color */
-	vga_wattr (fb_info->regs, VGA_ATC_PLANE_ENABLE, 15);	/* color plane enable */
-	vga_wattr (fb_info->regs, CL_AR33, 0);	/* pixel panning */
-	vga_wattr (fb_info->regs, VGA_ATC_COLOR_PAGE, 0);	/* color select */
-
-	/* [ EGS: SetOffset(); ] */
-	/* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
-	AttrOn (fb_info);
-
-	vga_wgfx (fb_info->regs, VGA_GFX_SR_VALUE, 0);	/* set/reset register */
-	vga_wgfx (fb_info->regs, VGA_GFX_SR_ENABLE, 0);		/* set/reset enable */
-	vga_wgfx (fb_info->regs, VGA_GFX_COMPARE_VALUE, 0);	/* color compare */
-	vga_wgfx (fb_info->regs, VGA_GFX_DATA_ROTATE, 0);	/* data rotate */
-	vga_wgfx (fb_info->regs, VGA_GFX_PLANE_READ, 0);	/* read map select */
-	vga_wgfx (fb_info->regs, VGA_GFX_MISC, 1);	/* miscellaneous register */
-	vga_wgfx (fb_info->regs, VGA_GFX_COMPARE_MASK, 15);	/* color don't care */
-	vga_wgfx (fb_info->regs, VGA_GFX_BIT_MASK, 255);	/* bit mask */
-
-	vga_wseq (fb_info->regs, CL_SEQR12, 0x0);	/* graphics cursor attributes: nothing special */
-
-	/* finally, turn on everything - turn off "FullBandwidth" bit */
-	/* also, set "DotClock%2" bit where requested */
-	tmp = 0x01;
-
-/*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ?
-    if (var->vmode & FB_VMODE_CLOCK_HALVE)
-	tmp |= 0x08;
-*/
-
-	vga_wseq (fb_info->regs, VGA_SEQ_CLOCK_MODE, tmp);
-	DPRINTK ("CL_SEQR1: %d\n", tmp);
-
-	fb_info->currentmode = *_par;
-
-	DPRINTK ("virtual offset: (%d,%d)\n", _par->var.xoffset, _par->var.yoffset);
-	/* pan to requested offset */
-	clgen_pan_display (&fb_info->currentmode.var, (struct fb_info_gen *) fb_info);
-
-#ifdef CLGEN_DEBUG
-	clgen_dump ();
-#endif
-
-	DPRINTK ("EXIT\n");
-	return;
-}
-
-
-static int clgen_getcolreg (unsigned regno, unsigned *red, unsigned *green,
-			    unsigned *blue, unsigned *transp,
-			    struct fb_info *info)
-{
-    struct clgenfb_info *fb_info = (struct clgenfb_info *)info;
-
-    if (regno > 255)
-	return 1;
-    *red = fb_info->palette[regno].red;
-    *green = fb_info->palette[regno].green;
-    *blue = fb_info->palette[regno].blue;
-    *transp = 0;
-    return 0;
-}
-
-
-static int clgenfb_setcolreg (unsigned regno, unsigned red, unsigned green,
-			      unsigned blue, unsigned transp,
-			      struct fb_info *info)
-{
-	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
-
-	if (regno > 255)
-		return -EINVAL;
-
-#ifdef FBCON_HAS_CFB8
-	switch (fb_info->currentmode.var.bits_per_pixel) {
-	case 8:
-		/* "transparent" stuff is completely ignored. */
-		WClut (fb_info, regno, red >> 10, green >> 10, blue >> 10);
-		break;
-	default:
-		/* do nothing */
-		break;
-	}
-#endif	/* FBCON_HAS_CFB8 */
-
-	fb_info->palette[regno].red = red;
-	fb_info->palette[regno].green = green;
-	fb_info->palette[regno].blue = blue;
-
-	if (regno >= 16)
-		return 0;
-
-	switch (fb_info->currentmode.var.bits_per_pixel) {
-
-#ifdef FBCON_HAS_CFB16
-	case 16:
-		assert (regno < 16);
-		if(isPReP) {
-			fb_info->fbcon_cmap.cfb16[regno] =
-			    ((red & 0xf800) >> 9) |
-			    ((green & 0xf800) >> 14) |
-			    ((green & 0xf800) << 2) |
-			    ((blue & 0xf800) >> 3);
-		} else {
-			fb_info->fbcon_cmap.cfb16[regno] =
-			    ((red & 0xf800) >> 1) |
-			    ((green & 0xf800) >> 6) |
-			    ((blue & 0xf800) >> 11);
-		}
-#endif /* FBCON_HAS_CFB16 */
-
-#ifdef FBCON_HAS_CFB24
-	case 24:
-		assert (regno < 16);
-		fb_info->fbcon_cmap.cfb24[regno] =
-			(red   << fb_info->currentmode.var.red.offset)   |
-			(green << fb_info->currentmode.var.green.offset) |
-			(blue  << fb_info->currentmode.var.blue.offset);
-		break;
-#endif /* FBCON_HAS_CFB24 */
-
-#ifdef FBCON_HAS_CFB32
-	case 32:
-		assert (regno < 16);
-		if(isPReP) {
-			fb_info->fbcon_cmap.cfb32[regno] =
-			    ((red & 0xff00)) |
-			    ((green & 0xff00) << 8) |
-			    ((blue & 0xff00) << 16);
-		} else {
-			fb_info->fbcon_cmap.cfb32[regno] =
-			    ((red & 0xff00) << 8) |
-			    ((green & 0xff00)) |
-			    ((blue & 0xff00) >> 8);
-		}
-		break;
-#endif /* FBCON_HAS_CFB32 */
-	default:
-		/* do nothing */
-		break;
-	}
-
-	return 0;
-}
-
-/*************************************************************************
-	clgen_pan_display()
-
-	performs display panning - provided hardware permits this
-**************************************************************************/
-static int clgen_pan_display (const struct fb_var_screeninfo *var,
-			      struct fb_info_gen *info)
-{
-	int xoffset = 0;
-	int yoffset = 0;
-	unsigned long base;
-	unsigned char tmp = 0, tmp2 = 0, xpix;
-	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
-
-	DPRINTK ("ENTER\n");
-
-	/* no range checks for xoffset and yoffset,   */
-	/* as fbgen_pan_display has already done this */
-
-	fb_info->currentmode.var.xoffset = var->xoffset;
-	fb_info->currentmode.var.yoffset = var->yoffset;
-
-	xoffset = var->xoffset * fb_info->currentmode.var.bits_per_pixel / 8;
-	yoffset = var->yoffset;
-
-	base = yoffset * fb_info->currentmode.line_length + xoffset;
-
-	if (fb_info->currentmode.var.bits_per_pixel == 1) {
-		/* base is already correct */
-		xpix = (unsigned char) (var->xoffset % 8);
-	} else {
-		base /= 4;
-		xpix = (unsigned char) ((xoffset % 4) * 2);
-	}
-
-	/* lower 8 + 8 bits of screen start address */
-	vga_wcrt (fb_info->regs, VGA_CRTC_START_LO, (unsigned char) (base & 0xff));
-	vga_wcrt (fb_info->regs, VGA_CRTC_START_HI, (unsigned char) (base >> 8));
-
-	/* construct bits 16, 17 and 18 of screen start address */
-	if (base & 0x10000)
-		tmp |= 0x01;
-	if (base & 0x20000)
-		tmp |= 0x04;
-	if (base & 0x40000)
-		tmp |= 0x08;
-
-	tmp2 = (vga_rcrt (fb_info->regs, CL_CRT1B) & 0xf2) | tmp;	/* 0xf2 is %11110010, exclude tmp bits */
-	vga_wcrt (fb_info->regs, CL_CRT1B, tmp2);
-
-	/* construct bit 19 of screen start address */
-	if (clgen_board_info[fb_info->btype].scrn_start_bit19) {
-		tmp2 = 0;
-		if (base & 0x80000)
-			tmp2 = 0x80;
-		vga_wcrt (fb_info->regs, CL_CRT1D, tmp2);
-	}
-
-	/* write pixel panning value to AR33; this does not quite work in 8bpp */
-	/* ### Piccolo..? Will this work? */
-	if (fb_info->currentmode.var.bits_per_pixel == 1)
-		vga_wattr (fb_info->regs, CL_AR33, xpix);
-
-
-	DPRINTK ("EXIT\n");
-	return (0);
-}
-
-
-static int clgen_blank (int blank_mode, struct fb_info_gen *info)
-{
-	/*
-	 *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL
-	 *  then the caller blanks by setting the CLUT (Color Look Up Table) to all
-	 *  black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
-	 *  to e.g. a video mode which doesn't support it. Implements VESA suspend
-	 *  and powerdown modes on hardware that supports disabling hsync/vsync:
-	 *    blank_mode == 2: suspend vsync
-	 *    blank_mode == 3: suspend hsync
-	 *    blank_mode == 4: powerdown
-	 */
-	unsigned char val;
-	static int current_mode = 0;
-	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
-
-	DPRINTK ("ENTER, blank mode = %d\n", blank_mode);
-
-	if (current_mode == blank_mode) {
-		DPRINTK ("EXIT, returning 0\n");
-		return 0;
-	}
-
-	/* Undo current */
-	switch (current_mode) {
-	case 0:		/* Screen is normal */
-		break;
-	case 1:		/* Screen is blanked */
-		val = vga_rseq (fb_info->regs, VGA_SEQ_CLOCK_MODE);
-		vga_wseq (fb_info->regs, VGA_SEQ_CLOCK_MODE, val & 0xdf);	/* clear "FullBandwidth" bit */
-		break;
-	case 2:		/* vsync suspended */
-	case 3:		/* hsync suspended */
-	case 4:		/* sceen is powered down */
-		vga_wgfx (fb_info->regs, CL_GRE, 0x00);
-		break;
-	default:
-		DPRINTK ("EXIT, returning 1\n");
-		return 1;
-	}
-
-	/* set new */
-	switch (blank_mode) {
-	case 0:		/* Unblank screen */
-		break;
-	case 1:		/* Blank screen */
-		val = vga_rseq (fb_info->regs, VGA_SEQ_CLOCK_MODE);
-		vga_wseq (fb_info->regs, VGA_SEQ_CLOCK_MODE, val | 0x20);	/* set "FullBandwidth" bit */
-		break;
-	case 2:		/* suspend vsync */
-		vga_wgfx (fb_info->regs, CL_GRE, 0x04);
-		break;
-	case 3:		/* suspend hsync */
-		vga_wgfx (fb_info->regs, CL_GRE, 0x02);
-		break;
-	case 4:		/* powerdown */
-		vga_wgfx (fb_info->regs, CL_GRE, 0x06);
-		break;
-	default:
-		DPRINTK ("EXIT, returning 1\n");
-		return 1;
-	}
-
-	current_mode = blank_mode;
-	DPRINTK ("EXIT, returning 0\n");
-	return 0;
-}
-/**** END   Hardware specific Routines **************************************/
-/****************************************************************************/
-/**** BEGIN Internal Routines ***********************************************/
-
-static void __init init_vgachip (struct clgenfb_info *fb_info)
-{
-	const struct clgen_board_info_rec *bi;
-
-	DPRINTK ("ENTER\n");
-
-	assert (fb_info != NULL);
-
-	bi = &clgen_board_info[fb_info->btype];
-
-	/* reset board globally */
-	switch (fb_info->btype) {
-	case BT_PICCOLO:
-		WSFR (fb_info, 0x01);
-		udelay (500);
-		WSFR (fb_info, 0x51);
-		udelay (500);
-		break;
-	case BT_PICASSO:
-		WSFR2 (fb_info, 0xff);
-		udelay (500);
-		break;
-	case BT_SD64:
-	case BT_SPECTRUM:
-		WSFR (fb_info, 0x1f);
-		udelay (500);
-		WSFR (fb_info, 0x4f);
-		udelay (500);
-		break;
-	case BT_PICASSO4:
-		vga_wcrt (fb_info->regs, CL_CRT51, 0x00);	/* disable flickerfixer */
-		mdelay (100);
-		vga_wgfx (fb_info->regs, CL_GR2F, 0x00);	/* from Klaus' NetBSD driver: */
-		vga_wgfx (fb_info->regs, CL_GR33, 0x00);	/* put blitter into 542x compat */
-		vga_wgfx (fb_info->regs, CL_GR31, 0x00);	/* mode */
-		break;
-
-	case BT_GD5480:
-		vga_wgfx (fb_info->regs, CL_GR2F, 0x00);	/* from Klaus' NetBSD driver: */
-		break;
-
-	case BT_ALPINE:
-		/* Nothing to do to reset the board. */
-		break;
-
-	default:
-		printk (KERN_ERR "clgen: Warning: Unknown board type\n");
-		break;
-	}
-
-	assert (fb_info->size > 0); /* make sure RAM size set by this point */
-
-	/* assume it's a "large memory" board (2/4 MB) */
-	fb_info->smallboard = FALSE;
-
-	/* the P4 is not fully initialized here; I rely on it having been */
-	/* inited under AmigaOS already, which seems to work just fine    */
-	/* (Klaus advised to do it this way)                              */
-
-	if (fb_info->btype != BT_PICASSO4) {
-		WGen (fb_info, CL_VSSM, 0x10);	/* EGS: 0x16 */
-		WGen (fb_info, CL_POS102, 0x01);
-		WGen (fb_info, CL_VSSM, 0x08);	/* EGS: 0x0e */
-
-		if (fb_info->btype != BT_SD64)
-			WGen (fb_info, CL_VSSM2, 0x01);
-
-		vga_wseq (fb_info->regs, CL_SEQR0, 0x03);	/* reset sequencer logic */
-
-		vga_wseq (fb_info->regs, VGA_SEQ_CLOCK_MODE, 0x21);	/* FullBandwidth (video off) and 8/9 dot clock */
-		WGen (fb_info, VGA_MIS_W, 0xc1);	/* polarity (-/-), disable access to display memory, VGA_CRTC_START_HI base address: color */
-
-/*      vga_wgfx (fb_info->regs, CL_GRA, 0xce);    "magic cookie" - doesn't make any sense to me.. */
-		vga_wseq (fb_info->regs, CL_SEQR6, 0x12);	/* unlock all extension registers */
-
-		vga_wgfx (fb_info->regs, CL_GR31, 0x04);	/* reset blitter */
-
-		switch (fb_info->btype) {
-		case BT_GD5480:
-			vga_wseq (fb_info->regs, CL_SEQRF, 0x98);
-			break;
-		case BT_ALPINE:
-			break;
-		case BT_SD64:
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb8);
-			break;
-		default:
-			vga_wseq (fb_info->regs, CL_SEQR16, 0x0f);
-			vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);
-			break;
-		}
-	}
-	vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0xff);	/* plane mask: nothing */
-	vga_wseq (fb_info->regs, VGA_SEQ_CHARACTER_MAP, 0x00);	/* character map select: doesn't even matter in gx mode */
-	vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x0e);	/* memory mode: chain-4, no odd/even, ext. memory */
-
-	/* controller-internal base address of video memory */
-	if (bi->init_sr07)
-		vga_wseq (fb_info->regs, CL_SEQR7, bi->sr07);
-
-	/*  vga_wseq (fb_info->regs, CL_SEQR8, 0x00); *//* EEPROM control: shouldn't be necessary to write to this at all.. */
-
-	vga_wseq (fb_info->regs, CL_SEQR10, 0x00);		/* graphics cursor X position (incomplete; position gives rem. 3 bits */
-	vga_wseq (fb_info->regs, CL_SEQR11, 0x00);		/* graphics cursor Y position (..."... ) */
-	vga_wseq (fb_info->regs, CL_SEQR12, 0x00);		/* graphics cursor attributes */
-	vga_wseq (fb_info->regs, CL_SEQR13, 0x00);		/* graphics cursor pattern address */
-
-	/* writing these on a P4 might give problems..  */
-	if (fb_info->btype != BT_PICASSO4) {
-		vga_wseq (fb_info->regs, CL_SEQR17, 0x00);		/* configuration readback and ext. color */
-		vga_wseq (fb_info->regs, CL_SEQR18, 0x02);		/* signature generator */
-	}
-
-	/* MCLK select etc. */
-	if (bi->init_sr1f)
-		vga_wseq (fb_info->regs, CL_SEQR1F, bi->sr1f);
-
-	vga_wcrt (fb_info->regs, VGA_CRTC_PRESET_ROW, 0x00);	/* Screen A preset row scan: none */
-	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_START, 0x20);	/* Text cursor start: disable text cursor */
-	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_END, 0x00);	/* Text cursor end: - */
-	vga_wcrt (fb_info->regs, VGA_CRTC_START_HI, 0x00);	/* Screen start address high: 0 */
-	vga_wcrt (fb_info->regs, VGA_CRTC_START_LO, 0x00);	/* Screen start address low: 0 */
-	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_HI, 0x00);	/* text cursor location high: 0 */
-	vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_LO, 0x00);	/* text cursor location low: 0 */
-
-	vga_wcrt (fb_info->regs, VGA_CRTC_UNDERLINE, 0x00);	/* Underline Row scanline: - */
-	vga_wcrt (fb_info->regs, VGA_CRTC_MODE, 0xc3);	/* mode control: timing enable, byte mode, no compat modes */
-	vga_wcrt (fb_info->regs, VGA_CRTC_LINE_COMPARE, 0x00);	/* Line Compare: not needed */
-	/* ### add 0x40 for text modes with > 30 MHz pixclock */
-	vga_wcrt (fb_info->regs, CL_CRT1B, 0x02);	/* ext. display controls: ext.adr. wrap */
-
-	vga_wgfx (fb_info->regs, VGA_GFX_SR_VALUE, 0x00);	/* Set/Reset registes: - */
-	vga_wgfx (fb_info->regs, VGA_GFX_SR_ENABLE, 0x00);	/* Set/Reset enable: - */
-	vga_wgfx (fb_info->regs, VGA_GFX_COMPARE_VALUE, 0x00);	/* Color Compare: - */
-	vga_wgfx (fb_info->regs, VGA_GFX_DATA_ROTATE, 0x00);	/* Data Rotate: - */
-	vga_wgfx (fb_info->regs, VGA_GFX_PLANE_READ, 0x00);	/* Read Map Select: - */
-	vga_wgfx (fb_info->regs, VGA_GFX_MODE, 0x00);	/* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
-	vga_wgfx (fb_info->regs, VGA_GFX_MISC, 0x01);	/* Miscellaneous: memory map base address, graphics mode */
-	vga_wgfx (fb_info->regs, VGA_GFX_COMPARE_MASK, 0x0f);	/* Color Don't care: involve all planes */
-	vga_wgfx (fb_info->regs, VGA_GFX_BIT_MASK, 0xff);	/* Bit Mask: no mask at all */
-	if (fb_info->btype == BT_ALPINE)
-		vga_wgfx (fb_info->regs, CL_GRB, 0x20);	/* (5434 can't have bit 3 set for bitblt) */
-	else
-		vga_wgfx (fb_info->regs, CL_GRB, 0x28);	/* Graphics controller mode extensions: finer granularity, 8byte data latches */
-
-	vga_wgfx (fb_info->regs, CL_GRC, 0xff);	/* Color Key compare: - */
-	vga_wgfx (fb_info->regs, CL_GRD, 0x00);	/* Color Key compare mask: - */
-	vga_wgfx (fb_info->regs, CL_GRE, 0x00);	/* Miscellaneous control: - */
-	/*  vga_wgfx (fb_info->regs, CL_GR10, 0x00); *//* Background color byte 1: - */
-/*  vga_wgfx (fb_info->regs, CL_GR11, 0x00); */
-
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTE0, 0x00);	/* Attribute Controller palette registers: "identity mapping" */
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTE1, 0x01);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTE2, 0x02);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTE3, 0x03);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTE4, 0x04);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTE5, 0x05);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTE6, 0x06);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTE7, 0x07);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTE8, 0x08);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTE9, 0x09);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTEA, 0x0a);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTEB, 0x0b);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTEC, 0x0c);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTED, 0x0d);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTEE, 0x0e);
-	vga_wattr (fb_info->regs, VGA_ATC_PALETTEF, 0x0f);
-
-	vga_wattr (fb_info->regs, VGA_ATC_MODE, 0x01);	/* Attribute Controller mode: graphics mode */
-	vga_wattr (fb_info->regs, VGA_ATC_OVERSCAN, 0x00);	/* Overscan color reg.: reg. 0 */
-	vga_wattr (fb_info->regs, VGA_ATC_PLANE_ENABLE, 0x0f);	/* Color Plane enable: Enable all 4 planes */
-/* ###  vga_wattr (fb_info->regs, CL_AR33, 0x00); * Pixel Panning: - */
-	vga_wattr (fb_info->regs, VGA_ATC_COLOR_PAGE, 0x00);	/* Color Select: - */
-
-	WGen (fb_info, VGA_PEL_MSK, 0xff);	/* Pixel mask: no mask */
-
-	if (fb_info->btype != BT_ALPINE && fb_info->btype != BT_GD5480)
-		WGen (fb_info, VGA_MIS_W, 0xc3);	/* polarity (-/-), enable display mem, VGA_CRTC_START_HI i/o base = color */
-
-	vga_wgfx (fb_info->regs, CL_GR31, 0x04);	/* BLT Start/status: Blitter reset */
-	vga_wgfx (fb_info->regs, CL_GR31, 0x00);	/* - " -           : "end-of-reset" */
-
-	/* CLUT setup */
-	WClut (fb_info, 0, 0x00, 0x00, 0x00);	/* background: black */
-	WClut (fb_info, 1, 0x3f, 0x3f, 0x3f);	/* foreground: white */
-	WClut (fb_info, 2, 0x00, 0x20, 0x00);
-	WClut (fb_info, 3, 0x00, 0x20, 0x20);
-	WClut (fb_info, 4, 0x20, 0x00, 0x00);
-	WClut (fb_info, 5, 0x20, 0x00, 0x20);
-	WClut (fb_info, 6, 0x20, 0x10, 0x00);
-	WClut (fb_info, 7, 0x20, 0x20, 0x20);
-	WClut (fb_info, 8, 0x10, 0x10, 0x10);
-	WClut (fb_info, 9, 0x10, 0x10, 0x30);
-	WClut (fb_info, 10, 0x10, 0x30, 0x10);
-	WClut (fb_info, 11, 0x10, 0x30, 0x30);
-	WClut (fb_info, 12, 0x30, 0x10, 0x10);
-	WClut (fb_info, 13, 0x30, 0x10, 0x30);
-	WClut (fb_info, 14, 0x30, 0x30, 0x10);
-	WClut (fb_info, 15, 0x30, 0x30, 0x30);
-
-	/* the rest a grey ramp */
-	{
-		int i;
-
-		for (i = 16; i < 256; i++)
-			WClut (fb_info, i, i >> 2, i >> 2, i >> 2);
-	}
-
-
-	/* misc... */
-	WHDR (fb_info, 0);	/* Hidden DAC register: - */
-
-	printk (KERN_INFO "clgen: This board has %ld bytes of DRAM memory\n", fb_info->size);
-	DPRINTK ("EXIT\n");
-	return;
-}
-
-static void switch_monitor (struct clgenfb_info *fb_info, int on)
-{
-#ifdef CONFIG_ZORRO /* only works on Zorro boards */
-	static int IsOn = 0;	/* XXX not ok for multiple boards */
-
-	DPRINTK ("ENTER\n");
-
-	if (fb_info->btype == BT_PICASSO4)
-		return;		/* nothing to switch */
-	if (fb_info->btype == BT_ALPINE)
-		return;		/* nothing to switch */
-	if (fb_info->btype == BT_GD5480)
-		return;		/* nothing to switch */
-	if (fb_info->btype == BT_PICASSO) {
-		if ((on && !IsOn) || (!on && IsOn))
-			WSFR (fb_info, 0xff);
-
-		DPRINTK ("EXIT\n");
-		return;
-	}
-	if (on) {
-		switch (fb_info->btype) {
-		case BT_SD64:
-			WSFR (fb_info, fb_info->SFR | 0x21);
-			break;
-		case BT_PICCOLO:
-			WSFR (fb_info, fb_info->SFR | 0x28);
-			break;
-		case BT_SPECTRUM:
-			WSFR (fb_info, 0x6f);
-			break;
-		default: /* do nothing */ break;
-		}
-	} else {
-		switch (fb_info->btype) {
-		case BT_SD64:
-			WSFR (fb_info, fb_info->SFR & 0xde);
-			break;
-		case BT_PICCOLO:
-			WSFR (fb_info, fb_info->SFR & 0xd7);
-			break;
-		case BT_SPECTRUM:
-			WSFR (fb_info, 0x4f);
-			break;
-		default: /* do nothing */ break;
-		}
-	}
-
-	DPRINTK ("EXIT\n");
-#endif /* CONFIG_ZORRO */
-}
-
-static void clgen_set_disp (const void *par, struct display *disp,
-			    struct fb_info_gen *info)
-{
-	struct clgenfb_par *_par = (struct clgenfb_par *) par;
-	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
-	int accel_text;
-
-	DPRINTK ("ENTER\n");
-
-	assert (_par != NULL);
-	assert (fb_info != NULL);
-
-	accel_text = _par->var.accel_flags & FB_ACCELF_TEXT;
-
-	printk ("Cirrus Logic video mode: ");
-	info->info.screen_base = (char *) fb_info->fbmem;
-	switch (_par->var.bits_per_pixel) {
-#ifdef FBCON_HAS_MFB
-	case 1:
-		printk ("monochrome\n");
-		if (fb_info->btype == BT_GD5480)
-			info->info.screen_base = (char *) fb_info->fbmem;
-		disp->dispsw = &fbcon_mfb;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB8
-	case 8:
-		printk ("8 bit color depth\n");
-		if (fb_info->btype == BT_GD5480)
-			info->info.screen_base = (char *) fb_info->fbmem;
-		if (accel_text)
-			disp->dispsw = &fbcon_clgen_8;
-		else
-			disp->dispsw = &fbcon_cfb8;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB16
-	case 16:
-		printk ("16 bit color depth\n");
-		if (accel_text)
-			disp->dispsw = &fbcon_clgen_16;
-		else
-			disp->dispsw = &fbcon_cfb16;
-		if (fb_info->btype == BT_GD5480)
-			info->info.screen_base = (char *) fb_info->fbmem + 1 * MB_;
-		disp->dispsw_data = fb_info->fbcon_cmap.cfb16;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB24
-	case 24:
-		printk ("24 bit color depth\n");
-		disp->dispsw = &fbcon_cfb24;
-		if (fb_info->btype == BT_GD5480)
-			info->info.screen_base = (char *) fb_info->fbmem + 2 * MB_;
-		disp->dispsw_data = fb_info->fbcon_cmap.cfb24;
-		break;
-#endif
-#ifdef FBCON_HAS_CFB32
-	case 32:
-		printk ("32 bit color depth\n");
-		if (accel_text)
-			disp->dispsw = &fbcon_clgen_32;
-		else
-			disp->dispsw = &fbcon_cfb32;
-		if (fb_info->btype == BT_GD5480)
-			info->info.screen_base = (char *) fb_info->fbmem + 2 * MB_;
-		disp->dispsw_data = fb_info->fbcon_cmap.cfb32;
-		break;
-#endif
-
-	default:
-		printk ("unsupported color depth\n");
-		disp->dispsw = &fbcon_dummy;
-		disp->dispsw_data = NULL;
-		break;
-	}
-
-	DPRINTK ("EXIT\n");
-}
-
-#ifdef FBCON_HAS_CFB8
-static void fbcon_clgen8_bmove (struct display *p, int sy, int sx,
-				int dy, int dx, int height, int width)
-{
-	struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
-
-	DPRINTK ("ENTER\n");
-
-	sx *= fontwidth (p);
-	sy *= fontheight (p);
-	dx *= fontwidth (p);
-	dy *= fontheight (p);
-	width *= fontwidth (p);
-	height *= fontheight (p);
-
-	clgen_BitBLT (fb_info->regs, (unsigned short) sx, (unsigned short) sy,
-		      (unsigned short) dx, (unsigned short) dy,
-		      (unsigned short) width, (unsigned short) height,
-		      fb_info->currentmode.line_length);
-
-	DPRINTK ("EXIT\n");
-}
-
-static void fbcon_clgen8_clear (struct vc_data *conp, struct display *p,
-				int sy, int sx, int height, int width)
-{
-	struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
-	unsigned short col;
-
-	DPRINTK ("ENTER\n");
-
-	sx *= fontwidth (p);
-	sy *= fontheight (p);
-	width *= fontwidth (p);
-	height *= fontheight (p);
-
-	col = attr_bgcol_ec (p, conp);
-	col &= 0xff;
-
-	clgen_RectFill (fb_info, (unsigned short) sx, (unsigned short) sy,
-			(unsigned short) width, (unsigned short) height,
-			col, fb_info->currentmode.line_length);
-
-	DPRINTK ("EXIT\n");
-}
-
-#endif
-
-#ifdef FBCON_HAS_CFB16
-static void fbcon_clgen16_bmove (struct display *p, int sy, int sx,
-				 int dy, int dx, int height, int width)
-{
-	struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
-
-	DPRINTK ("ENTER\n");
-
-	sx *= fontwidth (p) * 2;	/* 2 bytes/pixel */
-	sy *= fontheight (p);
-	dx *= fontwidth (p) * 2;	/* 2 bytes/pixel */
-	dy *= fontheight (p);
-	width *= fontwidth (p) * 2;	/* 2 bytes/pixel */
-	height *= fontheight (p);
-
-	clgen_BitBLT (fb_info->regs, (unsigned short) sx, (unsigned short) sy,
-		      (unsigned short) dx, (unsigned short) dy,
-		      (unsigned short) width, (unsigned short) height,
-		      fb_info->currentmode.line_length);
-
-	DPRINTK ("EXIT\n");
-}
-
-static void fbcon_clgen16_clear (struct vc_data *conp, struct display *p,
-				 int sy, int sx, int height, int width)
-{
-	struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
-	unsigned short col;
-
-	DPRINTK ("ENTER\n");
-
-	sx *= fontwidth (p) * 2;	/* 2 bytes/pixel */
-	sy *= fontheight (p);
-	width *= fontwidth (p) * 2;	/* 2 bytes/pixel? */
-	height *= fontheight (p);
-
-	col = attr_bgcol_ec (p, conp);
-	col &= 0xff;
-
-	clgen_RectFill (fb_info, (unsigned short) sx, (unsigned short) sy,
-			(unsigned short) width, (unsigned short) height,
-			col, fb_info->currentmode.line_length);
-
-	DPRINTK ("EXIT\n");
-}
-
-#endif
-
-#ifdef FBCON_HAS_CFB32
-static void fbcon_clgen32_bmove (struct display *p, int sy, int sx,
-				 int dy, int dx, int height, int width)
-{
-	struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
-
-	DPRINTK ("ENTER\n");
-
-	sx *= fontwidth (p) * 4;	/* 4 bytes/pixel */
-	sy *= fontheight (p);
-	dx *= fontwidth (p) * 4;	/* 4 bytes/pixel */
-	dy *= fontheight (p);
-	width *= fontwidth (p) * 4;	/* 4 bytes/pixel */
-	height *= fontheight (p);
-
-	clgen_BitBLT (fb_info->regs, (unsigned short) sx, (unsigned short) sy,
-		      (unsigned short) dx, (unsigned short) dy,
-		      (unsigned short) width, (unsigned short) height,
-		      fb_info->currentmode.line_length);
-
-	DPRINTK ("EXIT\n");
-}
-
-static void fbcon_clgen32_clear (struct vc_data *conp, struct display *p,
-				 int sy, int sx, int height, int width)
-{
-	struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
-
-	unsigned short col;
-
-	DPRINTK ("ENTER\n");
-
-	sx *= fontwidth (p) * 4;	/* 4 bytes/pixel */
-	sy *= fontheight (p);
-	width *= fontwidth (p) * 4;	/* 4 bytes/pixel? */
-	height *= fontheight (p);
-
-	col = attr_bgcol_ec (p, conp);
-	col &= 0xff;
-
-	clgen_RectFill (fb_info, (unsigned short) sx, (unsigned short) sy,
-			(unsigned short) width, (unsigned short) height,
-			col, fb_info->currentmode.line_length);
-
-	DPRINTK ("EXIT\n");
-}
-
-#endif				/* FBCON_HAS_CFB32 */
-
-
-
-
-#ifdef CONFIG_ALL_PPC
-#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
-#define PREP_IO_BASE    ((volatile unsigned char *) 0x80000000)
-static void __init get_prep_addrs (unsigned long *display, unsigned long *registers)
-{
-	DPRINTK ("ENTER\n");
-
-	*display = PREP_VIDEO_BASE;
-	*registers = (unsigned long) PREP_IO_BASE;
-
-	DPRINTK ("EXIT\n");
-}
-
-#endif				/* CONFIG_ALL_PPC */
-
-
-
-
-#ifdef CONFIG_PCI
-static int release_io_ports = 0;
-
-/* Pulled the logic from XFree86 Cirrus driver to get the memory size,
- * based on the DRAM bandwidth bit and DRAM bank switching bit.  This
- * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
- * seem to have. */
-static unsigned int __init clgen_get_memsize (caddr_t regbase)
-{
-	unsigned long mem;
-	unsigned char SRF;
-
-	DPRINTK ("ENTER\n");
-
-	SRF = vga_rseq (regbase, CL_SEQRF);
-	switch ((SRF & 0x18)) {
-	    case 0x08: mem = 512 * 1024; break;
-	    case 0x10: mem = 1024 * 1024; break;
-		/* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory
-		   * on the 5430. */
-	    case 0x18: mem = 2048 * 1024; break;
-	    default: printk ("CLgenfb: Unknown memory size!\n");
-		mem = 1024 * 1024;
-	}
-	if (SRF & 0x80) {
-		/* If DRAM bank switching is enabled, there must be twice as much
-		   * memory installed. (4MB on the 5434) */
-		mem *= 2;
-	}
-	/* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
-	return mem;
-
-	DPRINTK ("EXIT\n");
-}
-
-
-
-static struct pci_dev * __init clgen_pci_dev_get (clgen_board_t *btype)
-{
-	struct pci_dev *pdev;
-	int i;
-
-	DPRINTK ("ENTER\n");
-
-	for (i = 0; i < ARRAY_SIZE(clgen_pci_probe_list); i++) {
-		pdev = NULL;
-		while ((pdev = pci_find_device (PCI_VENDOR_ID_CIRRUS,
-				clgen_pci_probe_list[i].device, pdev)) != NULL) {
-			if (pci_enable_device(pdev) == 0) {
-				*btype = clgen_pci_probe_list[i].btype;
-				DPRINTK ("EXIT, returning pdev=%p\n", pdev);
-				return pdev;
-			}
-		}
-	}
-
-	DPRINTK ("EXIT, returning NULL\n");
-	return NULL;
-}
-
-
-
-
-static void __init get_pci_addrs (const struct pci_dev *pdev,
-			   unsigned long *display, unsigned long *registers)
-{
-	assert (pdev != NULL);
-	assert (display != NULL);
-	assert (registers != NULL);
-
-	DPRINTK ("ENTER\n");
-
-	*display = 0;
-	*registers = 0;
-
-	/* This is a best-guess for now */
-
-	if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
-		*display = pci_resource_start(pdev, 1);
-		*registers = pci_resource_start(pdev, 0);
-	} else {
-		*display = pci_resource_start(pdev, 0);
-		*registers = pci_resource_start(pdev, 1);
-	}
-
-	assert (*display != 0);
-
-	DPRINTK ("EXIT\n");
-}
-
-
-static void __exit clgen_pci_unmap (struct clgenfb_info *info)
-{
-	iounmap (info->fbmem);
-	release_mem_region(info->fbmem_phys, info->size);
-
-#if 0 /* if system didn't claim this region, we would... */
-	release_mem_region(0xA0000, 65535);
-#endif
-
-	if (release_io_ports)
-		release_region(0x3C0, 32);
-}
-
-
-static int __init clgen_pci_setup (struct clgenfb_info *info,
-				   clgen_board_t *btype)
-{
-	struct pci_dev *pdev;
-	unsigned long board_addr, board_size;
-
-	DPRINTK ("ENTER\n");
-
-	pdev = clgen_pci_dev_get (btype);
-	if (!pdev) {
-		printk (KERN_ERR " Couldn't find PCI device\n");
-		DPRINTK ("EXIT, returning 1\n");
-		return 1;
-	}
-	DPRINTK (" Found PCI device, base address 0 is 0x%lx, btype set to %d\n",
-		 pdev->resource[0].start, *btype);
-	DPRINTK (" base address 1 is 0x%lx\n", pdev->resource[1].start);
-
-	info->pdev = pdev;
-
-	if(isPReP) {
-		/* Xbh does this, though 0 seems to be the init value */
-		pcibios_write_config_dword (0, pdev->devfn, PCI_BASE_ADDRESS_0,
-			0x00000000);
-
-#ifdef CONFIG_ALL_PPC
-		get_prep_addrs (&board_addr, &info->fbregs_phys);
-#endif
-	} else {
-		DPRINTK ("Attempt to get PCI info for Cirrus Graphics Card\n");
-		get_pci_addrs (pdev, &board_addr, &info->fbregs_phys);
-	}
-
-	DPRINTK ("Board address: 0x%lx, register address: 0x%lx\n", board_addr, info->fbregs_phys);
-
-	if(isPReP) {
-		/* PReP dies if we ioremap the IO registers, but it works w/out... */
-		info->regs = (char *) info->fbregs_phys;
-	} else
-		info->regs = 0;		/* FIXME: this forces VGA.  alternatives? */
-
-	if (*btype == BT_GD5480) {
-		board_size = 32 * MB_;
-	} else {
-		board_size = clgen_get_memsize (info->regs);
-	}
-
-	if (!request_mem_region(board_addr, board_size, "clgenfb")) {
-		printk(KERN_ERR "clgen: cannot reserve region 0x%lx, abort\n",
-		       board_addr);
-		return -1;
-	}
-#if 0 /* if the system didn't claim this region, we would... */
-	if (!request_mem_region(0xA0000, 65535, "clgenfb")) {
-		printk(KERN_ERR "clgen: cannot reserve region 0x%lx, abort\n",
-		       0xA0000L);
-		release_mem_region(board_addr, board_size);
-		return -1;
-	}
-#endif
-	if (request_region(0x3C0, 32, "clgenfb"))
-		release_io_ports = 1;
-
-	info->fbmem = ioremap (board_addr, board_size);
-	info->fbmem_phys = board_addr;
-	info->size = board_size;
-
-	printk (" RAM (%lu kB) at 0x%lx, ", info->size / KB_, board_addr);
-
-	printk ("Cirrus Logic chipset on PCI bus\n");
-
-	DPRINTK ("EXIT, returning 0\n");
-	return 0;
-}
-#endif				/* CONFIG_PCI */
-
-
-
-
-#ifdef CONFIG_ZORRO
-static int __init clgen_zorro_find (struct zorro_dev **z_o,
-				    struct zorro_dev **z2_o,
-				    clgen_board_t *btype, unsigned long *size)
-{
-	struct zorro_dev *z = NULL;
-	int i;
-
-	assert (z_o != NULL);
-	assert (btype != NULL);
-
-	for (i = 0; i < ARRAY_SIZE(clgen_zorro_probe_list); i++)
-		if ((z = zorro_find_device(clgen_zorro_probe_list[i].id, NULL)))
-			break;
-
-	if (z) {
-		*z_o = z;
-		if (clgen_zorro_probe_list[i].id2)
-			*z2_o = zorro_find_device(clgen_zorro_probe_list[i].id2, NULL);
-		else
-			*z2_o = NULL;
-
-		*btype = clgen_zorro_probe_list[i].btype;
-		*size = clgen_zorro_probe_list[i].size;
-
-		printk (KERN_INFO "clgen: %s board detected; ",
-			clgen_board_info[*btype].name);
-
-		return 0;
-	}
-
-	printk (KERN_NOTICE "clgen: no supported board found.\n");
-	return -1;
-}
-
-
-static void __exit clgen_zorro_unmap (struct clgenfb_info *info)
-{
-	release_mem_region(info->board_addr, info->board_size);
-
-	if (info->btype == BT_PICASSO4) {
-		iounmap ((void *)info->board_addr);
-		iounmap ((void *)info->fbmem_phys);
-	} else {
-		if (info->board_addr > 0x01000000)
-			iounmap ((void *)info->board_addr);
-	}
-}
-
-
-static int __init clgen_zorro_setup (struct clgenfb_info *info,
-				     clgen_board_t *btype)
-{
-	struct zorro_dev *z = NULL, *z2 = NULL;
-	unsigned long board_addr, board_size, size;
-
-	assert (info != NULL);
-	assert (btype != NULL);
-
-	if (clgen_zorro_find (&z, &z2, btype, &size))
-		return -1;
-
-	assert (z > 0);
-	assert (z2 >= 0);
-	assert (*btype != BT_NONE);
-
-	info->board_addr = board_addr = z->resource.start;
-	info->board_size = board_size = z->resource.end-z->resource.start+1;
-	info->size = size;
-
-	if (!request_mem_region(board_addr, board_size, "clgenfb")) {
-		printk(KERN_ERR "clgen: cannot reserve region 0x%lx, abort\n",
-		       board_addr);
-		return -1;
-	}
-
-	printk (" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr);
-
-	if (*btype == BT_PICASSO4) {
-		printk (" REG at $%lx\n", board_addr + 0x600000);
-
-		/* To be precise, for the P4 this is not the */
-		/* begin of the board, but the begin of RAM. */
-		/* for P4, map in its address space in 2 chunks (### TEST! ) */
-		/* (note the ugly hardcoded 16M number) */
-		info->regs = ioremap (board_addr, 16777216);
-		DPRINTK ("clgen: Virtual address for board set to: $%p\n", info->regs);
-		info->regs += 0x600000;
-		info->fbregs_phys = board_addr + 0x600000;
-
-		info->fbmem_phys = board_addr + 16777216;
-		info->fbmem = ioremap (info->fbmem_phys, 16777216);
-	} else {
-		printk (" REG at $%lx\n", (unsigned long) z2->resource.start);
-
-		info->fbmem_phys = board_addr;
-		if (board_addr > 0x01000000)
-			info->fbmem = ioremap (board_addr, board_size);
-		else
-			info->fbmem = (caddr_t) ZTWO_VADDR (board_addr);
-
-		/* set address for REG area of board */
-		info->regs = (caddr_t) ZTWO_VADDR (z2->resource.start);
-		info->fbregs_phys = z2->resource.start;
-
-		DPRINTK ("clgen: Virtual address for board set to: $%p\n", info->regs);
-	}
-
-	printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
-
-	return 0;
-}
-#endif /* CONFIG_ZORRO */
-
-
-
-/********************************************************************/
-/* clgenfb_init() - master initialization function                  */
-/********************************************************************/
-int __init clgenfb_init(void)
-{
-	int err, j, k;
-
-	clgen_board_t btype = BT_NONE;
-	struct clgenfb_info *fb_info = NULL;
-
-	DPRINTK ("ENTER\n");
-
-	printk (KERN_INFO "clgen: Driver for Cirrus Logic based graphic boards, v" CLGEN_VERSION "\n");
-
-	fb_info = &boards[0];	/* FIXME support multiple boards ... */
-
-#ifdef CONFIG_PCI
-	if (clgen_pci_setup (fb_info, &btype)) { /* Also does OF setup */
-		DPRINTK ("EXIT, returning -ENXIO\n");
-		return -ENXIO;
-	}
-
-#elif defined(CONFIG_ZORRO)
-	/* FIXME: CONFIG_PCI and CONFIG_ZORRO may both be defined */
-	if (clgen_zorro_setup (fb_info, &btype)) {
-		DPRINTK ("EXIT, returning -ENXIO\n");
-		return -ENXIO;
-	}
-
-#else
-#error This driver requires Zorro or PCI bus.
-#endif				/* !CONFIG_PCI, !CONFIG_ZORRO */
-
-	/* sanity checks */
-	assert (btype != BT_NONE);
-	assert (btype == clgen_board_info[btype].btype);
-
-	fb_info->btype = btype;
-
-	DPRINTK ("clgen: (RAM start set to: 0x%p)\n", fb_info->fbmem);
-
-	if (noaccel)
-	{
-		printk("clgen: disabling text acceleration support\n");
-#ifdef FBCON_HAS_CFB8
-		fbcon_clgen_8.bmove = fbcon_cfb8_bmove;
-		fbcon_clgen_8.clear = fbcon_cfb8_clear;
-#endif
-#ifdef FBCON_HAS_CFB16
-		fbcon_clgen_16.bmove = fbcon_cfb16_bmove;
-		fbcon_clgen_16.clear = fbcon_cfb16_clear;
-#endif
-#ifdef FBCON_HAS_CFB32
-		fbcon_clgen_32.bmove = fbcon_cfb32_bmove;
-		fbcon_clgen_32.clear = fbcon_cfb32_clear;
-#endif
-	}
-
-	init_vgachip (fb_info);
-
-	/* set up a few more things, register framebuffer driver etc */
-	fb_info->gen.parsize = sizeof (struct clgenfb_par);
-	fb_info->gen.fbhw = &clgen_hwswitch;
-
-	strncpy (fb_info->gen.info.modename, clgen_board_info[btype].name,
-		 sizeof (fb_info->gen.info.modename));
-	fb_info->gen.info.modename [sizeof (fb_info->gen.info.modename) - 1] = 0;
-
-	fb_info->gen.info.node = NODEV;
-	fb_info->gen.info.fbops = &clgenfb_ops;
-	fb_info->gen.info.disp = &disp;
-	fb_info->gen.info.currcon = -1;
-	fb_info->gen.info.changevar = NULL;
-	fb_info->gen.info.switch_con = &fbgen_switch;
-	fb_info->gen.info.updatevar = &fbgen_update_var;
-	fb_info->gen.info.flags = FBINFO_FLAG_DEFAULT;
-
-	for (j = 0; j < 256; j++) {
-		if (j < 16) {
-			k = color_table[j];
-			fb_info->palette[j].red = default_red[k];
-			fb_info->palette[j].green = default_grn[k];
-			fb_info->palette[j].blue = default_blu[k];
-		} else {
-			fb_info->palette[j].red =
-			fb_info->palette[j].green =
-			fb_info->palette[j].blue = j;
-		}
-	}
-
-	/* now that we know the board has been registered n' stuff, we */
-	/* can finally initialize it to a default mode */
-	clgenfb_default = clgenfb_predefined[clgen_def_mode].var;
-	clgenfb_default.activate = FB_ACTIVATE_NOW;
-	clgenfb_default.yres_virtual = 480 * 3;		/* for fast scrolling (YPAN-Mode) */
-	err = fbgen_do_set_var (&clgenfb_default, 1, &fb_info->gen);
-
-	if (err) {
-		DPRINTK ("EXIT, returning -EINVAL\n");
-		return -EINVAL;
-	}
-
-	disp.var = clgenfb_default;
-	fbgen_set_disp (-1, &fb_info->gen);
-	do_install_cmap (0, &fb_info->gen.info);
-
-	err = register_framebuffer (&fb_info->gen.info);
-	if (err) {
-		printk (KERN_ERR "clgen: ERROR - could not register fb device; err = %d!\n", err);
-		DPRINTK ("EXIT, returning -EINVAL\n");
-		return -EINVAL;
-	}
-	DPRINTK ("EXIT, returning 0\n");
-	return 0;
-}
-
-
-
-    /*
-     *  Cleanup (only needed for module)
-     */
-static void __exit clgenfb_cleanup (struct clgenfb_info *info)
-{
-	DPRINTK ("ENTER\n");
-
-#ifdef CONFIG_ZORRO
-	switch_monitor (info, 0);
-
-	clgen_zorro_unmap (info);
-#else
-	clgen_pci_unmap (info);
-#endif				/* CONFIG_ZORRO */
-
-	unregister_framebuffer ((struct fb_info *) info);
-	printk ("Framebuffer unregistered\n");
-
-	DPRINTK ("EXIT\n");
-}
-
-
-#ifndef MODULE
-int __init clgenfb_setup(char *options) {
-	char *this_opt, s[32];
-	int i;
-
-	DPRINTK ("ENTER\n");
-
-	if (!options || !*options)
-		return 0;
-
-	while ((this_opt = strsep (&options, ",")) != NULL) {	
-		if (!*this_opt) continue;
-
-		DPRINTK("clgenfb_setup: option '%s'\n", this_opt);
-
-		for (i = 0; i < NUM_TOTAL_MODES; i++) {
-			sprintf (s, "mode:%s", clgenfb_predefined[i].name);
-			if (strcmp (this_opt, s) == 0)
-				clgen_def_mode = i;
-		}
-		if (!strcmp(this_opt, "noaccel"))
-			noaccel = 1;
-	}
-	return 0;
-}
-#endif
-
-
-    /*
-     *  Modularization
-     */
-
-MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
-MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
-MODULE_LICENSE("GPL");
-
-static void __exit clgenfb_exit (void)
-{
-	DPRINTK ("ENTER\n");
-
-	clgenfb_cleanup (&boards[0]);	/* FIXME: support multiple boards */
-
-	DPRINTK ("EXIT\n");
-}
-
-#ifdef MODULE
-module_init(clgenfb_init);
-#endif
-module_exit(clgenfb_exit);
-
-
-/**********************************************************************/
-/* about the following functions - I have used the same names for the */
-/* functions as Markus Wild did in his Retina driver for NetBSD as    */
-/* they just made sense for this purpose. Apart from that, I wrote    */
-/* these functions myself.                                            */
-/**********************************************************************/
-
-/*** WGen() - write into one of the external/general registers ***/
-static void WGen (const struct clgenfb_info *fb_info,
-		  int regnum, unsigned char val)
-{
-	unsigned long regofs = 0;
-
-	if (fb_info->btype == BT_PICASSO) {
-		/* Picasso II specific hack */
-/*              if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || regnum == CL_VSSM2) */
-		if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
-			regofs = 0xfff;
-	}
-
-	vga_w (fb_info->regs, regofs + regnum, val);
-}
-
-/*** RGen() - read out one of the external/general registers ***/
-static unsigned char RGen (const struct clgenfb_info *fb_info, int regnum)
-{
-	unsigned long regofs = 0;
-
-	if (fb_info->btype == BT_PICASSO) {
-		/* Picasso II specific hack */
-/*              if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || regnum == CL_VSSM2) */
-		if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
-			regofs = 0xfff;
-	}
-
-	return vga_r (fb_info->regs, regofs + regnum);
-}
-
-/*** AttrOn() - turn on VideoEnable for Attribute controller ***/
-static void AttrOn (const struct clgenfb_info *fb_info)
-{
-	assert (fb_info != NULL);
-
-	DPRINTK ("ENTER\n");
-
-	if (vga_rcrt (fb_info->regs, CL_CRT24) & 0x80) {
-		/* if we're just in "write value" mode, write back the */
-		/* same value as before to not modify anything */
-		vga_w (fb_info->regs, VGA_ATT_IW,
-		       vga_r (fb_info->regs, VGA_ATT_R));
-	}
-	/* turn on video bit */
-/*      vga_w (fb_info->regs, VGA_ATT_IW, 0x20); */
-	vga_w (fb_info->regs, VGA_ATT_IW, 0x33);
-
-	/* dummy write on Reg0 to be on "write index" mode next time */
-	vga_w (fb_info->regs, VGA_ATT_IW, 0x00);
-
-	DPRINTK ("EXIT\n");
-}
-
-/*** WHDR() - write into the Hidden DAC register ***/
-/* as the HDR is the only extension register that requires special treatment
- * (the other extension registers are accessible just like the "ordinary"
- * registers of their functional group) here is a specialized routine for
- * accessing the HDR
- */
-static void WHDR (const struct clgenfb_info *fb_info, unsigned char val)
-{
-	unsigned char dummy;
-
-	if (fb_info->btype == BT_PICASSO) {
-		/* Klaus' hint for correct access to HDR on some boards */
-		/* first write 0 to pixel mask (3c6) */
-		WGen (fb_info, VGA_PEL_MSK, 0x00);
-		udelay (200);
-		/* next read dummy from pixel address (3c8) */
-		dummy = RGen (fb_info, VGA_PEL_IW);
-		udelay (200);
-	}
-	/* now do the usual stuff to access the HDR */
-
-	dummy = RGen (fb_info, VGA_PEL_MSK);
-	udelay (200);
-	dummy = RGen (fb_info, VGA_PEL_MSK);
-	udelay (200);
-	dummy = RGen (fb_info, VGA_PEL_MSK);
-	udelay (200);
-	dummy = RGen (fb_info, VGA_PEL_MSK);
-	udelay (200);
-
-	WGen (fb_info, VGA_PEL_MSK, val);
-	udelay (200);
-
-	if (fb_info->btype == BT_PICASSO) {
-		/* now first reset HDR access counter */
-		dummy = RGen (fb_info, VGA_PEL_IW);
-		udelay (200);
-
-		/* and at the end, restore the mask value */
-		/* ## is this mask always 0xff? */
-		WGen (fb_info, VGA_PEL_MSK, 0xff);
-		udelay (200);
-	}
-}
-
-
-/*** WSFR() - write to the "special function register" (SFR) ***/
-static void WSFR (struct clgenfb_info *fb_info, unsigned char val)
-{
-#ifdef CONFIG_ZORRO
-	assert (fb_info->regs != NULL);
-	fb_info->SFR = val;
-	z_writeb (val, fb_info->regs + 0x8000);
-#endif
-}
-
-/* The Picasso has a second register for switching the monitor bit */
-static void WSFR2 (struct clgenfb_info *fb_info, unsigned char val)
-{
-#ifdef CONFIG_ZORRO
-	/* writing an arbitrary value to this one causes the monitor switcher */
-	/* to flip to Amiga display */
-	assert (fb_info->regs != NULL);
-	fb_info->SFR = val;
-	z_writeb (val, fb_info->regs + 0x9000);
-#endif
-}
-
-
-/*** WClut - set CLUT entry (range: 0..63) ***/
-static void WClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char red,
-	    unsigned char green, unsigned char blue)
-{
-	unsigned int data = VGA_PEL_D;
-
-	/* address write mode register is not translated.. */
-	vga_w (fb_info->regs, VGA_PEL_IW, regnum);
-
-	if (fb_info->btype == BT_PICASSO || fb_info->btype == BT_PICASSO4 ||
-	    fb_info->btype == BT_ALPINE || fb_info->btype == BT_GD5480) {
-		/* but DAC data register IS, at least for Picasso II */
-		if (fb_info->btype == BT_PICASSO)
-			data += 0xfff;
-		vga_w (fb_info->regs, data, red);
-		vga_w (fb_info->regs, data, green);
-		vga_w (fb_info->regs, data, blue);
-	} else {
-		vga_w (fb_info->regs, data, blue);
-		vga_w (fb_info->regs, data, green);
-		vga_w (fb_info->regs, data, red);
-	}
-}
-
-
-#if 0
-/*** RClut - read CLUT entry (range 0..63) ***/
-static void RClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char *red,
-	    unsigned char *green, unsigned char *blue)
-{
-	unsigned int data = VGA_PEL_D;
-
-	vga_w (fb_info->regs, VGA_PEL_IR, regnum);
-
-	if (fb_info->btype == BT_PICASSO || fb_info->btype == BT_PICASSO4 ||
-	    fb_info->btype == BT_ALPINE || fb_info->btype == BT_GD5480) {
-		if (fb_info->btype == BT_PICASSO)
-			data += 0xfff;
-		*red = vga_r (fb_info->regs, data);
-		*green = vga_r (fb_info->regs, data);
-		*blue = vga_r (fb_info->regs, data);
-	} else {
-		*blue = vga_r (fb_info->regs, data);
-		*green = vga_r (fb_info->regs, data);
-		*red = vga_r (fb_info->regs, data);
-	}
-}
-#endif
-
-
-/*******************************************************************
-	clgen_WaitBLT()
-
-	Wait for the BitBLT engine to complete a possible earlier job
-*********************************************************************/
-
-/* FIXME: use interrupts instead */
-extern inline void clgen_WaitBLT (caddr_t regbase)
-{
-	/* now busy-wait until we're done */
-	while (vga_rgfx (regbase, CL_GR31) & 0x08)
-		/* do nothing */ ;
-}
-
-/*******************************************************************
-	clgen_BitBLT()
-
-	perform accelerated "scrolling"
-********************************************************************/
-
-static void clgen_BitBLT (caddr_t regbase, u_short curx, u_short cury, u_short destx, u_short desty,
-		   u_short width, u_short height, u_short line_length)
-{
-	u_short nwidth, nheight;
-	u_long nsrc, ndest;
-	u_char bltmode;
-
-	DPRINTK ("ENTER\n");
-
-	nwidth = width - 1;
-	nheight = height - 1;
-
-	bltmode = 0x00;
-	/* if source adr < dest addr, do the Blt backwards */
-	if (cury <= desty) {
-		if (cury == desty) {
-			/* if src and dest are on the same line, check x */
-			if (curx < destx)
-				bltmode |= 0x01;
-		} else
-			bltmode |= 0x01;
-	}
-	if (!bltmode) {
-		/* standard case: forward blitting */
-		nsrc = (cury * line_length) + curx;
-		ndest = (desty * line_length) + destx;
-	} else {
-		/* this means start addresses are at the end, counting backwards */
-		nsrc = cury * line_length + curx + nheight * line_length + nwidth;
-		ndest = desty * line_length + destx + nheight * line_length + nwidth;
-	}
-
-        clgen_WaitBLT(regbase);
-
-	/*
-	   run-down of registers to be programmed:
-	   destination pitch
-	   source pitch
-	   BLT width/height
-	   source start
-	   destination start
-	   BLT mode
-	   BLT ROP
-	   VGA_GFX_SR_VALUE / VGA_GFX_SR_ENABLE: "fill color"
-	   start/stop
-	 */
-
-	/* pitch: set to line_length */
-	vga_wgfx (regbase, CL_GR24, line_length & 0xff);	/* dest pitch low */
-	vga_wgfx (regbase, CL_GR25, (line_length >> 8));	/* dest pitch hi */
-	vga_wgfx (regbase, CL_GR26, line_length & 0xff);	/* source pitch low */
-	vga_wgfx (regbase, CL_GR27, (line_length >> 8));	/* source pitch hi */
-
-	/* BLT width: actual number of pixels - 1 */
-	vga_wgfx (regbase, CL_GR20, nwidth & 0xff);	/* BLT width low */
-	vga_wgfx (regbase, CL_GR21, (nwidth >> 8));	/* BLT width hi */
-
-	/* BLT height: actual number of lines -1 */
-	vga_wgfx (regbase, CL_GR22, nheight & 0xff);	/* BLT height low */
-	vga_wgfx (regbase, CL_GR23, (nheight >> 8));	/* BLT width hi */
-
-	/* BLT destination */
-	vga_wgfx (regbase, CL_GR28, (u_char) (ndest & 0xff));	/* BLT dest low */
-	vga_wgfx (regbase, CL_GR29, (u_char) (ndest >> 8));	/* BLT dest mid */
-	vga_wgfx (regbase, CL_GR2A, (u_char) (ndest >> 16));	/* BLT dest hi */
-
-	/* BLT source */
-	vga_wgfx (regbase, CL_GR2C, (u_char) (nsrc & 0xff));	/* BLT src low */
-	vga_wgfx (regbase, CL_GR2D, (u_char) (nsrc >> 8));		/* BLT src mid */
-	vga_wgfx (regbase, CL_GR2E, (u_char) (nsrc >> 16));	/* BLT src hi */
-
-	/* BLT mode */
-	vga_wgfx (regbase, CL_GR30, bltmode);	/* BLT mode */
-
-	/* BLT ROP: SrcCopy */
-	vga_wgfx (regbase, CL_GR32, 0x0d);		/* BLT ROP */
-
-	/* and finally: GO! */
-	vga_wgfx (regbase, CL_GR31, 0x02);		/* BLT Start/status */
-
-	DPRINTK ("EXIT\n");
-}
-
-
-/*******************************************************************
-	clgen_RectFill()
-
-	perform accelerated rectangle fill
-********************************************************************/
-
-static void clgen_RectFill (struct clgenfb_info *fb_info,
-		     u_short x, u_short y, u_short width, u_short height,
-		     u_char color, u_short line_length)
-{
-	u_short nwidth, nheight;
-	u_long ndest;
-	u_char op;
-
-	DPRINTK ("ENTER\n");
-
-	nwidth = width - 1;
-	nheight = height - 1;
-
-	ndest = (y * line_length) + x;
-
-        clgen_WaitBLT(fb_info->regs);
-
-	/* pitch: set to line_length */
-	vga_wgfx (fb_info->regs, CL_GR24, line_length & 0xff);	/* dest pitch low */
-	vga_wgfx (fb_info->regs, CL_GR25, (line_length >> 8));	/* dest pitch hi */
-	vga_wgfx (fb_info->regs, CL_GR26, line_length & 0xff);	/* source pitch low */
-	vga_wgfx (fb_info->regs, CL_GR27, (line_length >> 8));	/* source pitch hi */
-
-	/* BLT width: actual number of pixels - 1 */
-	vga_wgfx (fb_info->regs, CL_GR20, nwidth & 0xff);	/* BLT width low */
-	vga_wgfx (fb_info->regs, CL_GR21, (nwidth >> 8));	/* BLT width hi */
-
-	/* BLT height: actual number of lines -1 */
-	vga_wgfx (fb_info->regs, CL_GR22, nheight & 0xff);		/* BLT height low */
-	vga_wgfx (fb_info->regs, CL_GR23, (nheight >> 8));		/* BLT width hi */
-
-	/* BLT destination */
-	vga_wgfx (fb_info->regs, CL_GR28, (u_char) (ndest & 0xff));	/* BLT dest low */
-	vga_wgfx (fb_info->regs, CL_GR29, (u_char) (ndest >> 8));	/* BLT dest mid */
-	vga_wgfx (fb_info->regs, CL_GR2A, (u_char) (ndest >> 16));		/* BLT dest hi */
-
-	/* BLT source: set to 0 (is a dummy here anyway) */
-	vga_wgfx (fb_info->regs, CL_GR2C, 0x00);	/* BLT src low */
-	vga_wgfx (fb_info->regs, CL_GR2D, 0x00);	/* BLT src mid */
-	vga_wgfx (fb_info->regs, CL_GR2E, 0x00);	/* BLT src hi */
-
-	/* This is a ColorExpand Blt, using the */
-	/* same color for foreground and background */
-	vga_wgfx (fb_info->regs, VGA_GFX_SR_VALUE, color);	/* foreground color */
-	vga_wgfx (fb_info->regs, VGA_GFX_SR_ENABLE, color);	/* background color */
-
-	op = 0xc0;
-	if (fb_info->currentmode.var.bits_per_pixel == 16) {
-		vga_wgfx (fb_info->regs, CL_GR10, color);	/* foreground color */
-		vga_wgfx (fb_info->regs, CL_GR11, color);	/* background color */
-		op = 0x50;
-		op = 0xd0;
-	} else if (fb_info->currentmode.var.bits_per_pixel == 32) {
-		vga_wgfx (fb_info->regs, CL_GR10, color);	/* foreground color */
-		vga_wgfx (fb_info->regs, CL_GR11, color);	/* background color */
-		vga_wgfx (fb_info->regs, CL_GR12, color);	/* foreground color */
-		vga_wgfx (fb_info->regs, CL_GR13, color);	/* background color */
-		vga_wgfx (fb_info->regs, CL_GR14, 0);	/* foreground color */
-		vga_wgfx (fb_info->regs, CL_GR15, 0);	/* background color */
-		op = 0x50;
-		op = 0xf0;
-	}
-	/* BLT mode: color expand, Enable 8x8 copy (faster?) */
-	vga_wgfx (fb_info->regs, CL_GR30, op);	/* BLT mode */
-
-	/* BLT ROP: SrcCopy */
-	vga_wgfx (fb_info->regs, CL_GR32, 0x0d);	/* BLT ROP */
-
-	/* and finally: GO! */
-	vga_wgfx (fb_info->regs, CL_GR31, 0x02);	/* BLT Start/status */
-
-	DPRINTK ("EXIT\n");
-}
-
-
-/**************************************************************************
- * bestclock() - determine closest possible clock lower(?) than the
- * desired pixel clock
- **************************************************************************/
-static void bestclock (long freq, long *best, long *nom,
-		       long *den, long *div, long maxfreq)
-{
-	long n, h, d, f;
-
-	assert (best != NULL);
-	assert (nom != NULL);
-	assert (den != NULL);
-	assert (div != NULL);
-	assert (maxfreq > 0);
-
-	*nom = 0;
-	*den = 0;
-	*div = 0;
-
-	DPRINTK ("ENTER\n");
-
-	if (freq < 8000)
-		freq = 8000;
-
-	if (freq > maxfreq)
-		freq = maxfreq;
-
-	*best = 0;
-	f = freq * 10;
-
-	for (n = 32; n < 128; n++) {
-		d = (143181 * n) / f;
-		if ((d >= 7) && (d <= 63)) {
-			if (d > 31)
-				d = (d / 2) * 2;
-			h = (14318 * n) / d;
-			if (abs (h - freq) < abs (*best - freq)) {
-				*best = h;
-				*nom = n;
-				if (d < 32) {
-					*den = d;
-					*div = 0;
-				} else {
-					*den = d / 2;
-					*div = 1;
-				}
-			}
-		}
-		d = ((143181 * n) + f - 1) / f;
-		if ((d >= 7) && (d <= 63)) {
-			if (d > 31)
-				d = (d / 2) * 2;
-			h = (14318 * n) / d;
-			if (abs (h - freq) < abs (*best - freq)) {
-				*best = h;
-				*nom = n;
-				if (d < 32) {
-					*den = d;
-					*div = 0;
-				} else {
-					*den = d / 2;
-					*div = 1;
-				}
-			}
-		}
-	}
-
-	DPRINTK ("Best possible values for given frequency:\n");
-	DPRINTK ("        best: %ld kHz  nom: %ld  den: %ld  div: %ld\n",
-		 freq, *nom, *den, *div);
-
-	DPRINTK ("EXIT\n");
-}
-
-
-/* -------------------------------------------------------------------------
- *
- * debugging functions
- *
- * -------------------------------------------------------------------------
- */
-
-#ifdef CLGEN_DEBUG
-
-/**
- * clgen_dbg_print_byte
- * @name: name associated with byte value to be displayed
- * @val: byte value to be displayed
- *
- * DESCRIPTION:
- * Display an indented string, along with a hexidecimal byte value, and
- * its decoded bits.  Bits 7 through 0 are listed in left-to-right
- * order.
- */
-
-static
-void clgen_dbg_print_byte (const char *name, unsigned char val)
-{
-	DPRINTK ("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n",
-		 name, val,
-		 val & 0x80 ? '1' : '0',
-		 val & 0x40 ? '1' : '0',
-		 val & 0x20 ? '1' : '0',
-		 val & 0x10 ? '1' : '0',
-		 val & 0x08 ? '1' : '0',
-		 val & 0x04 ? '1' : '0',
-		 val & 0x02 ? '1' : '0',
-		 val & 0x01 ? '1' : '0');
-}
-
-
-/**
- * clgen_dbg_print_regs
- * @base: If using newmmio, the newmmio base address, otherwise %NULL
- * @reg_class: type of registers to read: %CRT, or %SEQ
- *
- * DESCRIPTION:
- * Dumps the given list of VGA CRTC registers.  If @base is %NULL,
- * old-style I/O ports are queried for information, otherwise MMIO is
- * used at the given @base address to query the information.
- */
-
-static
-void clgen_dbg_print_regs (caddr_t regbase, clgen_dbg_reg_class_t reg_class,...)
-{
-	va_list list;
-	unsigned char val = 0;
-	unsigned reg;
-	char *name;
-
-	va_start (list, reg_class);
-
-	name = va_arg (list, char *);
-	while (name != NULL) {
-		reg = va_arg (list, int);
-
-		switch (reg_class) {
-		case CRT:
-			val = vga_rcrt (regbase, (unsigned char) reg);
-			break;
-		case SEQ:
-			val = vga_rseq (regbase, (unsigned char) reg);
-			break;
-		default:
-			/* should never occur */
-			assert (FALSE);
-			break;
-		}
-
-		clgen_dbg_print_byte (name, val);
-
-		name = va_arg (list, char *);
-	}
-
-	va_end (list);
-}
-
-
-/**
- * clgen_dump
- * @clgeninfo:
- *
- * DESCRIPTION:
- */
-
-static
-void clgen_dump (void)
-{
-	clgen_dbg_reg_dump (NULL);
-}
-
-
-/**
- * clgen_dbg_reg_dump
- * @base: If using newmmio, the newmmio base address, otherwise %NULL
- *
- * DESCRIPTION:
- * Dumps a list of interesting VGA and CLGEN registers.  If @base is %NULL,
- * old-style I/O ports are queried for information, otherwise MMIO is
- * used at the given @base address to query the information.
- */
-
-static
-void clgen_dbg_reg_dump (caddr_t regbase)
-{
-	DPRINTK ("CLGEN VGA CRTC register dump:\n");
-
-	clgen_dbg_print_regs (regbase, CRT,
-			   "CR00", 0x00,
-			   "CR01", 0x01,
-			   "CR02", 0x02,
-			   "CR03", 0x03,
-			   "CR04", 0x04,
-			   "CR05", 0x05,
-			   "CR06", 0x06,
-			   "CR07", 0x07,
-			   "CR08", 0x08,
-			   "CR09", 0x09,
-			   "CR0A", 0x0A,
-			   "CR0B", 0x0B,
-			   "CR0C", 0x0C,
-			   "CR0D", 0x0D,
-			   "CR0E", 0x0E,
-			   "CR0F", 0x0F,
-			   "CR10", 0x10,
-			   "CR11", 0x11,
-			   "CR12", 0x12,
-			   "CR13", 0x13,
-			   "CR14", 0x14,
-			   "CR15", 0x15,
-			   "CR16", 0x16,
-			   "CR17", 0x17,
-			   "CR18", 0x18,
-			   "CR22", 0x22,
-			   "CR24", 0x24,
-			   "CR26", 0x26,
-			   "CR2D", 0x2D,
-			   "CR2E", 0x2E,
-			   "CR2F", 0x2F,
-			   "CR30", 0x30,
-			   "CR31", 0x31,
-			   "CR32", 0x32,
-			   "CR33", 0x33,
-			   "CR34", 0x34,
-			   "CR35", 0x35,
-			   "CR36", 0x36,
-			   "CR37", 0x37,
-			   "CR38", 0x38,
-			   "CR39", 0x39,
-			   "CR3A", 0x3A,
-			   "CR3B", 0x3B,
-			   "CR3C", 0x3C,
-			   "CR3D", 0x3D,
-			   "CR3E", 0x3E,
-			   "CR3F", 0x3F,
-			   NULL);
-
-	DPRINTK ("\n");
-
-	DPRINTK ("CLGEN VGA SEQ register dump:\n");
-
-	clgen_dbg_print_regs (regbase, SEQ,
-			   "SR00", 0x00,
-			   "SR01", 0x01,
-			   "SR02", 0x02,
-			   "SR03", 0x03,
-			   "SR04", 0x04,
-			   "SR08", 0x08,
-			   "SR09", 0x09,
-			   "SR0A", 0x0A,
-			   "SR0B", 0x0B,
-			   "SR0D", 0x0D,
-			   "SR10", 0x10,
-			   "SR11", 0x11,
-			   "SR12", 0x12,
-			   "SR13", 0x13,
-			   "SR14", 0x14,
-			   "SR15", 0x15,
-			   "SR16", 0x16,
-			   "SR17", 0x17,
-			   "SR18", 0x18,
-			   "SR19", 0x19,
-			   "SR1A", 0x1A,
-			   "SR1B", 0x1B,
-			   "SR1C", 0x1C,
-			   "SR1D", 0x1D,
-			   "SR1E", 0x1E,
-			   "SR1F", 0x1F,
-			   NULL);
-
-	DPRINTK ("\n");
-}
-
-#endif				/* CLGEN_DEBUG */
-
diff -Nru a/drivers/video/clgenfb.h b/drivers/video/clgenfb.h
--- a/drivers/video/clgenfb.h	Mon Oct 28 21:14:42 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,122 +0,0 @@
-/*
- * drivers/video/clgenfb.h - Cirrus Logic chipset constants
- *
- * Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
- *
- * Original clgenfb author:  Frank Neumann
- *
- * Based on retz3fb.c and clgen.c:
- *      Copyright (C) 1997 Jes Sorensen
- *      Copyright (C) 1996 Frank Neumann
- *
- ***************************************************************
- *
- * Format this code with GNU indent '-kr -i8 -pcs' options.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive
- * for more details.
- *
- */
-
-#ifndef __CLGENFB_H__
-#define __CLGENFB_H__
-
-/* OLD COMMENT: definitions for Piccolo/SD64 VGA controller chip   */
-/* OLD COMMENT: these definitions might most of the time also work */
-/* OLD COMMENT: for other CL-GD542x/543x based boards..            */
-
-/*** External/General Registers ***/
-#define CL_POS102	0x102  	/* POS102 register */
-#define CL_VSSM		0x46e8 	/* Adapter Sleep */
-#define CL_VSSM2	0x3c3	/* Motherboard Sleep */
-
-/*** VGA Sequencer Registers ***/
-#define CL_SEQR0	0x0	/* Reset */
-/* the following are from the "extension registers" group */
-#define CL_SEQR6	0x6	/* Unlock ALL Extensions */
-#define CL_SEQR7	0x7	/* Extended Sequencer Mode */
-#define CL_SEQR8	0x8	/* EEPROM Control */
-#define CL_SEQR9	0x9	/* Scratch Pad 0 (do not access!) */
-#define CL_SEQRA	0xa	/* Scratch Pad 1 (do not access!) */
-#define CL_SEQRB	0xb	/* VCLK0 Numerator */
-#define CL_SEQRC	0xc	/* VCLK1 Numerator */
-#define CL_SEQRD	0xd	/* VCLK2 Numerator */
-#define CL_SEQRE	0xe	/* VCLK3 Numerator */
-#define CL_SEQRF	0xf	/* DRAM Control */
-#define CL_SEQR10	0x10	/* Graphics Cursor X Position */
-#define CL_SEQR11	0x11	/* Graphics Cursor Y Position */
-#define CL_SEQR12	0x12	/* Graphics Cursor Attributes */
-#define CL_SEQR13	0x13	/* Graphics Cursor Pattern Address Offset */
-#define CL_SEQR14	0x14	/* Scratch Pad 2 (CL-GD5426/'28 Only) (do not access!) */
-#define CL_SEQR15	0x15	/* Scratch Pad 3 (CL-GD5426/'28 Only) (do not access!) */
-#define CL_SEQR16	0x16	/* Performance Tuning (CL-GD5424/'26/'28 Only) */
-#define CL_SEQR17	0x17	/* Configuration ReadBack and Extended Control (CL-GF5428 Only) */
-#define CL_SEQR18	0x18	/* Signature Generator Control (Not CL-GD5420) */
-#define CL_SEQR19	0x19	/* Signature Generator Result Low Byte (Not CL-GD5420) */
-#define CL_SEQR1A	0x1a	/* Signature Generator Result High Byte (Not CL-GD5420) */
-#define CL_SEQR1B	0x1b	/* VCLK0 Denominator and Post-Scalar Value */
-#define CL_SEQR1C	0x1c	/* VCLK1 Denominator and Post-Scalar Value */
-#define CL_SEQR1D	0x1d	/* VCLK2 Denominator and Post-Scalar Value */
-#define CL_SEQR1E	0x1e	/* VCLK3 Denominator and Post-Scalar Value */
-#define CL_SEQR1F	0x1f	/* BIOS ROM write enable and MCLK Select */
-
-/*** CRT Controller Registers ***/
-#define CL_CRT22	0x22	/* Graphics Data Latches ReadBack */
-#define CL_CRT24	0x24	/* Attribute Controller Toggle ReadBack */
-#define CL_CRT26	0x26	/* Attribute Controller Index ReadBack */
-/* the following are from the "extension registers" group */
-#define CL_CRT19	0x19	/* Interlace End */
-#define CL_CRT1A	0x1a	/* Interlace Control */
-#define CL_CRT1B	0x1b	/* Extended Display Controls */
-#define CL_CRT1C	0x1c	/* Sync adjust and genlock register */
-#define CL_CRT1D	0x1d	/* Overlay Extended Control register */
-#define CL_CRT25	0x25	/* Part Status Register */
-#define CL_CRT27	0x27	/* ID Register */
-#define CL_CRT51	0x51	/* P4 disable "flicker fixer" */
-
-/*** Graphics Controller Registers ***/
-/* the following are from the "extension registers" group */
-#define CL_GR9		0x9	/* Offset Register 0 */
-#define CL_GRA		0xa	/* Offset Register 1 */
-#define CL_GRB		0xb	/* Graphics Controller Mode Extensions */
-#define CL_GRC		0xc	/* Color Key (CL-GD5424/'26/'28 Only) */
-#define CL_GRD		0xd	/* Color Key Mask (CL-GD5424/'26/'28 Only) */
-#define CL_GRE		0xe	/* Miscellaneous Control (Cl-GD5428 Only) */
-#define CL_GRF		0xf	/* Display Compression Control register */
-#define CL_GR10		0x10	/* 16-bit Pixel BG Color High Byte (Not CL-GD5420) */
-#define CL_GR11		0x11	/* 16-bit Pixel FG Color High Byte (Not CL-GD5420) */
-#define CL_GR12		0x12	/* Background Color Byte 2 Register */
-#define CL_GR13		0x13	/* Foreground Color Byte 2 Register */
-#define CL_GR14		0x14	/* Background Color Byte 3 Register */
-#define CL_GR15		0x15	/* Foreground Color Byte 3 Register */
-/* the following are CL-GD5426/'28 specific blitter registers */
-#define CL_GR20		0x20	/* BLT Width Low */
-#define CL_GR21		0x21	/* BLT Width High */
-#define CL_GR22		0x22	/* BLT Height Low */
-#define CL_GR23		0x23	/* BLT Height High */
-#define CL_GR24		0x24	/* BLT Destination Pitch Low */
-#define CL_GR25		0x25	/* BLT Destination Pitch High */
-#define CL_GR26		0x26	/* BLT Source Pitch Low */
-#define CL_GR27		0x27	/* BLT Source Pitch High */
-#define CL_GR28		0x28	/* BLT Destination Start Low */
-#define CL_GR29		0x29	/* BLT Destination Start Mid */
-#define CL_GR2A		0x2a	/* BLT Destination Start High */
-#define CL_GR2C		0x2c	/* BLT Source Start Low */
-#define CL_GR2D		0x2d	/* BLT Source Start Mid */
-#define CL_GR2E		0x2e	/* BLT Source Start High */
-#define CL_GR2F		0x2f	/* Picasso IV Blitter compat mode..? */
-#define CL_GR30		0x30	/* BLT Mode */
-#define CL_GR31		0x31	/* BLT Start/Status */
-#define CL_GR32		0x32	/* BLT Raster Operation */
-#define CL_GR33		0x33	/* another P4 "compat" register.. */
-#define CL_GR34		0x34	/* Transparent Color Select Low */
-#define CL_GR35		0x35	/* Transparent Color Select High */
-#define CL_GR38		0x38	/* Source Transparent Color Mask Low */
-#define CL_GR39		0x39	/* Source Transparent Color Mask High */
-
-/*** Attribute Controller Registers ***/
-#define CL_AR33		0x33	/* The "real" Pixel Panning register (?) */
-#define CL_AR34		0x34	/* TEST */
-
-#endif /* __CLGENFB_H__ */
diff -Nru a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
--- a/drivers/video/console/Kconfig	Sun Feb  9 17:29:49 2003
+++ b/drivers/video/console/Kconfig	Mon Mar 10 13:46:08 2003
@@ -59,7 +59,7 @@
 
 config SGI_NEWPORT_CONSOLE
         tristate "SGI Newport Console support"
-        depends on SGI_IP22  
+        depends on SGI_IP22 
         help
           Say Y here if you want the console on the Newport aka XL graphics
           card of your Indy.  Most people say Y here.
@@ -99,7 +99,7 @@
 
 config DUMMY_CONSOLE
 	bool
-	depends on PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y
+	depends on PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y 
 	default y
 
 config FRAMEBUFFER_CONSOLE
@@ -111,49 +111,8 @@
 	depends on FRAMEBUFFER_CONSOLE
 	default y
 
-config FBCON_ADVANCED
-	bool "Advanced low level driver options"
-	depends on FRAMEBUFFER_CONSOLE
-	---help---
-	  The frame buffer console uses character drawing routines that are
-	  tailored to the specific organization of pixels in the memory of
-	  your graphics hardware. These are called the low level frame buffer
-	  console drivers. Note that they are used for text console output
-	  only; they are NOT needed for graphical applications.
-
-	  If you say N here, the needed low level drivers are automatically
-	  enabled, depending on what frame buffer devices you selected above.
-	  This is recommended for most users.
-
-	  If you say Y here, you have more fine-grained control over which low
-	  level drivers are enabled. You can e.g. leave out low level drivers
-	  for color depths you do not intend to use for text consoles.
-
-	  Low level frame buffer console drivers can be modules ( = code which
-	  can be inserted and removed from the running kernel whenever you
-	  want). The modules will be called fbcon-*. If you want to compile
-	  (some of) them as modules, read <file:Documentation/modules.txt>.
-
-	  If unsure, say N.
-
-# Guess what we need
-
-config FONT_SUN8x16
-	bool "Sparc console 8x16 font"
-	depends on FRAMEBUFFER_CONSOLE && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64)
-	help
-	  This is the high resolution console font for Sun machines. Say Y.
-
-config FONT_SUN12x22
-	bool "Sparc console 12x22 font (not supported by all drivers)"
-	depends on FRAMEBUFFER_CONSOLE && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64)
-	help
-	  This is the high resolution console font for Sun machines with very
-	  big letters (like the letters used in the SPARC PROM). If the
-	  standard font is unreadable for you, say Y, otherwise say N.
-
 config FONTS
-	bool "Select other fonts" if SPARC32 || SPARC64
+	bool "Select compiled-in fonts"
 	depends on FRAMEBUFFER_CONSOLE
 	help
 	  Say Y here if you would like to use fonts other than the default
@@ -165,10 +124,6 @@
 
 	  If unsure, say N (the default choices are safe).
 
-config FONTS
-	prompt "Select compiled-in fonts"
-	depends on FRAMEBUFFER_CONSOLE && !SPARC32 && !SPARC64
-
 config FONT_8x8
 	bool "VGA 8x8 font" if FONTS
 	depends on FRAMEBUFFER_CONSOLE
@@ -220,6 +175,20 @@
 config FONT_MINI_4x6
 	bool "Mini 4x6 font"
 	depends on !SPARC32 && !SPARC64 && FONTS
+
+config FONT_SUN8x16
+	bool "Sparc console 8x16 font"
+	depends on FRAMEBUFFER_CONSOLE && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64)
+	help
+	  This is the high resolution console font for Sun machines. Say Y.
+
+config FONT_SUN12x22
+	bool "Sparc console 12x22 font (not supported by all drivers)"
+	depends on FRAMEBUFFER_CONSOLE && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64)
+	help
+	  This is the high resolution console font for Sun machines with very
+	  big letters (like the letters used in the SPARC PROM). If the
+	  standard font is unreadable for you, say Y, otherwise say N.
 
 endmenu
 
diff -Nru a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
--- a/drivers/video/console/fbcon.c	Tue Jan 14 14:48:29 2003
+++ b/drivers/video/console/fbcon.c	Fri Mar 21 14:13:57 2003
@@ -81,10 +81,6 @@
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#ifdef CONFIG_AMIGA
-#include <asm/amigahw.h>
-#include <asm/amigaints.h>
-#endif				/* CONFIG_AMIGA */
 #ifdef CONFIG_ATARI
 #include <asm/atariints.h>
 #endif
@@ -104,12 +100,9 @@
 #  define DPRINTK(fmt, args...)
 #endif
 
-#define LOGO_H			80
-#define LOGO_W			80
-#define LOGO_LINE	(LOGO_W/8)
-
 struct display fb_display[MAX_NR_CONSOLES];
 char con2fb_map[MAX_NR_CONSOLES];
+static int logo_height;
 static int logo_lines;
 static int logo_shown = -1;
 /* Software scrollback */
@@ -135,26 +128,19 @@
 
 static void fbcon_free_font(struct display *);
 static int fbcon_set_origin(struct vc_data *);
-static int cursor_drawn;
 
 #define CURSOR_DRAW_DELAY		(1)
 
 /* # VBL ints between cursor state changes */
 #define ARM_CURSOR_BLINK_RATE		(10)
-#define AMIGA_CURSOR_BLINK_RATE		(20)
 #define ATARI_CURSOR_BLINK_RATE		(42)
 #define MAC_CURSOR_BLINK_RATE		(32)
 #define DEFAULT_CURSOR_BLINK_RATE	(20)
 
 static int vbl_cursor_cnt;
-static int cursor_on;
 static int cursor_blink_rate;
-
-static inline void cursor_undrawn(void)
-{
-	vbl_cursor_cnt = 0;
-	cursor_drawn = 0;
-}
+static int cursor_drawn;
+static int cursor_on;
 
 #define divides(a, b)	((!(a) || (b)%(a)) ? 0 : 1)
 
@@ -185,22 +171,16 @@
 /*
  *  Internal routines
  */
-
-static int fbcon_changevar(int con);
-static void fbcon_set_display(int con, int init, int logo);
+static void fbcon_set_display(struct vc_data *vc, int init, int logo);
 static __inline__ int real_y(struct display *p, int ypos);
-static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp);
+static void fb_vbl_handler(int irq, void *dummy, struct pt_regs *fp);
 static __inline__ void updatescrollmode(struct display *p, struct vc_data *vc);
-static __inline__ void ywrap_up(struct display *p, struct vc_data *vc,
-				int count);
-static __inline__ void ywrap_down(struct display *p, struct vc_data *vc,
-				  int count);
-static __inline__ void ypan_up(struct display *p, struct vc_data *vc,
-			       int count);
-static __inline__ void ypan_down(struct display *p, struct vc_data *vc,
-				 int count);
-static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy,
-			    int dx, int height, int width, u_int y_break);
+static __inline__ void ywrap_up(struct vc_data *vc, int count);
+static __inline__ void ywrap_down(struct vc_data *vc, int count);
+static __inline__ void ypan_up(struct vc_data *vc, int count);
+static __inline__ void ypan_down(struct vc_data *vc, int count);
+static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx,
+			    int dy, int dx, int height, int width, u_int y_break);
 
 #ifdef CONFIG_MAC
 /*
@@ -208,7 +188,7 @@
  */
 static int vbl_detected;
 
-static void fbcon_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
+static void fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
 {
 	vbl_detected++;
 }
@@ -221,7 +201,9 @@
 
 static void cursor_timer_handler(unsigned long dev_addr)
 {
-	fbcon_vbl_handler(0, NULL, NULL);
+	struct fb_info *info = (struct fb_info *) dev_addr;
+	
+	fb_vbl_handler(0, info, NULL);
 	cursor_timer.expires = jiffies + HZ / 50;
 	add_timer(&cursor_timer);
 }
@@ -283,19 +265,6 @@
 
 __setup("fbcon=", fb_console_setup);
 
-void gen_set_disp(int con, struct fb_info *info)
-{
-	struct display *display = fb_display + con;
-
-	display->can_soft_blank = info->fbops->fb_blank ? 1 : 0;
-	if (info->var.accel_flags)
-		display->scrollmode = SCROLL_YNOMOVE;
-	else
-		display->scrollmode = SCROLL_YREDRAW;
-	fbcon_changevar(con);
-	return;
-}
-
 /**
  *	set_con2fb_map - map console to frame buffer device
  *	@unit: virtual console number to map
@@ -303,53 +272,113 @@
  *
  *	Maps a virtual console @unit to a frame buffer device
  *	@newidx.
- *
  */
-
 void set_con2fb_map(int unit, int newidx)
 {
-	int oldidx = con2fb_map[unit];
-	struct fb_info *oldfb, *newfb;
-	struct vc_data *vc;
-	char *fontdata;
-	int userfont;
+	struct vc_data *vc = vc_cons[unit].d;
 
-	if (newidx != con2fb_map[unit]) {
-		oldfb = registered_fb[oldidx];
-		newfb = registered_fb[newidx];
-		if (!try_module_get(newfb->fbops->owner))
-			return;
-		if (newfb->fbops->fb_open
-		    && newfb->fbops->fb_open(newfb, 0)) {
-			module_put(newfb->fbops->owner);
-			return;
-		}
-		if (oldfb->fbops->fb_release)
-			oldfb->fbops->fb_release(oldfb, 0);
-		module_put(oldfb->fbops->owner);
-		vc = fb_display[unit].conp;
-		fontdata = fb_display[unit].fontdata;
-		userfont = fb_display[unit].userfont;
-		con2fb_map[unit] = newidx;
-
-		fb_display[unit].conp = vc;
-		fb_display[unit].fontdata = fontdata;
-		fb_display[unit].userfont = userfont;
-		fb_display[unit].fb_info = newfb;
-		gen_set_disp(unit, newfb);
-		/* tell console var has changed */
-		fbcon_changevar(unit);
+	con2fb_map[unit] = newidx;
+	fbcon_is_default = (vc->vc_sw == &fb_con) ? 1 : 0;
+	take_over_console(&fb_con, unit, unit, fbcon_is_default);
+}
+
+/*
+ * drawing helpers
+ */
+static void putcs_unaligned(struct vc_data *vc, struct fb_info *info,
+			    struct fb_image *image, int count,
+			    const unsigned short *s)
+{
+	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+	unsigned int width = (vc->vc_font.width + 7)/8;
+	unsigned int cellsize = vc->vc_font.height * width;
+	unsigned int maxcnt = info->pixmap.size/cellsize;
+	unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
+	unsigned int shift_high = 8, size, pitch, cnt, k;
+	unsigned int buf_align = info->pixmap.buf_align - 1;
+	unsigned int scan_align = info->pixmap.scan_align - 1;
+	unsigned int idx = vc->vc_font.width/8;
+	u8 mask, *src, *dst, *dst0;
+
+	while (count) {
+		if (count > maxcnt)
+			cnt = k = maxcnt;
+		else
+			cnt = k = count;
+
+		image->width = vc->vc_font.width * cnt;
+		pitch = (image->width + 7)/8 + scan_align;
+		pitch &= ~scan_align;
+		size = pitch * vc->vc_font.height + buf_align;
+		size &= ~buf_align;
+		dst0 = info->pixmap.addr + fb_get_buffer_offset(info, size);
+		image->data = dst0;
+		while (k--) {
+			src = vc->vc_font.data + (scr_readw(s++) & charmask)*
+			cellsize;
+			dst = dst0;
+			mask = (u8) (0xfff << shift_high);
+			move_buf_unaligned(info, dst, src, pitch, image->height,
+					mask, shift_high, shift_low, mod, idx);
+			shift_low += mod;
+			dst0 += (shift_low >= 8) ? width : width - 1;
+			shift_low &= 7;
+			shift_high = 8 - shift_low;
+		}
+		info->fbops->fb_imageblit(info, image);
+		image->dx += cnt * vc->vc_font.width;
+		count -= cnt;
+		atomic_dec(&info->pixmap.count);
+		smp_mb__after_atomic_dec();
+	}
+}
+
+static void putcs_aligned(struct vc_data *vc, struct fb_info *info,
+			  struct fb_image *image, int count,
+			  const unsigned short *s)
+{
+	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+	unsigned int width = vc->vc_font.width/8;
+	unsigned int cellsize = vc->vc_font.height * width;
+	unsigned int maxcnt = info->pixmap.size/cellsize;
+	unsigned int scan_align = info->pixmap.scan_align - 1;
+	unsigned int buf_align = info->pixmap.buf_align - 1;
+	unsigned int pitch, cnt, size, k;
+	u8 *src, *dst, *dst0;
+
+	while (count) {
+		if (count > maxcnt)
+			cnt = k = maxcnt;
+		else
+			cnt = k = count;
+		
+		pitch = width * cnt + scan_align;
+		pitch &= ~scan_align;
+		size = pitch * vc->vc_font.height + buf_align;
+		size &= ~buf_align;
+		image->width = vc->vc_font.width * cnt;
+		dst0 = info->pixmap.addr + fb_get_buffer_offset(info, size);
+		image->data = dst0;
+		while (k--) {
+			src = vc->vc_font.data + (scr_readw(s++)&charmask)*cellsize;
+			dst = dst0;
+			move_buf_aligned(info, dst, src, pitch, width, image->height);
+			dst0 += width;
+		}
+		info->fbops->fb_imageblit(info, image);
+		image->dx += cnt * vc->vc_font.width;
+		count -= cnt;
+		atomic_dec(&info->pixmap.count);
+		smp_mb__after_atomic_dec();
 	}
 }
 
 /*
  * Accelerated handlers.
  */
-void accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			int height, int width)
+void accel_bmove(struct vc_data *vc, struct fb_info *info, int sy, 
+		int sx, int dy, int dx, int height, int width)
 {
-	struct fb_info *info = p->fb_info;
-	struct vc_data *vc = p->conp;
 	struct fb_copyarea area;
 
 	area.sx = sx * vc->vc_font.width;
@@ -362,13 +391,13 @@
 	info->fbops->fb_copyarea(info, &area);
 }
 
-void accel_clear(struct vc_data *vc, struct display *p, int sy,
+void accel_clear(struct vc_data *vc, struct fb_info *info, int sy,
 			int sx, int height, int width)
 {
-	struct fb_info *info = p->fb_info;
+	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
 	struct fb_fillrect region;
 
-	region.color = attr_bgcol_ec(p, vc);
+	region.color = attr_bgcol_ec(bgshift, vc);
 	region.dx = sx * vc->vc_font.width;
 	region.dy = sy * vc->vc_font.height;
 	region.width = width * vc->vc_font.width;
@@ -378,85 +407,80 @@
 	info->fbops->fb_fillrect(info, &region);
 }	
 
-#define FB_PIXMAPSIZE 8192
-void accel_putcs(struct vc_data *vc, struct display *p,
+static void accel_putc(struct vc_data *vc, struct fb_info *info,
+                      int c, int ypos, int xpos)
+{
+	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+	unsigned int width = (vc->vc_font.width + 7)/8;
+	unsigned int scan_align = info->pixmap.scan_align - 1;
+	unsigned int buf_align = info->pixmap.buf_align - 1;
+	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
+	unsigned int size, pitch;
+	struct fb_image image;
+	u8 *src, *dst;
+
+	image.dx = xpos * vc->vc_font.width;
+	image.dy = ypos * vc->vc_font.height;
+	image.width = vc->vc_font.width;
+	image.height = vc->vc_font.height;
+	image.fg_color = attr_fgcol(fgshift, c);
+	image.bg_color = attr_bgcol(bgshift, c);
+	image.depth = 0;
+
+	pitch = width + scan_align;
+	pitch &= ~scan_align;
+	size = pitch * vc->vc_font.height;
+	size += buf_align;
+	size &= ~buf_align;
+	dst = info->pixmap.addr + fb_get_buffer_offset(info, size);
+	image.data = dst;
+	src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * width;
+
+	move_buf_aligned(info, dst, src, pitch, width, image.height);
+
+	info->fbops->fb_imageblit(info, &image);
+	atomic_dec(&info->pixmap.count);
+	smp_mb__after_atomic_dec();
+}
+
+void accel_putcs(struct vc_data *vc, struct fb_info *info,
 			const unsigned short *s, int count, int yy, int xx)
 {
-	struct fb_info *info = p->fb_info;
-	unsigned short charmask = p->charmask;
-	unsigned int width = ((vc->vc_font.width + 7)/8);
-	unsigned int cellsize = vc->vc_font.height * width;
+	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
 	struct fb_image image;
 	u16 c = scr_readw(s);
-	static u8 pixmap[FB_PIXMAPSIZE];
-	
-	image.fg_color = attr_fgcol(p, c);
-	image.bg_color = attr_bgcol(p, c);
+
+	image.fg_color = attr_fgcol(fgshift, c);
+	image.bg_color = attr_bgcol(bgshift, c);
 	image.dx = xx * vc->vc_font.width;
 	image.dy = yy * vc->vc_font.height;
 	image.height = vc->vc_font.height;
-	image.depth = 1;
+	image.depth = 0;
 
-	if (!(vc->vc_font.width & 7)) {
-		unsigned int pitch, cnt, i, j, k;
-		unsigned int maxcnt = FB_PIXMAPSIZE/(vc->vc_font.height * width);
-		char *src, *dst, *dst0;
-
-		image.data = pixmap;
-		while (count) {
-			if (count > maxcnt) 
-				cnt = k = maxcnt;
-			else
-				cnt = k = count;
-			
-			dst0 = pixmap;
-			pitch = width * cnt;
-			image.width = vc->vc_font.width * cnt;
-			while (k--) {
-				src = p->fontdata + (scr_readw(s++)&charmask)*
-					cellsize;
-				dst = dst0;
-				for (i = image.height; i--; ) {
-					for (j = 0; j < width; j++) 
-						dst[j] = *src++;
-					dst += pitch;
-				}
-				dst0 += width;
-			}
-
-			info->fbops->fb_imageblit(info, &image);
-			image.dx += cnt * vc->vc_font.width;
-			count -= cnt;
-		}
-	} else {
-		image.width = vc->vc_font.width;
-		while (count--) {
-			image.data = p->fontdata + 
-				(scr_readw(s++) & charmask) * cellsize;
-			info->fbops->fb_imageblit(info, &image);
-			image.dx += vc->vc_font.width;
-		}	
-	}
-	if (info->fbops->fb_sync)
-		info->fbops->fb_sync(info);
+	if (!(vc->vc_font.width & 7))
+               putcs_aligned(vc, info, &image, count, s);
+        else
+               putcs_unaligned(vc, info, &image, count, s);
 }
 
-void accel_clear_margins(struct vc_data *vc, struct display *p,
+void accel_clear_margins(struct vc_data *vc, struct fb_info *info,
 				int bottom_only)
 {
-	struct fb_info *info = p->fb_info;
+	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
 	unsigned int cw = vc->vc_font.width;
 	unsigned int ch = vc->vc_font.height;
-	unsigned int rw = info->var.xres % cw;
-	unsigned int bh = info->var.yres % ch;
+	unsigned int rw = info->var.xres - (vc->vc_cols*cw);
+	unsigned int bh = info->var.yres - (vc->vc_rows*ch);
 	unsigned int rs = info->var.xres - rw;
 	unsigned int bs = info->var.yres - bh;
 	struct fb_fillrect region;
 
-	region.color = attr_bgcol_ec(p, vc);
+	region.color = attr_bgcol_ec(bgshift, vc);
 	region.rop = ROP_COPY;
 
-	if (rw & !bottom_only) {
+	if (rw && !bottom_only) {
 		region.dx = info->var.xoffset + rs;
 		region.dy = 0;
 		region.width = rw;
@@ -473,105 +497,6 @@
 	}	
 }	
 
-void accel_cursor(struct display *p, int flags, int xx, int yy)
-{
-	static char mask[64], image[64], *dest;
-	struct vc_data *vc = p->conp;
-	static int fgcolor, bgcolor, shape, width, height;
-	struct fb_info *info = p->fb_info;
-	struct fb_cursor cursor;
-	char *font;
-	int c;
-
-	cursor.set = FB_CUR_SETPOS;
-	
-	if (width != vc->vc_font.width || height != vc->vc_font.height) {
-		width = vc->vc_font.width;
-		height = vc->vc_font.height;
-		cursor.set |= FB_CUR_SETSIZE;
-	}	
-
-	if ((vc->vc_cursor_type & 0x0f) != shape) {
-		shape = vc->vc_cursor_type & 0x0f;
-		cursor.set |= FB_CUR_SETSHAPE;
-	}
-
-	c = scr_readw((u16 *) vc->vc_pos);
-
-	if (fgcolor != (int) attr_fgcol(p, c) ||
-	    bgcolor != (int) attr_bgcol(p, c)) {
-		fgcolor = (int) attr_fgcol(p, c);
-		bgcolor = (int) attr_bgcol(p, c);
-		cursor.set |= FB_CUR_SETCMAP;
-	}
-	c &= p->charmask;
-	font = p->fontdata + (c * ((width + 7) / 8) * height);
-	if (font != dest) {
-		dest = font;
-		cursor.set |= FB_CUR_SETDEST;
-	}
-
-	if (flags & FB_CUR_SETCUR)
-		cursor.enable = 1;
-	else
-		cursor.enable = 0;
-
-	if (cursor.set & FB_CUR_SETSIZE) {
-		memset(image, 0xff, 64);
-		cursor.set |= FB_CUR_SETSHAPE;
-	}		
-
-	if (cursor.set & FB_CUR_SETSHAPE) {
-		int w, cur_height, size, i = 0;
-
-		w = (width + 7) / 8;
-
-		switch (shape) {
-			case CUR_NONE:
-				cur_height = 0;
-				break;
-			case CUR_UNDERLINE:
-				cur_height = (height < 10) ? 1 : 2;
-				break;
-			case CUR_LOWER_THIRD:
-				cur_height = height/3;
-				break;
-			case CUR_LOWER_HALF:
-				cur_height = height/2;
-				break;
-			case CUR_TWO_THIRDS:
-				cur_height = (height * 2)/3;
-				break;
-			case CUR_BLOCK:
-			default:
-				cur_height = height;
-				break;
-		}
-
-		size = (height - cur_height) * w;
-		while (size--)
-			mask[i++] = 0;
-		size = cur_height * w;
-		while (size--)
-			mask[i++] = 0xff;
-	}
-	
-	cursor.image.width = width;
-	cursor.image.height = height;
-	cursor.image.dx = xx * width;
-	cursor.image.dy = yy * height;
-	cursor.image.depth = 1;
-	cursor.image.data = image;
-	cursor.image.bg_color = bgcolor;
-	cursor.image.fg_color = fgcolor;
-	cursor.mask = mask;
-	cursor.dest = dest;
-	cursor.rop = ROP_XOR;
-
-	if (info->fbops->fb_cursor)
-		info->fbops->fb_cursor(info, &cursor);
-}
-	
 /*
  *  Low Level Operations
  */
@@ -642,7 +567,7 @@
 
 	vc->vc_cols = info->var.xres/vc->vc_font.width;
 	vc->vc_rows = info->var.yres/vc->vc_font.height;
-	
+
 	/* We trust the mode the driver supplies. */
 	if (info->fbops->fb_set_par)
 		info->fbops->fb_set_par(info);
@@ -655,20 +580,13 @@
 
 	info->display_fg = vc;
 	
-#ifdef CONFIG_AMIGA
-	if (MACH_IS_AMIGA) {
-		cursor_blink_rate = AMIGA_CURSOR_BLINK_RATE;
-		irqres = request_irq(IRQ_AMIGA_VERTB, fbcon_vbl_handler, 0,
-				     "console/cursor", fbcon_vbl_handler);
-	}
-#endif				/* CONFIG_AMIGA */
 #ifdef CONFIG_ATARI
 	if (MACH_IS_ATARI) {
 		cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;
 		irqres =
-		    request_irq(IRQ_AUTO_4, fbcon_vbl_handler,
-				IRQ_TYPE_PRIO, "console/cursor",
-				fbcon_vbl_handler);
+		    request_irq(IRQ_AUTO_4, fb_vbl_handler,
+				IRQ_TYPE_PRIO, "framebuffer vbl",
+				info);
 	}
 #endif				/* CONFIG_ATARI */
 
@@ -683,8 +601,8 @@
 		/*
 		 * Probe for VBL: set temp. handler ...
 		 */
-		irqres = request_irq(IRQ_MAC_VBL, fbcon_vbl_detect, 0,
-				     "console/cursor", fbcon_vbl_detect);
+		irqres = request_irq(IRQ_MAC_VBL, fb_vbl_detect, 0,
+				     "framebuffer vbl", info);
 		vbl_detected = 0;
 
 		/*
@@ -697,7 +615,7 @@
 			printk
 			    ("fbcon_startup: No VBL detected, using timer based cursor.\n");
 
-		free_irq(IRQ_MAC_VBL, fbcon_vbl_detect);
+		free_irq(IRQ_MAC_VBL, fb_vbl_detect);
 
 		if (vbl_detected) {
 			/*
@@ -705,9 +623,8 @@
 			 */
 			cursor_blink_rate = MAC_CURSOR_BLINK_RATE;
 			irqres =
-			    request_irq(IRQ_MAC_VBL, fbcon_vbl_handler, 0,
-					"console/cursor",
-					fbcon_vbl_handler);
+			    request_irq(IRQ_MAC_VBL, fb_vbl_handler, 0,
+					"framebuffer vbl", info);
 		} else {
 			/*
 			 * VBL not detected: fall through, use timer based cursor
@@ -719,13 +636,14 @@
 
 #if defined(__arm__) && defined(IRQ_VSYNCPULSE)
 	cursor_blink_rate = ARM_CURSOR_BLINK_RATE;
-	irqres = request_irq(IRQ_VSYNCPULSE, fbcon_vbl_handler, SA_SHIRQ,
-			     "console/cursor", fbcon_vbl_handler);
+	irqres = request_irq(IRQ_VSYNCPULSE, fb_vbl_handler, SA_SHIRQ,
+			     "framebuffer vbl", info);
 #endif
 
 	if (irqres) {
 		cursor_blink_rate = DEFAULT_CURSOR_BLINK_RATE;
 		cursor_timer.expires = jiffies + HZ / 50;
+		cursor_timer.data = (unsigned long ) info;
 		add_timer(&cursor_timer);
 	}
 	return display_desc;
@@ -738,142 +656,24 @@
 
 	/* on which frame buffer will we open this console? */
 	info = registered_fb[(int) con2fb_map[unit]];
-
-	gen_set_disp(unit, info);
-	fb_display[unit].conp = vc;
-	fb_display[unit].fb_info = info;
-
-	fbcon_set_display(unit, init, !init);
+	
+	if (info->var.accel_flags)
+		fb_display[unit].scrollmode = SCROLL_YNOMOVE;
+	else
+		fb_display[unit].scrollmode = SCROLL_YREDRAW;
+	fbcon_set_display(vc, init, !init);
 }
 
-
 static void fbcon_deinit(struct vc_data *vc)
 {
-	int unit = vc->vc_num;
-	struct display *p = &fb_display[unit];
+	struct display *p = &fb_display[vc->vc_num];
 
 	fbcon_free_font(p);
-	p->conp = 0;
-}
-
-#define fontwidthvalid(p,w) ((p)->fontwidthmask & FONTWIDTH(w))
-
-static int fbcon_changevar(int con)
-{
-	if (fb_display[con].conp) {
-		struct display *p = &fb_display[con];
-		struct fb_info *info = p->fb_info;
-		struct vc_data *vc = p->conp;
-		int nr_rows, nr_cols;
-		int old_rows, old_cols;
-		unsigned short *save = NULL, *q;
-		int i, charcnt = 256;
-		struct font_desc *font;
-
-		info->var.xoffset = info->var.yoffset = p->yscroll = 0;	/* reset wrap/pan */
-
-		for (i = 0; i < MAX_NR_CONSOLES; i++)
-			if (i != con && fb_display[i].fb_info == info &&
-		    		fb_display[i].conp && fb_display[i].fontdata)
-					break;
-
-		fbcon_free_font(p);
-		if (i < MAX_NR_CONSOLES) {
-			struct display *q = &fb_display[i];
-			struct vc_data *tmp = vc_cons[i].d;
-			
-			if (fontwidthvalid(p, vc->vc_font.width)) {
-				/* If we are not the first console on this
-				   fb, copy the font from that console */
-				tmp->vc_font.width = vc->vc_font.width;
-				tmp->vc_font.height = vc->vc_font.height;
-				p->fontdata = q->fontdata;
-				p->userfont = q->userfont;
-				if (p->userfont) {
-					REFCOUNT(p->fontdata)++;
-					charcnt = FNTCHARCNT(p->fontdata);
-				}
-				con_copy_unimap(con, i);
-			}
-		}
-
-		if (!p->fontdata) {
-			if (!p->fontname[0] || !(font = find_font(p->fontname)))
-			    	font = get_default_font(info->var.xres,
-						   		info->var.yres);
-			vc->vc_font.width = font->width;
-			vc->vc_font.height = font->height;
-			p->fontdata = font->data;
-		}
-
-		updatescrollmode(p, vc);
-
-		old_cols = vc->vc_cols;
-		old_rows = vc->vc_rows;
-
-		nr_cols = info->var.xres / vc->vc_font.width;
-		nr_rows = info->var.yres / vc->vc_font.height;
-
-		/*
-	 	 *  ++guenther: console.c:vc_allocate() relies on initializing
-	 	 *  vc_{cols,rows}, but we must not set those if we are only
-	 	 *  resizing the console.
-	 	 */
-		p->vrows = info->var.yres_virtual / vc->vc_font.height;
-		if ((info->var.yres % vc->vc_font.height) &&
-	    	    (info->var.yres_virtual % vc->vc_font.height <
-	     	     info->var.yres % vc->vc_font.height))
-			p->vrows--;
-		vc->vc_can_do_color = info->var.bits_per_pixel != 1;
-		vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
-		if (charcnt == 256) {
-			vc->vc_hi_font_mask = 0;
-			p->fgshift = 8;
-			p->bgshift = 12;
-			p->charmask = 0xff;
-		} else {
-			vc->vc_hi_font_mask = 0x100;
-			if (vc->vc_can_do_color)
-				vc->vc_complement_mask <<= 1;
-			p->fgshift = 9;
-			p->bgshift = 13;
-			p->charmask = 0x1ff;
-		}
-
-		if (vc->vc_cols != nr_cols || vc->vc_rows != nr_rows)
-			vc_resize(con, nr_cols, nr_rows);
-		else if (CON_IS_VISIBLE(vc) &&
-		 	vt_cons[vc->vc_num]->vc_mode == KD_TEXT) {
-			accel_clear_margins(vc, p, 0);
-			update_screen(con);
-		}
-		if (save) {
-			q = (unsigned short *) (vc->vc_origin +
-						vc->vc_size_row *
-						old_rows);
-			scr_memcpyw(q, save, logo_lines * nr_cols * 2);
-			vc->vc_y += logo_lines;
-			vc->vc_pos += logo_lines * vc->vc_size_row;
-			kfree(save);
-		}
-
-		if (con == fg_console && softback_buf) {
-			int l = fbcon_softback_size / vc->vc_size_row;
-			if (l > 5)
-				softback_end = softback_buf + l * vc->vc_size_row;
-			else {
-				/* Smaller scrollback makes no sense, and 0 would screw
-			   	the operation totally */
-				softback_top = 0;
-			}
-		}
-	}	
-	return 0;
 }
 
 static __inline__ void updatescrollmode(struct display *p, struct vc_data *vc)
 {
-	struct fb_info *info = p->fb_info;
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
 
 	int m;
 	if (p->scrollmode & __SCROLL_YFIXED)
@@ -891,32 +691,24 @@
 	p->scrollmode = (p->scrollmode & ~__SCROLL_YMASK) | m;
 }
 
-static void fbcon_set_display(int con, int init, int logo)
+static void fbcon_set_display(struct vc_data *vc, int init, int logo)
 {
-	struct display *p = &fb_display[con];
-	struct fb_info *info = p->fb_info;
-	struct vc_data *vc = p->conp;
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
 	int nr_rows, nr_cols;
 	int old_rows, old_cols;
 	unsigned short *save = NULL, *r, *q;
 	int i, charcnt = 256;
 	struct font_desc *font;
 
-	if (con != fg_console || (info->flags & FBINFO_FLAG_MODULE) ||
+	if (vc->vc_num != fg_console || (info->flags & FBINFO_FLAG_MODULE) ||
 	    info->fix.type == FB_TYPE_TEXT)
 		logo = 0;
 
 	info->var.xoffset = info->var.yoffset = p->yscroll = 0;	/* reset wrap/pan */
 
-	/*
-	 * FIXME: need to set this in order for KDFONTOP ioctl
-	 *        to work
-	 */
-	p->fontwidthmask = FONTWIDTHRANGE(1,16);
-
 	for (i = 0; i < MAX_NR_CONSOLES; i++)
-		if (i != con && fb_display[i].fb_info == info &&
-		    fb_display[i].conp && fb_display[i].fontdata)
+		if (vc && i != vc->vc_num && fb_display[i].fontdata) 
 			break;
 
 	fbcon_free_font(p);
@@ -924,18 +716,18 @@
 		struct display *q = &fb_display[i];
 		struct vc_data *tmp = vc_cons[i].d;
 		
-		if (!fontwidthvalid(p, vc->vc_font.width)) {
+		if (vc->vc_font.width > 32) {
 			/* If we are not the first console on this
 			   fb, copy the font from that console */
 			vc->vc_font.width = tmp->vc_font.width;
 			vc->vc_font.height = tmp->vc_font.height;
-			p->fontdata = q->fontdata;
+			vc->vc_font.data = p->fontdata = q->fontdata;
 			p->userfont = q->userfont;
 			if (p->userfont) {
 				REFCOUNT(p->fontdata)++;
 				charcnt = FNTCHARCNT(p->fontdata);
 			}
-			con_copy_unimap(con, i);
+			con_copy_unimap(vc->vc_num, i);
 		}
 	}
 
@@ -945,7 +737,7 @@
 						   info->var.yres);
 		vc->vc_font.width = font->width;
 		vc->vc_font.height = font->height;
-		p->fontdata = font->data;
+		vc->vc_font.data = p->fontdata = font->data;
 	}
 
 	updatescrollmode(p, vc);
@@ -961,7 +753,9 @@
 		int cnt;
 		int step;
 
-		logo_lines = (LOGO_H + vc->vc_font.height - 1) / vc->vc_font.height;
+		logo_height = fb_prepare_logo(info);
+		logo_lines = (logo_height + vc->vc_font.height - 1) /
+			     vc->vc_font.height;
 		q = (unsigned short *) (vc->vc_origin +
 					vc->vc_size_row * old_rows);
 		step = logo_lines * old_cols;
@@ -1012,6 +806,9 @@
 		vc->vc_rows = nr_rows;
 	}
 	p->vrows = info->var.yres_virtual / vc->vc_font.height;
+	if(info->var.yres > (vc->vc_font.height * (vc->vc_rows + 1))) {
+		p->vrows -= (info->var.yres - (vc->vc_font.height * vc->vc_rows)) / vc->vc_font.height;
+	}
 	if ((info->var.yres % vc->vc_font.height) &&
 	    (info->var.yres_virtual % vc->vc_font.height <
 	     info->var.yres % vc->vc_font.height))
@@ -1020,25 +817,19 @@
 	vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
 	if (charcnt == 256) {
 		vc->vc_hi_font_mask = 0;
-		p->fgshift = 8;
-		p->bgshift = 12;
-		p->charmask = 0xff;
 	} else {
 		vc->vc_hi_font_mask = 0x100;
 		if (vc->vc_can_do_color)
 			vc->vc_complement_mask <<= 1;
-		p->fgshift = 9;
-		p->bgshift = 13;
-		p->charmask = 0x1ff;
 	}
 
 	if (!init) {
 		if (vc->vc_cols != nr_cols || vc->vc_rows != nr_rows)
-			vc_resize(con, nr_cols, nr_rows);
+			vc_resize(vc->vc_num, nr_cols, nr_rows);
 		else if (CON_IS_VISIBLE(vc) &&
 			 vt_cons[vc->vc_num]->vc_mode == KD_TEXT) {
-			accel_clear_margins(vc, p, 0);
-			update_screen(con);
+			accel_clear_margins(vc, info, 0);
+			update_screen(vc->vc_num);
 		}
 		if (save) {
 			q = (unsigned short *) (vc->vc_origin +
@@ -1055,14 +846,14 @@
 		if (logo_lines > vc->vc_bottom) {
 			logo_shown = -1;
 			printk(KERN_INFO
-			       "fbcon_startup: disable boot-logo (boot-logo bigger than screen).\n");
+			       "fbcon_init: disable boot-logo (boot-logo bigger than screen).\n");
 		} else {
 			logo_shown = -2;
 			vc->vc_top = logo_lines;
 		}
 	}
 
-	if (con == fg_console && softback_buf) {
+	if (vc->vc_num == fg_console && softback_buf) {
 		int l = fbcon_softback_size / vc->vc_size_row;
 		if (l > 5)
 			softback_end = softback_buf + l * vc->vc_size_row;
@@ -1091,7 +882,7 @@
  *
  *	fbcon_bmove_physical_8()    -- These functions fast implementations
  *	fbcon_clear_physical_8()    -- of original fbcon_XXX fns.
- *	fbcon_putc_physical_8()	    -- (fontwidth != 8) may be added later
+ *	fbcon_putc_physical_8()	    -- (font width != 8) may be added later
  *
  *  WARNING:
  *
@@ -1112,101 +903,163 @@
 static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
 			int width)
 {
-	int unit = vc->vc_num;
-	struct display *p = &fb_display[unit];
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	
+	struct display *p = &fb_display[vc->vc_num];
 	u_int y_break;
-	int redraw_cursor = 0;
 
-	if (!p->can_soft_blank && console_blanked)
+	if (!info->fbops->fb_blank && console_blanked)
 		return;
 
 	if (!height || !width)
 		return;
 
-	if ((sy <= p->cursor_y) && (p->cursor_y < sy + height) &&
-	    (sx <= p->cursor_x) && (p->cursor_x < sx + width)) {
-		cursor_undrawn();
-		redraw_cursor = 1;
-	}
-
 	/* Split blits that cross physical y_wrap boundary */
 
 	y_break = p->vrows - p->yscroll;
 	if (sy < y_break && sy + height - 1 >= y_break) {
 		u_int b = y_break - sy;
-		accel_clear(vc, p, real_y(p, sy), sx, b, width);
-		accel_clear(vc, p, real_y(p, sy + b), sx, height - b,
+		accel_clear(vc, info, real_y(p, sy), sx, b, width);
+		accel_clear(vc, info, real_y(p, sy + b), sx, height - b,
 				 width);
 	} else
-		accel_clear(vc, p, real_y(p, sy), sx, height, width);
-
-	if (redraw_cursor)
-		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+		accel_clear(vc, info, real_y(p, sy), sx, height, width);
 }
 
 
 static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
 {
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
 	struct display *p = &fb_display[vc->vc_num];
-	struct fb_info *info = p->fb_info;
-	unsigned short charmask = p->charmask;
-	unsigned int width = ((vc->vc_font.width + 7) >> 3);
-	struct fb_image image;
-	int redraw_cursor = 0;
 
-	if (!p->can_soft_blank && console_blanked)
+	if (!info->fbops->fb_blank && console_blanked)
 		return;
 
 	if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
 		return;
 
-	if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) {
-		cursor_undrawn();
-		redraw_cursor = 1;
-	}
-
-	image.fg_color = attr_fgcol(p, c);
-	image.bg_color = attr_bgcol(p, c);
-	image.dx = xpos * vc->vc_font.width;
-	image.dy = real_y(p, ypos) * vc->vc_font.height;
-	image.width = vc->vc_font.width;
-	image.height = vc->vc_font.height;
-	image.depth = 1;
-	image.data = p->fontdata + (c & charmask) * vc->vc_font.height * width;
-
-	info->fbops->fb_imageblit(info, &image);
-
-	if (redraw_cursor)
-		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+	accel_putc(vc, info, c, real_y(p, ypos), xpos);
 }
 
-
 static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
 			int count, int ypos, int xpos)
 {
-	int unit = vc->vc_num;
-	struct display *p = &fb_display[unit];
-	int redraw_cursor = 0;
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
 
-	if (!p->can_soft_blank && console_blanked)
+	if (!info->fbops->fb_blank && console_blanked)
 		return;
 
-	if (vt_cons[unit]->vc_mode != KD_TEXT)
+	if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
 		return;
 
-	if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) &&
-	    (p->cursor_x < (xpos + count))) {
-		cursor_undrawn();
-		redraw_cursor = 1;
-	}
-	accel_putcs(vc, p, s, count, real_y(p, ypos), xpos);
-	if (redraw_cursor)
-		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+	accel_putcs(vc, info, s, count, real_y(p, ypos), xpos);
 }
 
+void accel_cursor(struct vc_data *vc, struct fb_info *info, struct fb_cursor *cursor,
+		  int yy)
+{
+	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
+	int height, width, size, c;
+	int w, cur_height, i = 0;
+	char *font, *mask, *data;
+	
+	if (cursor->set & FB_CUR_SETCUR)
+		cursor->enable = 1;
+	else
+		cursor->enable = 0;
+
+	cursor->set |= FB_CUR_SETPOS;
+
+	height = info->cursor.image.height;
+	width = info->cursor.image.width;
+
+	if (width != vc->vc_font.width || 
+	    height != vc->vc_font.height) {
+		width = vc->vc_font.width;
+		height = vc->vc_font.height;
+		cursor->set |= FB_CUR_SETSIZE;
+	}	
+
+	size = ((width + 7) >> 3) * height;
+
+	data = kmalloc(size, GFP_KERNEL);
+	mask = kmalloc(size, GFP_KERNEL);
+	
+	if (cursor->set & FB_CUR_SETSIZE) {
+		memset(data, 0xff, size);
+		cursor->set |= FB_CUR_SETSHAPE;
+	}
+
+	c = scr_readw((u16 *) vc->vc_pos);
+
+	if (info->cursor.image.fg_color != attr_fgcol(fgshift, c) ||
+	    info->cursor.image.bg_color != attr_bgcol(bgshift, c)) {
+		cursor->image.fg_color = attr_fgcol(fgshift, c);
+		cursor->image.bg_color = attr_bgcol(bgshift, c);
+		cursor->set |= FB_CUR_SETCMAP;
+	}
+	font = vc->vc_font.data + ((c & charmask) * size);
+	if (font != info->cursor.dest) {
+		cursor->dest = font;
+		cursor->set |= FB_CUR_SETDEST;
+	}
+
+	w = (width + 7) >> 3;
+
+	switch (vc->vc_cursor_type & 0x0f) {
+		case CUR_NONE:
+			cur_height = 0;
+			break;
+		case CUR_UNDERLINE:
+			cur_height = (height < 10) ? 1 : 2;
+			break;
+		case CUR_LOWER_THIRD:
+			cur_height = height/3;
+			break;
+		case CUR_LOWER_HALF:
+			cur_height = height/2;
+			break;
+		case CUR_TWO_THIRDS:
+			cur_height = (height * 2)/3;
+			break;
+		case CUR_BLOCK:
+		default:
+			cur_height = height;
+			break;
+	}
+
+	size = (height - cur_height) * w;
+	while (size--)
+		mask[i++] = 0;
+	size = cur_height * w;
+	while (size--)
+		mask[i++] = 0xff;
+
+	if (!info->cursor.mask ||  (memcmp(mask, info->cursor.mask, w*height)))
+		cursor->set |= FB_CUR_SETSHAPE;
+
+	cursor->image.width = width;
+	cursor->image.height = height;
+	cursor->image.dx = vc->vc_x * width;
+	cursor->image.dy = yy * height;
+	cursor->image.depth = 0;
+	cursor->image.data = data;
+	cursor->mask = mask;
+	cursor->rop = ROP_XOR;
+
+	info->fbops->fb_cursor(info, cursor);
+	kfree(data);
+	kfree(mask);
+}
+	
 static void fbcon_cursor(struct vc_data *vc, int mode)
 {
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
 	struct display *p = &fb_display[vc->vc_num];
+	struct fb_cursor cursor;
 	int y = vc->vc_y;
 
 	if (mode & CM_SOFTBACK) {
@@ -1221,56 +1074,54 @@
 		fbcon_set_origin(vc);
 
 	/* Avoid flickering if there's no real change. */
-	if (p->cursor_x == vc->vc_x && p->cursor_y == y &&
-	    (mode == CM_ERASE) == !cursor_on)
+	if ((mode == CM_ERASE) == !cursor_on)
 		return;
 
 	cursor_on = 0;
-	if (cursor_drawn)
-		accel_cursor(p, 0, p->cursor_x,
-				  real_y(p, p->cursor_y));
-
-	p->cursor_x = vc->vc_x;
-	p->cursor_y = y;
-	p->cursor_pos = vc->vc_pos;
 
 	switch (mode) {
 	case CM_ERASE:
+		if (cursor_drawn) {
+			cursor.set = 0;
+			accel_cursor(vc, info, &cursor,
+				     real_y(p, y));
+		}	
 		cursor_drawn = 0;
 		break;
 	case CM_MOVE:
 	case CM_DRAW:
-		if (cursor_drawn)
-			accel_cursor(p, FB_CUR_SETCUR, p->cursor_x,
-					  real_y(p, p->cursor_y));
+		if (cursor_drawn) {
+			cursor.set = FB_CUR_SETCUR;
+			accel_cursor(vc, info, &cursor, 
+				     real_y(p, y));
+		}	
 		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
 		cursor_on = 1;
 		break;
 	}
-
 }
 
-static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp)
+static void fb_vbl_handler(int irq, void *dev_id, struct pt_regs *fp)
 {
-	struct display *p;
-
+	struct fb_info *info = dev_id;
+	struct display *p = &fb_display[fg_console];
+	struct vc_data *vc = vc_cons[fg_console].d;
+	struct fb_cursor cursor;
+	
 	if (!cursor_on)
 		return;
 
 	if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {
-		int flag;
+		cursor.set = 0;
 
-		p = &fb_display[fg_console];
-		flag = 0;
 		if (!cursor_drawn)
-			flag = FB_CUR_SETCUR;
-		accel_cursor(p, flag, p->cursor_x,
-				  real_y(p, p->cursor_y));
+			cursor.set = FB_CUR_SETCUR;
+		accel_cursor(vc, info, &cursor, real_y(p, vc->vc_y));
 		cursor_drawn ^= 1;
-		vbl_cursor_cnt = cursor_blink_rate;
+		vbl_cursor_cnt = cursor_blink_rate; 
 	}
-}
-
+}	
+	
 static int scrollback_phys_max = 0;
 static int scrollback_max = 0;
 static int scrollback_current = 0;
@@ -1279,15 +1130,14 @@
 {
 	if (con == info->currcon) 
 		return fb_pan_display(&info->var, info);
-
 	return 0;
 }
 
-static __inline__ void ywrap_up(struct display *p, struct vc_data *vc,
-				int count)
+static __inline__ void ywrap_up(struct vc_data *vc, int count)
 {
-	struct fb_info *info = p->fb_info;
-
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
+	
 	p->yscroll += count;
 	if (p->yscroll >= p->vrows)	/* Deal with wrap */
 		p->yscroll -= p->vrows;
@@ -1301,11 +1151,11 @@
 	scrollback_current = 0;
 }
 
-static __inline__ void ywrap_down(struct display *p, struct vc_data *vc,
-				  int count)
+static __inline__ void ywrap_down(struct vc_data *vc, int count)
 {
-	struct fb_info *info = p->fb_info;
-
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
+	
 	p->yscroll -= count;
 	if (p->yscroll < 0)	/* Deal with wrap */
 		p->yscroll += p->vrows;
@@ -1319,45 +1169,44 @@
 	scrollback_current = 0;
 }
 
-static __inline__ void ypan_up(struct display *p, struct vc_data *vc,
-			       int count)
+static __inline__ void ypan_up(struct vc_data *vc, int count)
 {
-	struct fb_info *info = p->fb_info;
-
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
+	
 	p->yscroll += count;
 	if (p->yscroll > p->vrows - vc->vc_rows) {
-		accel_bmove(p, p->vrows - vc->vc_rows, 0, 0, 0,
-				 vc->vc_rows, vc->vc_cols);
+		accel_bmove(vc, info, p->vrows - vc->vc_rows, 
+			 	0, 0, 0, vc->vc_rows, vc->vc_cols);
 		p->yscroll -= p->vrows - vc->vc_rows;
 	}
 	info->var.xoffset = 0;
 	info->var.yoffset = p->yscroll * vc->vc_font.height;
 	info->var.vmode &= ~FB_VMODE_YWRAP;
 	update_var(vc->vc_num, info);
-	accel_clear_margins(vc, p, 1);
+	accel_clear_margins(vc, info, 1);
 	scrollback_max += count;
 	if (scrollback_max > scrollback_phys_max)
 		scrollback_max = scrollback_phys_max;
 	scrollback_current = 0;
 }
 
-
-static __inline__ void ypan_down(struct display *p, struct vc_data *vc,
-				 int count)
+static __inline__ void ypan_down(struct vc_data *vc, int count)
 {
-	struct fb_info *info = p->fb_info;
-
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
+	
 	p->yscroll -= count;
 	if (p->yscroll < 0) {
-		accel_bmove(p, 0, 0, p->vrows - vc->vc_rows, 0,
-				 vc->vc_rows, vc->vc_cols);
+		accel_bmove(vc, info, 0, 0, p->vrows - vc->vc_rows,
+			 	0, vc->vc_rows, vc->vc_cols);
 		p->yscroll += p->vrows - vc->vc_rows;
 	}
 	info->var.xoffset = 0;
 	info->var.yoffset = p->yscroll * vc->vc_font.height;
 	info->var.vmode &= ~FB_VMODE_YWRAP;
 	update_var(vc->vc_num, info);
-	accel_clear_margins(vc, p, 1);
+	accel_clear_margins(vc, info, 1);
 	scrollback_max -= count;
 	if (scrollback_max < 0)
 		scrollback_max = 0;
@@ -1367,10 +1216,11 @@
 static void fbcon_redraw_softback(struct vc_data *vc, struct display *p,
 				  long delta)
 {
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	int count = vc->vc_rows;
 	unsigned short *d, *s;
 	unsigned long n;
 	int line = 0;
-	int count = vc->vc_rows;
 
 	d = (u16 *) softback_curr;
 	if (d == (u16 *) softback_in)
@@ -1423,20 +1273,16 @@
 			if (attr != (c & 0xff00)) {
 				attr = c & 0xff00;
 				if (s > start) {
-					accel_putcs(vc, p, start,
-							 s - start,
-							 real_y(p, line),
-							 x);
+					accel_putcs(vc, info, start, s - start,
+						    real_y(p, line), x);
 					x += s - start;
 					start = s;
 				}
 			}
 			if (c == scr_readw(d)) {
 				if (s > start) {
-					accel_putcs(vc, p, start,
-							 s - start,
-							 real_y(p, line),
-							 x);
+					accel_putcs(vc, info, start, s - start,
+						    real_y(p, line), x);
 					x += s - start + 1;
 					start = s + 1;
 				} else {
@@ -1448,8 +1294,8 @@
 			d++;
 		} while (s < le);
 		if (s > start)
-			accel_putcs(vc, p, start, s - start,
-					 real_y(p, line), x);
+			accel_putcs(vc, info, start, s - start,
+				    real_y(p, line), x);
 		line++;
 		if (d == (u16 *) softback_end)
 			d = (u16 *) softback_buf;
@@ -1467,6 +1313,7 @@
 {
 	unsigned short *d = (unsigned short *)
 	    (vc->vc_origin + vc->vc_size_row * line);
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
 	unsigned short *s = d + offset;
 
 	while (count--) {
@@ -1481,20 +1328,16 @@
 			if (attr != (c & 0xff00)) {
 				attr = c & 0xff00;
 				if (s > start) {
-					accel_putcs(vc, p, start,
-							 s - start,
-							 real_y(p, line),
-							 x);
+					accel_putcs(vc, info, start, s - start,
+						    real_y(p, line), x);
 					x += s - start;
 					start = s;
 				}
 			}
 			if (c == scr_readw(d)) {
 				if (s > start) {
-					accel_putcs(vc, p, start,
-							 s - start,
-							 real_y(p, line),
-							 x);
+					accel_putcs(vc, info, start, s - start,
+						    real_y(p, line), x);
 					x += s - start + 1;
 					start = s + 1;
 				} else {
@@ -1508,8 +1351,8 @@
 			d++;
 		} while (s < le);
 		if (s > start)
-			accel_putcs(vc, p, start, s - start,
-					 real_y(p, line), x);
+			accel_putcs(vc, info, start, s - start,
+				    real_y(p, line), x);
 		console_conditional_schedule();
 		if (offset > 0)
 			line++;
@@ -1522,98 +1365,6 @@
 	}
 }
 
-/**
- *	fbcon_redraw_clear - clear area of the screen
- *	@vc: stucture pointing to current active virtual console
- *	@p: display structure
- *	@sy: starting Y coordinate
- *	@sx: starting X coordinate
- *	@height: height of area to clear
- *	@width: width of area to clear
- *
- *	Clears a specified area of the screen.  All dimensions are in
- *	pixels.
- *
- */
-
-void fbcon_redraw_clear(struct vc_data *vc, struct display *p, int sy,
-			int sx, int height, int width)
-{
-	int x, y;
-	for (y = 0; y < height; y++)
-		for (x = 0; x < width; x++)
-			fbcon_putc(vc, ' ', sy + y, sx + x);
-}
-
-
-/**
- *	fbcon_redraw_bmove - copy area of screen to another area
- *	@p: display structure
- *	@sy: origin Y coordinate
- *	@sx: origin X coordinate
- *	@dy: destination Y coordinate
- *	@dx: destination X coordinate
- *	@h: height of area to copy
- *	@w: width of area to copy
- *
- *	Copies an area of the screen to another area of the same screen.
- *	All dimensions are in pixels.
- *
- *	Note that this function cannot be used together with ypan or
- *	ywrap.
- *
- */
-
-void fbcon_redraw_bmove(struct vc_data *vc, struct display *p, int sy, int sx, int dy, int dx,
-			int h, int w)
-{
-	if (sy != dy)
-		panic("fbcon_redraw_bmove width sy != dy");
-	/* h will be always 1, but it does not matter if we are more generic */
-
-	while (h-- > 0) {
-		unsigned short *d = (unsigned short *)
-		    (vc->vc_origin + vc->vc_size_row * dy + dx * 2);
-		unsigned short *s = d + (dx - sx);
-		unsigned short *start = d;
-		unsigned short *ls = d;
-		unsigned short *le = d + w;
-		unsigned short c;
-		int x = dx;
-		unsigned short attr = 1;
-
-		do {
-			c = scr_readw(d);
-			if (attr != (c & 0xff00)) {
-				attr = c & 0xff00;
-				if (d > start) {
-					accel_putcs(vc, p, start,
-							 d - start, dy, x);
-					x += d - start;
-					start = d;
-				}
-			}
-			if (s >= ls && s < le && c == scr_readw(s)) {
-				if (d > start) {
-					accel_putcs(vc, p, start,
-							 d - start, dy, x);
-					x += d - start + 1;
-					start = d + 1;
-				} else {
-					x++;
-					start++;
-				}
-			}
-			s++;
-			d++;
-		} while (d < le);
-		if (d > start)
-			accel_putcs(vc, p, start, d - start, dy, x);
-		sy++;
-		dy++;
-	}
-}
-
 static inline void fbcon_softback_note(struct vc_data *vc, int t,
 				       int count)
 {
@@ -1642,14 +1393,14 @@
 static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
 			int count)
 {
-	int unit = vc->vc_num;
-	struct display *p = &fb_display[unit];
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
 	int scroll_partial = !(p->scrollmode & __SCROLL_YNOPARTIAL);
 
-	if (!p->can_soft_blank && console_blanked)
+	if (!info->fbops->fb_blank && console_blanked)
 		return 0;
 
-	if (!count || vt_cons[unit]->vc_mode != KD_TEXT)
+	if (!count || vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
 		return 0;
 
 	fbcon_cursor(vc, CM_ERASE);
@@ -1670,9 +1421,9 @@
 			goto redraw_up;
 		switch (p->scrollmode & __SCROLL_YMASK) {
 		case __SCROLL_YMOVE:
-			accel_bmove(p, t + count, 0, t, 0,
+			accel_bmove(vc, info, t + count, 0, t, 0,
 					 b - t - count, vc->vc_cols);
-			accel_clear(vc, p, b - count, 0, count,
+			accel_clear(vc, info, b - count, 0, count,
 					 vc->vc_cols);
 			break;
 
@@ -1681,7 +1432,7 @@
 				if (t > 0)
 					fbcon_bmove(vc, 0, 0, count, 0, t,
 						    vc->vc_cols);
-				ywrap_up(p, vc, count);
+				ywrap_up(vc, count);
 				if (vc->vc_rows - b > 0)
 					fbcon_bmove(vc, b - count, 0, b, 0,
 						    vc->vc_rows - b,
@@ -1704,7 +1455,7 @@
 				if (t > 0)
 					fbcon_bmove(vc, 0, 0, count, 0, t,
 						    vc->vc_cols);
-				ypan_up(p, vc, count);
+				ypan_up(vc, count);
 				if (vc->vc_rows - b > 0)
 					fbcon_bmove(vc, b - count, 0, b, 0,
 						    vc->vc_rows - b,
@@ -1721,7 +1472,7 @@
 		      redraw_up:
 			fbcon_redraw(vc, p, t, b - t - count,
 				     count * vc->vc_cols);
-			accel_clear(vc, p, real_y(p, b - count), 0,
+			accel_clear(vc, info, real_y(p, b - count), 0,
 					 count, vc->vc_cols);
 			scr_memsetw((unsigned short *) (vc->vc_origin +
 							vc->vc_size_row *
@@ -1737,9 +1488,9 @@
 			count = vc->vc_rows;
 		switch (p->scrollmode & __SCROLL_YMASK) {
 		case __SCROLL_YMOVE:
-			accel_bmove(p, t, 0, t + count, 0,
+			accel_bmove(vc, info, t, 0, t + count, 0,
 					 b - t - count, vc->vc_cols);
-			accel_clear(vc, p, t, 0, count, vc->vc_cols);
+			accel_clear(vc, info, t, 0, count, vc->vc_cols);
 			break;
 
 		case __SCROLL_YWRAP:
@@ -1748,7 +1499,7 @@
 					fbcon_bmove(vc, b, 0, b - count, 0,
 						    vc->vc_rows - b,
 						    vc->vc_cols);
-				ywrap_down(p, vc, count);
+				ywrap_down(vc, count);
 				if (t > 0)
 					fbcon_bmove(vc, count, 0, 0, 0, t,
 						    vc->vc_cols);
@@ -1770,7 +1521,7 @@
 					fbcon_bmove(vc, b, 0, b - count, 0,
 						    vc->vc_rows - b,
 						    vc->vc_cols);
-				ypan_down(p, vc, count);
+				ypan_down(vc, count);
 				if (t > 0)
 					fbcon_bmove(vc, count, 0, 0, 0, t,
 						    vc->vc_cols);
@@ -1786,7 +1537,7 @@
 		      redraw_down:
 			fbcon_redraw(vc, p, b - 1, b - t - count,
 				     -count * vc->vc_cols);
-			accel_clear(vc, p, real_y(p, t), 0, count,
+			accel_clear(vc, info, real_y(p, t), 0, count,
 					 vc->vc_cols);
 			scr_memsetw((unsigned short *) (vc->vc_origin +
 							vc->vc_size_row *
@@ -1803,21 +1554,15 @@
 static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
 			int height, int width)
 {
-	int unit = vc->vc_num;
-	struct display *p = &fb_display[unit];
-
-	if (!p->can_soft_blank && console_blanked)
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
+	
+	if (!info->fbops->fb_blank && console_blanked)
 		return;
 
 	if (!width || !height)
 		return;
 
-	if (((sy <= p->cursor_y) && (p->cursor_y < sy + height) &&
-	     (sx <= p->cursor_x) && (p->cursor_x < sx + width)) ||
-	    ((dy <= p->cursor_y) && (p->cursor_y < dy + height) &&
-	     (dx <= p->cursor_x) && (p->cursor_x < dx + width)))
-		fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK);
-
 	/*  Split blits that cross physical y_wrap case.
 	 *  Pathological case involves 4 blits, better to use recursive
 	 *  code rather than unrolled case
@@ -1825,26 +1570,27 @@
 	 *  Recursive invocations don't need to erase the cursor over and
 	 *  over again, so we use fbcon_bmove_rec()
 	 */
-	fbcon_bmove_rec(p, sy, sx, dy, dx, height, width,
+	fbcon_bmove_rec(vc, p, sy, sx, dy, dx, height, width,
 			p->vrows - p->yscroll);
 }
 
-static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy,
-			    int dx, int height, int width, u_int y_break)
+static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, 
+			    int dy, int dx, int height, int width, u_int y_break)
 {
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
 	u_int b;
 
 	if (sy < y_break && sy + height > y_break) {
 		b = y_break - sy;
 		if (dy < sy) {	/* Avoid trashing self */
-			fbcon_bmove_rec(p, sy, sx, dy, dx, b, width,
+			fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
 					y_break);
-			fbcon_bmove_rec(p, sy + b, sx, dy + b, dx,
+			fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
 					height - b, width, y_break);
 		} else {
-			fbcon_bmove_rec(p, sy + b, sx, dy + b, dx,
+			fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
 					height - b, width, y_break);
-			fbcon_bmove_rec(p, sy, sx, dy, dx, b, width,
+			fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
 					y_break);
 		}
 		return;
@@ -1853,47 +1599,57 @@
 	if (dy < y_break && dy + height > y_break) {
 		b = y_break - dy;
 		if (dy < sy) {	/* Avoid trashing self */
-			fbcon_bmove_rec(p, sy, sx, dy, dx, b, width,
+			fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
 					y_break);
-			fbcon_bmove_rec(p, sy + b, sx, dy + b, dx,
+			fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
 					height - b, width, y_break);
 		} else {
-			fbcon_bmove_rec(p, sy + b, sx, dy + b, dx,
+			fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
 					height - b, width, y_break);
-			fbcon_bmove_rec(p, sy, sx, dy, dx, b, width,
+			fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
 					y_break);
 		}
 		return;
 	}
-	accel_bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height,
-			 width);
+	accel_bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
+			height, width);
 }
 
-
 static int fbcon_resize(struct vc_data *vc, unsigned int width, 
 			unsigned int height)
 {
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
 	struct display *p = &fb_display[vc->vc_num];
-	struct fb_info *info = p->fb_info;
 	struct fb_var_screeninfo var = info->var;
-	int err;
-
-	var.xres = width * vc->vc_font.width;
-	var.yres = height * vc->vc_font.height;
-	var.activate = FB_ACTIVATE_NOW;
-
-	err = fb_set_var(&var, info);
-	return  (err || var.xres != info->var.xres ||
-		 var.yres != info->var.yres) ?
-		-EINVAL : 0;
-	  
+	int err; int x_diff, y_diff;
+	int fw = vc->vc_font.width;
+	int fh = vc->vc_font.height;
+
+	var.xres = width * fw;
+	var.yres = height * fh;
+	x_diff = info->var.xres - var.xres;
+	y_diff = info->var.yres - var.yres;
+	if (x_diff < 0 || x_diff > fw ||
+	   (y_diff < 0 || y_diff > fh)) {
+		var.activate = FB_ACTIVATE_TEST;
+		err = fb_set_var(&var, info);
+		if (err || width > var.xres/fw ||
+		    height > var.yres/fh)
+			return -EINVAL;
+		DPRINTK("resize now %ix%i\n", var.xres, var.yres);
+		var.activate = FB_ACTIVATE_NOW;
+		fb_set_var(&var, info);
+	}
+	p->vrows = var.yres_virtual/fh;
+	if(var.yres > (fh * (height + 1)))
+		p->vrows -= (var.yres - (fh * height)) / fh;
+	return 0;
 }
 
 static int fbcon_switch(struct vc_data *vc)
 {
-	int unit = vc->vc_num;
-	struct display *p = &fb_display[unit];
-	struct fb_info *info = p->fb_info;
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
 
 	if (softback_top) {
 		int l = fbcon_softback_size / vc->vc_size_row;
@@ -1920,6 +1676,7 @@
 	}
 	if (info)
 		info->var.yoffset = p->yscroll = 0;
+        fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
 	switch (p->scrollmode & __SCROLL_YMASK) {
 	case __SCROLL_YWRAP:
 		scrollback_phys_max = p->vrows - vc->vc_rows;
@@ -1936,17 +1693,17 @@
 	scrollback_max = 0;
 	scrollback_current = 0;
 
-	info->currcon = unit;
+	info->currcon = vc->vc_num;
 	
-        fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
-	update_var(unit, info);
+	update_var(vc->vc_num, info);
 	fbcon_set_palette(vc, color_table); 	
 
-	if (vt_cons[unit]->vc_mode == KD_TEXT)
-		accel_clear_margins(vc, p, 0);
+	if (vt_cons[vc->vc_num]->vc_mode == KD_TEXT)
+		accel_clear_margins(vc, info, 0);
 	if (logo_shown == -2) {
 		logo_shown = fg_console;
-		fb_show_logo(info);	/* This is protected above by initmem_freed */
+		/* This is protected above by initmem_freed */
+		fb_show_logo(info);
 		update_region(fg_console,
 			      vc->vc_origin + vc->vc_size_row * vc->vc_top,
 			      vc->vc_size_row * (vc->vc_bottom -
@@ -1958,40 +1715,34 @@
 
 static int fbcon_blank(struct vc_data *vc, int blank)
 {
+	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
 	struct display *p = &fb_display[vc->vc_num];
-	struct fb_info *info = p->fb_info;
 
 	if (blank < 0)		/* Entering graphics mode */
 		return 0;
 
 	fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
 
-	if (!p->can_soft_blank) {
+	if (!info->fbops->fb_blank) {
 		if (blank) {
 			unsigned short oldc;
 			u_int height;
 			u_int y_break;
 
 			oldc = vc->vc_video_erase_char;
-			vc->vc_video_erase_char &= p->charmask;
+			vc->vc_video_erase_char &= charmask;
 			height = vc->vc_rows;
 			y_break = p->vrows - p->yscroll;
 			if (height > y_break) {
-				accel_clear(vc, p,
-						 real_y(p, 0), 0,
-						 y_break,
-						 vc->vc_cols);
-				accel_clear(vc, p,
-						 real_y(p,
-						y_break),
-						0,
-						 height - y_break,
-						 vc->vc_cols);
+				accel_clear(vc, info, real_y(p, 0),
+					    0, y_break, vc->vc_cols);
+				accel_clear(vc, info, real_y(p, y_break),
+					    0, height - y_break, 
+					    vc->vc_cols);
 			} else
-				accel_clear(vc, p,
-						 real_y(p, 0), 0,
-						 height,
-						 vc->vc_cols);
+				accel_clear(vc, info, real_y(p, 0),
+					    0, height, vc->vc_cols);
 			vc->vc_video_erase_char = oldc;
 		} else
 			update_screen(vc->vc_num);
@@ -2010,14 +1761,13 @@
 
 static inline int fbcon_get_font(struct vc_data *vc, struct console_font_op *op)
 {
-	struct display *p = &fb_display[vc->vc_num];
+	u8 *fontdata = vc->vc_font.data;
 	u8 *data = op->data;
-	u8 *fontdata = p->fontdata;
 	int i, j;
 
 	op->width = vc->vc_font.width;
 	op->height = vc->vc_font.height;
-	op->charcount = (p->charmask == 0x1ff) ? 512 : 256;
+	op->charcount = vc->vc_hi_font_mask ? 512 : 256;
 	if (!op->data)
 		return 0;
 
@@ -2063,15 +1813,15 @@
 static int fbcon_do_set_font(struct vc_data *vc, struct console_font_op *op,
 			     u8 * data, int userfont)
 {
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
 	struct display *p = &fb_display[vc->vc_num];
-	struct fb_info *info = p->fb_info;
 	int resize;
 	int w = op->width;
 	int h = op->height;
 	int cnt;
 	char *old_data = NULL;
 
-	if (!fontwidthvalid(p, w)) {
+	if (!w > 32) {
 		if (userfont && op->op != KD_FONT_OP_COPY)
 			kfree(data - FONT_EXTRA_WORDS * sizeof(int));
 		return -ENXIO;
@@ -2082,12 +1832,12 @@
 
 	resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
 	if (p->userfont)
-		old_data = p->fontdata;
+		old_data = vc->vc_font.data;
 	if (userfont)
 		cnt = FNTCHARCNT(data);
 	else
 		cnt = 256;
-	p->fontdata = data;
+	vc->vc_font.data = p->fontdata = data;
 	if ((p->userfont = userfont))
 		REFCOUNT(data)++;
 	vc->vc_font.width = w;
@@ -2096,9 +1846,6 @@
 		vc->vc_hi_font_mask = 0;
 		if (vc->vc_can_do_color)
 			vc->vc_complement_mask >>= 1;
-		p->fgshift--;
-		p->bgshift--;
-		p->charmask = 0xff;
 
 		/* ++Edmund: reorder the attribute bits */
 		if (vc->vc_can_do_color) {
@@ -2116,14 +1863,10 @@
 			    ((c & 0xfe00) >> 1) | (c & 0xff);
 			vc->vc_attr >>= 1;
 		}
-
 	} else if (!vc->vc_hi_font_mask && cnt == 512) {
 		vc->vc_hi_font_mask = 0x100;
 		if (vc->vc_can_do_color)
 			vc->vc_complement_mask <<= 1;
-		p->fgshift++;
-		p->bgshift++;
-		p->charmask = 0x1ff;
 
 		/* ++Edmund: reorder the attribute bits */
 		{
@@ -2157,6 +1900,11 @@
 		/* reset wrap/pan */
 		info->var.xoffset = info->var.yoffset = p->yscroll = 0;
 		p->vrows = info->var.yres_virtual / h;
+
+#if 0          /* INCOMPLETE - let the console gurus handle this */
+		if(info->var.yres > (h * (vc->vc_rows + 1))
+			p->vrows -= (info->var.yres - (h * vc->vc_rows)) / h;
+#endif
 		if ((info->var.yres % h)
 		    && (info->var.yres_virtual % h < info->var.yres % h))
 			p->vrows--;
@@ -2175,7 +1923,7 @@
 		}
 	} else if (CON_IS_VISIBLE(vc)
 		   && vt_cons[vc->vc_num]->vc_mode == KD_TEXT) {
-		accel_clear_margins(vc, p, 0);
+		accel_clear_margins(vc, info, 0);
 		update_screen(vc->vc_num);
 	}
 
@@ -2186,7 +1934,7 @@
 
 static inline int fbcon_copy_font(struct vc_data *vc, struct console_font_op *op)
 {
-	struct display *od, *p = &fb_display[vc->vc_num];
+	struct display *od;
 	int h = op->height;
 
 	if (h < 0 || !vc_cons_allocated(h))
@@ -2194,7 +1942,7 @@
 	if (h == vc->vc_num)
 		return 0;	/* nothing to do */
 	od = &fb_display[h];
-	if (od->fontdata == p->fontdata)
+	if (od->fontdata == vc->vc_font.data)
 		return 0;	/* already the same font... */
 	op->width = vc->vc_font.width;
 	op->height = vc->vc_font.height;
@@ -2289,10 +2037,9 @@
 
 static inline int fbcon_set_def_font(struct vc_data *vc, struct console_font_op *op)
 {
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
 	char name[MAX_FONT_NAME];
 	struct font_desc *f;
-	struct display *p = &fb_display[vc->vc_num];
-	struct fb_info *info = p->fb_info;
 
 	if (!op->data)
 		f = get_default_font(info->var.xres, info->var.yres);
@@ -2334,13 +2081,12 @@
 
 static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
 {
-	struct display *p = &fb_display[vc->vc_num];
-	struct fb_info *info = p->fb_info;
+	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
 	int i, j, k;
 	u8 val;
 
 	if (!vc->vc_can_do_color
-	    || (!p->can_soft_blank && console_blanked))
+	    || (!info->fbops->fb_blank && console_blanked))
 		return -EINVAL;
 	for (i = j = 0; i < 16; i++) {
 		k = table[i];
@@ -2361,9 +2107,9 @@
 
 static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
 {
-	int line;
 	unsigned long p;
-
+	int line;
+	
 	if (vc->vc_num != fg_console || !softback_lines)
 		return (u16 *) (vc->vc_origin + offset);
 	line = offset / vc->vc_size_row;
@@ -2379,8 +2125,9 @@
 static unsigned long fbcon_getxy(struct vc_data *vc, unsigned long pos,
 				 int *px, int *py)
 {
-	int x, y;
 	unsigned long ret;
+	int x, y;
+
 	if (pos >= vc->vc_origin && pos < vc->vc_scr_end) {
 		unsigned long offset = (pos - vc->vc_origin) / 2;
 
@@ -2438,18 +2185,14 @@
 
 static int fbcon_scrolldelta(struct vc_data *vc, int lines)
 {
-	int unit, offset, limit, scrollback_old;
-	struct fb_info *info;
-	struct display *p;
-
-	unit = fg_console;
-	p = &fb_display[unit];
-	info = p->fb_info;
+	struct fb_info *info = registered_fb[(int) con2fb_map[fg_console]];
+	struct display *p = &fb_display[fg_console];
+	int offset, limit, scrollback_old;
 
 	if (softback_top) {
-		if (vc->vc_num != unit)
+		if (vc->vc_num != fg_console)
 			return 0;
-		if (vt_cons[unit]->vc_mode != KD_TEXT || !lines)
+		if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT || !lines)
 			return 0;
 		if (logo_shown >= 0) {
 			struct vc_data *conp2 = vc_cons[logo_shown].d;
@@ -2457,7 +2200,7 @@
 			if (conp2->vc_top == logo_lines
 			    && conp2->vc_bottom == conp2->vc_rows)
 				conp2->vc_top = 0;
-			if (logo_shown == unit) {
+			if (logo_shown == vc->vc_num) {
 				unsigned long p, q;
 				int i;
 
@@ -2475,7 +2218,7 @@
 						    vc->vc_size_row);
 				}
 				softback_in = p;
-				update_region(unit, vc->vc_origin,
+				update_region(vc->vc_num, vc->vc_origin,
 					      logo_lines * vc->vc_cols);
 			}
 			logo_shown = -1;
@@ -2498,8 +2241,8 @@
 	if (scrollback_current == scrollback_old)
 		return 0;
 
-	if (!p->can_soft_blank &&
-	    (console_blanked || vt_cons[unit]->vc_mode != KD_TEXT
+	if (!info->fbops->fb_blank &&
+	    (console_blanked || vt_cons[vc->vc_num]->vc_mode != KD_TEXT
 	     || !lines))
 		return 0;
 	fbcon_cursor(vc, CM_ERASE);
@@ -2521,7 +2264,7 @@
 		offset -= limit;
 	info->var.xoffset = 0;
 	info->var.yoffset = offset * vc->vc_font.height;
-	update_var(unit, info);
+	update_var(vc->vc_num, info);
 	if (!scrollback_current)
 		fbcon_cursor(vc, CM_DRAW);
 	return 0;
@@ -2581,8 +2324,6 @@
  */
 
 EXPORT_SYMBOL(fb_display);
-EXPORT_SYMBOL(fbcon_redraw_bmove);
-EXPORT_SYMBOL(fbcon_redraw_clear);
 EXPORT_SYMBOL(fb_con);
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
--- a/drivers/video/console/fbcon.h	Sat Dec 21 13:15:36 2002
+++ b/drivers/video/console/fbcon.h	Mon Mar 17 16:00:31 2003
@@ -25,59 +25,42 @@
 
 struct display {
     /* Filled in by the frame buffer device */
-    u_short can_soft_blank;         /* zero if no hardware blanking */
     u_short inverse;                /* != 0 text black on white as default */
-    struct display_switch *dispsw;  /* low level operations */
-
     /* Filled in by the low-level console driver */
-    struct vc_data *conp;           /* pointer to console data */
-    struct fb_info *fb_info;        /* frame buffer for this console */
-    int vrows;                      /* number of virtual rows */
-    unsigned short cursor_x;        /* current cursor position */
-    unsigned short cursor_y;
-    unsigned long cursor_pos;
     char fontname[40];              /* Font associated to this display */	
     u_char *fontdata;
     int userfont;                   /* != 0 if fontdata kmalloc()ed */
     u_short scrollmode;             /* Scroll Method */
     short yscroll;                  /* Hardware scrolling */
-    unsigned char fgshift, bgshift;
-    unsigned short charmask;        /* 0xff or 0x1ff */
-    unsigned int fontwidthmask;      /* 1 at (1 << (width - 1)) if width is supported */
+    int vrows;                      /* number of virtual rows */
 };
 
 /* drivers/video/console/fbcon.c */
-extern struct display fb_display[MAX_NR_CONSOLES];
 extern char con2fb_map[MAX_NR_CONSOLES];
 extern void set_con2fb_map(int unit, int newidx);
 
-/* fontwidth w is supported by dispsw */
-#define FONTWIDTH(w)	(1 << ((w) - 1))
-/* fontwidths w1-w2 inclusive are supported by dispsw */
-#define FONTWIDTHRANGE(w1,w2)	(FONTWIDTH(w2+1) - FONTWIDTH(w1))
-
     /*
      *  Attribute Decoding
      */
 
 /* Color */
-#define attr_fgcol(p,s)    \
-	(((s) >> ((p)->fgshift)) & 0x0f)
-#define attr_bgcol(p,s)    \
-	(((s) >> ((p)->bgshift)) & 0x0f)
-#define	attr_bgcol_ec(p,conp) \
-	((conp) ? (((conp)->vc_video_erase_char >> ((p)->bgshift)) & 0x0f) : 0)
-#define attr_fgcol_ec(p,vc) \
-	((vc) ? (((vc)->vc_video_erase_char >> ((p)->fgshift)) & 0x0f) : 0)
+#define attr_fgcol(fgshift,s)    \
+	(((s) >> (fgshift)) & 0x0f)
+#define attr_bgcol(bgshift,s)    \
+	(((s) >> (bgshift)) & 0x0f)
+#define	attr_bgcol_ec(bgshift,vc) \
+	((vc) ? (((vc)->vc_video_erase_char >> (bgshift)) & 0x0f) : 0)
+#define attr_fgcol_ec(fgshift,vc) \
+	((vc) ? (((vc)->vc_video_erase_char >> (fgshift)) & 0x0f) : 0)
 
 /* Monochrome */
-#define attr_bold(p,s) \
+#define attr_bold(s) \
 	((s) & 0x200)
-#define attr_reverse(p,s) \
-	(((s) & 0x800) ^ ((p)->inverse ? 0x800 : 0))
-#define attr_underline(p,s) \
+#define attr_reverse(s, inverse) \
+	(((s) & 0x800) ^ (inverse ? 0x800 : 0))
+#define attr_underline(s) \
 	((s) & 0x400)
-#define attr_blink(p,s) \
+#define attr_blink(s) \
 	((s) & 0x8000)
 	
     /*
@@ -119,7 +102,6 @@
 /* Namespace consistency */
 #define SCROLL_YNOPARTIAL	__SCROLL_YNOPARTIAL
 
-extern void fbcon_redraw_clear(struct vc_data *, struct display *, int, int, int, int);
-extern void fbcon_redraw_bmove(struct vc_data *, struct display *, int, int, int, int, int, int);
+extern int fb_console_init(void);
 
 #endif /* _VIDEO_FBCON_H */
diff -Nru a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
--- a/drivers/video/console/newport_con.c	Sat Dec 28 10:27:08 2002
+++ b/drivers/video/console/newport_con.c	Thu Feb 13 18:50:29 2003
@@ -26,13 +26,10 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <video/newport.h>
-#define INCLUDE_LINUX_LOGO_DATA
-#include <asm/linux_logo.h>
 
+#include <linux/linux_logo.h>
 #include <linux/font.h>
 
-#define LOGO_W		80
-#define LOGO_H		80
 
 extern struct font_desc font_vga_8x16;
 
@@ -98,30 +95,11 @@
 	}
 }
 
-static inline void newport_show_logo(void)
-{
-	unsigned long i;
-
-	for (i = 0; i < LINUX_LOGO_COLORS; i++) {
-		newport_bfwait();
-		newport_cmap_setaddr(npregs, i + 0x20);
-		newport_cmap_setrgb(npregs,
-				    linux_logo_red[i],
-				    linux_logo_green[i],
-				    linux_logo_blue[i]);
-	}
-
-	newport_wait();
-	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
-				 NPORT_DMODE0_CHOST);
-
-	npregs->set.xystarti = ((newport_xsize - LOGO_W) << 16) | (0);
-	npregs->set.xyendi = ((newport_xsize - 1) << 16);
-	newport_wait();
-
-	for (i = 0; i < LOGO_W * LOGO_H; i++)
-		npregs->go.hostrw0 = linux_logo[i] << 24;
-}
+#ifdef CONFIG_LOGO_SGI_CLUT224
+static void newport_show_logo(void);
+#else
+#define newport_show_logo()	do { } while (0)
+#endif
 
 static inline void newport_clear_screen(int xstart, int ystart, int xend,
 					int yend, int ci)
@@ -743,3 +721,38 @@
 	return 0;
 }
 #endif
+
+
+#ifdef CONFIG_LOGO_SGI_CLUT224
+
+#undef __initdata
+#define __initdata
+#include "../logo/logo_sgi_clut224.c"
+
+static void newport_show_logo(void)
+{
+	const struct linux_logo *logo = &logo_sgi_clut224;
+	const unsigned char *clut = logo->clut;
+	const unsigned char *data = logo->data;
+	unsigned long i;
+
+	for (i = 0; i < logo->clutsize; i++) {
+		newport_bfwait();
+		newport_cmap_setaddr(npregs, i + 0x20);
+		newport_cmap_setrgb(npregs, clut[0], clut[1], clut[2]);
+		clut += 3;
+	}
+
+	newport_wait();
+	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
+				 NPORT_DMODE0_CHOST);
+
+	npregs->set.xystarti = ((newport_xsize - logo->width) << 16) | (0);
+	npregs->set.xyendi = ((newport_xsize - 1) << 16);
+	newport_wait();
+
+	for (i = 0; i < logo->width*logo->height; i++)
+		npregs->go.hostrw0 = *data++ << 24;
+}
+#endif /* CONFIG_LOGO_SGI_CLUT224 */
+
diff -Nru a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
--- a/drivers/video/console/vgacon.c	Fri Nov  8 00:03:28 2002
+++ b/drivers/video/console/vgacon.c	Tue Mar 11 09:17:29 2003
@@ -49,10 +49,11 @@
 #include <linux/spinlock.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
-
+#include <video/vga.h>
 #include <asm/io.h>
 
 static spinlock_t vga_lock = SPIN_LOCK_UNLOCKED;
+static struct vgastate state;
 
 #define BLANK 0x0020
 
@@ -66,16 +67,6 @@
  */
 #undef TRIDENT_GLITCH
 
-#define dac_reg		0x3c8
-#define dac_val		0x3c9
-#define attrib_port	0x3c0
-#define seq_port_reg	0x3c4
-#define seq_port_val	0x3c5
-#define gr_port_reg	0x3ce
-#define gr_port_val	0x3cf
-#define video_misc_rd	0x3cc
-#define video_misc_wr	0x3c2
-
 /*
  *  Interface used by the world
  */
@@ -87,36 +78,38 @@
 static int vgacon_switch(struct vc_data *c);
 static int vgacon_blank(struct vc_data *c, int blank);
 static int vgacon_font_op(struct vc_data *c, struct console_font_op *op);
-static int vgacon_set_palette(struct vc_data *c, unsigned char *table);
+static int vgacon_set_palette(struct vc_data *vc, unsigned char *table);
 static int vgacon_scrolldelta(struct vc_data *c, int lines);
 static int vgacon_set_origin(struct vc_data *c);
 static void vgacon_save_screen(struct vc_data *c);
-static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines);
-static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, u8 blink, u8 underline, u8 reverse);
-static void vgacon_invert_region(struct vc_data *c, u16 *p, int count);
+static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
+			 int lines);
+static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
+			    u8 blink, u8 underline, u8 reverse);
+static void vgacon_invert_region(struct vc_data *c, u16 * p, int count);
 static unsigned long vgacon_uni_pagedir[2];
 
 
 /* Description of the hardware situation */
-static unsigned long   vga_vram_base;		/* Base of video memory */
-static unsigned long   vga_vram_end;		/* End of video memory */
-static u16             vga_video_port_reg;	/* Video register select port */
-static u16             vga_video_port_val;	/* Video register value port */
-static unsigned int    vga_video_num_columns;	/* Number of text columns */
-static unsigned int    vga_video_num_lines;	/* Number of text lines */
-static int	       vga_can_do_color = 0;	/* Do we support colors? */
-static unsigned int    vga_default_font_height;	/* Height of default screen font */
-static unsigned char   vga_video_type;		/* Card type */
-static unsigned char   vga_hardscroll_enabled;
-static unsigned char   vga_hardscroll_user_enable = 1;
-static unsigned char   vga_font_is_default = 1;
-static int	       vga_vesa_blanked;
-static int	       vga_palette_blanked;
-static int	       vga_is_gfx;
-static int	       vga_512_chars;
-static int	       vga_video_font_height;
-static unsigned int    vga_rolled_over = 0;
-
+static unsigned long	vga_vram_base;		/* Base of video memory */
+static unsigned long	vga_vram_end;		/* End of video memory */
+static u16		vga_video_port_reg;	/* Video register select port */
+static u16		vga_video_port_val;	/* Video register value port */
+static unsigned int	vga_video_num_columns;	/* Number of text columns */
+static unsigned int	vga_video_num_lines;	/* Number of text lines */
+static int		vga_can_do_color = 0;	/* Do we support colors? */
+static unsigned int	vga_default_font_height;/* Height of default screen font */
+static unsigned char	vga_video_type;		/* Card type */
+static unsigned char	vga_hardscroll_enabled;
+static unsigned char	vga_hardscroll_user_enable = 1;
+static unsigned char	vga_font_is_default = 1;
+static int		vga_vesa_blanked;
+static int 		vga_palette_blanked;
+static int 		vga_is_gfx;
+static int 		vga_512_chars;
+static int 		vga_video_font_height;
+static int 		vga_scan_lines;
+static unsigned int 	vga_rolled_over = 0;
 
 static int __init no_scroll(char *str)
 {
@@ -147,7 +140,7 @@
 	 * ddprintk might set the console position from interrupt
 	 * handlers, thus the write has to be IRQ-atomic.
 	 */
-	spin_lock_irqsave(&vga_lock, flags);	
+	spin_lock_irqsave(&vga_lock, flags);
 
 #ifndef SLOW_VGA
 	v1 = reg + (val & 0xff00);
@@ -157,7 +150,7 @@
 #else
 	outb_p(reg, vga_video_port_reg);
 	outb_p(val >> 8, vga_video_port_val);
-	outb_p(reg+1, vga_video_port_reg);
+	outb_p(reg + 1, vga_video_port_reg);
 	outb_p(val & 0xff, vga_video_port_val);
 #endif
 	spin_unlock_irqrestore(&vga_lock, flags);
@@ -170,7 +163,7 @@
 	volatile u16 *p;
 
 	if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB) {
-	no_vga:
+	      no_vga:
 #ifdef CONFIG_DUMMY_CONSOLE
 		conswitchp = &dummy_con;
 		return conswitchp->con_startup();
@@ -180,63 +173,68 @@
 	}
 
 	/* VGA16 modes are not handled by VGACON */
-	if ((ORIG_VIDEO_MODE == 0x0D) || /* 320x200/4 */
-	    (ORIG_VIDEO_MODE == 0x0E) || /* 640x200/4 */
-	    (ORIG_VIDEO_MODE == 0x10) || /* 640x350/4 */
-	    (ORIG_VIDEO_MODE == 0x12) || /* 640x480/4 */
-	    (ORIG_VIDEO_MODE == 0x6A))   /* 800x600/4, 0x6A is very common */
+	if ((ORIG_VIDEO_MODE == 0x0D) ||	/* 320x200/4 */
+	    (ORIG_VIDEO_MODE == 0x0E) ||	/* 640x200/4 */
+	    (ORIG_VIDEO_MODE == 0x10) ||	/* 640x350/4 */
+	    (ORIG_VIDEO_MODE == 0x12) ||	/* 640x480/4 */
+	    (ORIG_VIDEO_MODE == 0x6A))	/* 800x600/4, 0x6A is very common */
 		goto no_vga;
 
 	vga_video_num_lines = ORIG_VIDEO_LINES;
 	vga_video_num_columns = ORIG_VIDEO_COLS;
+	state.vgabase = NULL;
 
-	if (ORIG_VIDEO_MODE == 7)	/* Is this a monochrome display? */
-	{
+	if (ORIG_VIDEO_MODE == 7) {	/* Is this a monochrome display? */
 		vga_vram_base = 0xb0000;
-		vga_video_port_reg = 0x3b4;
-		vga_video_port_val = 0x3b5;
-		if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
-		{
-			static struct resource ega_console_resource = { "ega", 0x3B0, 0x3BF };
+		vga_video_port_reg = VGA_CRT_IM;
+		vga_video_port_val = VGA_CRT_DM;
+		if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) {
+			static struct resource ega_console_resource =
+			    { "ega", 0x3B0, 0x3BF };
 			vga_video_type = VIDEO_TYPE_EGAM;
 			vga_vram_end = 0xb8000;
 			display_desc = "EGA+";
-			request_resource(&ioport_resource, &ega_console_resource);
-		}
-		else
-		{
-			static struct resource mda1_console_resource = { "mda", 0x3B0, 0x3BB };
-			static struct resource mda2_console_resource = { "mda", 0x3BF, 0x3BF };
+			request_resource(&ioport_resource,
+					 &ega_console_resource);
+		} else {
+			static struct resource mda1_console_resource =
+			    { "mda", 0x3B0, 0x3BB };
+			static struct resource mda2_console_resource =
+			    { "mda", 0x3BF, 0x3BF };
 			vga_video_type = VIDEO_TYPE_MDA;
 			vga_vram_end = 0xb2000;
 			display_desc = "*MDA";
-			request_resource(&ioport_resource, &mda1_console_resource);
-			request_resource(&ioport_resource, &mda2_console_resource);
+			request_resource(&ioport_resource,
+					 &mda1_console_resource);
+			request_resource(&ioport_resource,
+					 &mda2_console_resource);
 			vga_video_font_height = 14;
 		}
-	}
-	else				/* If not, it is color. */
-	{
+	} else {
+		/* If not, it is color. */
 		vga_can_do_color = 1;
 		vga_vram_base = 0xb8000;
-		vga_video_port_reg = 0x3d4;
-		vga_video_port_val = 0x3d5;
-		if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
-		{
+		vga_video_port_reg = VGA_CRT_IC;
+		vga_video_port_val = VGA_CRT_DC;
+		if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) {
 			int i;
 
 			vga_vram_end = 0xc0000;
 
 			if (!ORIG_VIDEO_ISVGA) {
-				static struct resource ega_console_resource = { "ega", 0x3C0, 0x3DF };
+				static struct resource ega_console_resource
+				    = { "ega", 0x3C0, 0x3DF };
 				vga_video_type = VIDEO_TYPE_EGAC;
 				display_desc = "EGA";
-				request_resource(&ioport_resource, &ega_console_resource);
+				request_resource(&ioport_resource,
+						 &ega_console_resource);
 			} else {
-				static struct resource vga_console_resource = { "vga+", 0x3C0, 0x3DF };
+				static struct resource vga_console_resource
+				    = { "vga+", 0x3C0, 0x3DF };
 				vga_video_type = VIDEO_TYPE_VGAC;
 				display_desc = "VGA+";
-				request_resource(&ioport_resource, &vga_console_resource);
+				request_resource(&ioport_resource,
+						 &vga_console_resource);
 
 #ifdef VGA_CAN_DO_64KB
 				/*
@@ -247,41 +245,41 @@
 				 */
 				vga_vram_base = 0xa0000;
 				vga_vram_end = 0xb0000;
-				outb_p (6, 0x3ce) ;
-				outb_p (6, 0x3cf) ;
+				outb_p(6, VGA_GFX_I);
+				outb_p(6, VGA_GFX_D);
 #endif
-
 				/*
 				 * Normalise the palette registers, to point
 				 * the 16 screen colours to the first 16
 				 * DAC entries.
 				 */
 
-				for (i=0; i<16; i++) {
-					inb_p (0x3da) ;
-					outb_p (i, 0x3c0) ;
-					outb_p (i, 0x3c0) ;
+				for (i = 0; i < 16; i++) {
+					inb_p(VGA_IS1_RC);
+					outb_p(i, VGA_ATT_W);
+					outb_p(i, VGA_ATT_W);
 				}
-				outb_p (0x20, 0x3c0) ;
-
-				/* now set the DAC registers back to their
-				 * default values */
+				outb_p(0x20, VGA_ATT_W);
 
-				for (i=0; i<16; i++) {
-					outb_p (color_table[i], 0x3c8) ;
-					outb_p (default_red[i], 0x3c9) ;
-					outb_p (default_grn[i], 0x3c9) ;
-					outb_p (default_blu[i], 0x3c9) ;
+				/*
+				 * Now set the DAC registers back to their
+				 * default values
+				 */
+				for (i = 0; i < 16; i++) {
+					outb_p(color_table[i], VGA_PEL_IW);
+					outb_p(default_red[i], VGA_PEL_D);
+					outb_p(default_grn[i], VGA_PEL_D);
+					outb_p(default_blu[i], VGA_PEL_D);
 				}
 			}
-		}
-		else
-		{
-			static struct resource cga_console_resource = { "cga", 0x3D4, 0x3D5 };
+		} else {
+			static struct resource cga_console_resource =
+			    { "cga", 0x3D4, 0x3D5 };
 			vga_video_type = VIDEO_TYPE_CGA;
 			vga_vram_end = 0xba000;
 			display_desc = "*CGA";
-			request_resource(&ioport_resource, &cga_console_resource);
+			request_resource(&ioport_resource,
+					 &cga_console_resource);
 			vga_video_font_height = 8;
 		}
 	}
@@ -290,10 +288,10 @@
 	vga_vram_end = VGA_MAP_MEM(vga_vram_end);
 
 	/*
-	 *	Find out if there is a graphics card present.
-	 *	Are there smarter methods around?
+	 *      Find out if there is a graphics card present.
+	 *      Are there smarter methods around?
 	 */
-	p = (volatile u16 *)vga_vram_base;
+	p = (volatile u16 *) vga_vram_base;
 	saved1 = scr_readw(p);
 	saved2 = scr_readw(p + 1);
 	scr_writew(0xAA55, p);
@@ -320,22 +318,22 @@
 		vga_default_font_height = ORIG_VIDEO_POINTS;
 		vga_video_font_height = ORIG_VIDEO_POINTS;
 		/* This may be suboptimal but is a safe bet - go with it */
-		video_scan_lines =
-			vga_video_font_height * vga_video_num_lines;
+		vga_scan_lines =
+		    vga_video_font_height * vga_video_num_lines;
 	}
-	video_font_height = vga_video_font_height;
-
 	return display_desc;
 }
 
 static void vgacon_init(struct vc_data *c, int init)
 {
 	unsigned long p;
-	
+
 	/* We cannot be loaded as a module, therefore init is always 1 */
 	c->vc_can_do_color = vga_can_do_color;
 	c->vc_cols = vga_video_num_columns;
 	c->vc_rows = vga_video_num_lines;
+	c->vc_scan_lines = vga_scan_lines;
+	c->vc_font.height = vga_video_font_height;
 	c->vc_complement_mask = 0x7700;
 	p = *c->vc_uni_pagedir_loc;
 	if (c->vc_uni_pagedir_loc == &c->vc_uni_pagedir ||
@@ -349,7 +347,7 @@
 
 static inline void vga_set_mem_top(struct vc_data *c)
 {
-	write_vga(12, (c->vc_visible_origin-vga_vram_base)/2);
+	write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2);
 }
 
 static void vgacon_deinit(struct vc_data *c)
@@ -364,7 +362,8 @@
 	con_set_default_unimap(c->vc_num);
 }
 
-static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, u8 blink, u8 underline, u8 reverse)
+static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
+			    u8 blink, u8 underline, u8 reverse)
 {
 	u8 attr = color;
 
@@ -375,7 +374,9 @@
 			attr = (attr & 0xf0) | c->vc_halfcolor;
 	}
 	if (reverse)
-		attr = ((attr) & 0x88) | ((((attr) >> 4) | ((attr) << 4)) & 0x77);
+		attr =
+		    ((attr) & 0x88) | ((((attr) >> 4) | ((attr) << 4)) &
+				       0x77);
 	if (blink)
 		attr ^= 0x80;
 	if (intensity == 2)
@@ -389,14 +390,15 @@
 	return attr;
 }
 
-static void vgacon_invert_region(struct vc_data *c, u16 *p, int count)
+static void vgacon_invert_region(struct vc_data *c, u16 * p, int count)
 {
 	int col = vga_can_do_color;
 
 	while (count--) {
 		u16 a = scr_readw(p);
 		if (col)
-			a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
+			a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) |
+			    (((a) & 0x0700) << 4);
 		else
 			a ^= ((a & 0x0700) == 0x0100) ? 0x7000 : 0x7700;
 		scr_writew(a, p++);
@@ -410,70 +412,84 @@
 	static int lastfrom, lastto;
 
 #ifdef TRIDENT_GLITCH
-	if (xpos<16) from--, to--;
+	if (xpos < 16)
+		from--, to--;
 #endif
 
-	if ((from == lastfrom) && (to == lastto)) return;
-	lastfrom = from; lastto = to;
+	if ((from == lastfrom) && (to == lastto))
+		return;
+	lastfrom = from;
+	lastto = to;
 
 	spin_lock_irqsave(&vga_lock, flags);
-	outb_p(0x0a, vga_video_port_reg);		/* Cursor start */
+	outb_p(0x0a, vga_video_port_reg);	/* Cursor start */
 	curs = inb_p(vga_video_port_val);
-	outb_p(0x0b, vga_video_port_reg);		/* Cursor end */
+	outb_p(0x0b, vga_video_port_reg);	/* Cursor end */
 	cure = inb_p(vga_video_port_val);
 
 	curs = (curs & 0xc0) | from;
 	cure = (cure & 0xe0) | to;
 
-	outb_p(0x0a, vga_video_port_reg);		/* Cursor start */
+	outb_p(0x0a, vga_video_port_reg);	/* Cursor start */
 	outb_p(curs, vga_video_port_val);
-	outb_p(0x0b, vga_video_port_reg);		/* Cursor end */
+	outb_p(0x0b, vga_video_port_reg);	/* Cursor end */
 	outb_p(cure, vga_video_port_val);
 	spin_unlock_irqrestore(&vga_lock, flags);
 }
 
 static void vgacon_cursor(struct vc_data *c, int mode)
 {
-    if (c->vc_origin != c->vc_visible_origin)
-	vgacon_scrolldelta(c, 0);
-    switch (mode) {
+	if (c->vc_origin != c->vc_visible_origin)
+		vgacon_scrolldelta(c, 0);
+	switch (mode) {
 	case CM_ERASE:
-	    write_vga(14, (vga_vram_end - vga_vram_base - 1)/2);
-	    break;
+		write_vga(14, (vga_vram_end - vga_vram_base - 1) / 2);
+		break;
 
 	case CM_MOVE:
 	case CM_DRAW:
-	    write_vga(14, (c->vc_pos-vga_vram_base)/2);
-	    switch (c->vc_cursor_type & 0x0f) {
+		write_vga(14, (c->vc_pos - vga_vram_base) / 2);
+		switch (c->vc_cursor_type & 0x0f) {
 		case CUR_UNDERLINE:
-			vgacon_set_cursor_size(c->vc_x, 
-					video_font_height - (video_font_height < 10 ? 2 : 3),
-					video_font_height - (video_font_height < 10 ? 1 : 2));
+			vgacon_set_cursor_size(c->vc_x,
+					       c->vc_font.height -
+					       (c->vc_font.height <
+						10 ? 2 : 3),
+					       c->vc_font.height -
+					       (c->vc_font.height <
+						10 ? 1 : 2));
 			break;
 		case CUR_TWO_THIRDS:
-			vgacon_set_cursor_size(c->vc_x, 
-					 video_font_height / 3,
-					 video_font_height - (video_font_height < 10 ? 1 : 2));
+			vgacon_set_cursor_size(c->vc_x,
+					       c->vc_font.height / 3,
+					       c->vc_font.height -
+					       (c->vc_font.height <
+						10 ? 1 : 2));
 			break;
 		case CUR_LOWER_THIRD:
-			vgacon_set_cursor_size(c->vc_x, 
-					 (video_font_height*2) / 3,
-					 video_font_height - (video_font_height < 10 ? 1 : 2));
+			vgacon_set_cursor_size(c->vc_x,
+					       (c->vc_font.height * 2) / 3,
+					       c->vc_font.height -
+					       (c->vc_font.height <
+						10 ? 1 : 2));
 			break;
 		case CUR_LOWER_HALF:
-			vgacon_set_cursor_size(c->vc_x, 
-					 video_font_height / 2,
-					 video_font_height - (video_font_height < 10 ? 1 : 2));
+			vgacon_set_cursor_size(c->vc_x,
+					       c->vc_font.height / 2,
+					       c->vc_font.height -
+					       (c->vc_font.height <
+						10 ? 1 : 2));
 			break;
 		case CUR_NONE:
 			vgacon_set_cursor_size(c->vc_x, 31, 30);
 			break;
-          	default:
-			vgacon_set_cursor_size(c->vc_x, 1, video_font_height);
+		default:
+			vgacon_set_cursor_size(c->vc_x, 1,
+					       c->vc_font.height);
 			break;
 		}
-	    break;
-    }
+		break;
+	}
 }
 
 static int vgacon_switch(struct vc_data *c)
@@ -486,28 +502,30 @@
 	vga_video_num_columns = c->vc_cols;
 	vga_video_num_lines = c->vc_rows;
 	if (!vga_is_gfx)
-		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size);
-	return 0;	/* Redrawing not needed */
+		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
+			    c->vc_screenbuf_size);
+	return 0;		/* Redrawing not needed */
 }
 
-static void vga_set_palette(struct vc_data *c, unsigned char *table)
+static void vga_set_palette(struct vc_data *vc, unsigned char *table)
 {
-	int i, j ;
+	int i, j;
 
-	for (i=j=0; i<16; i++) {
-		outb_p (table[i], dac_reg) ;
-		outb_p (c->vc_palette[j++]>>2, dac_val) ;
-		outb_p (c->vc_palette[j++]>>2, dac_val) ;
-		outb_p (c->vc_palette[j++]>>2, dac_val) ;
+	for (i = j = 0; i < 16; i++) {
+		vga_w(state.vgabase, VGA_PEL_IW, table[i]);
+		vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
+		vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
+		vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
 	}
 }
 
-static int vgacon_set_palette(struct vc_data *c, unsigned char *table)
+static int vgacon_set_palette(struct vc_data *vc, unsigned char *table)
 {
 #ifdef CAN_LOAD_PALETTE
-	if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked || !CON_IS_VISIBLE(c))
+	if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked
+	    || !CON_IS_VISIBLE(vc))
 		return -EINVAL;
-	vga_set_palette(c, table);
+	vga_set_palette(vc, table);
 	return 0;
 #else
 	return -EINVAL;
@@ -516,59 +534,57 @@
 
 /* structure holding original VGA register settings */
 static struct {
-	unsigned char	SeqCtrlIndex;		/* Sequencer Index reg.   */
-	unsigned char	CrtCtrlIndex;		/* CRT-Contr. Index reg.  */
-	unsigned char	CrtMiscIO;		/* Miscellaneous register */
-	unsigned char	HorizontalTotal;	/* CRT-Controller:00h */
-	unsigned char	HorizDisplayEnd;	/* CRT-Controller:01h */
-	unsigned char	StartHorizRetrace;	/* CRT-Controller:04h */
-	unsigned char	EndHorizRetrace;	/* CRT-Controller:05h */
-	unsigned char	Overflow;		/* CRT-Controller:07h */
-	unsigned char	StartVertRetrace;	/* CRT-Controller:10h */
-	unsigned char	EndVertRetrace;		/* CRT-Controller:11h */
-	unsigned char	ModeControl;		/* CRT-Controller:17h */
-	unsigned char	ClockingMode;		/* Seq-Controller:01h */
+	unsigned char SeqCtrlIndex;	/* Sequencer Index reg.   */
+	unsigned char CrtCtrlIndex;	/* CRT-Contr. Index reg.  */
+	unsigned char CrtMiscIO;	/* Miscellaneous register */
+	unsigned char HorizontalTotal;	/* CRT-Controller:00h */
+	unsigned char HorizDisplayEnd;	/* CRT-Controller:01h */
+	unsigned char StartHorizRetrace;	/* CRT-Controller:04h */
+	unsigned char EndHorizRetrace;	/* CRT-Controller:05h */
+	unsigned char Overflow;	/* CRT-Controller:07h */
+	unsigned char StartVertRetrace;	/* CRT-Controller:10h */
+	unsigned char EndVertRetrace;	/* CRT-Controller:11h */
+	unsigned char ModeControl;	/* CRT-Controller:17h */
+	unsigned char ClockingMode;	/* Seq-Controller:01h */
 } vga_state;
 
-static void vga_vesa_blank(int mode)
+static void vga_vesa_blank(struct vgastate *state, int mode)
 {
 	/* save original values of VGA controller registers */
-	if(!vga_vesa_blanked) {
+	if (!vga_vesa_blanked) {
 		spin_lock_irq(&vga_lock);
-		vga_state.SeqCtrlIndex = inb_p(seq_port_reg);
+		vga_state.SeqCtrlIndex = vga_r(state->vgabase, VGA_SEQ_I);
 		vga_state.CrtCtrlIndex = inb_p(vga_video_port_reg);
-		vga_state.CrtMiscIO = inb_p(video_misc_rd);
+		vga_state.CrtMiscIO = vga_r(state->vgabase, VGA_MIS_R);
 		spin_unlock_irq(&vga_lock);
 
-		outb_p(0x00,vga_video_port_reg);	/* HorizontalTotal */
+		outb_p(0x00, vga_video_port_reg);	/* HorizontalTotal */
 		vga_state.HorizontalTotal = inb_p(vga_video_port_val);
-		outb_p(0x01,vga_video_port_reg);	/* HorizDisplayEnd */
+		outb_p(0x01, vga_video_port_reg);	/* HorizDisplayEnd */
 		vga_state.HorizDisplayEnd = inb_p(vga_video_port_val);
-		outb_p(0x04,vga_video_port_reg);	/* StartHorizRetrace */
+		outb_p(0x04, vga_video_port_reg);	/* StartHorizRetrace */
 		vga_state.StartHorizRetrace = inb_p(vga_video_port_val);
-		outb_p(0x05,vga_video_port_reg);	/* EndHorizRetrace */
+		outb_p(0x05, vga_video_port_reg);	/* EndHorizRetrace */
 		vga_state.EndHorizRetrace = inb_p(vga_video_port_val);
-		outb_p(0x07,vga_video_port_reg);	/* Overflow */
+		outb_p(0x07, vga_video_port_reg);	/* Overflow */
 		vga_state.Overflow = inb_p(vga_video_port_val);
-		outb_p(0x10,vga_video_port_reg);	/* StartVertRetrace */
+		outb_p(0x10, vga_video_port_reg);	/* StartVertRetrace */
 		vga_state.StartVertRetrace = inb_p(vga_video_port_val);
-		outb_p(0x11,vga_video_port_reg);	/* EndVertRetrace */
+		outb_p(0x11, vga_video_port_reg);	/* EndVertRetrace */
 		vga_state.EndVertRetrace = inb_p(vga_video_port_val);
-		outb_p(0x17,vga_video_port_reg);	/* ModeControl */
+		outb_p(0x17, vga_video_port_reg);	/* ModeControl */
 		vga_state.ModeControl = inb_p(vga_video_port_val);
-		outb_p(0x01,seq_port_reg);		/* ClockingMode */
-		vga_state.ClockingMode = inb_p(seq_port_val);
+		vga_state.ClockingMode = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
 	}
 
 	/* assure that video is enabled */
 	/* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
 	spin_lock_irq(&vga_lock);
-	outb_p(0x01,seq_port_reg);
-	outb_p(vga_state.ClockingMode | 0x20,seq_port_val);
+	vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, vga_state.ClockingMode | 0x20);
 
 	/* test for vertical retrace in process.... */
 	if ((vga_state.CrtMiscIO & 0x80) == 0x80)
-		outb_p(vga_state.CrtMiscIO & 0xef,video_misc_wr);
+		vga_w(state->vgabase, VGA_MIS_W, vga_state.CrtMiscIO & 0xEF);
 
 	/*
 	 * Set <End of vertical retrace> to minimum (0) and
@@ -576,12 +592,12 @@
 	 * Result: turn off vertical sync (VSync) pulse.
 	 */
 	if (mode & VESA_VSYNC_SUSPEND) {
-		outb_p(0x10,vga_video_port_reg);	/* StartVertRetrace */
-		outb_p(0xff,vga_video_port_val); 	/* maximum value */
-		outb_p(0x11,vga_video_port_reg);	/* EndVertRetrace */
-		outb_p(0x40,vga_video_port_val);	/* minimum (bits 0..3)  */
-		outb_p(0x07,vga_video_port_reg);	/* Overflow */
-		outb_p(vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */
+		outb_p(0x10, vga_video_port_reg);	/* StartVertRetrace */
+		outb_p(0xff, vga_video_port_val);	/* maximum value */
+		outb_p(0x11, vga_video_port_reg);	/* EndVertRetrace */
+		outb_p(0x40, vga_video_port_val);	/* minimum (bits 0..3)  */
+		outb_p(0x07, vga_video_port_reg);	/* Overflow */
+		outb_p(vga_state.Overflow | 0x84, vga_video_port_val);	/* bits 9,10 of vert. retrace */
 	}
 
 	if (mode & VESA_HSYNC_SUSPEND) {
@@ -590,67 +606,67 @@
 		 *  <Start of horizontal Retrace> to maximum
 		 * Result: turn off horizontal sync (HSync) pulse.
 		 */
-		outb_p(0x04,vga_video_port_reg);	/* StartHorizRetrace */
-		outb_p(0xff,vga_video_port_val);	/* maximum */
-		outb_p(0x05,vga_video_port_reg);	/* EndHorizRetrace */
-		outb_p(0x00,vga_video_port_val);	/* minimum (0) */
+		outb_p(0x04, vga_video_port_reg);	/* StartHorizRetrace */
+		outb_p(0xff, vga_video_port_val);	/* maximum */
+		outb_p(0x05, vga_video_port_reg);	/* EndHorizRetrace */
+		outb_p(0x00, vga_video_port_val);	/* minimum (0) */
 	}
 
 	/* restore both index registers */
-	outb_p(vga_state.SeqCtrlIndex,seq_port_reg);
-	outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg);
+	vga_w(state->vgabase, VGA_SEQ_I, vga_state.SeqCtrlIndex);
+	outb_p(vga_state.CrtCtrlIndex, vga_video_port_reg);
 	spin_unlock_irq(&vga_lock);
 }
 
-static void vga_vesa_unblank(void)
+static void vga_vesa_unblank(struct vgastate *state)
 {
 	/* restore original values of VGA controller registers */
 	spin_lock_irq(&vga_lock);
-	outb_p(vga_state.CrtMiscIO,video_misc_wr);
+	vga_w(state->vgabase, VGA_MIS_W, vga_state.CrtMiscIO);
 
-	outb_p(0x00,vga_video_port_reg);		/* HorizontalTotal */
-	outb_p(vga_state.HorizontalTotal,vga_video_port_val);
-	outb_p(0x01,vga_video_port_reg);		/* HorizDisplayEnd */
-	outb_p(vga_state.HorizDisplayEnd,vga_video_port_val);
-	outb_p(0x04,vga_video_port_reg);		/* StartHorizRetrace */
-	outb_p(vga_state.StartHorizRetrace,vga_video_port_val);
-	outb_p(0x05,vga_video_port_reg);		/* EndHorizRetrace */
-	outb_p(vga_state.EndHorizRetrace,vga_video_port_val);
-	outb_p(0x07,vga_video_port_reg);		/* Overflow */
-	outb_p(vga_state.Overflow,vga_video_port_val);
-	outb_p(0x10,vga_video_port_reg);		/* StartVertRetrace */
-	outb_p(vga_state.StartVertRetrace,vga_video_port_val);
-	outb_p(0x11,vga_video_port_reg);		/* EndVertRetrace */
-	outb_p(vga_state.EndVertRetrace,vga_video_port_val);
-	outb_p(0x17,vga_video_port_reg);		/* ModeControl */
-	outb_p(vga_state.ModeControl,vga_video_port_val);
-	outb_p(0x01,seq_port_reg);		/* ClockingMode */
-	outb_p(vga_state.ClockingMode,seq_port_val);
+	outb_p(0x00, vga_video_port_reg);	/* HorizontalTotal */
+	outb_p(vga_state.HorizontalTotal, vga_video_port_val);
+	outb_p(0x01, vga_video_port_reg);	/* HorizDisplayEnd */
+	outb_p(vga_state.HorizDisplayEnd, vga_video_port_val);
+	outb_p(0x04, vga_video_port_reg);	/* StartHorizRetrace */
+	outb_p(vga_state.StartHorizRetrace, vga_video_port_val);
+	outb_p(0x05, vga_video_port_reg);	/* EndHorizRetrace */
+	outb_p(vga_state.EndHorizRetrace, vga_video_port_val);
+	outb_p(0x07, vga_video_port_reg);	/* Overflow */
+	outb_p(vga_state.Overflow, vga_video_port_val);
+	outb_p(0x10, vga_video_port_reg);	/* StartVertRetrace */
+	outb_p(vga_state.StartVertRetrace, vga_video_port_val);
+	outb_p(0x11, vga_video_port_reg);	/* EndVertRetrace */
+	outb_p(vga_state.EndVertRetrace, vga_video_port_val);
+	outb_p(0x17, vga_video_port_reg);	/* ModeControl */
+	outb_p(vga_state.ModeControl, vga_video_port_val);
+	/* ClockingMode */
+	vga_wseq(state->vgabase, VGA_SEQ_CLOCK_MODE, vga_state.ClockingMode);
 
 	/* restore index/control registers */
-	outb_p(vga_state.SeqCtrlIndex,seq_port_reg);
-	outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg);
+	vga_w(state->vgabase, VGA_SEQ_I, vga_state.SeqCtrlIndex);
+	outb_p(vga_state.CrtCtrlIndex, vga_video_port_reg);
 	spin_unlock_irq(&vga_lock);
 }
 
-static void vga_pal_blank(void)
+static void vga_pal_blank(struct vgastate *state)
 {
 	int i;
 
-	for (i=0; i<16; i++) {
-		outb_p (i, dac_reg) ;
-		outb_p (0, dac_val) ;
-		outb_p (0, dac_val) ;
-		outb_p (0, dac_val) ;
+	for (i = 0; i < 16; i++) {
+		vga_w(state->vgabase, VGA_PEL_IW, i);
+		vga_w(state->vgabase, VGA_PEL_D, 0);
+		vga_w(state->vgabase, VGA_PEL_D, 0);
+		vga_w(state->vgabase, VGA_PEL_D, 0);
 	}
 }
 
 static int vgacon_blank(struct vc_data *c, int blank)
 {
 	switch (blank) {
-	case 0:				/* Unblank */
+	case 0:		/* Unblank */
 		if (vga_vesa_blanked) {
-			vga_vesa_unblank();
+			vga_vesa_unblank(&state);
 			vga_vesa_blanked = 0;
 		}
 		if (vga_palette_blanked) {
@@ -661,22 +677,24 @@
 		vga_is_gfx = 0;
 		/* Tell console.c that it has to restore the screen itself */
 		return 1;
-	case 1:				/* Normal blanking */
+	case 1:		/* Normal blanking */
 		if (vga_video_type == VIDEO_TYPE_VGAC) {
-			vga_pal_blank();
+			vga_pal_blank(&state);
 			vga_palette_blanked = 1;
 			return 0;
 		}
 		vgacon_set_origin(c);
-		scr_memsetw((void *)vga_vram_base, BLANK, c->vc_screenbuf_size);
+		scr_memsetw((void *) vga_vram_base, BLANK,
+			    c->vc_screenbuf_size);
 		return 1;
-	case -1:			/* Entering graphic mode */
-		scr_memsetw((void *)vga_vram_base, BLANK, c->vc_screenbuf_size);
+	case -1:		/* Entering graphic mode */
+		scr_memsetw((void *) vga_vram_base, BLANK,
+			    c->vc_screenbuf_size);
 		vga_is_gfx = 1;
 		return 1;
-	default:			/* VESA blanking */
+	default:		/* VESA blanking */
 		if (vga_video_type == VIDEO_TYPE_VGAC) {
-			vga_vesa_blank(blank-1);
+			vga_vesa_blank(&state, blank - 1);
 			vga_vesa_blanked = blank;
 		}
 		return 0;
@@ -703,38 +721,35 @@
 #define blackwmap 0xa0000
 #define cmapsz 8192
 
-static int
-vgacon_do_font_op(char *arg, int set, int ch512)
+static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
 {
-	int i;
-	char *charmap;
-	int beg;
 	unsigned short video_port_status = vga_video_port_reg + 6;
-	int font_select = 0x00;
-
+	int font_select = 0x00, beg, i;
+	char *charmap;
+	
 	if (vga_video_type != VIDEO_TYPE_EGAM) {
-		charmap = (char *)VGA_MAP_MEM(colourmap);
+		charmap = (char *) VGA_MAP_MEM(colourmap);
 		beg = 0x0e;
 #ifdef VGA_CAN_DO_64KB
 		if (vga_video_type == VIDEO_TYPE_VGAC)
 			beg = 0x06;
 #endif
 	} else {
-		charmap = (char *)VGA_MAP_MEM(blackwmap);
+		charmap = (char *) VGA_MAP_MEM(blackwmap);
 		beg = 0x0a;
 	}
-	
+
 #ifdef BROKEN_GRAPHICS_PROGRAMS
 	/*
 	 * All fonts are loaded in slot 0 (0:1 for 512 ch)
 	 */
 
 	if (!arg)
-		return -EINVAL;		/* Return to default font not supported */
+		return -EINVAL;	/* Return to default font not supported */
 
 	vga_font_is_default = 0;
 	font_select = ch512 ? 0x04 : 0x00;
-#else	
+#else
 	/*
 	 * The default font is kept in slot 0 and is never touched.
 	 * A custom font is loaded in slot 2 (256 ch) or 2:3 (512 ch)
@@ -743,38 +758,38 @@
 	if (set) {
 		vga_font_is_default = !arg;
 		if (!arg)
-			ch512 = 0;		/* Default font is always 256 */
+			ch512 = 0;	/* Default font is always 256 */
 		font_select = arg ? (ch512 ? 0x0e : 0x0a) : 0x00;
 	}
 
-	if ( !vga_font_is_default )
-		charmap += 4*cmapsz;
+	if (!vga_font_is_default)
+		charmap += 4 * cmapsz;
 #endif
 
 	spin_lock_irq(&vga_lock);
-	outb_p( 0x00, seq_port_reg );   /* First, the sequencer */
-	outb_p( 0x01, seq_port_val );   /* Synchronous reset */
-	outb_p( 0x02, seq_port_reg );
-	outb_p( 0x04, seq_port_val );   /* CPU writes only to map 2 */
-	outb_p( 0x04, seq_port_reg );
-	outb_p( 0x07, seq_port_val );   /* Sequential addressing */
-	outb_p( 0x00, seq_port_reg );
-	outb_p( 0x03, seq_port_val );   /* Clear synchronous reset */
-
-	outb_p( 0x04, gr_port_reg );    /* Now, the graphics controller */
-	outb_p( 0x02, gr_port_val );    /* select map 2 */
-	outb_p( 0x05, gr_port_reg );
-	outb_p( 0x00, gr_port_val );    /* disable odd-even addressing */
-	outb_p( 0x06, gr_port_reg );
-	outb_p( 0x00, gr_port_val );    /* map start at A000:0000 */
+	/* First, the Sequencer */
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
+	/* CPU writes only to map 2 */
+	vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x04);	
+	/* Sequential addressing */
+	vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x07);	
+	/* Clear synchronous reset */
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x03);
+
+	/* Now, the graphics controller, select map 2 */
+	vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x02);		
+	/* disable odd-even addressing */
+	vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x00);
+	/* map start at A000:0000 */
+	vga_wgfx(state->vgabase, VGA_GFX_MISC, 0x00);
 	spin_unlock_irq(&vga_lock);
-	
+
 	if (arg) {
 		if (set)
-			for (i=0; i<cmapsz ; i++)
+			for (i = 0; i < cmapsz; i++)
 				vga_writeb(arg[i], charmap + i);
 		else
-			for (i=0; i<cmapsz ; i++)
+			for (i = 0; i < cmapsz; i++)
 				arg[i] = vga_readb(charmap + i);
 
 		/*
@@ -783,56 +798,57 @@
 		 */
 
 		if (ch512) {
-			charmap += 2*cmapsz;
+			charmap += 2 * cmapsz;
 			arg += cmapsz;
 			if (set)
-				for (i=0; i<cmapsz ; i++)
-					vga_writeb(arg[i], charmap+i);
+				for (i = 0; i < cmapsz; i++)
+					vga_writeb(arg[i], charmap + i);
 			else
-				for (i=0; i<cmapsz ; i++)
-					arg[i] = vga_readb(charmap+i);
+				for (i = 0; i < cmapsz; i++)
+					arg[i] = vga_readb(charmap + i);
 		}
 	}
-	
-	spin_lock_irq(&vga_lock);
-	outb_p( 0x00, seq_port_reg );   /* First, the sequencer */
-	outb_p( 0x01, seq_port_val );   /* Synchronous reset */
-	outb_p( 0x02, seq_port_reg );
-	outb_p( 0x03, seq_port_val );   /* CPU writes to maps 0 and 1 */
-	outb_p( 0x04, seq_port_reg );
-	outb_p( 0x03, seq_port_val );   /* odd-even addressing */
-	if (set) {
-		outb_p( 0x03, seq_port_reg ); /* Character Map Select */
-		outb_p( font_select, seq_port_val );
-	}
-	outb_p( 0x00, seq_port_reg );
-	outb_p( 0x03, seq_port_val );   /* clear synchronous reset */
 
-	outb_p( 0x04, gr_port_reg );    /* Now, the graphics controller */
-	outb_p( 0x00, gr_port_val );    /* select map 0 for CPU */
-	outb_p( 0x05, gr_port_reg );
-	outb_p( 0x10, gr_port_val );    /* enable even-odd addressing */
-	outb_p( 0x06, gr_port_reg );
-	outb_p( beg, gr_port_val );     /* map starts at b800:0 or b000:0 */
+	spin_lock_irq(&vga_lock);
+	/* First, the sequencer, Synchronous reset */
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x01);	
+	/* CPU writes to maps 0 and 1 */
+	vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x03);
+	/* odd-even addressing */
+	vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x03);
+	/* Character Map Select */
+	if (set)
+		vga_wseq(state->vgabase, VGA_SEQ_CHARACTER_MAP, font_select);
+	/* clear synchronous reset */
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x03);
+
+	/* Now, the graphics controller, select map 0 for CPU */
+	vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x00);
+	/* enable even-odd addressing */
+	vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x10);
+	/* map starts at b800:0 or b000:0 */
+	vga_wgfx(state->vgabase, VGA_GFX_MISC, beg);
 
 	/* if 512 char mode is already enabled don't re-enable it. */
-	if ((set)&&(ch512!=vga_512_chars)) {	/* attribute controller */
-		int i;
-		for(i=0; i<MAX_NR_CONSOLES; i++) {
+	if ((set) && (ch512 != vga_512_chars)) {
+		int i;	
+		
+		/* attribute controller */
+		for (i = 0; i < MAX_NR_CONSOLES; i++) {
 			struct vc_data *c = vc_cons[i].d;
 			if (c && c->vc_sw == &vga_con)
 				c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
 		}
-		vga_512_chars=ch512;
+		vga_512_chars = ch512;
 		/* 256-char: enable intensity bit
 		   512-char: disable intensity bit */
-		inb_p( video_port_status );	/* clear address flip-flop */
-		outb_p ( 0x12, attrib_port ); /* color plane enable register */
-		outb_p ( ch512 ? 0x07 : 0x0f, attrib_port );
+		inb_p(video_port_status);	/* clear address flip-flop */
+		/* color plane enable register */
+		vga_wattr(state->vgabase, VGA_ATC_PLANE_ENABLE, ch512 ? 0x07 : 0x0f);
 		/* Wilton (1987) mentions the following; I don't know what
 		   it means, but it works, and it appears necessary */
-		inb_p( video_port_status );
-		outb_p ( 0x20, attrib_port );
+		inb_p(video_port_status);
+		vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0);	
 	}
 	spin_unlock_irq(&vga_lock);
 	return 0;
@@ -841,19 +857,18 @@
 /*
  * Adjust the screen to fit a font of a certain height
  */
-static int
-vgacon_adjust_height(unsigned fontheight)
+static int vgacon_adjust_height(struct vc_data *vc, unsigned fontheight)
 {
 	unsigned char ovr, vde, fsr;
 	int rows, maxscan, i;
 
-	if (fontheight == vga_video_font_height)
+	if (fontheight == vc->vc_font.height)
 		return 0;
 
-	vga_video_font_height = video_font_height = fontheight;
+	vc->vc_font.height = fontheight;
 
-	rows = video_scan_lines/fontheight;	/* Number of video rows we end up with */
-	maxscan = rows*fontheight - 1;		/* Scan lines to actually display-1 */
+	rows = vc->vc_scan_lines / fontheight;	/* Number of video rows we end up with */
+	maxscan = rows * fontheight - 1;	/* Scan lines to actually display-1 */
 
 	/* Reprogram the CRTC for the new font size
 	   Note: the attempt to read the overflow register will fail
@@ -866,26 +881,25 @@
 	   are all don't care bits on EGA, so I guess it doesn't matter. */
 
 	spin_lock_irq(&vga_lock);
-	outb_p( 0x07, vga_video_port_reg );		/* CRTC overflow register */
+	outb_p(0x07, vga_video_port_reg);	/* CRTC overflow register */
 	ovr = inb_p(vga_video_port_val);
-	outb_p( 0x09, vga_video_port_reg );		/* Font size register */
+	outb_p(0x09, vga_video_port_reg);	/* Font size register */
 	fsr = inb_p(vga_video_port_val);
 	spin_unlock_irq(&vga_lock);
 
-	vde = maxscan & 0xff;			/* Vertical display end reg */
-	ovr = (ovr & 0xbd) +			/* Overflow register */
-	      ((maxscan & 0x100) >> 7) +
-	      ((maxscan & 0x200) >> 3);
-	fsr = (fsr & 0xe0) + (fontheight-1);    /*  Font size register */
+	vde = maxscan & 0xff;	/* Vertical display end reg */
+	ovr = (ovr & 0xbd) +	/* Overflow register */
+	    ((maxscan & 0x100) >> 7) + ((maxscan & 0x200) >> 3);
+	fsr = (fsr & 0xe0) + (fontheight - 1);	/*  Font size register */
 
 	spin_lock_irq(&vga_lock);
-	outb_p( 0x07, vga_video_port_reg );		/* CRTC overflow register */
-	outb_p( ovr, vga_video_port_val );
-	outb_p( 0x09, vga_video_port_reg );		/* Font size */
-	outb_p( fsr, vga_video_port_val );
-	outb_p( 0x12, vga_video_port_reg );		/* Vertical display limit */
-	outb_p( vde, vga_video_port_val );
-	spin_unlock_irq(&vga_lock);	
+	outb_p(0x07, vga_video_port_reg);	/* CRTC overflow register */
+	outb_p(ovr, vga_video_port_val);
+	outb_p(0x09, vga_video_port_reg);	/* Font size */
+	outb_p(fsr, vga_video_port_val);
+	outb_p(0x12, vga_video_port_reg);	/* Vertical display limit */
+	outb_p(vde, vga_video_port_val);
+	spin_unlock_irq(&vga_lock);
 
 	for (i = 0; i < MAX_NR_CONSOLES; i++) {
 		struct vc_data *c = vc_cons[i].d;
@@ -904,17 +918,19 @@
 		return -EINVAL;
 
 	if (op->op == KD_FONT_OP_SET) {
-		if (op->width != 8 || (op->charcount != 256 && op->charcount != 512))
+		if (op->width != 8
+		    || (op->charcount != 256 && op->charcount != 512))
 			return -EINVAL;
-		rc = vgacon_do_font_op(op->data, 1, op->charcount == 512);
+		rc = vgacon_do_font_op(&state, op->data, 1, op->charcount == 512);
 		if (!rc && !(op->flags & KD_FONT_FLAG_DONT_RECALC))
-			rc = vgacon_adjust_height(op->height);
+			rc = vgacon_adjust_height(c, op->height);
 	} else if (op->op == KD_FONT_OP_GET) {
 		op->width = 8;
-		op->height = vga_video_font_height;
+		op->height = c->vc_font.height;
 		op->charcount = vga_512_chars ? 512 : 256;
-		if (!op->data) return 0;
-		rc = vgacon_do_font_op(op->data, 0, 0);
+		if (!op->data)
+			return 0;
+		rc = vgacon_do_font_op(&state, op->data, 0, 0);
 	} else
 		rc = -ENOSYS;
 	return rc;
@@ -931,21 +947,23 @@
 
 static int vgacon_scrolldelta(struct vc_data *c, int lines)
 {
-	if (!lines)			/* Turn scrollback off */
+	if (!lines)		/* Turn scrollback off */
 		c->vc_visible_origin = c->vc_origin;
 	else {
 		int vram_size = vga_vram_end - vga_vram_base;
 		int margin = c->vc_size_row * 4;
 		int ul, we, p, st;
 
-		if (vga_rolled_over > (c->vc_scr_end - vga_vram_base) + margin) {
+		if (vga_rolled_over >
+		    (c->vc_scr_end - vga_vram_base) + margin) {
 			ul = c->vc_scr_end - vga_vram_base;
 			we = vga_rolled_over + c->vc_size_row;
 		} else {
 			ul = 0;
 			we = vram_size;
 		}
-		p = (c->vc_visible_origin - vga_vram_base - ul + we) % we + lines * c->vc_size_row;
+		p = (c->vc_visible_origin - vga_vram_base - ul + we) % we +
+		    lines * c->vc_size_row;
 		st = (c->vc_origin - vga_vram_base - ul + we) % we;
 		if (p < margin)
 			p = 0;
@@ -982,46 +1000,52 @@
 		c->vc_y = ORIG_Y;
 	}
 	if (!vga_is_gfx)
-		scr_memcpyw((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin, c->vc_screenbuf_size);
+		scr_memcpyw((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin,
+			    c->vc_screenbuf_size);
 }
 
-static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
+static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
+			 int lines)
 {
 	unsigned long oldo;
 	unsigned int delta;
-	
+
 	if (t || b != c->vc_rows || vga_is_gfx)
 		return 0;
 
 	if (c->vc_origin != c->vc_visible_origin)
 		vgacon_scrolldelta(c, 0);
 
-	if (!vga_hardscroll_enabled || lines >= c->vc_rows/2)
+	if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2)
 		return 0;
 
 	oldo = c->vc_origin;
 	delta = lines * c->vc_size_row;
 	if (dir == SM_UP) {
 		if (c->vc_scr_end + delta >= vga_vram_end) {
-			scr_memcpyw((u16 *)vga_vram_base,
-				    (u16 *)(oldo + delta),
+			scr_memcpyw((u16 *) vga_vram_base,
+				    (u16 *) (oldo + delta),
 				    c->vc_screenbuf_size - delta);
 			c->vc_origin = vga_vram_base;
 			vga_rolled_over = oldo - vga_vram_base;
 		} else
 			c->vc_origin += delta;
-		scr_memsetw((u16 *)(c->vc_origin + c->vc_screenbuf_size - delta), c->vc_video_erase_char, delta);
+		scr_memsetw((u16 *) (c->vc_origin + c->vc_screenbuf_size -
+				     delta), c->vc_video_erase_char,
+			    delta);
 	} else {
 		if (oldo - delta < vga_vram_base) {
-			scr_memmovew((u16 *)(vga_vram_end - c->vc_screenbuf_size + delta),
-				     (u16 *)oldo,
+			scr_memmovew((u16 *) (vga_vram_end -
+					      c->vc_screenbuf_size +
+					      delta), (u16 *) oldo,
 				     c->vc_screenbuf_size - delta);
 			c->vc_origin = vga_vram_end - c->vc_screenbuf_size;
 			vga_rolled_over = 0;
 		} else
 			c->vc_origin -= delta;
 		c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
-		scr_memsetw((u16 *)(c->vc_origin), c->vc_video_erase_char, delta);
+		scr_memsetw((u16 *) (c->vc_origin), c->vc_video_erase_char,
+			    delta);
 	}
 	c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
 	c->vc_visible_origin = c->vc_origin;
@@ -1043,24 +1067,24 @@
 #define DUMMY (void *) vgacon_dummy
 
 const struct consw vga_con = {
-	.con_startup =		vgacon_startup,
-	.con_init =		vgacon_init,
-	.con_deinit =		vgacon_deinit,
-	.con_clear =		DUMMY,
-	.con_putc =		DUMMY,
-	.con_putcs =		DUMMY,
-	.con_cursor =		vgacon_cursor,
-	.con_scroll =		vgacon_scroll,
-	.con_bmove =		DUMMY,
-	.con_switch =		vgacon_switch,
-	.con_blank =		vgacon_blank,
-	.con_font_op =		vgacon_font_op,
-	.con_set_palette =	vgacon_set_palette,
-	.con_scrolldelta =	vgacon_scrolldelta,
-	.con_set_origin =	vgacon_set_origin,
-	.con_save_screen =	vgacon_save_screen,
-	.con_build_attr =	vgacon_build_attr,
-	.con_invert_region =	vgacon_invert_region,
+	.con_startup = vgacon_startup,
+	.con_init = vgacon_init,
+	.con_deinit = vgacon_deinit,
+	.con_clear = DUMMY,
+	.con_putc = DUMMY,
+	.con_putcs = DUMMY,
+	.con_cursor = vgacon_cursor,
+	.con_scroll = vgacon_scroll,
+	.con_bmove = DUMMY,
+	.con_switch = vgacon_switch,
+	.con_blank = vgacon_blank,
+	.con_font_op = vgacon_font_op,
+	.con_set_palette = vgacon_set_palette,
+	.con_scrolldelta = vgacon_scrolldelta,
+	.con_set_origin = vgacon_set_origin,
+	.con_save_screen = vgacon_save_screen,
+	.con_build_attr = vgacon_build_attr,
+	.con_invert_region = vgacon_invert_region,
 };
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/controlfb.c b/drivers/video/controlfb.c
--- a/drivers/video/controlfb.c	Mon Feb 24 09:56:37 2003
+++ b/drivers/video/controlfb.c	Thu Mar 20 06:36:41 2003
@@ -43,7 +43,6 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/fb.h>
-#include <linux/selection.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/nvram.h>
@@ -162,7 +161,6 @@
 
 static struct fb_info_control *control_fb;
 
-static char fontname[40] __initdata = { 0 };
 static int default_vmode __initdata = VMODE_NVRAM;
 static int default_cmode __initdata = CMODE_NVRAM;
 
@@ -178,6 +176,7 @@
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
 };
 
 
diff -Nru a/drivers/video/dnfb.c b/drivers/video/dnfb.c
--- a/drivers/video/dnfb.c	Fri Nov 22 13:46:59 2002
+++ b/drivers/video/dnfb.c	Fri Mar 21 14:13:56 2003
@@ -103,17 +103,12 @@
 
 #define SWAP(A) ((A>>8) | ((A&0xff) <<8))
 
-#if 0
-#define outb(a,d) *(char *)(a)=(d)
-#define outw(a,d) *(unsigned short *)a=d
-#endif
-
 static struct fb_info fb_info;
 
 /* frame buffer operations */
 
 static int dnfb_blank(int blank, struct fb_info *info);
-static void dnfb_copyarea(struct fb_info *info, struct fb_copyarea *area);
+static void dnfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
 
 static struct fb_ops dn_fb_ops = {
 	.owner		= THIS_MODULE,
@@ -147,25 +142,24 @@
 static int dnfb_blank(int blank, struct fb_info *info)
 {
 	if (blank)
-		outb(0x0, AP_CONTROL_3A);
+		out_8(AP_CONTROL_3A, 0x0);
 	else
-		outb(0x1, AP_CONTROL_3A);
+		out_8(AP_CONTROL_3A, 0x1);
 	return 0;
 }
 
 static 
-void dnfb_copyarea(struct fb_info *info, struct fb_copyarea *area)
+void dnfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
 
 	int incr, y_delta, pre_read = 0, x_end, x_word_count;
-	ushort *src, dummy;
 	uint start_mask, end_mask, dest;
+	ushort *src, dummy;
 	short i, j;
 
 	incr = (area->dy <= area->sy) ? 1 : -1;
 
-	src =
-	    (ushort *) (info->screen_base + area->sy * info->fix.line_length +
+	src = (ushort *)(info->screen_base + area->sy * info->fix.line_length +
 			(area->sx >> 4));
 	dest = area->dy * (info->fix.line_length >> 1) + (area->dx >> 4);
 
@@ -175,8 +169,8 @@
 		x_word_count = (x_end >> 4) - (area->dx >> 4) + 1;
 		start_mask = 0xffff0000 >> (area->dx & 0xf);
 		end_mask = 0x7ffff >> (x_end & 0xf);
-		outb((((area->dx & 0xf) - (area->sx & 0xf)) % 16) | (0x4 << 5),
-		     AP_CONTROL_0);
+		out_8(AP_CONTROL_0,
+		     (((area->dx & 0xf) - (area->sx & 0xf)) % 16) | (0x4 << 5));
 		if ((area->dx & 0xf) < (area->sx & 0xf))
 			pre_read = 1;
 	} else {
@@ -185,15 +179,16 @@
 		x_word_count = (area->dx >> 4) - (x_end >> 4) + 1;
 		start_mask = 0x7ffff >> (area->dx & 0xf);
 		end_mask = 0xffff0000 >> (x_end & 0xf);
-		outb(((-((area->sx & 0xf) - (area->dx & 0xf))) %
-		      16) | (0x4 << 5), AP_CONTROL_0);
+		out_8(AP_CONTROL_0,
+		     ((-((area->sx & 0xf) - (area->dx & 0xf))) % 16) |
+		     (0x4 << 5));
 		if ((area->dx & 0xf) > (area->sx & 0xf))
 			pre_read = 1;
 	}
 
 	for (i = 0; i < area->height; i++) {
 
-		outb(0xc | (dest >> 16), AP_CONTROL_3A);
+		out_8(AP_CONTROL_3A, 0xc | (dest >> 16));
 
 		if (pre_read) {
 			dummy = *src;
@@ -201,11 +196,11 @@
 		}
 
 		if (x_word_count) {
-			outb(start_mask, AP_WRITE_ENABLE);
+			out_8(AP_WRITE_ENABLE, start_mask);
 			*src = dest;
 			src += incr;
 			dest += incr;
-			outb(0, AP_WRITE_ENABLE);
+			out_8(AP_WRITE_ENABLE, 0);
 
 			for (j = 1; j < (x_word_count - 1); j++) {
 				*src = dest;
@@ -213,12 +208,12 @@
 				dest += incr;
 			}
 
-			outb(start_mask, AP_WRITE_ENABLE);
+			out_8(AP_WRITE_ENABLE, start_mask);
 			*src = dest;
 			dest += incr;
 			src += incr;
 		} else {
-			outb(start_mask | end_mask, AP_WRITE_ENABLE);
+			out_8(AP_WRITE_ENABLE, start_mask | end_mask);
 			*src = dest;
 			dest += incr;
 			src += incr;
@@ -226,7 +221,7 @@
 		src += (y_delta / 16);
 		dest += (y_delta / 16);
 	}
-	outb(NORMAL_MODE, AP_CONTROL_0);
+	out_8(AP_CONTROL_0, NORMAL_MODE);
 }
 
 
@@ -247,12 +242,12 @@
 		panic("unable to register apollo frame buffer\n");
 
 	/* now we have registered we can safely setup the hardware */
-	outb(RESET_CREG, AP_CONTROL_3A);
-	outw(0x0, AP_WRITE_ENABLE);
-	outb(NORMAL_MODE, AP_CONTROL_0);
-	outb((AD_BLT | DST_EQ_SRC | NORM_CREG1), AP_CONTROL_1);
-	outb(S_DATA_PLN, AP_CONTROL_2);
-	outw(SWAP(0x3), AP_ROP_1);
+	out_8(AP_CONTROL_3A, RESET_CREG);
+	out_be16(AP_WRITE_ENABLE, 0x0);
+	out_8(AP_CONTROL_0, NORMAL_MODE);
+	out_8(AP_CONTROL_1, (AD_BLT | DST_EQ_SRC | NORM_CREG1));
+	out_8(AP_CONTROL_2, S_DATA_PLN);
+	out_be16(AP_ROP_1, SWAP(0x3));
 
 	printk("apollo frame buffer alive and kicking !\n");
 	return mem_start;
diff -Nru a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
--- a/drivers/video/fbcmap.c	Thu Oct 31 12:05:49 2002
+++ b/drivers/video/fbcmap.c	Tue Mar 18 10:12:57 2003
@@ -226,7 +226,7 @@
 	    hred = *red;
 	    hgreen = *green;
 	    hblue = *blue;
-	    htransp = transp ? *transp : 0;
+	    htransp = transp ? *transp : 0xffff;
 	} else {
 	    get_user(hred, red);
 	    get_user(hgreen, green);
@@ -234,7 +234,7 @@
 	    if (transp)
 		get_user(htransp, transp);
 	    else
-		htransp = 0;
+		htransp = 0xffff;
 	}
 	red++;
 	green++;
diff -Nru a/drivers/video/fbmem.c b/drivers/video/fbmem.c
--- a/drivers/video/fbmem.c	Fri Mar  7 18:42:54 2003
+++ b/drivers/video/fbmem.c	Sat Mar 22 07:38:03 2003
@@ -41,8 +41,6 @@
 #include <asm/pgtable.h>
 
 #include <linux/fb.h>
-#define INCLUDE_LINUX_LOGO_DATA
-#include <asm/linux_logo.h>
 
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE
 #include "console/fbcon.h"
@@ -171,7 +169,7 @@
 	 * Chipset specific drivers that use resource management
 	 */
 #ifdef CONFIG_FB_RETINAZ3
-	{ "retz3", retz3fb_init, retz3fb_setup },
+	{ "retz3fb", retz3fb_init, retz3fb_setup },
 #endif
 #ifdef CONFIG_FB_AMIGA
 	{ "amifb", amifb_init, amifb_setup },
@@ -183,10 +181,10 @@
 	{ "clps711xfb", clps711xfb_init, NULL },
 #endif
 #ifdef CONFIG_FB_CYBER
-	{ "cyber", cyberfb_init, cyberfb_setup },
+	{ "cyberfb", cyberfb_init, cyberfb_setup },
 #endif
 #ifdef CONFIG_FB_CYBER2000
-	{ "cyber2000", cyber2000fb_init, cyber2000fb_setup },
+	{ "cyber2000fb", cyber2000fb_init, cyber2000fb_setup },
 #endif
 #ifdef CONFIG_FB_PM2
 	{ "pm2fb", pm2fb_init, pm2fb_setup },
@@ -195,28 +193,28 @@
 	{ "pm3fb", pm3fb_init, pm3fb_setup },
 #endif           
 #ifdef CONFIG_FB_CLGEN
-	{ "clgen", clgenfb_init, clgenfb_setup },
+	{ "clgenfb", clgenfb_init, clgenfb_setup },
 #endif
 #ifdef CONFIG_FB_ATY
 	{ "atyfb", atyfb_init, atyfb_setup },
 #endif
 #ifdef CONFIG_FB_MATROX
-	{ "matrox", matroxfb_init, matroxfb_setup },
+	{ "matroxfb", matroxfb_init, matroxfb_setup },
 #endif
 #ifdef CONFIG_FB_ATY128
 	{ "aty128fb", aty128fb_init, aty128fb_setup },
 #endif
 #ifdef CONFIG_FB_NEOMAGIC
-	{ "neo", neofb_init, neofb_setup },
+	{ "neofb", neofb_init, neofb_setup },
 #endif
 #ifdef CONFIG_FB_VIRGE
-	{ "virge", virgefb_init, virgefb_setup },
+	{ "virgefb", virgefb_init, virgefb_setup },
 #endif
 #ifdef CONFIG_FB_RIVA
-	{ "riva", rivafb_init, rivafb_setup },
+	{ "rivafb", rivafb_init, rivafb_setup },
 #endif
 #ifdef CONFIG_FB_RADEON
-	{ "radeon", radeonfb_init, radeonfb_setup },
+	{ "radeonfb", radeonfb_init, radeonfb_setup },
 #endif
 #ifdef CONFIG_FB_CONTROL
 	{ "controlfb", control_init, control_setup },
@@ -234,7 +232,7 @@
 	{ "imsttfb", imsttfb_init, imsttfb_setup },
 #endif
 #ifdef CONFIG_FB_S3TRIO
-	{ "s3trio", s3triofb_init, NULL },
+	{ "s3triofb", s3triofb_init, NULL },
 #endif 
 #ifdef CONFIG_FB_FM2
 	{ "fm2fb", fm2fb_init, fm2fb_setup },
@@ -243,7 +241,7 @@
 	{ "sisfb", sisfb_init, sisfb_setup },
 #endif
 #ifdef CONFIG_FB_TRIDENT
-	{ "trident", tridentfb_init, tridentfb_setup },
+	{ "tridentfb", tridentfb_init, tridentfb_setup },
 #endif
 #ifdef CONFIG_FB_I810
 	{ "i810fb", i810fb_init, i810fb_setup },
@@ -255,25 +253,25 @@
 	{ "ffb", ffb_init, ffb_setup },
 #endif
 #ifdef CONFIG_FB_CG6
-	{ "cg6", cg6_init, cg6_setup },
+	{ "cg6fb", cg6_init, cg6_setup },
 #endif
 #ifdef CONFIG_FB_CG3
-	{ "cg3", cg3_init, cg3_setup },
+	{ "cg3fb", cg3_init, cg3_setup },
 #endif
 #ifdef CONFIG_FB_BW2
-	{ "bw2", bw2_init, bw2_setup },
+	{ "bw2fb", bw2_init, bw2_setup },
 #endif
 #ifdef CONFIG_FB_CG14
-	{ "cg14", cg14_init, cg14_setup },
+	{ "cg14fb", cg14_init, cg14_setup },
 #endif
 #ifdef CONFIG_FB_P9100
-	{ "p9100", p9100_init, p9100_setup },
+	{ "p9100fb", p9100_init, p9100_setup },
 #endif
 #ifdef CONFIG_FB_TCX
-	{ "tcx", tcx_init, tcx_setup },
+	{ "tcxfb", tcx_init, tcx_setup },
 #endif
 #ifdef CONFIG_FB_LEO
-	{ "leo", leo_init, leo_setup },
+	{ "leofb", leo_init, leo_setup },
 #endif
 
 	/*
@@ -288,7 +286,7 @@
 	{ "offb", offb_init, NULL },
 #endif
 #ifdef CONFIG_FB_VESA
-	{ "vesa", vesafb_init, vesafb_setup },
+	{ "vesafb", vesafb_init, vesafb_setup },
 #endif 
 
 	/*
@@ -296,13 +294,13 @@
 	 */
 
 #ifdef CONFIG_FB_3DFX
-	{ "tdfx", tdfxfb_init, tdfxfb_setup },
+	{ "tdfxfb", tdfxfb_init, tdfxfb_setup },
 #endif
 #ifdef CONFIG_FB_SGIVW
-	{ "sgivw", sgivwfb_init, sgivwfb_setup },
+	{ "sgivwfb", sgivwfb_init, sgivwfb_setup },
 #endif
 #ifdef CONFIG_FB_ACORN
-	{ "acorn", acornfb_init, acornfb_setup },
+	{ "acornfb", acornfb_init, acornfb_setup },
 #endif
 #ifdef CONFIG_FB_ATARI
 	{ "atafb", atafb_init, atafb_setup },
@@ -311,43 +309,43 @@
 	{ "macfb", macfb_init, macfb_setup },
 #endif
 #ifdef CONFIG_FB_HGA
-	{ "hga", hgafb_init, hgafb_setup },
+	{ "hgafb", hgafb_init, hgafb_setup },
 #endif 
 #ifdef CONFIG_FB_IGA
 	{ "igafb", igafb_init, igafb_setup },
 #endif
 #ifdef CONFIG_APOLLO
-	{ "apollo", dnfb_init, NULL },
+	{ "apollofb", dnfb_init, NULL },
 #endif
 #ifdef CONFIG_FB_Q40
 	{ "q40fb", q40fb_init, NULL },
 #endif
 #ifdef CONFIG_FB_TGA
-	{ "tga", tgafb_init, tgafb_setup },
+	{ "tgafb", tgafb_init, tgafb_setup },
 #endif
 #ifdef CONFIG_FB_HP300
 	{ "hpfb", hpfb_init, NULL },
 #endif 
 #ifdef CONFIG_FB_G364
-	{ "g364", g364fb_init, NULL },
+	{ "g364fb", g364fb_init, NULL },
 #endif
 #ifdef CONFIG_FB_SA1100
-	{ "sa1100", sa1100fb_init, NULL },
+	{ "sa1100fb", sa1100fb_init, NULL },
 #endif
 #ifdef CONFIG_FB_SUN3
-	{ "sun3", sun3fb_init, sun3fb_setup },
+	{ "sun3fb", sun3fb_init, sun3fb_setup },
 #endif
 #ifdef CONFIG_FB_HIT
 	{ "hitfb", hitfb_init, NULL },
 #endif
 #ifdef CONFIG_FB_TX3912
-	{ "tx3912", tx3912fb_init, tx3912fb_setup },
+	{ "tx3912fb", tx3912fb_init, tx3912fb_setup },
 #endif
 #ifdef CONFIG_FB_E1355
 	{ "e1355fb", e1355fb_init, e1355fb_setup },
 #endif
 #ifdef CONFIG_FB_PVR2
-	{ "pvr2", pvr2fb_init, pvr2fb_setup },
+	{ "pvr2fb", pvr2fb_init, pvr2fb_setup },
 #endif
 #ifdef CONFIG_FB_PMAG_BA
 	{ "pmagbafb", pmagbafb_init, NULL },
@@ -359,19 +357,19 @@
 	{ "maxinefb", maxinefb_init, NULL },
 #endif            
 #ifdef CONFIG_FB_VOODOO1
-	{ "sst", sstfb_init, sstfb_setup },
+	{ "sstfb", sstfb_init, sstfb_setup },
 #endif
 	/*
 	 * Generic drivers that don't use resource management (yet)
 	 */
 
 #ifdef CONFIG_FB_VGA16
-	{ "vga16", vga16fb_init, vga16fb_setup },
+	{ "vga16fb", vga16fb_init, vga16fb_setup },
 #endif 
 
 #ifdef CONFIG_GSP_RESOLVER
 	/* Not a real frame buffer device... */
-	{ "resolver", NULL, resolver_video_setup },
+	{ "resolverfb", NULL, resolver_video_setup },
 #endif
 
 #ifdef CONFIG_FB_VIRTUAL
@@ -384,6 +382,7 @@
 };
 
 #define NUM_FB_DRIVERS	(sizeof(fb_drivers)/sizeof(*fb_drivers))
+#define FBPIXMAPSIZE	8192
 
 extern const char *global_mode_option;
 
@@ -396,21 +395,105 @@
 static int ofonly __initdata = 0;
 #endif
 
-#define LOGO_H		80
-#define LOGO_W		80
+/*
+ * Drawing helpers.
+ */
+u8 sys_inbuf(u8 *src)
+{	
+	return *src;
+}
+
+void sys_outbuf(u8 src, u8 *dst)
+{
+	*dst = src;
+}	
+
+void move_buf_aligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch, 
+			u32 s_pitch, u32 height)
+{
+	int i, j;
+	
+	for (i = height; i--; ) {
+		for (j = 0; j < s_pitch; j++)
+			info->pixmap.outbuf(*src++, dst+j);
+		dst += d_pitch;
+	}	
+}	
+
+void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch, 
+			u32 height, u32 mask, u32 shift_high, u32 shift_low,
+			u32 mod, u32 idx)
+{
+	int i, j;
+	u8 tmp;
+
+	for (i = height; i--; ) {
+		for (j = 0; j < idx; j++) {
+			tmp = info->pixmap.inbuf(dst+j);
+			tmp &= mask;
+			tmp |= *src >> shift_low;
+			info->pixmap.outbuf(tmp, dst+j);
+			info->pixmap.outbuf(*src << shift_high, dst+j+1);
+			src++;
+		}
+		tmp = info->pixmap.inbuf(dst+idx);
+		tmp &= mask;
+		tmp |= *src >> shift_low;
+		info->pixmap.outbuf(tmp, dst+idx);
+		if (shift_high < mod)
+			info->pixmap.outbuf(*src<<shift_high, dst+idx+1);
+		src++;
+		dst += d_pitch;
+	}	
+}	
+
+/*
+ * we need to lock this section since fb_cursor
+ * may use fb_imageblit()
+ */
+u32 fb_get_buffer_offset(struct fb_info *info, u32 size)
+{
+	u32 align = info->pixmap.buf_align - 1;
+	u32 offset, count = 1000;
+
+	spin_lock_irqsave(&info->pixmap.lock,
+			  info->pixmap.lock_flags);
+	offset = info->pixmap.offset + align;
+	offset &= ~align;
+	if (offset + size > info->pixmap.size) {
+		while (atomic_read(&info->pixmap.count) && count--);
+		if (info->fbops->fb_sync && 
+		    info->pixmap.flags & FB_PIXMAP_SYNC)
+			info->fbops->fb_sync(info);
+		offset = 0;
+	}
+	info->pixmap.offset = offset + size;
+
+	atomic_inc(&info->pixmap.count);	
+	smp_mb__after_atomic_inc();
+
+	spin_unlock_irqrestore(&info->pixmap.lock,
+			       info->pixmap.lock_flags);
+	return offset;
+}
+
+#ifdef CONFIG_LOGO
+#include <linux/linux_logo.h>
 
 static inline unsigned safe_shift(unsigned d, int n)
 {
 	return n < 0 ? d >> -n : d << n;
 }
 
-static void __init fb_set_logocmap(struct fb_info *info)
+static void __init fb_set_logocmap(struct fb_info *info,
+				   const struct linux_logo *logo)
 {
 	struct fb_cmap palette_cmap;
 	u16 palette_green[16];
 	u16 palette_blue[16];
 	u16 palette_red[16];
 	int i, j, n;
+	const unsigned char *clut = logo->clut;
 
 	palette_cmap.start = 0;
 	palette_cmap.len = 16;
@@ -419,34 +502,32 @@
 	palette_cmap.blue = palette_blue;
 	palette_cmap.transp = NULL;
 
-	for (i = 0; i < LINUX_LOGO_COLORS; i += n) {
-		n = LINUX_LOGO_COLORS - i;
+	for (i = 0; i < logo->clutsize; i += n) {
+		n = logo->clutsize - i;
 		/* palette_cmap provides space for only 16 colors at once */
 		if (n > 16)
 			n = 16;
 		palette_cmap.start = 32 + i;
 		palette_cmap.len = n;
 		for (j = 0; j < n; ++j) {
-			palette_cmap.red[j] =
-				(linux_logo_red[i + j] << 8) |
-				 linux_logo_red[i + j];
-			palette_cmap.green[j] =
-				(linux_logo_green[i + j] << 8) |
-				 linux_logo_green[i + j];
-			palette_cmap.blue[j] =
-				(linux_logo_blue[i + j] << 8) |
-				 linux_logo_blue[i + j];
+			palette_cmap.red[j] = clut[0] << 8 | clut[0];
+			palette_cmap.green[j] = clut[1] << 8 | clut[1];
+			palette_cmap.blue[j] = clut[2] << 8 | clut[2];
+			clut += 3;
 		}
 		fb_set_cmap(&palette_cmap, 1, info);
 	}
 }
 
-static void  __init fb_set_logo_truepalette(struct fb_info *info, u32 *palette)
+static void  __init fb_set_logo_truepalette(struct fb_info *info,
+					    const struct linux_logo *logo,
+					    u32 *palette)
 {
 	unsigned char mask[9] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
 	unsigned char redmask, greenmask, bluemask;
 	int redshift, greenshift, blueshift;
 	int i;
+	const unsigned char *clut = logo->clut;
 
 	/*
 	 * We have to create a temporary palette since console palette is only
@@ -460,14 +541,17 @@
 	greenshift = info->var.green.offset - (8 - info->var.green.length);
 	blueshift  = info->var.blue.offset  - (8 - info->var.blue.length);
 
-	for ( i = 0; i < LINUX_LOGO_COLORS; i++) {
-		palette[i+32] = (safe_shift((linux_logo_red[i]   & redmask), redshift) |
-				 safe_shift((linux_logo_green[i] & greenmask), greenshift) |
-				 safe_shift((linux_logo_blue[i]  & bluemask), blueshift));
+	for ( i = 0; i < logo->clutsize; i++) {
+		palette[i+32] = (safe_shift((clut[0] & redmask), redshift) |
+				 safe_shift((clut[1] & greenmask), greenshift) |
+				 safe_shift((clut[2] & bluemask), blueshift));
+		clut += 3;
 	}
 }
 
-static void __init fb_set_logo_directpalette(struct fb_info *info, u32 *palette)
+static void __init fb_set_logo_directpalette(struct fb_info *info,
+					     const struct linux_logo *logo,
+					     u32 *palette)
 {
 	int redshift, greenshift, blueshift;
 	int i;
@@ -476,40 +560,54 @@
 	greenshift = info->var.green.offset;
 	blueshift = info->var.blue.offset;
 
-	for (i = 32; i < LINUX_LOGO_COLORS; i++)
+	for (i = 32; i < logo->clutsize; i++)
 		palette[i] = i << redshift | i << greenshift | i << blueshift;
 }
 
-static void __init fb_set_logo(struct fb_info *info, u8 *logo, int needs_logo)
+static void __init fb_set_logo(struct fb_info *info,
+			       const struct linux_logo *logo, u8 *dst,
+			       int needs_logo)
 {
-	int i, j;
+	int i, j, shift;
+	const u8 *src = logo->data;
+	u8 d, xor = 0;
 
 	switch (needs_logo) {
 	case 4:
-		for (i = 0; i < (LOGO_W * LOGO_H)/2; i++) {
-			logo[i*2] = linux_logo16[i] >> 4;
-			logo[(i*2)+1] = linux_logo16[i] & 0xf;
-		}
+		for (i = 0; i < logo->height; i++)
+			for (j = 0; j < logo->width; src++) {
+				*dst++ = *src >> 4;
+				j++;
+				if (j < logo->width) {
+					*dst++ = *src & 0x0f;
+					j++;
+				}
+			}
 		break;
-	case 1:
 	case ~1:
-	default:
-		for (i = 0; i < (LOGO_W * LOGO_H)/8; i++)
-			for (j = 0; j < 8; j++)
-				logo[i*8 + j] = (linux_logo_bw[i] &  (7 - j)) ?
-						((needs_logo == 1) ? 1 : 0) :
-						((needs_logo == 1) ? 0 : 1);
-			break;
+		xor = 0xff;
+	case 1:
+		for (i = 0; i < logo->height; i++) {
+			shift = 7;
+			d = *src++ ^ xor;
+			for (j = 0; j < logo->width; j++) {
+				*dst++ = (d >> shift) & 1;
+				shift = (shift-1) & 7;
+				if (shift == 7)
+					d = *src++ ^ xor;
+			}
+		}
+		break;
 	}
 }
 
 /*
- * Three (3) kinds of logo maps exist.  linux_logo (>16 colors), linux_logo_16
- * (16 colors) and linux_logo_bw (2 colors).  Depending on the visual format and
- * color depth of the framebuffer, the DAC, the pseudo_palette, and the logo data
- * will be adjusted accordingly.
+ * Three (3) kinds of logo maps exist.  linux_logo_clut224 (>16 colors),
+ * linux_logo_vga16 (16 colors) and linux_logo_mono (2 colors).  Depending on
+ * the visual format and color depth of the framebuffer, the DAC, the
+ * pseudo_palette, and the logo data will be adjusted accordingly.
  *
- * Case 1 - linux_logo:
+ * Case 1 - linux_logo_clut224:
  * Color exceeds the number of console colors (16), thus we set the hardware DAC
  * using fb_set_cmap() appropriately.  The "needs_cmapreset"  flag will be set.
  *
@@ -517,135 +615,161 @@
  * one for temporary use. The "needs_directpalette" or "needs_truepalette" flags
  * will be set.
  *
- * Case 2 - linux_logo_16:
+ * Case 2 - linux_logo_vga16:
  * The number of colors just matches the console colors, thus there is no need
  * to set the DAC or the pseudo_palette.  However, the bitmap is packed, ie,
  * each byte contains color information for two pixels (upper and lower nibble).
  * To be consistent with fb_imageblit() usage, we therefore separate the two
  * nibbles into separate bytes. The "needs_logo" flag will be set to 4.
  *
- * Case 3 - linux_logo_bw:
+ * Case 3 - linux_logo_mono:
  * This is similar with Case 2.  Each byte contains information for 8 pixels.
  * We isolate each bit and expand each into a byte. The "needs_logo" flag will
  * be set to 1.
  */
-int fb_show_logo(struct fb_info *info)
-{
-	unsigned char *fb = info->screen_base, *logo_new = NULL;
-	u32 *palette = NULL, *saved_pseudo_palette = NULL;
-	int needs_directpalette = 0;
-	int needs_truepalette = 0;
-	int needs_cmapreset = 0;
-	struct fb_image image;
-	int needs_logo = 0;
-	int done = 0, x;
-
-	/* Return if the frame buffer is not mapped */
-	if (!fb || !info->fbops->fb_imageblit)
-		return 0;
+static struct logo_data {
+	int depth;
+	int needs_logo;
+	int needs_directpalette;
+	int needs_truepalette;
+	int needs_cmapreset;
+	int type;
+	const struct linux_logo *logo;
+} fb_logo;
 
-	image.depth = info->var.bits_per_pixel;
+int fb_prepare_logo(struct fb_info *info)
+{
+	memset(&fb_logo, 0, sizeof(struct logo_data));
 
-	/* reasonable default */
-	if (image.depth >= 8)
-		image.data = linux_logo;
-	else if (image.depth >= 4)
-		image.data = linux_logo16;
-	else
-		image.data = linux_logo_bw;
+	fb_logo.depth = info->var.bits_per_pixel;
 
 	switch (info->fix.visual) {
 	case FB_VISUAL_TRUECOLOR:
-		needs_truepalette = 1;
-		if (image.depth >= 4 && image.depth <= 8)
-			needs_logo = 4;
-		else if (image.depth < 4)
-			needs_logo = 1;
+		if (fb_logo.depth >= 8) {
+			fb_logo.needs_truepalette = 1;
+			fb_logo.needs_logo = 8;
+		} else if (fb_logo.depth >= 4)
+			fb_logo.needs_logo = 4;
+		else 
+			fb_logo.needs_logo = 1;
 		break;
 	case FB_VISUAL_DIRECTCOLOR:
-		if (image.depth >= 24) {
-			needs_directpalette = 1;
-			needs_cmapreset = 1;
-		}
-		/* 16 colors */
-		else if (image.depth >= 16)
-			needs_logo = 4;
-		/* 2 colors */
+		if (fb_logo.depth >= 24) {
+			fb_logo.needs_directpalette = 1;
+			fb_logo.needs_cmapreset = 1;
+			fb_logo.needs_logo = 8;
+		} else if (fb_logo.depth >= 16)	/* 16 colors */
+			fb_logo.needs_logo = 4;
 		else
-			needs_logo = 1;
+			fb_logo.needs_logo = 1;	/* 2 colors */
 		break;
 	case FB_VISUAL_MONO01:
 		/* reversed 0 = fg, 1 = bg */
-		needs_logo = ~1;
+		fb_logo.needs_logo = ~1;
 		break;
 	case FB_VISUAL_MONO10:
-		needs_logo = 1;
+		fb_logo.needs_logo = 1;
 		break;
-	case FB_VISUAL_PSEUDOCOLOR:
-	default:
-		if (image.depth >= 8)
-			needs_cmapreset = 1;
-		/* fall through */
 	case FB_VISUAL_STATIC_PSEUDOCOLOR:
-		/* 16 colors */
-		if (image.depth >= 4 && image.depth < 8)
-			needs_logo = 4;
-		/* 2 colors */
-		else if (image.depth < 4)
-			needs_logo = 1;
+		if (fb_logo.depth >= 8) {
+			fb_logo.needs_logo = 8;
+			if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
+				fb_logo.needs_cmapreset = 1;
+		} else if (fb_logo.depth >= 4)
+			fb_logo.needs_logo = 4;	/* 16 colors */
+		else
+			fb_logo.needs_logo = 1;	
 		break;
 	}
 
-	if (needs_cmapreset)
-		fb_set_logocmap(info);
+	if (fb_logo.needs_logo >= 8)
+		fb_logo.type = LINUX_LOGO_CLUT224;
+	else if (fb_logo.needs_logo >= 4)
+		fb_logo.type = LINUX_LOGO_VGA16;
+	else
+		fb_logo.type = LINUX_LOGO_MONO;
 
-	if (needs_truepalette || needs_directpalette) {
+	/* Return if no suitable logo was found */
+	fb_logo.logo = fb_find_logo(fb_logo.type);
+	if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) {
+		fb_logo.logo = NULL;
+		return 0;
+	}
+	return fb_logo.logo->height;
+}
+
+int fb_show_logo(struct fb_info *info)
+{
+	unsigned char *fb = info->screen_base, *logo_new = NULL;
+	u32 *palette = NULL, *saved_pseudo_palette = NULL;
+	struct fb_image image;
+	int x;
+
+	/* Return if the frame buffer is not mapped */
+	if (!fb || !info->fbops->fb_imageblit ||
+	    fb_logo.logo == NULL)
+		return 0;
+
+	image.depth = fb_logo.depth;
+	image.data = fb_logo.logo->data;
+
+	if (fb_logo.needs_cmapreset)
+		fb_set_logocmap(info, fb_logo.logo);
+
+	if (fb_logo.needs_truepalette || 
+	    fb_logo.needs_directpalette) {
 		palette = kmalloc(256 * 4, GFP_KERNEL);
 		if (palette == NULL)
-			return 1;
+			return 0;
 
-		if (needs_truepalette)
-			fb_set_logo_truepalette(info, palette);
+		if (fb_logo.needs_truepalette)
+			fb_set_logo_truepalette(info, fb_logo.logo, palette);
 		else
-			fb_set_logo_directpalette(info, palette);
+			fb_set_logo_directpalette(info, fb_logo.logo, palette);
 
 		saved_pseudo_palette = info->pseudo_palette;
 		info->pseudo_palette = palette;
 	}
 
-	if (needs_logo) {
-		logo_new = kmalloc(LOGO_W * LOGO_H, GFP_KERNEL);
+	if (fb_logo.needs_logo != 8) {
+		logo_new = kmalloc(fb_logo.logo->width * fb_logo.logo->height, 
+				   GFP_KERNEL);
 		if (logo_new == NULL) {
 			if (palette)
 				kfree(palette);
 			if (saved_pseudo_palette)
 				info->pseudo_palette = saved_pseudo_palette;
-			return 1;
+			return 0;
 		}
 
 		image.data = logo_new;
-		fb_set_logo(info, logo_new, needs_logo);
+		fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.needs_logo);
 	}
 
-	image.width = LOGO_W;
-	image.height = LOGO_H;
+	image.width = fb_logo.logo->width;
+	image.height = fb_logo.logo->height;
 	image.dy = 0;
 
-	for (x = 0; x < num_online_cpus() * (LOGO_W + 8) &&
-	     x < info->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
+	for (x = 0; x < num_online_cpus() * (fb_logo.logo->width + 8) &&
+	     x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) {
 		image.dx = x;
 		info->fbops->fb_imageblit(info, &image);
-		done = 1;
+		atomic_dec(&info->pixmap.count);
+		smp_mb__after_atomic_dec();
 	}
-
+	
 	if (palette != NULL)
 		kfree(palette);
 	if (saved_pseudo_palette != NULL)
 		info->pseudo_palette = saved_pseudo_palette;
 	if (logo_new != NULL)
 		kfree(logo_new);
-	return 0;
+	return fb_logo.logo->height;
 }
+#else
+int fb_prepare_logo(struct fb_info *info) { return 0; }
+int fb_show_logo(struct fb_info *info) { return 0; }
+#endif /* CONFIG_LOGO */
 
 static int fbmem_read_proc(char *buf, char **start, off_t offset,
 			   int len, int *eof, void *private)
@@ -891,11 +1015,9 @@
 		if (!registered_fb[con2fb.framebuffer])
 		    return -EINVAL;
 		if (con2fb.console != 0)
-		    set_con2fb_map(con2fb.console-1, con2fb.framebuffer);
+			set_con2fb_map(con2fb.console-1, con2fb.framebuffer);
 		else
-		    /* set them all */
-		    for (i = 0; i < MAX_NR_CONSOLES; i++)
-			set_con2fb_map(i, con2fb.framebuffer);
+			fb_console_init();		
 		return 0;
 #endif	/* CONFIG_FRAMEBUFFER_CONSOLE */
 	case FBIOBLANK:
@@ -1082,6 +1204,23 @@
 		if (!registered_fb[i])
 			break;
 	fb_info->node = mk_kdev(FB_MAJOR, i);
+	
+	if (fb_info->pixmap.addr == NULL) {
+		fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
+		if (fb_info->pixmap.addr) {
+			fb_info->pixmap.size = FBPIXMAPSIZE;
+			fb_info->pixmap.buf_align = 1;
+			fb_info->pixmap.scan_align = 1;
+			fb_info->pixmap.flags = FB_PIXMAP_DEFAULT;
+		}
+	}	
+	fb_info->pixmap.offset = 0;
+	if (fb_info->pixmap.outbuf == NULL)
+		fb_info->pixmap.outbuf = sys_outbuf;
+	if (fb_info->pixmap.inbuf == NULL)
+		fb_info->pixmap.inbuf = sys_inbuf;
+	spin_lock_init(&fb_info->pixmap.lock);
+	
 	registered_fb[i] = fb_info;
 	sprintf(name_buf, "fb/%d", i);
 	devfs_register(NULL, name_buf, DEVFS_FL_DEFAULT,
@@ -1110,6 +1249,9 @@
 	if (!registered_fb[i])
 		return -EINVAL;
 	devfs_remove("fb/%d", i);
+
+	if (fb_info->pixmap.addr)
+		kfree(fb_info->pixmap.addr);
 	registered_fb[i]=NULL;
 	num_registered_fb--;
 	return 0;
@@ -1132,7 +1274,7 @@
 
 	create_proc_read_entry("fb", 0, 0, fbmem_read_proc, NULL);
 
-	devfs_mk_dir(NULL, "fb", NULL);
+	devfs_mk_dir("fb");
 	if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
 		printk("unable to get major %d for fb devs\n", FB_MAJOR);
 
@@ -1221,9 +1363,13 @@
 EXPORT_SYMBOL(unregister_framebuffer);
 EXPORT_SYMBOL(num_registered_fb);
 EXPORT_SYMBOL(registered_fb);
+EXPORT_SYMBOL(fb_prepare_logo);
 EXPORT_SYMBOL(fb_show_logo);
 EXPORT_SYMBOL(fb_set_var);
 EXPORT_SYMBOL(fb_blank);
 EXPORT_SYMBOL(fb_pan_display);
+EXPORT_SYMBOL(fb_get_buffer_offset);
+EXPORT_SYMBOL(move_buf_unaligned);
+EXPORT_SYMBOL(move_buf_aligned);
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/fbmon.c b/drivers/video/fbmon.c
--- a/drivers/video/fbmon.c	Fri Jan 10 16:51:25 2003
+++ b/drivers/video/fbmon.c	Mon Mar 10 10:17:51 2003
@@ -14,6 +14,9 @@
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
 #endif
+#ifdef CONFIG_ALL_PPC
+#include <asm/prom.h>
+#endif
 
 /* 
  * EDID parser
@@ -573,6 +576,10 @@
 			timings.vfreq = vfmax;
 			fb_timings_vfreq(&timings);
 		}
+		if (timings.dclk > dclkmax) {
+			timings.dclk = dclkmax;
+			fb_timings_dclk(&timings);
+		}
 		break;
 	case FB_VSYNCTIMINGS: /* vrefresh driven */
 		timings.vfreq = val;
@@ -666,7 +673,8 @@
 	vfreq = hfreq/vtotal;
 
 	return (vfreq < vfmin || vfreq > vfmax || 
-		hfreq < hfmin || hfreq > hfmax) ?
+		hfreq < hfmin || hfreq > hfmax ||
+		pixclock < dclkmin || pixclock > dclkmax) ?
 		-EINVAL : 0;
 }
 
diff -Nru a/drivers/video/ffb.c b/drivers/video/ffb.c
--- a/drivers/video/ffb.c	Tue Mar  4 09:55:26 2003
+++ b/drivers/video/ffb.c	Sun Mar 23 00:28:04 2003
@@ -33,9 +33,9 @@
 static int ffb_blank(int, struct fb_info *);
 static void ffb_init_fix(struct fb_info *);
 
-static void ffb_imageblit(struct fb_info *, struct fb_image *);
-static void ffb_fillrect(struct fb_info *, struct fb_fillrect *);
-static void ffb_copyarea(struct fb_info *, struct fb_copyarea *);
+static void ffb_imageblit(struct fb_info *, const struct fb_image *);
+static void ffb_fillrect(struct fb_info *, const struct fb_fillrect *);
+static void ffb_copyarea(struct fb_info *, const struct fb_copyarea *);
 static int ffb_sync(struct fb_info *);
 static int ffb_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
 static int ffb_ioctl(struct inode *, struct file *, unsigned int,
@@ -491,7 +491,7 @@
  *      @info: frame buffer structure that represents a single frame buffer
  *      @rect: structure defining the rectagle and operation.
  */
-static void ffb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
 	struct ffb_par *par = (struct ffb_par *) info->par;
 	struct ffb_fbc *fbc = par->fbc;
@@ -540,7 +540,7 @@
  */
 
 static void
-ffb_copyarea(struct fb_info *info, struct fb_copyarea *area) 
+ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 
 {
 	struct ffb_par *par = (struct ffb_par *) info->par;
 	struct ffb_fbc *fbc = par->fbc;
@@ -576,11 +576,11 @@
  *      @info: frame buffer structure that represents a single frame buffer
  *      @image: structure defining the image.
  */
-static void ffb_imageblit(struct fb_info *info, struct fb_image *image)
+static void ffb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
 	struct ffb_par *par = (struct ffb_par *) info->par;
 	struct ffb_fbc *fbc = par->fbc;
-	u8 *data = (u8 *) image->data;
+	const u8 *data = image->data;
 	unsigned long flags;
 	u32 fg, bg, xy;
 	u64 fgbg;
diff -Nru a/drivers/video/hgafb.c b/drivers/video/hgafb.c
--- a/drivers/video/hgafb.c	Wed Nov 27 07:45:24 2002
+++ b/drivers/video/hgafb.c	Mon Mar  3 19:41:18 2003
@@ -45,9 +45,6 @@
 #include <asm/io.h>
 #include <asm/vga.h>
 
-#define INCLUDE_LINUX_LOGO_DATA
-#include <linux/linux_logo.h>
-
 #if 0
 #define DPRINTK(args...) printk(KERN_DEBUG __FILE__": " ##args)
 #else
@@ -246,13 +243,15 @@
 
 static void hga_show_logo(struct fb_info *info)
 {
+/*
 	unsigned long dest = hga_vram_base;
 	char *logo = linux_logo_bw;
 	int x, y;
 	
-	for (y = 134; y < 134 + 80 ; y++) /* this needs some cleanup */
+	for (y = 134; y < 134 + 80 ; y++) * this needs some cleanup *
 		for (x = 0; x < 10 ; x++)
 			isa_writeb(~*(logo++),(dest + HGA_ROWADDR(y) + x + 40));
+*/
 }
 
 static void hga_pan(unsigned int xoffset, unsigned int yoffset)
@@ -449,7 +448,7 @@
 	return 0;
 }
 
-static void hgafb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+static void hgafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
 	u_int rows, y;
 	u8 *dest;
@@ -469,7 +468,7 @@
 	}
 }
 
-static void hgafb_copyarea(struct fb_info *info, struct fb_copyarea *area)
+static void hgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
 	u_int rows, y1, y2;
 	u8 *src, *dest;
@@ -499,9 +498,9 @@
 	}
 }
 
-static void hgafb_imageblit(struct fb_info *info, struct fb_image *image)
+static void hgafb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
-	u8 *dest, *cdat = image->data;
+	u8 *dest, *cdat = (u8 *) image->data;
 	u_int rows, y = image->dy;
 	u8 d;
 
diff -Nru a/drivers/video/hitfb.c b/drivers/video/hitfb.c
--- a/drivers/video/hitfb.c	Fri Nov 22 13:47:00 2002
+++ b/drivers/video/hitfb.c	Wed Mar  5 09:22:33 2003
@@ -107,14 +107,12 @@
     
 	if (regno < 16) {
 		switch(info->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB16
 		case 16:
 			((u16 *)(info->pseudo_palette))[regno] =
 					((red   & 0xf800)      ) |
 					((green & 0xfc00) >>  5) |
 					((blue  & 0xf800) >> 11);
 			break;
-#endif
 		}
 	}
 	return 0;
diff -Nru a/drivers/video/hpfb.c b/drivers/video/hpfb.c
--- a/drivers/video/hpfb.c	Fri Nov 22 13:47:00 2002
+++ b/drivers/video/hpfb.c	Mon Mar  3 19:41:18 2003
@@ -86,7 +86,7 @@
 	return 0;
 }
 
-void hpfb_copyarea(struct fb_info *info, struct fb_copyarea *area) 
+void hpfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 
 {
 	while (in_8(fb_regs + BUSY) & fb_bitmask);
 	out_8(fb_regs + WMRR, 0x3);
diff -Nru a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h
--- a/drivers/video/i810/i810.h	Mon Jan  6 14:40:00 2003
+++ b/drivers/video/i810/i810.h	Sun Feb 16 10:36:47 2003
@@ -170,13 +170,6 @@
 #define REF_FREQ                    24000000
 #define TARGET_N_MAX                30
 
-#define FLYBACK                     550
-#define V_FRONTPORCH                1
-#define H_OFFSET                    40
-#define H_SCALEFACTOR               20
-#define H_BLANKSCALE                128
-#define H_GRADIENT                   600
-
 #define MAX_PIXELCLOCK              230000000
 #define MIN_PIXELCLOCK               15000000
 #define VFMAX                       60
@@ -263,6 +256,7 @@
 	drm_agp_t                *drm_agp;
 	atomic_t                 use_count;
 	u32 pseudo_palette[17];
+	u32 pci_state[16];
 	unsigned long mmio_start_phys;
 	u8 *mmio_start_virtual;
 	u32 cursor_reset;
@@ -280,6 +274,7 @@
 	u32 depth;
 	u32 blit_bpp;
 	u32 ovract;
+	u32 cur_state;
 	int mtrr_reg;
 	u16 bltcntl;
 	u8 interlace;
diff -Nru a/drivers/video/i810/i810_accel.c b/drivers/video/i810/i810_accel.c
--- a/drivers/video/i810/i810_accel.c	Mon Jan  6 14:40:00 2003
+++ b/drivers/video/i810/i810_accel.c	Sun Feb 16 10:36:47 2003
@@ -75,8 +75,6 @@
 	return 1;
 }
 
-
-
 /** 
  * wait_for_engine_idle - waits for all hardware engines to finish
  * @par: pointer to i810fb_par structure
@@ -154,12 +152,14 @@
 				    int blit_bpp, struct i810fb_par *par)
 {
 	if (begin_iring(par, 24 + IRING_PAD)) return;
+
 	PUT_RING(BLIT | SOURCE_COPY_BLIT | 4);
 	PUT_RING(xdir | rop << 16 | dpitch | DYN_COLOR_EN | blit_bpp);
 	PUT_RING(dheight << 16 | dwidth);
 	PUT_RING(dest);
 	PUT_RING(dpitch);
 	PUT_RING(src);
+
 	end_iring(par);
 }	
 
@@ -184,12 +184,14 @@
 			      struct i810fb_par *par)
 {
 	if (begin_iring(par, 24 + IRING_PAD)) return;
+
 	PUT_RING(BLIT | COLOR_BLT | 3);
 	PUT_RING(rop << 16 | pitch | SOLIDPATTERN | DYN_COLOR_EN | blit_bpp);
 	PUT_RING(height << 16 | width);
 	PUT_RING(dest);
 	PUT_RING(what);
 	PUT_RING(NOP);
+
 	end_iring(par);
 }
  
@@ -220,17 +222,16 @@
 					  int dest, const u32 *src, int bg,
 					  int fg, struct i810fb_par *par)
 {
-	u32 i, *s = (u32 *) src;
-
 	if (begin_iring(par, 24 + (dsize << 2) + IRING_PAD)) return;
+
 	PUT_RING(BLIT | MONO_SOURCE_COPY_IMMEDIATE | (4 + dsize));
 	PUT_RING(DYN_COLOR_EN | blit_bpp | rop << 16 | dpitch);
 	PUT_RING(dheight << 16 | dwidth);
 	PUT_RING(dest);
 	PUT_RING(bg);
 	PUT_RING(fg);
-	for (i = dsize; i--; ) 
-		PUT_RING(*s++);
+	while (dsize--) 
+		PUT_RING(*src++);
 
 	end_iring(par);
 }
@@ -314,26 +315,19 @@
 	i810_writel(IRING + 12, mmio, tmp);
 }       
 
-void i810fb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
+void i810fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
-	struct i810fb_par *par = (struct i810fb_par *) p->par;
+	struct i810fb_par *par = (struct i810fb_par *) info->par;
 	u32 dx, dy, width, height, dest, rop = 0, color = 0;
 
-	if (!p->var.accel_flags || par->dev_flags & LOCKUP) {
-		cfb_fillrect(p, rect);
-		return;
-	}
+	if (!info->var.accel_flags || par->dev_flags & LOCKUP ||
+	    par->depth == 4) 
+		return cfb_fillrect(info, rect);
 
-	if (par->depth == 4) {
-		wait_for_engine_idle(par);
-		cfb_fillrect(p, rect);
-		return;
-	}
-			
 	if (par->depth == 1) 
 		color = rect->color;
 	else 
-		color = ((u32 *) (p->pseudo_palette))[rect->color];
+		color = ((u32 *) (info->pseudo_palette))[rect->color];
 
 	rop = i810fb_rop[rect->rop];
 
@@ -342,26 +336,19 @@
 	dy = rect->dy;
 	height = rect->height;
 
-	dest = p->fix.smem_start + (dy * p->fix.line_length) + dx;
-	color_blit(width, height, p->fix.line_length, dest, rop, color, 
+	dest = info->fix.smem_start + (dy * info->fix.line_length) + dx;
+	color_blit(width, height, info->fix.line_length, dest, rop, color, 
 		   par->blit_bpp, par);
 }
 	
-void i810fb_copyarea(struct fb_info *p, struct fb_copyarea *region) 
+void i810fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) 
 {
-	struct i810fb_par *par = (struct i810fb_par *) p->par;
+	struct i810fb_par *par = (struct i810fb_par *) info->par;
 	u32 sx, sy, dx, dy, pitch, width, height, src, dest, xdir;
 
-	if (!p->var.accel_flags || par->dev_flags & LOCKUP) {
-		cfb_copyarea(p, region);
-		return;
-	}
-
-	if (par->depth == 4) {
-		wait_for_engine_idle(par);
-		cfb_copyarea(p, region);
-		return;
-	}
+	if (!info->var.accel_flags || par->dev_flags & LOCKUP ||
+	    par->depth == 4)
+		return cfb_copyarea(info, region);
 
 	dx = region->dx * par->depth;
 	sx = region->sx * par->depth;
@@ -379,73 +366,68 @@
 		dx += width - 1;
 	}
 	if (dy <= sy) {
-		pitch = p->fix.line_length;
+		pitch = info->fix.line_length;
 	}
 	else {
-		pitch = (-(p->fix.line_length)) & 0xFFFF;
+		pitch = (-(info->fix.line_length)) & 0xFFFF;
 		sy += height - 1;
 		dy += height - 1;
 	}
-	src = p->fix.smem_start + (sy * p->fix.line_length) + sx;
-	dest = p->fix.smem_start + (dy * p->fix.line_length) + dx;
+	src = info->fix.smem_start + (sy * info->fix.line_length) + sx;
+	dest = info->fix.smem_start + (dy * info->fix.line_length) + dx;
 
 	source_copy_blit(width, height, pitch, xdir, src, dest,
 			 PAT_COPY_ROP, par->blit_bpp, par);
 }
 
-void i810fb_imageblit(struct fb_info *p, struct fb_image *image)
+void i810fb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
-	struct i810fb_par *par = (struct i810fb_par *) p->par;
+	struct i810fb_par *par = (struct i810fb_par *) info->par;
 	u32 fg = 0, bg = 0, s_pitch, d_pitch, size, offset, dst, i, j;
 	u8 *s_addr, *d_addr;
 	
-	if (!p->var.accel_flags || par->dev_flags & LOCKUP) {
-		cfb_imageblit(p, image);
-		return;
-	}
+	if (!info->var.accel_flags || par->dev_flags & LOCKUP ||
+	    par->depth == 4 || image->depth != 0) 
+		return cfb_imageblit(info, image);
 
-	if (par->depth == 4 || image->depth != 1) {
-		wait_for_engine_idle(par);
-		cfb_imageblit(p, image);
-		return;
-	}
-
-	switch (p->var.bits_per_pixel) {
+	switch (info->var.bits_per_pixel) {
 	case 8:
 		fg = image->fg_color;
 		bg = image->bg_color;
 		break;
 	case 16:
 	case 24:
-		fg = ((u32 *)(p->pseudo_palette))[image->fg_color];
-		bg = ((u32 *)(p->pseudo_palette))[image->bg_color];
+		fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
+		bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
 		break;
 	}	
 	
-	dst = p->fix.smem_start + (image->dy * p->fix.line_length) + 
+	dst = info->fix.smem_start + (image->dy * info->fix.line_length) + 
 		(image->dx * par->depth);
 
-	s_pitch = image->width/8;
+	s_pitch = (image->width+7)/8;
 	d_pitch = (s_pitch + 1) & ~1;
-	
 	size = d_pitch * image->height;
-
-	if (image->width & 15) {
-		offset = get_buffer_offset(size, par);
-		
+	if (s_pitch != d_pitch || size & 7) {
+		size += 7;
+		size &= ~7;
+		offset = get_buffer_offset(size, par);		
 		d_addr = par->pixmap.virtual + offset;
-		s_addr = image->data;
+		s_addr = (u8 *) image->data;
 		
-		for (i = image->height; i--; ) {
-			for (j = 0; j < s_pitch; j++) 
-				i810_writeb(j, d_addr, s_addr[j]);
-			s_addr += s_pitch;
-			d_addr += d_pitch;
+		if (s_pitch == d_pitch) {
+			memcpy_toio(d_addr, s_addr, s_pitch * image->height);
+		} else { 
+			for (i = image->height; i--; ) {
+				for (j = 0; j < s_pitch; j++) 
+					i810_writeb(j, d_addr, s_addr[j]);
+				s_addr += s_pitch;
+				d_addr += d_pitch;
+			}
 		}
-		
 		mono_src_copy_blit(image->width * par->depth, image->height, 
-				   p->fix.line_length, size/8, par->blit_bpp,
-				   PAT_COPY_ROP, dst, 
+				   info->fix.line_length, size/8, 
+				   par->blit_bpp, PAT_COPY_ROP, dst, 
 				   par->pixmap.physical + offset,
 				   bg, fg, par);
 	}
@@ -454,18 +436,18 @@
 	 */
 	else {
 		mono_src_copy_imm_blit(image->width * par->depth, 
-				       image->height, p->fix.line_length, 
+				       image->height, info->fix.line_length, 
 				       size/4, par->blit_bpp,
 				       PAT_COPY_ROP, dst, (u32 *) image->data, 
 				       bg, fg, par);
 	} 
 }
 
-int i810fb_sync(struct fb_info *p)
+int i810fb_sync(struct fb_info *info)
 {
-	struct i810fb_par *par = (struct i810fb_par *) p->par;
+	struct i810fb_par *par = (struct i810fb_par *) info->par;
 	
-	if (!p->var.accel_flags)
+	if (!info->var.accel_flags || par->dev_flags & LOCKUP)
 		return 0;
 
 	return wait_for_engine_idle(par);
diff -Nru a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
--- a/drivers/video/i810/i810_main.c	Mon Jan  6 14:40:00 2003
+++ b/drivers/video/i810/i810_main.c	Sun Feb 16 10:36:47 2003
@@ -623,7 +623,7 @@
 	}
 
 	n_reg = m_reg = n_target = 3;	
-	while ((diff_min || mod_min) && (n_target < n_target_max)) {
+	while (diff_min && mod_min && (n_target < n_target_max)) {
 		f_out = (p_divisor * n_reg * 1000000)/(4 * 24 * m_reg);
 		mod = (p_divisor * n_reg * 1000000) % (4 * 24 * m_reg);
 		m_target = m_reg;
@@ -654,261 +654,6 @@
 	if (p) *p = (p_target << 4);
 }
 
-/**
- * i810_get_vblank - get vertical blank time
- * @hfreq: horizontal freq
- *
- * DESCRIPTION:
- * vblank = right_margin + vsync_len + left_margin 
- *    given: right_margin = 1 (V_FRONTPORCH)
- *           vsync_len    = 3
- *           flyback      = 550
- *
- *                          flyback * hfreq
- *           left_margin  = --------------- - vsync_len
- *                           1000000
- *           and flyback is set to 550
- */
-static u32 i810_get_vblank(u32 hfreq)
-{
-	u32 vblank;
-
-	vblank = (hfreq * FLYBACK)/1000; 
-	vblank = (vblank + 500)/1000;
-	return (vblank + V_FRONTPORCH);
-}
-
-/** 
- * i810_get_hblank - get horizontal blank time
- * @hfreq: horizontal freq
- * @xres: horizontal resolution in pixels
- *
- * DESCRIPTION:
- * duty cycle is the percent of htotal assigned to inactive display
- * duty cycle = C - (M/Hfreq)
- * where: C = ((offset - scale factor) * blank_scale)
- *            -------------------------------------- + scale factor
- *                        256 
- *        M = blank_scale * gradient
- *
- *           xres * duty_cycle
- * hblank = ------------------
- *           100 - duty_cycle
- */
-static u32 i810_get_hblank(u32 hfreq, u32 xres)
-{
-	u32 c_val, m_val, duty_cycle, hblank;
-
-	c_val = (((H_OFFSET - H_SCALEFACTOR) * H_BLANKSCALE)/256 + 
-		 H_SCALEFACTOR) * 1000;
-	m_val = (H_BLANKSCALE * H_GRADIENT)/256;
-	m_val = (m_val * 1000000)/hfreq;
-	duty_cycle = c_val - m_val;
-	hblank = (xres * duty_cycle)/(100000 - duty_cycle);
-	hblank = (hblank + 4) & ~7;
-	return (hblank);
-}
-
-/**
- * i810_estimate_hfreq - estimate hsync
- * @vfreq: vertical refresh rate
- * @yres: vertical resolution
- *
- * DESCRIPTION:
- * Based on:
- *
- *          (yres + front_port) * vfreq * 1000000
- * hfreq = -------------------------------------
- *          (1000000 - (vfreq * FLYBACK)
- * 
- */
-
-static u32 i810_estimate_hfreq(u32 vfreq, u32 yres)
-{
-	u64 hfreq;
-	u32 divisor;
-	
-	divisor = 1000000 - (vfreq * FLYBACK);
-	
-	hfreq = (u64) (yres + V_FRONTPORCH) *  
-		(u64) (vfreq)  * 1000000;
-	do_div(hfreq, divisor);
-	
-	return ((u32) hfreq);
-}
-
-/**
- * i810_calculate_timings - calculate video timings 
- * @info: pointer to fb_info structure
- * @var: pointer to current var
- * 
- * DESCRIPTION:
- * htotal: calculated using GTF
- * vtotal: calculated using GTF
- * hsync pulse:  8% of htotal
- * vsync pulse:  3 
- * left margin : (htotal - xres)/2 - hsync
- * right margin: sync + left margin
- * upper margin: 1
- * lower margin: vtotal - (yres + vsync + upper margin)
- *
- * Calculates necessary timing information based on 
- * monitor specifications.  This will use the 
- * VESA generalized timing formula. New values are
- * written to @var.
- */                      
-static int i810_calculate_timings(struct fb_info *info, 
-				  struct fb_var_screeninfo *var,
-				  u32 xres, u32 yres)
-{
-	u64 num = 1000000000000;
-	u32 htotal = 0, vtotal, hfreq, vfreq, hblank, vblank; 
-	u32 dclk, interlace = 0, dscan = 0;
-	u32 max_pixclock = 0;
-
-	switch (var->bits_per_pixel) {
-	case 8:
-		max_pixclock = 234000000;
-		break;
-	case 16:
-		max_pixclock = 229000000;
-		break;
-	case 24:
-	case 32:
-		max_pixclock = 204000000;
-		break;
-	default:
-		max_pixclock = 0;
-	}
-
-	if (var->vmode & FB_VMODE_INTERLACED) { 
-		yres >>= 1;
-		interlace = 1;
-	}
-	if (var->vmode & FB_VMODE_DOUBLE) {
-		yres <<= 1;
-		dscan = 1;
-	}
-
-	hfreq = info->monspecs.hfmax;
-	vblank = i810_get_vblank(hfreq);
-	vtotal = yres + vblank;
-	vfreq = hfreq/vtotal;
-	if (vfreq > info->monspecs.vfmax) { 
-		vfreq = info->monspecs.vfmax;
-		hfreq = i810_estimate_hfreq(vfreq, yres);
-		vblank = i810_get_vblank(hfreq);
-		vtotal = yres + vblank;
-	}	
-	hblank = i810_get_hblank(hfreq, xres);
-	htotal = xres + hblank;
-	dclk = htotal * hfreq;
-	while(dclk > max_pixclock          &&  
-	      hfreq > info->monspecs.hfmin &&
-	      vfreq > info->monspecs.vfmin)   {
-		hfreq -= 1000;
-		vblank = i810_get_vblank(hfreq);
-		vtotal = yres + vblank;
-		vfreq = hfreq/vtotal;
-		hblank = i810_get_hblank(hfreq, xres);
-		htotal = xres + hblank;
-		dclk = hfreq * htotal;
-	} 
-	if (vfreq < info->monspecs.vfmin) {
-		printk("i810fb: required vertical refresh, %dHz, "
-		       "for %dx%d is out of range\n",
-		       vfreq, xres, yres);
-		return -1;
-	}
-	if (hfreq < info->monspecs.hfmin) {
-		printk("i810fb: required horizontal sync frequency, %dKHz, "
-		       "for %dx%d is out of range\n", hfreq/1000, xres, yres);
-		return -1;
-	}
-	if (dclk < MIN_PIXELCLOCK) {
-		printk("i810fb: required pixelclock, %dMHz, for %dx%d"
-		       " is out of range\n", dclk/1000000, xres, yres);
-		return -1;
-	}
-
-	do_div(num, dclk);
-	var->pixclock = (u32) num;
-	var->hsync_len = ((htotal * 8)/100 + 4) & ~7;
-	var->right_margin = ((hblank >> 1) - var->hsync_len + 4) & ~7;
-	var->left_margin = (hblank-var->right_margin-var->hsync_len + 4) & ~7;
-
-	var->vsync_len = (3 << interlace) >> dscan; 
-	var->lower_margin = (1 << interlace) >> dscan;
-	var->upper_margin = ((vblank << interlace) >> dscan) -
-		(var->vsync_len + var->lower_margin);
-
-	if (yres > 480 || (yres == 200 && vfreq == 60 && hfreq/100 == 157))
-		var->sync |= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT;
-	else {
-		if (yres == 400 && vfreq == 70 && hfreq/100 == 315)
-			var->sync |= FB_SYNC_VERT_HIGH_ACT;
-		if (yres == 350 && vfreq == 60 && hfreq/100 == 218)
-			var->sync |= FB_SYNC_HOR_HIGH_ACT;
-	}
-	return 0;
-}
-
-/**
- * i810_check_custom_timings - validates user entered timings
- * @info: pointer to fb_info
- * @var: pointer to current fb_var_screeninfo
- *
- * DESCRIPTION:
- * Validates user entered timings in @var.
- */
-static int i810_check_custom_timings(struct fb_info *info, 
-				     struct fb_var_screeninfo *var,
-				     u32 xres, u32 yres)
-{
-	u64 num = 1000000000000;
-	u32 hfreq, vfreq, htotal, vtotal, pixclock;
-	u32 max_pixclock = 0;
-
-	if (!var->pixclock)
-		return -EINVAL;
-	do_div(num, var->pixclock);
-	pixclock = (u32) num;
-
-	htotal = xres + var->right_margin + var->hsync_len + var->left_margin;
-	vtotal = yres + var->lower_margin + var->vsync_len + var->upper_margin;
-
-	if (var->vmode & FB_VMODE_INTERLACED) 
-		vtotal >>= 1;
-
-	if (var->vmode & FB_VMODE_DOUBLE)
-		vtotal <<= 1;
-
-	hfreq = pixclock/htotal;
-	vfreq = hfreq/vtotal;
-
-	switch (var->bits_per_pixel) {
-	case 8:
-		max_pixclock = 234000000;
-		break;
-	case 16:
-		max_pixclock = 229000000;
-		break;
-	case 24:
-	case 32:
-		max_pixclock = 204000000;
-		break;
-	default:
-		max_pixclock = 0;
-	}
-
-	if (pixclock < MIN_PIXELCLOCK || pixclock > max_pixclock ||
-	    hfreq < info->monspecs.hfmin || hfreq > info->monspecs.hfmax ||
-	    vfreq < info->monspecs.vfmin || vfreq > info->monspecs.vfmax)
-		return -EINVAL;
-	
-	return 0;
-}
-
 /*************************************************************
  *                Hardware Cursor Routines                   *
  *************************************************************/
@@ -950,19 +695,25 @@
 				   struct i810fb_par *par)
 {
 	u8 *addr = par->cursor_heap.virtual;
-	int i, j, w = (width + 7)/8;
-
+	int i, j, w = width/8;
+	int mod = width % 8, t_mask, d_mask;
+	
+	t_mask = 0xff >> mod;
+	d_mask = ~(0xff >> mod); 
 	for (i = height; i--; ) {
 		for (j = 0; j < w; j++) {
 			i810_writeb(j+0, addr, 0x00);
 			i810_writeb(j+8, addr, *data++);
 		}
+		if (mod) {
+			i810_writeb(j+0, addr, t_mask);
+			i810_writeb(j+8, addr, *data++ & d_mask);
+		}
 		addr += 16;
 	}
 }
 
-static void i810_load_cursor_colors(int fg, int bg, 
-				    struct fb_info *info)
+static void i810_load_cursor_colors(int fg, int bg, struct fb_info *info)
 {
 	struct i810fb_par *par = (struct i810fb_par *) info->par;
 	u8 *mmio = par->mmio_start_virtual, temp;
@@ -1097,28 +848,14 @@
 		var->transp.length = 0;
 		break;
 	case 16:
-		if (var->green.length == 5) {
-			/* RGB 555 */
-			var->red.offset = 10;
-			var->red.length = 5;
-			var->green.offset = 5;
-			var->green.length = 5;
-			var->blue.offset = 0;
-			var->blue.length = 5;
-			var->transp.offset = 15;
-			var->transp.length = 1;
-		}
-		else {
-			/* RGB 565 */
-			var->red.offset = 11;
-			var->red.length = 5;
-			var->green.offset = 5;
-			var->green.length = 6;
-			var->blue.offset = 0;
-			var->blue.length = 5;
-			var->transp.offset = 0;
-			var->transp.length = 0;
-		}
+		var->green.length = (var->green.length == 5) ? 5 : 6;
+		var->red.length = 5;
+		var->blue.length = 5;
+		var->transp.length = 6 - var->green.length;
+		var->blue.offset = 0;
+		var->green.offset = 5;
+		var->red.offset = 5 + var->green.length;
+		var->transp.offset =  (5 + var->red.offset) & 15;
 		break;
 	case 24:	/* RGB 888   */
 	case 32:	/* RGBA 8888 */
@@ -1128,15 +865,9 @@
 		var->green.length = 8;
 		var->blue.offset = 0;
 		var->blue.length = 8;
-		if (var->bits_per_pixel == 24) {
-			var->transp.offset = 0;
-			var->transp.length = 0;
-		}
-		else {
-			var->transp.offset = 24;
-			var->transp.length = 8;
-			break;
-		}
+		var->transp.length = var->bits_per_pixel - 24;
+		var->transp.offset = (var->transp.length) ? 24 : 0;
+		break;
 	}
 	var->red.msb_right = 0;
 	var->green.msb_right = 0;
@@ -1195,11 +926,24 @@
 	/*
 	 * Monitor limit
 	 */
-	if (i810_check_custom_timings(info, var, xres, yres)) {
-		if (i810_calculate_timings(info, var, xres, yres)) {
-			return -EINVAL;
+	if (fb_validate_mode(var, info)) {
+		switch (var->bits_per_pixel) {
+		case 8:
+			info->monspecs.dclkmax = 234000000;
+			break;
+		case 16:
+			info->monspecs.dclkmax = 229000000;
+			break;
+		case 24:
+		case 32:
+			info->monspecs.dclkmax = 204000000;
+			break;
 		}
+		info->monspecs.dclkmin = 15000000;
+		if (fb_get_mode(FB_MAXTIMINGS, 0, var, info))
+			return -EINVAL;
 	}
+	
 	var->xres = xres;
 	var->yres = yres;
 	var->xres_virtual = vxres;
@@ -1245,8 +989,7 @@
 		return -EINVAL;
 	}
     	fix->ywrapstep = 0;
-	fix->line_length = get_line_length(par, info->var.xres_virtual, 
-					   info->var.bits_per_pixel);
+	fix->line_length = par->pitch;
 	fix->mmio_start = par->mmio_start_phys;
 	fix->mmio_len = MMIO_SIZE;
 	fix->accel = FB_ACCEL_I810;
@@ -1258,14 +1001,13 @@
  * decode_var - modify par according to contents of var
  * @var: pointer to fb_var_screeninfo
  * @par: pointer to i810fb_par
- * @info: pointer to fb_info
  *
  * DESCRIPTION:
  * Based on the contents of @var, @par will be dynamically filled up.
  * @par contains all information necessary to modify the hardware. 
 */
 static void decode_var(const struct fb_var_screeninfo *var, 
-		       struct i810fb_par *par, struct fb_info *info)
+		       struct i810fb_par *par)
 {
 	u32 xres, yres, vxres, vyres;
 
@@ -1569,7 +1311,7 @@
 {
 	struct i810fb_par *par = (struct i810fb_par *) info->par;
 
-	decode_var(&info->var, par, info);
+	decode_var(&info->var, par);
 	i810_load_regs(par);
 	i810_init_cursor(par);
 	par->cursor_reset = 1;
@@ -1608,9 +1350,8 @@
 	u8 *mmio = par->mmio_start_virtual;	
 	u16 flags = cursor->set;
 
-	if (!info->var.accel_flags || par->dev_flags & LOCKUP) {
+	if (!info->var.accel_flags || par->dev_flags & LOCKUP) 
 		return soft_cursor(info, cursor);
-	}
 
 	if (cursor->image.width > 64 || cursor->image.height > 64 ||
 	    (cursor->dest == NULL && cursor->rop == ROP_XOR))
@@ -1655,9 +1396,9 @@
 		switch (cursor->rop) {
 		case ROP_XOR:
 			for (i = 0; i < size; i++) {
-				data[i] = (cursor->image.data[i] & 
-					   cursor->mask[i]) ^
-					cursor->dest[i];
+				data[i] = ((cursor->image.data[i] & 
+					    cursor->mask[i]) ^
+					   cursor->dest[i]);
 			}
 			break;
 		case ROP_COPY:
@@ -1680,22 +1421,84 @@
 }
 
 static struct fb_ops i810fb_ops __initdata = {
-    .owner =             THIS_MODULE,
-    .fb_open =           i810fb_open,
-    .fb_release =        i810fb_release,
-    .fb_check_var =      i810fb_check_var,
-    .fb_set_par =        i810fb_set_par,
-    .fb_setcolreg =      i810fb_setcolreg,
-    .fb_blank =          i810fb_blank,
-    .fb_pan_display =    i810fb_pan_display, 
-    .fb_fillrect =       i810fb_fillrect,
-    .fb_copyarea =       i810fb_copyarea,
-    .fb_imageblit =      i810fb_imageblit,
-    .fb_cursor =         i810fb_cursor,
-    .fb_sync =           i810fb_sync,
+	.owner =             THIS_MODULE,
+	.fb_open =           i810fb_open,
+	.fb_release =        i810fb_release,
+	.fb_check_var =      i810fb_check_var,
+	.fb_set_par =        i810fb_set_par,
+	.fb_setcolreg =      i810fb_setcolreg,
+	.fb_blank =          i810fb_blank,
+	.fb_pan_display =    i810fb_pan_display, 
+	.fb_fillrect =       i810fb_fillrect,
+	.fb_copyarea =       i810fb_copyarea,
+	.fb_imageblit =      i810fb_imageblit,
+	.fb_cursor =         i810fb_cursor,
+	.fb_sync =           i810fb_sync,
 };
 
 /***********************************************************************
+ *                         Power Management                            *
+ ***********************************************************************/
+static int i810fb_suspend(struct pci_dev *dev, u32 state)
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+	struct i810fb_par *par = (struct i810fb_par *) info->par;
+	int blank = 0, prev_state = par->cur_state;
+
+	if (state == prev_state)
+		return 0;
+
+	par->cur_state = state;
+
+	switch (state) {
+	case 1:
+		blank = VESA_VSYNC_SUSPEND;
+		break;
+	case 2:
+		blank = VESA_HSYNC_SUSPEND;
+		break;
+	case 3:
+		blank = VESA_POWERDOWN;
+		break;
+	default:
+		return -EINVAL;
+	}
+	info->fbops->fb_blank(blank, info);
+
+	if (!prev_state) { 
+		par->drm_agp->unbind_memory(par->i810_gtt.i810_fb_memory);
+		par->drm_agp->unbind_memory(par->i810_gtt.i810_cursor_memory);
+		pci_disable_device(dev);
+	}
+	pci_save_state(dev, par->pci_state);
+	pci_set_power_state(dev, state);
+
+	return 0;
+}
+
+static int i810fb_resume(struct pci_dev *dev) 
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+	struct i810fb_par *par = (struct i810fb_par *) info->par;
+
+	if (par->cur_state == 0)
+		return 0;
+
+	pci_restore_state(dev, par->pci_state);
+	pci_set_power_state(dev, 0);
+	pci_enable_device(dev);
+	par->drm_agp->bind_memory(par->i810_gtt.i810_fb_memory, 
+				  par->fb.offset);
+	par->drm_agp->bind_memory(par->i810_gtt.i810_cursor_memory, 
+				  par->cursor_heap.offset);
+
+	info->fbops->fb_blank(VESA_NO_BLANKING, info);
+
+	par->cur_state = 0;
+
+	return 0;
+}
+/***********************************************************************
  *                  AGP resource allocation                            *
  ***********************************************************************/
   
@@ -1728,13 +1531,13 @@
 	par->fb.offset = v_offset_default << 20;
 	par->fb.offset >>= 12;
 
-	par->iring.offset = par->fb.offset + (par->fb.size >> 12);
-	par->iring.size = RINGBUFFER_SIZE;
-
-	par->pixmap.offset = par->iring.offset + (RINGBUFFER_SIZE >> 12);
+	par->pixmap.offset = par->fb.offset + (par->fb.size >> 12);
 	par->pixmap.size = PIXMAP_SIZE;
 
-	par->cursor_heap.offset = par->pixmap.offset + (PIXMAP_SIZE >> 12);
+	par->iring.offset = par->pixmap.offset + (PIXMAP_SIZE >> 12);
+	par->iring.size = RINGBUFFER_SIZE;
+
+	par->cursor_heap.offset = par->iring.offset + (RINGBUFFER_SIZE >> 12);
 	par->cursor_heap.size = 4096;
 }
 
@@ -1864,7 +1667,7 @@
 	info->var.yres = yres;
 	info->var.yres_virtual = vyres;
 	info->var.bits_per_pixel = bpp;
-	
+
 	if (dcolor)
 		info->var.nonstd = 1;
 
@@ -2076,22 +1879,17 @@
 	vfreq = hfreq/(info->var.yres + info->var.upper_margin +
 		       info->var.vsync_len + info->var.lower_margin);
 
-      	printk("fb: %s v%d.%d.%d%s, Tony Daplas\n"
-      	       "     Video RAM      : %dK\n" 
-	       "     Mode           : %dx%d-%dbpp@%dHz\n"
-	       "     Acceleration   : %sabled\n"
-	       "     MTRR           : %sabled\n"
-	       "     External VGA   : %sabled\n"
-	       "     Video Timings  : %s\n",	
+      	printk("I810FB: fb%d         : %s v%d.%d.%d%s\n"
+      	       "I810FB: Video RAM   : %dK\n" 
+	       "I810FB: Monitor     : H: %d-%d KHz V: %d-%d Hz\n"
+	       "I810FB: Mode        : %dx%d-%dbpp@%dHz\n",
+	       minor(info->node),
 	       i810_pci_list[entry->driver_data],
 	       VERSION_MAJOR, VERSION_MINOR, VERSION_TEENIE, BRANCH_VERSION,
-	       (int) par->fb.size>>10, info->var.xres, 
-	       info->var.yres, info->var.bits_per_pixel, vfreq, 
-	       (par->dev_flags & HAS_ACCELERATION) ? "en" : "dis", 
-	       (par->dev_flags & HAS_MTRR) ? "en" : "dis", 
-	       (ext_vga) ? "en" : "dis", (IS_DVT) ? 
-	       "Intel(R) DVT" : "VESA GTF (US)");
-
+	       (int) par->fb.size>>10, info->monspecs.hfmin/1000,
+	       info->monspecs.hfmax/1000, info->monspecs.vfmin,
+	       info->monspecs.vfmax, info->var.xres, 
+	       info->var.yres, info->var.bits_per_pixel, vfreq);
 	return 0;
 }
 
@@ -2161,7 +1959,10 @@
 		return -ENODEV;
 	}
 
-	return (pci_module_init(&i810fb_driver));
+	if (pci_register_driver(&i810fb_driver) > 0)
+		return 0;
+	pci_unregister_driver(&i810fb_driver);
+	return -ENODEV;
 }
 #endif 
 
@@ -2177,7 +1978,10 @@
 	hsync1 *= 1000;
 	hsync2 *= 1000;
 
-	return (pci_module_init(&i810fb_driver));
+	if (pci_register_driver(&i810fb_driver) > 0)
+		return 0;
+	pci_unregister_driver(&i810fb_driver);
+	return -ENODEV;
 }
 
 MODULE_PARM(vram, "i");
diff -Nru a/drivers/video/i810/i810_main.h b/drivers/video/i810/i810_main.h
--- a/drivers/video/i810/i810_main.h	Mon Jan  6 14:40:00 2003
+++ b/drivers/video/i810/i810_main.h	Sun Feb 16 10:36:47 2003
@@ -43,12 +43,16 @@
 static int  __init i810fb_init_pci (struct pci_dev *dev, 
 				       const struct pci_device_id *entry);
 static void __exit i810fb_remove_pci(struct pci_dev *dev);
+static int i810fb_resume(struct pci_dev *dev);
+static int i810fb_suspend(struct pci_dev *dev, u32 state);
 
 static struct pci_driver i810fb_driver = {
 	.name     =	"i810fb",
 	.id_table =	i810fb_pci_tbl,
 	.probe    =	i810fb_init_pci,
 	.remove   =	__exit_p(i810fb_remove_pci),
+	.suspend  =     i810fb_suspend,
+	.resume   =     i810fb_resume,
 };	
 
 static int i810_init  __initdata = 0;
@@ -121,9 +125,11 @@
 extern void i810fb_fill_var_timings(struct fb_var_screeninfo *var);
 				    
 /* Accelerated Functions */
-extern void i810fb_fillrect (struct fb_info *p, struct fb_fillrect *rect);
-extern void i810fb_copyarea (struct fb_info *p, struct fb_copyarea *region);
-extern void i810fb_imageblit(struct fb_info *p, struct fb_image *image);
+extern void i810fb_fillrect (struct fb_info *p, 
+			     const struct fb_fillrect *rect);
+extern void i810fb_copyarea (struct fb_info *p, 
+			     const struct fb_copyarea *region);
+extern void i810fb_imageblit(struct fb_info *p, const struct fb_image *image);
 extern int  i810fb_sync     (struct fb_info *p);
 
 extern void i810fb_init_ringbuffer   (struct i810fb_par *par);
diff -Nru a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
--- a/drivers/video/imsttfb.c	Wed Nov 13 16:08:15 2002
+++ b/drivers/video/imsttfb.c	Wed Mar  5 15:53:46 2003
@@ -28,8 +28,6 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/fb.h>
-#include <linux/console.h>
-#include <linux/selection.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <asm/io.h>
@@ -39,15 +37,9 @@
 #include <linux/nvram.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
-#include <video/macmodes.h>
+#include "macmodes.h"
 #endif
 
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-
 #ifndef __powerpc__
 #define eieio()		/* Enforce In-order Execution of I/O */
 #endif
@@ -325,47 +317,14 @@
 	__u8 lckl_p[3];	/* P value of LCKL PLL */
 };
 
-struct imstt_cursor {
-	struct timer_list timer;
-	int enable;
-	int on;
-	int vbl_cnt;
-	int blink_rate;
-	__u16 x, y, width, height;
-};
-
-struct fb_info_imstt {
-	struct fb_info info;
-	struct fb_fix_screeninfo fix;
-	struct display disp;
-	struct display_switch dispsw;
-	union {
-#ifdef FBCON_HAS_CFB16
-		__u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB24
-		__u32 cfb24[16];
-#endif
-#ifdef FBCON_HAS_CFB32
-		__u32 cfb32[16];
-#endif
-	} fbcon_cmap;
-	struct {
-		__u8 red, green, blue;
-	} palette[256];
+struct imstt_par {
 	struct imstt_regvals init;
-	struct imstt_cursor cursor;
-	unsigned long frame_buffer_phys;
-	unsigned long board_size;
-	__u8 *frame_buffer;
-	unsigned long dc_regs_phys;
 	__u32 *dc_regs;
 	unsigned long cmap_regs_phys;
 	__u8 *cmap_regs;
-	__u32 total_vram;
 	__u32 ramdac;
 };
-
+ 
 enum {
 	IBM = 0,
 	TVP = 1
@@ -375,13 +334,9 @@
 #define INIT_BPP		8
 #define INIT_XRES		640
 #define INIT_YRES		480
-#define CURSOR_BLINK_RATE	20
-#define CURSOR_DRAW_DELAY	2
 
 static int inverse = 0;
 static char fontname[40] __initdata = { 0 };
-static char curblink __initdata = 1;
-static char noaccel __initdata = 0;
 #if defined(CONFIG_PPC)
 static signed char init_vmode __initdata = -1, init_cmode __initdata = -1;
 #endif
@@ -448,20 +403,41 @@
 static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
 static void imsttfb_remove(struct pci_dev *pdev);
 
+/*
+ * Register access
+ */
+static inline u32 read_reg_le32(volatile u32 *base, int regindex)
+{
+#ifdef __powerpc__
+	in_le32((volatile u32 *) (base + regindex));
+#else
+	return readl(base + regindex);
+#endif
+}
+
+static inline void write_reg_le32(volatile u32 *base, int regindex, u32 val)
+{
+#ifdef __powerpc__
+	out_le32((volatile u32 *) (base + regindex), val);
+#else
+	writel(val, base + regindex);
+#endif
+}
+
 static __u32
-getclkMHz (struct fb_info_imstt *p)
+getclkMHz(struct imstt_par *par)
 {
 	__u32 clk_m, clk_n, clk_p;
 
-	clk_m = p->init.pclk_m;
-	clk_n = p->init.pclk_n;
-	clk_p = p->init.pclk_p;
+	clk_m = par->init.pclk_m;
+	clk_n = par->init.pclk_n;
+	clk_p = par->init.pclk_p;
 
 	return 20 * (clk_m + 1) / ((clk_n + 1) * (clk_p ? 2 * clk_p : 1));
 }
 
 static void
-setclkMHz (struct fb_info_imstt *p, __u32 MHz)
+setclkMHz(struct imstt_par *par, __u32 MHz)
 {
 	__u32 clk_m, clk_n, clk_p, x, stage, spilled;
 
@@ -487,15 +463,15 @@
 		}
 	}
 
-	p->init.pclk_m = clk_m;
-	p->init.pclk_n = clk_n;
-	p->init.pclk_p = clk_p;
+	par->init.pclk_m = clk_m;
+	par->init.pclk_n = clk_n;
+	par->init.pclk_p = clk_p;
 }
 
 static struct imstt_regvals *
-compute_imstt_regvals_ibm (struct fb_info_imstt *p, int xres, int yres)
+compute_imstt_regvals_ibm(struct imstt_par *par, int xres, int yres)
 {
-	struct imstt_regvals *init = &p->init;
+	struct imstt_regvals *init = &par->init;
 	__u32 MHz, hes, heb, veb, htp, vtp;
 
 	switch (xres) {
@@ -527,7 +503,7 @@
 			return 0;
 	}
 
-	setclkMHz(p, MHz);
+	setclkMHz(par, MHz);
 
 	init->hes = hes;
 	init->heb = heb;
@@ -540,12 +516,11 @@
 	init->vil = init->vsb;
 
 	init->pitch = xres;
-
 	return init;
 }
 
 static struct imstt_regvals *
-compute_imstt_regvals_tvp (struct fb_info_imstt *p, int xres, int yres)
+compute_imstt_regvals_tvp(struct imstt_par *par, int xres, int yres)
 {
 	struct imstt_regvals *init;
 
@@ -574,48 +549,48 @@
 		default:
 			return 0;
 	}
-	p->init = *init;
-
+	par->init = *init;
 	return init;
 }
 
 static struct imstt_regvals *
-compute_imstt_regvals (struct fb_info_imstt *p, u_int xres, u_int yres)
+compute_imstt_regvals (struct imstt_par *par, u_int xres, u_int yres)
 {
-	if (p->ramdac == IBM)
-		return compute_imstt_regvals_ibm(p, xres, yres);
+	if (par->ramdac == IBM)
+		return compute_imstt_regvals_ibm(par, xres, yres);
 	else
-		return compute_imstt_regvals_tvp(p, xres, yres);
+		return compute_imstt_regvals_tvp(par, xres, yres);
 }
 
 static void
-set_imstt_regvals_ibm (struct fb_info_imstt *p, u_int bpp)
+set_imstt_regvals_ibm (struct imstt_par *par, u_int bpp)
 {
-	struct imstt_regvals *init = &p->init;
+	struct imstt_regvals *init = &par->init;
 	__u8 pformat = (bpp >> 3) + 2;
 
-	p->cmap_regs[PIDXHI] = 0;		eieio();
-	p->cmap_regs[PIDXLO] = PIXM0;		eieio();
-	p->cmap_regs[PIDXDATA] = init->pclk_m;	eieio();
-	p->cmap_regs[PIDXLO] = PIXN0;		eieio();
-	p->cmap_regs[PIDXDATA] = init->pclk_n;	eieio();
-	p->cmap_regs[PIDXLO] = PIXP0;		eieio();
-	p->cmap_regs[PIDXDATA] = init->pclk_p;	eieio();
-	p->cmap_regs[PIDXLO] = PIXC0;		eieio();
-	p->cmap_regs[PIDXDATA] = 0x02;		eieio();
+	par->cmap_regs[PIDXHI] = 0;		eieio();
+	par->cmap_regs[PIDXLO] = PIXM0;		eieio();
+	par->cmap_regs[PIDXDATA] = init->pclk_m;eieio();
+	par->cmap_regs[PIDXLO] = PIXN0;		eieio();
+	par->cmap_regs[PIDXDATA] = init->pclk_n;eieio();
+	par->cmap_regs[PIDXLO] = PIXP0;		eieio();
+	par->cmap_regs[PIDXDATA] = init->pclk_p;eieio();
+	par->cmap_regs[PIDXLO] = PIXC0;		eieio();
+	par->cmap_regs[PIDXDATA] = 0x02;	eieio();
 
-	p->cmap_regs[PIDXLO] = PIXFMT;		eieio();
-	p->cmap_regs[PIDXDATA] = pformat;	eieio();
+	par->cmap_regs[PIDXLO] = PIXFMT;	eieio();
+	par->cmap_regs[PIDXDATA] = pformat;	eieio();
 }
 
 static void
-set_imstt_regvals_tvp (struct fb_info_imstt *p, u_int bpp)
+set_imstt_regvals_tvp (struct imstt_par *par, u_int bpp)
 {
-	struct imstt_regvals *init = &p->init;
+	struct imstt_regvals *init = &par->init;
 	__u8 tcc, mxc, lckl_n, mic;
 	__u8 mlc, lckl_p;
 
 	switch (bpp) {
+		default:
 		case 8:
 			tcc = 0x80;
 			mxc = 0x4d;
@@ -647,48 +622,49 @@
 	}
 	mic = 0x08;
 
-	p->cmap_regs[TVPADDRW] = TVPIRPLA;	eieio();
-	p->cmap_regs[TVPIDATA] = 0x00;		eieio();
-	p->cmap_regs[TVPADDRW] = TVPIRPPD;	eieio();
-	p->cmap_regs[TVPIDATA] = init->pclk_m;	eieio();
-	p->cmap_regs[TVPADDRW] = TVPIRPPD;	eieio();
-	p->cmap_regs[TVPIDATA] = init->pclk_n;	eieio();
-	p->cmap_regs[TVPADDRW] = TVPIRPPD;	eieio();
-	p->cmap_regs[TVPIDATA] = init->pclk_p;	eieio();
-
-	p->cmap_regs[TVPADDRW] = TVPIRTCC;	eieio();
-	p->cmap_regs[TVPIDATA] = tcc;		eieio();
-	p->cmap_regs[TVPADDRW] = TVPIRMXC;	eieio();
-	p->cmap_regs[TVPIDATA] = mxc;		eieio();
-	p->cmap_regs[TVPADDRW] = TVPIRMIC;	eieio();
-	p->cmap_regs[TVPIDATA] = mic;		eieio();
-
-	p->cmap_regs[TVPADDRW] = TVPIRPLA;	eieio();
-	p->cmap_regs[TVPIDATA] = 0x00;		eieio();
-	p->cmap_regs[TVPADDRW] = TVPIRLPD;	eieio();
-	p->cmap_regs[TVPIDATA] = lckl_n;	eieio();
-
-	p->cmap_regs[TVPADDRW] = TVPIRPLA;	eieio();
-	p->cmap_regs[TVPIDATA] = 0x15;		eieio();
-	p->cmap_regs[TVPADDRW] = TVPIRMLC;	eieio();
-	p->cmap_regs[TVPIDATA] = mlc;		eieio();
-
-	p->cmap_regs[TVPADDRW] = TVPIRPLA;	eieio();
-	p->cmap_regs[TVPIDATA] = 0x2a;		eieio();
-	p->cmap_regs[TVPADDRW] = TVPIRLPD;	eieio();
-	p->cmap_regs[TVPIDATA] = lckl_p;	eieio();
+	par->cmap_regs[TVPADDRW] = TVPIRPLA;		eieio();
+	par->cmap_regs[TVPIDATA] = 0x00;		eieio();
+	par->cmap_regs[TVPADDRW] = TVPIRPPD;		eieio();
+	par->cmap_regs[TVPIDATA] = init->pclk_m;	eieio();
+	par->cmap_regs[TVPADDRW] = TVPIRPPD;		eieio();
+	par->cmap_regs[TVPIDATA] = init->pclk_n;	eieio();
+	par->cmap_regs[TVPADDRW] = TVPIRPPD;		eieio();
+	par->cmap_regs[TVPIDATA] = init->pclk_p;	eieio();
+
+	par->cmap_regs[TVPADDRW] = TVPIRTCC;		eieio();
+	par->cmap_regs[TVPIDATA] = tcc;			eieio();
+	par->cmap_regs[TVPADDRW] = TVPIRMXC;		eieio();
+	par->cmap_regs[TVPIDATA] = mxc;			eieio();
+	par->cmap_regs[TVPADDRW] = TVPIRMIC;		eieio();
+	par->cmap_regs[TVPIDATA] = mic;			eieio();
+
+	par->cmap_regs[TVPADDRW] = TVPIRPLA;		eieio();
+	par->cmap_regs[TVPIDATA] = 0x00;		eieio();
+	par->cmap_regs[TVPADDRW] = TVPIRLPD;		eieio();
+	par->cmap_regs[TVPIDATA] = lckl_n;		eieio();
+
+	par->cmap_regs[TVPADDRW] = TVPIRPLA;		eieio();
+	par->cmap_regs[TVPIDATA] = 0x15;		eieio();
+	par->cmap_regs[TVPADDRW] = TVPIRMLC;		eieio();
+	par->cmap_regs[TVPIDATA] = mlc;			eieio();
+
+	par->cmap_regs[TVPADDRW] = TVPIRPLA;		eieio();
+	par->cmap_regs[TVPIDATA] = 0x2a;		eieio();
+	par->cmap_regs[TVPADDRW] = TVPIRLPD;		eieio();
+	par->cmap_regs[TVPIDATA] = lckl_p;		eieio();
 }
 
 static void
-set_imstt_regvals (struct fb_info_imstt *p, u_int bpp)
+set_imstt_regvals (struct fb_info *info, u_int bpp)
 {
-	struct imstt_regvals *init = &p->init;
+	struct imstt_par *par = (struct imstt_par *) info->par;
+	struct imstt_regvals *init = &par->init;
 	__u32 ctl, pitch, byteswap, scr;
 
-	if (p->ramdac == IBM)
-		set_imstt_regvals_ibm(p, bpp);
+	if (par->ramdac == IBM)
+		set_imstt_regvals_ibm(par, bpp);
 	else
-		set_imstt_regvals_tvp(p, bpp);
+		set_imstt_regvals_tvp(par, bpp);
 
   /*
    * From what I (jsk) can gather poking around with MacsBug,
@@ -702,6 +678,7 @@
    *       32bpp          1       1
    */
 	switch (bpp) {
+		default:
 		case 8:
 			ctl = 0x17b1;
 			pitch = init->pitch >> 2;
@@ -714,7 +691,7 @@
 			break;
 		case 24:
 			ctl = 0x17b9;
-			pitch = init->pitch - (p->init.pitch >> 2);
+			pitch = init->pitch - (init->pitch >> 2);
 			byteswap = 0x200;
 			break;
 		case 32:
@@ -723,36 +700,36 @@
 			byteswap = 0x300;
 			break;
 	}
-	if (p->ramdac == TVP)
+	if (par->ramdac == TVP)
 		ctl -= 0x30;
 
-	out_le32(&p->dc_regs[HES], init->hes);
-	out_le32(&p->dc_regs[HEB], init->heb);
-	out_le32(&p->dc_regs[HSB], init->hsb);
-	out_le32(&p->dc_regs[HT], init->ht);
-	out_le32(&p->dc_regs[VES], init->ves);
-	out_le32(&p->dc_regs[VEB], init->veb);
-	out_le32(&p->dc_regs[VSB], init->vsb);
-	out_le32(&p->dc_regs[VT], init->vt);
-	out_le32(&p->dc_regs[VIL], init->vil);
-	out_le32(&p->dc_regs[HCIV], 1);
-	out_le32(&p->dc_regs[VCIV], 1);
-	out_le32(&p->dc_regs[TCDR], 4);
-	out_le32(&p->dc_regs[RRCIV], 1);
-	out_le32(&p->dc_regs[RRSC], 0x980);
-	out_le32(&p->dc_regs[RRCR], 0x11);
-
-	if (p->ramdac == IBM) {
-		out_le32(&p->dc_regs[HRIR], 0x0100);
-		out_le32(&p->dc_regs[CMR], 0x00ff);
-		out_le32(&p->dc_regs[SRGCTL], 0x0073);
+	write_reg_le32(par->dc_regs, HES, init->hes);
+	write_reg_le32(par->dc_regs, HEB, init->heb);
+	write_reg_le32(par->dc_regs, HSB, init->hsb);
+	write_reg_le32(par->dc_regs, HT, init->ht);
+	write_reg_le32(par->dc_regs, VES, init->ves);
+	write_reg_le32(par->dc_regs, VEB, init->veb);
+	write_reg_le32(par->dc_regs, VSB, init->vsb);
+	write_reg_le32(par->dc_regs, VT, init->vt);
+	write_reg_le32(par->dc_regs, VIL, init->vil);
+	write_reg_le32(par->dc_regs, HCIV, 1);
+	write_reg_le32(par->dc_regs, VCIV, 1);
+	write_reg_le32(par->dc_regs, TCDR, 4);
+	write_reg_le32(par->dc_regs, RRCIV, 1);
+	write_reg_le32(par->dc_regs, RRSC, 0x980);
+	write_reg_le32(par->dc_regs, RRCR, 0x11);
+
+	if (par->ramdac == IBM) {
+		write_reg_le32(par->dc_regs, HRIR, 0x0100);
+		write_reg_le32(par->dc_regs, CMR, 0x00ff);
+		write_reg_le32(par->dc_regs, SRGCTL, 0x0073);
 	} else {
-		out_le32(&p->dc_regs[HRIR], 0x0200);
-		out_le32(&p->dc_regs[CMR], 0x01ff);
-		out_le32(&p->dc_regs[SRGCTL], 0x0003);
+		write_reg_le32(par->dc_regs, HRIR, 0x0200);
+		write_reg_le32(par->dc_regs, CMR, 0x01ff);
+		write_reg_le32(par->dc_regs, SRGCTL, 0x0003);
 	}
 
-	switch (p->total_vram) {
+	switch (info->fix.smem_len) {
 		case 0x200000:
 			scr = 0x059d | byteswap;
 			break;
@@ -764,432 +741,139 @@
 			break;
 	}
 
-	out_le32(&p->dc_regs[SCR], scr);
-	out_le32(&p->dc_regs[SPR], pitch);
-	out_le32(&p->dc_regs[STGCTL], ctl);
+	write_reg_le32(par->dc_regs, SCR, scr);
+	write_reg_le32(par->dc_regs, SPR, pitch);
+	write_reg_le32(par->dc_regs, STGCTL, ctl);
 }
 
 static inline void
-set_offset (struct display *disp, struct fb_info_imstt *p)
+set_offset (struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	__u32 off = disp->var.yoffset * (p->info.fix.line_length >> 3)
-		    + ((disp->var.xoffset * (disp->var.bits_per_pixel >> 3)) >> 3);
-	out_le32(&p->dc_regs[SSR], off);
+	struct imstt_par *par = (struct imstt_par *) info->par;
+	__u32 off = var->yoffset * (info->fix.line_length >> 3)
+		    + ((var->xoffset * (var->bits_per_pixel >> 3)) >> 3);
+	write_reg_le32(par->dc_regs, SSR, off);
 }
 
 static inline void
-set_555 (struct fb_info_imstt *p)
+set_555 (struct imstt_par *par)
 {
-	if (p->ramdac == IBM) {
-		p->cmap_regs[PIDXHI] = 0;	eieio();
-		p->cmap_regs[PIDXLO] = BPP16;	eieio();
-		p->cmap_regs[PIDXDATA] = 0x01;	eieio();
+	if (par->ramdac == IBM) {
+		par->cmap_regs[PIDXHI] = 0;		eieio();
+		par->cmap_regs[PIDXLO] = BPP16;		eieio();
+		par->cmap_regs[PIDXDATA] = 0x01;	eieio();
 	} else {
-		p->cmap_regs[TVPADDRW] = TVPIRTCC;	eieio();
-		p->cmap_regs[TVPIDATA] = 0x44;		eieio();
+		par->cmap_regs[TVPADDRW] = TVPIRTCC;	eieio();
+		par->cmap_regs[TVPIDATA] = 0x44;	eieio();
 	}
 }
 
 static inline void
-set_565 (struct fb_info_imstt *p)
+set_565 (struct imstt_par *par)
 {
-	if (p->ramdac == IBM) {
-		p->cmap_regs[PIDXHI] = 0;	eieio();
-		p->cmap_regs[PIDXLO] = BPP16;	eieio();
-		p->cmap_regs[PIDXDATA] = 0x03;	eieio();
+	if (par->ramdac == IBM) {
+		par->cmap_regs[PIDXHI] = 0;		eieio();
+		par->cmap_regs[PIDXLO] = BPP16;		eieio();
+		par->cmap_regs[PIDXDATA] = 0x03;	eieio();
 	} else {
-		p->cmap_regs[TVPADDRW] = TVPIRTCC;	eieio();
-		p->cmap_regs[TVPIDATA] = 0x45;		eieio();
-	}
-}
-
-static void
-imstt_set_cursor (struct fb_info_imstt *p, int on)
-{
-	struct imstt_cursor *c = &p->cursor;
-
-	if (p->ramdac == IBM) {
-		p->cmap_regs[PIDXHI] = 0;	eieio();
-		if (!on) {
-			p->cmap_regs[PIDXLO] = CURSCTL;	eieio();
-			p->cmap_regs[PIDXDATA] = 0x00;	eieio();
-		} else {
-			p->cmap_regs[PIDXLO] = CURSXHI;		eieio();
-			p->cmap_regs[PIDXDATA] = c->x >> 8;	eieio();
-			p->cmap_regs[PIDXLO] = CURSXLO;		eieio();
-			p->cmap_regs[PIDXDATA] = c->x & 0xff;	eieio();
-			p->cmap_regs[PIDXLO] = CURSYHI;		eieio();
-			p->cmap_regs[PIDXDATA] = c->y >> 8;	eieio();
-			p->cmap_regs[PIDXLO] = CURSYLO;		eieio();
-			p->cmap_regs[PIDXDATA] = c->y & 0xff;	eieio();
-			p->cmap_regs[PIDXLO] = CURSCTL;		eieio();
-			p->cmap_regs[PIDXDATA] = 0x02;		eieio();
-		}
-	} else {
-		if (!on) {
-			p->cmap_regs[TVPADDRW] = TVPIRICC;	eieio();
-			p->cmap_regs[TVPIDATA] = 0x00;		eieio();
-		} else {
-			__u16 x = c->x + 0x40, y = c->y + 0x40;
-
-			p->cmap_regs[TVPCXPOH] = x >> 8;	eieio();
-			p->cmap_regs[TVPCXPOL] = x & 0xff;	eieio();
-			p->cmap_regs[TVPCYPOH] = y >> 8;	eieio();
-			p->cmap_regs[TVPCYPOL] = y & 0xff;	eieio();
-			p->cmap_regs[TVPADDRW] = TVPIRICC;	eieio();
-			p->cmap_regs[TVPIDATA] = 0x02;		eieio();
-		}
-	}
-}
-
-static void
-imsttfbcon_cursor (struct display *disp, int mode, int x, int y)
-{
-	struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info;
-	struct imstt_cursor *c = &p->cursor;
-
-	x *= fontwidth(disp);
-	y *= fontheight(disp);
-
-	if (c->x == x && c->y == y && (mode == CM_ERASE) == !c->enable)
-		return;
-
-	c->enable = 0;
-	if (c->on)
-		imstt_set_cursor(p, 0);
-	c->x = x - disp->var.xoffset;
-	c->y = y - disp->var.yoffset;
-
-	switch (mode) {
-		case CM_ERASE:
-			c->on = 0;
-			break;
-		case CM_DRAW:
-		case CM_MOVE:
-			if (c->on)
-				imstt_set_cursor(p, c->on);
-			else
-				c->vbl_cnt = CURSOR_DRAW_DELAY;
-			c->enable = 1;
-			break;
+		par->cmap_regs[TVPADDRW] = TVPIRTCC;	eieio();
+		par->cmap_regs[TVPIDATA] = 0x45;	eieio();
 	}
 }
 
 static int
-imsttfbcon_set_font (struct display *disp, int width, int height)
+imsttfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info;
-	struct imstt_cursor *c = &p->cursor;
-	u_int x, y;
-	__u8 fgc;
-
-	if (width > 32 || height > 32)
+	if ((var->bits_per_pixel != 8 && var->bits_per_pixel != 16
+	    && var->bits_per_pixel != 24 && var->bits_per_pixel != 32)
+	    || var->xres_virtual < var->xres || var->yres_virtual < var->yres
+	    || var->nonstd
+	    || (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
 		return -EINVAL;
 
-	c->height = height;
-	c->width = width;
-
-	fgc = ~attr_bgcol_ec(disp, disp->conp);
-
-	if (p->ramdac == IBM) {
-		p->cmap_regs[PIDXHI] = 1;	eieio();
-		for (x = 0; x < 0x100; x++) {
-			p->cmap_regs[PIDXLO] = x;	eieio();
-			p->cmap_regs[PIDXDATA] = 0x00;	eieio();
-		}
-		p->cmap_regs[PIDXHI] = 1;	eieio();
-		for (y = 0; y < height; y++)
-			for (x = 0; x < width >> 2; x++) {
-				p->cmap_regs[PIDXLO] = x + y * 8;	eieio();
-				p->cmap_regs[PIDXDATA] = 0xff;		eieio();
-			}
-		p->cmap_regs[PIDXHI] = 0;	eieio();
-		p->cmap_regs[PIDXLO] = CURS1R;	eieio();
-		p->cmap_regs[PIDXDATA] = fgc;	eieio();
-		p->cmap_regs[PIDXLO] = CURS1G;	eieio();
-		p->cmap_regs[PIDXDATA] = fgc;	eieio();
-		p->cmap_regs[PIDXLO] = CURS1B;	eieio();
-		p->cmap_regs[PIDXDATA] = fgc;	eieio();
-		p->cmap_regs[PIDXLO] = CURS2R;	eieio();
-		p->cmap_regs[PIDXDATA] = fgc;	eieio();
-		p->cmap_regs[PIDXLO] = CURS2G;	eieio();
-		p->cmap_regs[PIDXDATA] = fgc;	eieio();
-		p->cmap_regs[PIDXLO] = CURS2B;	eieio();
-		p->cmap_regs[PIDXDATA] = fgc;	eieio();
-		p->cmap_regs[PIDXLO] = CURS3R;	eieio();
-		p->cmap_regs[PIDXDATA] = fgc;	eieio();
-		p->cmap_regs[PIDXLO] = CURS3G;	eieio();
-		p->cmap_regs[PIDXDATA] = fgc;	eieio();
-		p->cmap_regs[PIDXLO] = CURS3B;	eieio();
-		p->cmap_regs[PIDXDATA] = fgc;	eieio();
-	} else {
-		p->cmap_regs[TVPADDRW] = TVPIRICC;	eieio();
-		p->cmap_regs[TVPIDATA] &= 0x03;		eieio();
-		p->cmap_regs[TVPADDRW] = 0;		eieio();
-		for (x = 0; x < 0x200; x++) {
-			p->cmap_regs[TVPCRDAT] = 0x00;	eieio();
-		}
-		for (x = 0; x < 0x200; x++) {
-			p->cmap_regs[TVPCRDAT] = 0xff;	eieio();
-		}
-		p->cmap_regs[TVPADDRW] = TVPIRICC;	eieio();
-		p->cmap_regs[TVPIDATA] &= 0x03;		eieio();
-		for (y = 0; y < height; y++)
-			for (x = 0; x < width >> 3; x++) {
-				p->cmap_regs[TVPADDRW] = x + y * 8;	eieio();
-				p->cmap_regs[TVPCRDAT] = 0xff;		eieio();
-			}
-		p->cmap_regs[TVPADDRW] = TVPIRICC;	eieio();
-		p->cmap_regs[TVPIDATA] |= 0x08;		eieio();
-		for (y = 0; y < height; y++)
-			for (x = 0; x < width >> 3; x++) {
-				p->cmap_regs[TVPADDRW] = x + y * 8;	eieio();
-				p->cmap_regs[TVPCRDAT] = 0xff;		eieio();
-			}
-		p->cmap_regs[TVPCADRW] = 0x00;	eieio();
-		for (x = 0; x < 12; x++) {
-			p->cmap_regs[TVPCDATA] = fgc;	eieio();
-		}
-	}
-
-	return 1;
-}
-
-static void
-imstt_cursor_timer_handler (unsigned long dev_addr)
-{
-	struct fb_info_imstt *p = (struct fb_info_imstt *)dev_addr;
-	struct imstt_cursor *c = &p->cursor;
-
-	if (!c->enable)
-		goto out;
-
-	if (c->vbl_cnt && --c->vbl_cnt == 0) {
-		c->on ^= 1;
-		imstt_set_cursor(p, c->on);
-		c->vbl_cnt = c->blink_rate;
-	}
-
-out:
-	c->timer.expires = jiffies + (HZ / 50);
-	add_timer(&c->timer);
-}
-
-static void __init 
-imstt_cursor_init (struct fb_info_imstt *p)
-{
-	struct imstt_cursor *c = &p->cursor;
-
-	imsttfbcon_set_font(&p->disp, fontwidth(&p->disp), fontheight(&p->disp));
-
-	c->enable = 1;
-	c->on = 1;
-	c->x = c->y = 0;
-	c->blink_rate = 0;
-	c->vbl_cnt = CURSOR_DRAW_DELAY;
-
-	if (curblink) {
-		c->blink_rate = CURSOR_BLINK_RATE;
-		init_timer(&c->timer);
-		c->timer.expires = jiffies + (HZ / 50);
-		c->timer.data = (unsigned long)p;
-		c->timer.function = imstt_cursor_timer_handler;
-		add_timer(&c->timer);
-	}
-}
-
-static void
-imsttfbcon_bmove (struct display *disp, int sy, int sx, int dy, int dx, int height, int width)
-{
-	struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info;
-	__u32	Bpp, line_pitch,
-		fb_offset_old, fb_offset_new,
-		sp, dp_octl, cnt, bltctl;
-
-	Bpp = disp->var.bits_per_pixel >> 3,
-
-	sy *= fontheight(disp);
-	sx *= fontwidth(disp);
-	sx *= Bpp;
-	dy *= fontheight(disp);
-	dx *= fontwidth(disp);
-	dx *= Bpp;
-	height *= fontheight(disp);
-	height--;
-	width *= fontwidth(disp);
-	width *= Bpp;
-	width--;
-
-	line_pitch = p->info.fix.line_length;
-	bltctl = 0x05;
-	sp = line_pitch << 16;
-	cnt = height << 16;
+	if ((var->xres * var->yres) * (var->bits_per_pixel >> 3) > info->fix.smem_len
+	    || (var->xres_virtual * var->yres_virtual) * (var->bits_per_pixel >> 3) > info->fix.smem_len)
+		return -EINVAL;
 
-	if (sy < dy) {
-		sy += height;
-		dy += height;
-		sp |= -(line_pitch) & 0xffff;
-		dp_octl = -(line_pitch) & 0xffff;
-	} else {
-		sp |= line_pitch;
-		dp_octl = line_pitch;
-	}
-	if (sx < dx) {
-		sx += width;
-		dx += width;
-		bltctl |= 0x80;
-		cnt |= -(width) & 0xffff;
-	} else {
-		cnt |= width;
+	switch (var->bits_per_pixel) {
+		case 8:
+			var->red.offset = 0;
+			var->red.length = 8;
+			var->green.offset = 0;
+			var->green.length = 8;
+			var->blue.offset = 0;
+			var->blue.length = 8;
+			var->transp.offset = 0;
+			var->transp.length = 0;
+			break;
+		case 16:	/* RGB 555 or 565 */
+			if (var->green.length != 6)
+				var->red.offset = 10;
+			var->red.length = 5;
+			var->green.offset = 5;
+			if (var->green.length != 6)
+				var->green.length = 5;
+			var->blue.offset = 0;
+			var->blue.length = 5;
+			var->transp.offset = 0;
+			var->transp.length = 0;
+			break;
+		case 24:	/* RGB 888 */
+			var->red.offset = 16;
+			var->red.length = 8;
+			var->green.offset = 8;
+			var->green.length = 8;
+			var->blue.offset = 0;
+			var->blue.length = 8;
+			var->transp.offset = 0;
+			var->transp.length = 0;
+			break;
+		case 32:	/* RGBA 8888 */
+			var->red.offset = 16;
+			var->red.length = 8;
+			var->green.offset = 8;
+			var->green.length = 8;
+			var->blue.offset = 0;
+			var->blue.length = 8;
+			var->transp.offset = 24;
+			var->transp.length = 8;
+			break;
 	}
-	fb_offset_old = sy * line_pitch + sx;
-	fb_offset_new = dy * line_pitch + dx;
-
-	while(in_le32(&p->dc_regs[SSTATUS]) & 0x80);
-	out_le32(&p->dc_regs[S1SA], fb_offset_old);
-	out_le32(&p->dc_regs[SP], sp);
-	out_le32(&p->dc_regs[DSA], fb_offset_new);
-	out_le32(&p->dc_regs[CNT], cnt);
-	out_le32(&p->dc_regs[DP_OCTL], dp_octl);
-	out_le32(&p->dc_regs[BLTCTL], bltctl);
-	while(in_le32(&p->dc_regs[SSTATUS]) & 0x80);
-	while(in_le32(&p->dc_regs[SSTATUS]) & 0x40);
-}
 
-static void
-imsttfbcon_clear (struct vc_data *conp, struct display *disp,
-		  int sy, int sx, int height, int width)
-{
-	struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info;
-	__u32 Bpp, line_pitch, bgc;
-
-	bgc = attr_bgcol_ec(disp, conp);
-	bgc |= (bgc << 8);
-	bgc |= (bgc << 16);
-
-	Bpp = disp->var.bits_per_pixel >> 3,
-	line_pitch = p->info.fix.line_length;
-
-	sy *= fontheight(disp);
-	sy *= line_pitch;
-	sx *= fontwidth(disp);
-	sx *= Bpp;
-	height *= fontheight(disp);
-	height--;
-	width *= fontwidth(disp);
-	width *= Bpp;
-	width--;
-
-	while(in_le32(&p->dc_regs[SSTATUS]) & 0x80);
-	out_le32(&p->dc_regs[DSA], sy + sx);
-	out_le32(&p->dc_regs[CNT], (height << 16) | width);
-	out_le32(&p->dc_regs[DP_OCTL], line_pitch);
-	out_le32(&p->dc_regs[BI], 0xffffffff);
-	out_le32(&p->dc_regs[MBC], 0xffffffff);
-	out_le32(&p->dc_regs[CLR], bgc);
-	out_le32(&p->dc_regs[BLTCTL], 0x840); /* 0x200000 */
-	while(in_le32(&p->dc_regs[SSTATUS]) & 0x80);
-	while(in_le32(&p->dc_regs[SSTATUS]) & 0x40);
+	if (var->yres == var->yres_virtual) {
+		__u32 vram = (info->fix.smem_len - (PAGE_SIZE << 2));
+		var->yres_virtual = ((vram << 3) / var->bits_per_pixel) / var->xres_virtual;
+		if (var->yres_virtual < var->yres)
+			var->yres_virtual = var->yres;
+	}
+
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
+	var->blue.msb_right = 0;
+	var->transp.msb_right = 0;
+	var->height = -1;
+	var->width = -1;
+	var->vmode = FB_VMODE_NONINTERLACED;
+	var->left_margin = var->right_margin = 16;
+	var->upper_margin = var->lower_margin = 16;
+	var->hsync_len = var->vsync_len = 8;
+	return 0;
 }
 
-static void
-imsttfbcon_revc (struct display *disp, int sx, int sy)
-{
-	struct fb_info_imstt *p = (struct fb_info_imstt *)disp->fb_info;
-	__u32 Bpp, line_pitch, height, width;
-
-	Bpp = disp->var.bits_per_pixel >> 3,
-	line_pitch = p->info.fix.line_length;
-
-	height = fontheight(disp);
-	width = fontwidth(disp) * Bpp;
-	sy *= height;
-	sy *= line_pitch;
-	sx *= width;
-	height--;
-	width--;
-
-	while(in_le32(&p->dc_regs[SSTATUS]) & 0x80);
-	out_le32(&p->dc_regs[DSA], sy + sx);
-	out_le32(&p->dc_regs[S1SA], sy + sx);
-	out_le32(&p->dc_regs[CNT], (height << 16) | width);
-	out_le32(&p->dc_regs[DP_OCTL], line_pitch);
-	out_le32(&p->dc_regs[SP], line_pitch);
-	out_le32(&p->dc_regs[BLTCTL], 0x40005);
-	while(in_le32(&p->dc_regs[SSTATUS]) & 0x80);
-	while(in_le32(&p->dc_regs[SSTATUS]) & 0x40);
-}
-
-#ifdef FBCON_HAS_CFB8
-static struct display_switch fbcon_imstt8 = {
-	.setup =	fbcon_cfb8_setup,
-	.bmove =	imsttfbcon_bmove,
-	.clear =	imsttfbcon_clear,
-	.putc =		fbcon_cfb8_putc,
-	.putcs =	fbcon_cfb8_putcs,
-	.revc =		imsttfbcon_revc,
-	.cursor =	imsttfbcon_cursor,
-	.set_font =	imsttfbcon_set_font,
-	.clear_margins =fbcon_cfb8_clear_margins,
-	.fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-#ifdef FBCON_HAS_CFB16
-static struct display_switch fbcon_imstt16 = {
-	.setup =	fbcon_cfb16_setup,
-	.bmove =	imsttfbcon_bmove,
-	.clear =	imsttfbcon_clear,
-	.putc =		fbcon_cfb16_putc,
-	.putcs =	fbcon_cfb16_putcs,
-	.revc =		imsttfbcon_revc,
-	.cursor =	imsttfbcon_cursor,
-	.set_font =	imsttfbcon_set_font,
-	.clear_margins =fbcon_cfb16_clear_margins,
-	.fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-#ifdef FBCON_HAS_CFB24
-static struct display_switch fbcon_imstt24 = {
-	.setup =	fbcon_cfb24_setup,
-	.bmove =	imsttfbcon_bmove,
-	.clear =	imsttfbcon_clear,
-	.putc =		fbcon_cfb24_putc,
-	.putcs =	fbcon_cfb24_putcs,
-	.revc =		imsttfbcon_revc,
-	.cursor =	imsttfbcon_cursor,
-	.set_font =	imsttfbcon_set_font,
-	.clear_margins =fbcon_cfb24_clear_margins,
-	.fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-#ifdef FBCON_HAS_CFB32
-static struct display_switch fbcon_imstt32 = {
-	.setup =	fbcon_cfb32_setup,
-	.bmove =	imsttfbcon_bmove,
-	.clear =	imsttfbcon_clear,
-	.putc =		fbcon_cfb32_putc,
-	.putcs =	fbcon_cfb32_putcs,
-	.revc =		imsttfbcon_revc,
-	.cursor =	imsttfbcon_cursor,
-	.set_font =	imsttfbcon_set_font,
-	.clear_margins =fbcon_cfb32_clear_margins,
-	.fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-
 static int
-imsttfb_getcolreg (u_int regno, u_int *red, u_int *green,
-		   u_int *blue, u_int *transp, struct fb_info *info)
+imsttfb_set_par(struct fb_info *info) 
 {
-	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
-
-	if (regno > 255)
-		return 1;
-	*red = (p->palette[regno].red << 8) | p->palette[regno].red;
-	*green = (p->palette[regno].green << 8) | p->palette[regno].green;
-	*blue = (p->palette[regno].blue << 8) | p->palette[regno].blue;
-	*transp = 0;
+	struct imstt_par *par = (struct imstt_par *) info->par;
+		
+	if (!compute_imstt_regvals(par, info->var.xres, info->var.yres))
+		return -EINVAL;
 
+	if (info->var.green.length == 6)
+		set_565(par);
+	else
+		set_555(par);
+	set_imstt_regvals(info, info->var.bits_per_pixel);
+	info->var.pixclock = 1000000 / getclkMHz(par);
 	return 0;
 }
 
@@ -1197,8 +881,8 @@
 imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue,
 		   u_int transp, struct fb_info *info)
 {
-	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
-	u_int bpp = fb_display[info->currcon].var.bits_per_pixel;
+	struct imstt_par *par = (struct imstt_par *) info->par;
+	u_int bpp = info->var.bits_per_pixel;
 
 	if (regno > 255)
 		return 1;
@@ -1207,312 +891,369 @@
 	green >>= 8;
 	blue >>= 8;
 
-	p->palette[regno].red = red;
-	p->palette[regno].green = green;
-	p->palette[regno].blue = blue;
-
 	/* PADDRW/PDATA are the same as TVPPADDRW/TVPPDATA */
 	if (0 && bpp == 16)	/* screws up X */
-		p->cmap_regs[PADDRW] = regno << 3;
+		par->cmap_regs[PADDRW] = regno << 3;
 	else
-		p->cmap_regs[PADDRW] = regno;
+		par->cmap_regs[PADDRW] = regno;
 	eieio();
 
-	p->cmap_regs[PDATA] = red;	eieio();
-	p->cmap_regs[PDATA] = green;	eieio();
-	p->cmap_regs[PDATA] = blue;	eieio();
+	par->cmap_regs[PDATA] = red;	eieio();
+	par->cmap_regs[PDATA] = green;	eieio();
+	par->cmap_regs[PDATA] = blue;	eieio();
 
 	if (regno < 16)
 		switch (bpp) {
-#ifdef FBCON_HAS_CFB16
 			case 16:
-				p->fbcon_cmap.cfb16[regno] = (regno << (fb_display[info->currcon].var.green.length == 5 ? 10 : 11)) | (regno << 5) | regno;
+				((u16 *)info->pseudo_palette)[regno] = (regno << (info->var.green.length == 5 ? 10 : 11)) | (regno << 5) | regno;
 				break;
-#endif
-#ifdef FBCON_HAS_CFB24
 			case 24:
-				p->fbcon_cmap.cfb24[regno] = (regno << 16) | (regno << 8) | regno;
+				((u32 *)info->pseudo_palette)[regno] = (regno << 16) | (regno << 8) | regno;
 				break;
-#endif
-#ifdef FBCON_HAS_CFB32
 			case 32: {
 				int i = (regno << 8) | regno;
-				p->fbcon_cmap.cfb32[regno] = (i << 16) | i;
+				((u32 *)info->pseudo_palette)[regno] = (i << 16) | i;
 				break;
 			}
-#endif
 		}
-
 	return 0;
 }
 
-static void
-set_dispsw (struct display *disp, struct fb_info_imstt *p)
+static int
+imsttfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	u_int accel = disp->var.accel_flags & FB_ACCELF_TEXT;
+	if (var->xoffset + info->var.xres > info->var.xres_virtual
+	    || var->yoffset + info->var.yres > info->var.yres_virtual)
+		return -EINVAL;
 
-	if (disp->conp && disp->conp->vc_sw && disp->conp->vc_sw->con_cursor)
-		disp->conp->vc_sw->con_cursor(disp->conp, CM_ERASE);
+	info->var.xoffset = var->xoffset;
+	info->var.yoffset = var->yoffset;
+	set_offset(var, info);
+	return 0;
+}
 
-	p->dispsw = fbcon_dummy;
-	disp->dispsw = &p->dispsw;
-	disp->dispsw_data = 0;
-	switch (disp->var.bits_per_pixel) {
-		case 8:
-			disp->var.red.offset = 0;
-			disp->var.red.length = 8;
-			disp->var.green.offset = 0;
-			disp->var.green.length = 8;
-			disp->var.blue.offset = 0;
-			disp->var.blue.length = 8;
-			disp->var.transp.offset = 0;
-			disp->var.transp.length = 0;
-#ifdef FBCON_HAS_CFB8
-			p->dispsw = accel ? fbcon_imstt8 : fbcon_cfb8;
-#endif
+static int 
+imsttfb_blank(int blank, struct fb_info *info)
+{
+	struct imstt_par *par = (struct imstt_par *) info->par;
+	__u32 ctrl;
+
+	ctrl = read_reg_le32(par->dc_regs, STGCTL);
+	if (blank > 0) {
+		switch (blank - 1) {
+		case VESA_NO_BLANKING:
+		case VESA_POWERDOWN:
+			ctrl &= ~0x00000380;
+			if (par->ramdac == IBM) {
+				par->cmap_regs[PIDXHI] = 0;		eieio();
+				par->cmap_regs[PIDXLO] = MISCTL2;	eieio();
+				par->cmap_regs[PIDXDATA] = 0x55;	eieio();
+				par->cmap_regs[PIDXLO] = MISCTL1;	eieio();
+				par->cmap_regs[PIDXDATA] = 0x11;	eieio();
+				par->cmap_regs[PIDXLO] = SYNCCTL;	eieio();
+				par->cmap_regs[PIDXDATA] = 0x0f;	eieio();
+				par->cmap_regs[PIDXLO] = PWRMNGMT;	eieio();
+				par->cmap_regs[PIDXDATA] = 0x1f;	eieio();
+				par->cmap_regs[PIDXLO] = CLKCTL;	eieio();
+				par->cmap_regs[PIDXDATA] = 0xc0;
+			}
 			break;
-		case 16:	/* RGB 555 or 565 */
-			if (disp->var.green.length != 6)
-				disp->var.red.offset = 10;
-			disp->var.red.length = 5;
-			disp->var.green.offset = 5;
-			if (disp->var.green.length != 6)
-				disp->var.green.length = 5;
-			disp->var.blue.offset = 0;
-			disp->var.blue.length = 5;
-			disp->var.transp.offset = 0;
-			disp->var.transp.length = 0;
-#ifdef FBCON_HAS_CFB16
-			p->dispsw = accel ? fbcon_imstt16 : fbcon_cfb16;
-			disp->dispsw_data = p->fbcon_cmap.cfb16;
-#endif
+		case VESA_VSYNC_SUSPEND:
+			ctrl &= ~0x00000020;
 			break;
-		case 24:	/* RGB 888 */
-			disp->var.red.offset = 16;
-			disp->var.red.length = 8;
-			disp->var.green.offset = 8;
-			disp->var.green.length = 8;
-			disp->var.blue.offset = 0;
-			disp->var.blue.length = 8;
-			disp->var.transp.offset = 0;
-			disp->var.transp.length = 0;
-#ifdef FBCON_HAS_CFB24
-			p->dispsw = accel ? fbcon_imstt24 : fbcon_cfb24;
-			disp->dispsw_data = p->fbcon_cmap.cfb24;
-#endif
+		case VESA_HSYNC_SUSPEND:
+			ctrl &= ~0x00000010;
 			break;
-		case 32:	/* RGBA 8888 */
-			disp->var.red.offset = 16;
-			disp->var.red.length = 8;
-			disp->var.green.offset = 8;
-			disp->var.green.length = 8;
-			disp->var.blue.offset = 0;
-			disp->var.blue.length = 8;
-			disp->var.transp.offset = 24;
-			disp->var.transp.length = 8;
-#ifdef FBCON_HAS_CFB32
-			p->dispsw = accel ? fbcon_imstt32 : fbcon_cfb32;
-			disp->dispsw_data = p->fbcon_cmap.cfb32;
-#endif
-			break;
-	}
-
-	if (accel && p->ramdac != IBM) {
-		p->dispsw.cursor = 0;
-		p->dispsw.set_font = 0;
+		}
+	} else {
+		if (par->ramdac == IBM) {
+			ctrl |= 0x000017b0;
+			par->cmap_regs[PIDXHI] = 0;		eieio();
+			par->cmap_regs[PIDXLO] = CLKCTL;	eieio();
+			par->cmap_regs[PIDXDATA] = 0x01;	eieio();
+			par->cmap_regs[PIDXLO] = PWRMNGMT;	eieio();
+			par->cmap_regs[PIDXDATA] = 0x00;	eieio();
+			par->cmap_regs[PIDXLO] = SYNCCTL;	eieio();
+			par->cmap_regs[PIDXDATA] = 0x00;	eieio();
+			par->cmap_regs[PIDXLO] = MISCTL1;	eieio();
+			par->cmap_regs[PIDXDATA] = 0x01;	eieio();
+			par->cmap_regs[PIDXLO] = MISCTL2;	eieio();
+			par->cmap_regs[PIDXDATA] = 0x45;	eieio();
+		} else
+			ctrl |= 0x00001780;
 	}
+	write_reg_le32(par->dc_regs, STGCTL, ctrl);
+	return 0;
 }
 
 static void
-set_disp (struct display *disp, struct fb_info_imstt *p)
-{
-	u_int accel = disp->var.accel_flags & FB_ACCELF_TEXT;
+imsttfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+{ 
+	struct imstt_par *par = (struct imstt_par *) info->par;
+	__u32 Bpp, line_pitch, bgc, dx, dy, width, height;
 
-	disp->fb_info = &p->info;
+	bgc = rect->color;
+	bgc |= (bgc << 8);
+	bgc |= (bgc << 16);
 
-	set_dispsw(disp, p);
+	Bpp = info->var.bits_per_pixel >> 3,
+	line_pitch = info->fix.line_length;
 
-	disp->can_soft_blank = 1;
-	if (accel) {
-		disp->scrollmode = SCROLL_YNOMOVE;
-		if (disp->var.yres == disp->var.yres_virtual) {
-			__u32 vram = (p->total_vram - (PAGE_SIZE << 2));
-			disp->var.yres_virtual = ((vram << 3) / disp->var.bits_per_pixel) / disp->var.xres_virtual;
-			if (disp->var.yres_virtual < disp->var.yres)
-				disp->var.yres_virtual = disp->var.yres;
-		}
+	dy = rect->dy * line_pitch;
+	dx = rect->dx * Bpp;
+	height = rect->height;
+	height--;
+	width = rect->width * Bpp;
+	width--;
+
+	if (rect->rop == ROP_COPY) {
+		while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80);
+		write_reg_le32(par->dc_regs, DSA, dy + dx);
+		write_reg_le32(par->dc_regs, CNT, (height << 16) | width);
+		write_reg_le32(par->dc_regs, DP_OCTL, line_pitch);
+		write_reg_le32(par->dc_regs, BI, 0xffffffff);
+		write_reg_le32(par->dc_regs, MBC, 0xffffffff);
+		write_reg_le32(par->dc_regs, CLR, bgc);
+		write_reg_le32(par->dc_regs, BLTCTL, 0x840); /* 0x200000 */
+		while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80);
+		while(read_reg_le32(par->dc_regs, SSTATUS) & 0x40);
 	} else {
-		disp->scrollmode = SCROLL_YREDRAW;
+		while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80);
+		write_reg_le32(par->dc_regs, DSA, dy + dx);
+		write_reg_le32(par->dc_regs, S1SA, dy + dx);
+		write_reg_le32(par->dc_regs, CNT, (height << 16) | width);
+		write_reg_le32(par->dc_regs, DP_OCTL, line_pitch);
+		write_reg_le32(par->dc_regs, SP, line_pitch);
+		write_reg_le32(par->dc_regs, BLTCTL, 0x40005);
+		while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80);
+		while(read_reg_le32(par->dc_regs, SSTATUS) & 0x40);
 	}
-
-	disp->var.activate = 0;
-	disp->var.red.msb_right = 0;
-	disp->var.green.msb_right = 0;
-	disp->var.blue.msb_right = 0;
-	disp->var.transp.msb_right = 0;
-	disp->var.height = -1;
-	disp->var.width = -1;
-	disp->var.vmode = FB_VMODE_NONINTERLACED;
-	disp->var.left_margin = disp->var.right_margin = 16;
-	disp->var.upper_margin = disp->var.lower_margin = 16;
-	disp->var.hsync_len = disp->var.vsync_len = 8;
 }
 
-static int
-imsttfb_set_var (struct fb_var_screeninfo *var, int con, struct fb_info *info)
+static void
+imsttfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
-	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
-	struct display *disp;
-	u_int oldbpp, oldxres, oldyres, oldgreenlen, oldaccel;
-
-	disp = &fb_display[con];
-
-	if ((var->bits_per_pixel != 8 && var->bits_per_pixel != 16
-	    && var->bits_per_pixel != 24 && var->bits_per_pixel != 32)
-	    || var->xres_virtual < var->xres || var->yres_virtual < var->yres
-	    || var->nonstd
-	    || (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
-		return -EINVAL;
-
-	if ((var->xres * var->yres) * (var->bits_per_pixel >> 3) > p->total_vram
-	    || (var->xres_virtual * var->yres_virtual) * (var->bits_per_pixel >> 3) > p->total_vram)
-		return -EINVAL;
-
-	if (!((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW))
-		return 0;
+	struct imstt_par *par = (struct imstt_par *) info->par;
+	__u32 Bpp, line_pitch, fb_offset_old, fb_offset_new, sp, dp_octl;
+ 	__u32 cnt, bltctl, sx, sy, dx, dy, height, width;
+
+	Bpp = info->var.bits_per_pixel >> 3,
+
+	sx = area->sx * Bpp;
+	sy = area->sy;
+	dx = area->dx * Bpp;
+	dy = area->dy;
+	height = area->height;
+	height--;
+	width = area->width * Bpp;
+	width--;
 
-	if (!compute_imstt_regvals(p, var->xres, var->yres))
-		return -EINVAL;
+	line_pitch = info->fix.line_length;
+	bltctl = 0x05;
+	sp = line_pitch << 16;
+	cnt = height << 16;
 
-	oldbpp = disp->var.bits_per_pixel;
-	oldxres = disp->var.xres;
-	oldyres = disp->var.yres;
-	oldgreenlen = disp->var.green.length;
-	oldaccel = disp->var.accel_flags;
-
-	disp->var.bits_per_pixel = var->bits_per_pixel;
-	disp->var.xres = var->xres;
-	disp->var.yres = var->yres;
-	disp->var.xres_virtual = var->xres_virtual;
-	disp->var.yres_virtual = var->yres_virtual;
-	disp->var.green.length = var->green.length;
-	disp->var.accel_flags = var->accel_flags;
-
-	set_disp(disp, p);
-
-	if (info->changevar)
-		(*info->changevar)(con);
-
-	if (con == info->currcon) {
-		if (oldgreenlen != disp->var.green.length) {
-			if (disp->var.green.length == 6)
-				set_565(p);
-			else
-				set_555(p);
-		}
-		if (oldxres != disp->var.xres || oldyres != disp->var.yres || oldbpp != disp->var.bits_per_pixel)
-			set_imstt_regvals(p, disp->var.bits_per_pixel);
-			
-	}
-	disp->var.pixclock = 1000000 / getclkMHz(p);
-
-	if (oldbpp != disp->var.bits_per_pixel) {
-		int err = fb_alloc_cmap(&disp->cmap, 0, 0);
-		if (err)
-			return err;
-		do_install_cmap(con, info);
+	if (sy < dy) {
+		sy += height;
+		dy += height;
+		sp |= -(line_pitch) & 0xffff;
+		dp_octl = -(line_pitch) & 0xffff;
+	} else {
+		sp |= line_pitch;
+		dp_octl = line_pitch;
+	}
+	if (sx < dx) {
+		sx += width;
+		dx += width;
+		bltctl |= 0x80;
+		cnt |= -(width) & 0xffff;
+	} else {
+		cnt |= width;
 	}
-	*var = disp->var;
+	fb_offset_old = sy * line_pitch + sx;
+	fb_offset_new = dy * line_pitch + dx;
 
-	return 0;
+	while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80);
+	write_reg_le32(par->dc_regs, S1SA, fb_offset_old);
+	write_reg_le32(par->dc_regs, SP, sp);
+	write_reg_le32(par->dc_regs, DSA, fb_offset_new);
+	write_reg_le32(par->dc_regs, CNT, cnt);
+	write_reg_le32(par->dc_regs, DP_OCTL, dp_octl);
+	write_reg_le32(par->dc_regs, BLTCTL, bltctl);
+	while(read_reg_le32(par->dc_regs, SSTATUS) & 0x80);
+	while(read_reg_le32(par->dc_regs, SSTATUS) & 0x40);
 }
 
 static int
-imsttfb_pan_display (struct fb_var_screeninfo *var, int con, struct fb_info *info)
+imsttfb_load_cursor_image(struct imstt_par *par, int width, int height, __u8 fgc)
 {
-	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
-	struct display *disp = &fb_display[con];
+	u_int x, y;
 
-	if (var->xoffset + disp->var.xres > disp->var.xres_virtual
-	    || var->yoffset + disp->var.yres > disp->var.yres_virtual)
+	if (width > 32 || height > 32)
 		return -EINVAL;
 
-	disp->var.xoffset = var->xoffset;
-	disp->var.yoffset = var->yoffset;
-	if (con == info->currcon)
-		set_offset(disp, p);
-
-	return 0;
+	if (par->ramdac == IBM) {
+		par->cmap_regs[PIDXHI] = 1;	eieio();
+		for (x = 0; x < 0x100; x++) {
+			par->cmap_regs[PIDXLO] = x;		eieio();
+			par->cmap_regs[PIDXDATA] = 0x00;	eieio();
+		}
+		par->cmap_regs[PIDXHI] = 1;	eieio();
+		for (y = 0; y < height; y++)
+			for (x = 0; x < width >> 2; x++) {
+				par->cmap_regs[PIDXLO] = x + y * 8;	eieio();
+				par->cmap_regs[PIDXDATA] = 0xff;	eieio();
+			}
+		par->cmap_regs[PIDXHI] = 0;		eieio();
+		par->cmap_regs[PIDXLO] = CURS1R;	eieio();
+		par->cmap_regs[PIDXDATA] = fgc;		eieio();
+		par->cmap_regs[PIDXLO] = CURS1G;	eieio();
+		par->cmap_regs[PIDXDATA] = fgc;		eieio();
+		par->cmap_regs[PIDXLO] = CURS1B;	eieio();
+		par->cmap_regs[PIDXDATA] = fgc;		eieio();
+		par->cmap_regs[PIDXLO] = CURS2R;	eieio();
+		par->cmap_regs[PIDXDATA] = fgc;		eieio();
+		par->cmap_regs[PIDXLO] = CURS2G;	eieio();
+		par->cmap_regs[PIDXDATA] = fgc;		eieio();
+		par->cmap_regs[PIDXLO] = CURS2B;	eieio();
+		par->cmap_regs[PIDXDATA] = fgc;		eieio();
+		par->cmap_regs[PIDXLO] = CURS3R;	eieio();
+		par->cmap_regs[PIDXDATA] = fgc;		eieio();
+		par->cmap_regs[PIDXLO] = CURS3G;	eieio();
+		par->cmap_regs[PIDXDATA] = fgc;		eieio();
+		par->cmap_regs[PIDXLO] = CURS3B;	eieio();
+		par->cmap_regs[PIDXDATA] = fgc;		eieio();
+	} else {
+		par->cmap_regs[TVPADDRW] = TVPIRICC;	eieio();
+		par->cmap_regs[TVPIDATA] &= 0x03;	eieio();
+		par->cmap_regs[TVPADDRW] = 0;		eieio();
+		for (x = 0; x < 0x200; x++) {
+			par->cmap_regs[TVPCRDAT] = 0x00;	eieio();
+		}
+		for (x = 0; x < 0x200; x++) {
+			par->cmap_regs[TVPCRDAT] = 0xff;	eieio();
+		}
+		par->cmap_regs[TVPADDRW] = TVPIRICC;	eieio();
+		par->cmap_regs[TVPIDATA] &= 0x03;	eieio();
+		for (y = 0; y < height; y++)
+			for (x = 0; x < width >> 3; x++) {
+				par->cmap_regs[TVPADDRW] = x + y * 8;	eieio();
+				par->cmap_regs[TVPCRDAT] = 0xff;		eieio();
+			}
+		par->cmap_regs[TVPADDRW] = TVPIRICC;	eieio();
+		par->cmap_regs[TVPIDATA] |= 0x08;	eieio();
+		for (y = 0; y < height; y++)
+			for (x = 0; x < width >> 3; x++) {
+				par->cmap_regs[TVPADDRW] = x + y * 8;	eieio();
+				par->cmap_regs[TVPCRDAT] = 0xff;		eieio();
+			}
+		par->cmap_regs[TVPCADRW] = 0x00;	eieio();
+		for (x = 0; x < 12; x++)
+			par->cmap_regs[TVPCDATA] = fgc;	eieio();
+	}
+	return 1;
 }
 
-static int
-imsttfb_get_cmap (struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
+static void
+imstt_set_cursor(struct imstt_par *par, struct fb_image *d, int on)
 {
-	if (con == info->currcon)	/* current console? */
-		return fb_get_cmap(cmap, kspc, imsttfb_getcolreg, info);
-	else if (fb_display[con].cmap.len)	/* non default colormap? */
-		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-	else {
-		u_int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
-		fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
-	}
+	if (par->ramdac == IBM) {
+		par->cmap_regs[PIDXHI] = 0;	eieio();
+		if (!on) {
+			par->cmap_regs[PIDXLO] = CURSCTL;	eieio();
+			par->cmap_regs[PIDXDATA] = 0x00;	eieio();
+		} else {
+			par->cmap_regs[PIDXLO] = CURSXHI;	eieio();
+			par->cmap_regs[PIDXDATA] = d->dx >> 8;	eieio();
+			par->cmap_regs[PIDXLO] = CURSXLO;	eieio();
+			par->cmap_regs[PIDXDATA] = d->dx & 0xff;eieio();
+			par->cmap_regs[PIDXLO] = CURSYHI;	eieio();
+			par->cmap_regs[PIDXDATA] = d->dy >> 8;	eieio();
+			par->cmap_regs[PIDXLO] = CURSYLO;	eieio();
+			par->cmap_regs[PIDXDATA] = d->dy & 0xff;eieio();
+			par->cmap_regs[PIDXLO] = CURSCTL;	eieio();
+			par->cmap_regs[PIDXDATA] = 0x02;	eieio();
+		}
+	} else {
+		if (!on) {
+			par->cmap_regs[TVPADDRW] = TVPIRICC;	eieio();
+			par->cmap_regs[TVPIDATA] = 0x00;	eieio();
+		} else {
+			__u16 x = d->dx + 0x40, y = d->dy + 0x40;
 
-	return 0;
+			par->cmap_regs[TVPCXPOH] = x >> 8;	eieio();
+			par->cmap_regs[TVPCXPOL] = x & 0xff;	eieio();
+			par->cmap_regs[TVPCYPOH] = y >> 8;	eieio();
+			par->cmap_regs[TVPCYPOL] = y & 0xff;	eieio();
+			par->cmap_regs[TVPADDRW] = TVPIRICC;	eieio();
+			par->cmap_regs[TVPIDATA] = 0x02;	eieio();
+		}
+	}
 }
 
+#if 0
 static int 
-imsttfb_blank (int blank, struct fb_info *info)
+imsttfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
-	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
-	__u32 ctrl;
+	struct imstt_par *par = (struct imstt_par *) info->par;
+        u32 flags = cursor->set, fg, bg, xx, yy;
 
-	ctrl = in_le32(&p->dc_regs[STGCTL]);
-	if (blank > 0) {
-		switch (blank - 1) {
-			case VESA_NO_BLANKING:
-			case VESA_POWERDOWN:
-				ctrl &= ~0x00000380;
-				if (p->ramdac == IBM) {
-					p->cmap_regs[PIDXHI] = 0;	eieio();
-					p->cmap_regs[PIDXLO] = MISCTL2;	eieio();
-					p->cmap_regs[PIDXDATA] = 0x55;	eieio();
-					p->cmap_regs[PIDXLO] = MISCTL1;	eieio();
-					p->cmap_regs[PIDXDATA] = 0x11;	eieio();
-					p->cmap_regs[PIDXLO] = SYNCCTL;	eieio();
-					p->cmap_regs[PIDXDATA] = 0x0f;	eieio();
-					p->cmap_regs[PIDXLO] = PWRMNGMT;eieio();
-					p->cmap_regs[PIDXDATA] = 0x1f;	eieio();
-					p->cmap_regs[PIDXLO] = CLKCTL;	eieio();
-					p->cmap_regs[PIDXDATA] = 0xc0;
-				}
-				break;
-			case VESA_VSYNC_SUSPEND:
-				ctrl &= ~0x00000020;
-				break;
-			case VESA_HSYNC_SUSPEND:
-				ctrl &= ~0x00000010;
-				break;
+	if (cursor->dest == NULL && cursor->rop == ROP_XOR)
+		return 1;
+	
+	imstt_set_cursor(info, cursor, 0);
+
+	if (flags & FB_CUR_SETPOS) {
+		xx = cursor->image.dx - info->var.xoffset;
+		yy = cursor->image.dy - info->var.yoffset;
+	}
+
+	if (flags & FB_CUR_SETSIZE) {
+        }
+
+        if (flags & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETDEST)) {
+                int fg_idx = cursor->image.fg_color;
+                int width = (cursor->image.width+7)/8;
+                u8 *dat = (u8 *) cursor->image.data;
+                u8 *dst = (u8 *) cursor->dest;
+                u8 *msk = (u8 *) cursor->mask;
+
+                switch (cursor->rop) {
+                case ROP_XOR:
+                        for (i = 0; i < cursor->image.height; i++) {
+                                for (j = 0; j < width; j++) {
+                                        d_idx = i * MAX_CURS/8  + j;
+                                        data[d_idx] =  byte_rev[dat[s_idx] ^
+                                                                dst[s_idx]];
+                                        mask[d_idx] = byte_rev[msk[s_idx]];
+                                        s_idx++;
+                                }
+                        }
+                        break;
+                case ROP_COPY:
+                default:
+                        for (i = 0; i < cursor->image.height; i++) {
+                                for (j = 0; j < width; j++) {
+                                        d_idx = i * MAX_CURS/8 + j;
+                                        data[d_idx] = byte_rev[dat[s_idx]];
+                                        mask[d_idx] = byte_rev[msk[s_idx]];
+                                        s_idx++;
+                                }
+			}
+			break;
 		}
-	} else {
-		if (p->ramdac == IBM) {
-			ctrl |= 0x000017b0;
-			p->cmap_regs[PIDXHI] = 0;	eieio();
-			p->cmap_regs[PIDXLO] = CLKCTL;	eieio();
-			p->cmap_regs[PIDXDATA] = 0x01;	eieio();
-			p->cmap_regs[PIDXLO] = PWRMNGMT;eieio();
-			p->cmap_regs[PIDXDATA] = 0x00;	eieio();
-			p->cmap_regs[PIDXLO] = SYNCCTL;	eieio();
-			p->cmap_regs[PIDXDATA] = 0x00;	eieio();
-			p->cmap_regs[PIDXLO] = MISCTL1;	eieio();
-			p->cmap_regs[PIDXDATA] = 0x01;	eieio();
-			p->cmap_regs[PIDXLO] = MISCTL2;	eieio();
-			p->cmap_regs[PIDXDATA] = 0x45;	eieio();
-		} else
-			ctrl |= 0x00001780;
+
+		fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
+                     ((info->cmap.green[fg_idx] & 0xf8) << 2) |
+                     ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
+
+		imsttfb_load_cursor_image(par, xx, yy, fgc);
 	}
-	out_le32(&p->dc_regs[STGCTL], ctrl);
+	if (cursor->enable)
+		imstt_set_cursor(info, cursor, 1);
 	return 0;
 }
+#endif
 
 #define FBIMSTT_SETREG		0x545401
 #define FBIMSTT_GETREG		0x545402
@@ -1522,51 +1263,51 @@
 #define FBIMSTT_GETIDXREG	0x545406
 
 static int
-imsttfb_ioctl (struct inode *inode, struct file *file, u_int cmd,
-	       u_long arg, int con, struct fb_info *info)
+imsttfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+	      u_long arg, struct fb_info *info)
 {
-	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
-	__u8 idx[2];
+	struct imstt_par *par = (struct imstt_par *) info->par;
 	__u32 reg[2];
+	__u8 idx[2];
 
 	switch (cmd) {
 		case FBIMSTT_SETREG:
 			if (copy_from_user(reg, (void *)arg, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
 				return -EFAULT;
-			out_le32(&p->dc_regs[reg[0]], reg[1]);
+			write_reg_le32(par->dc_regs, reg[0], reg[1]);
 			return 0;
 		case FBIMSTT_GETREG:
 			if (copy_from_user(reg, (void *)arg, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
 				return -EFAULT;
-			reg[1] = in_le32(&p->dc_regs[reg[0]]);
+			reg[1] = read_reg_le32(par->dc_regs, reg[0]);
 			if (copy_to_user((void *)(arg + 4), &reg[1], 4))
 				return -EFAULT;
 			return 0;
 		case FBIMSTT_SETCMAPREG:
 			if (copy_from_user(reg, (void *)arg, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
 				return -EFAULT;
-			out_le32(&((u_int *)p->cmap_regs)[reg[0]], reg[1]);
+			write_reg_le32(((u_int *)par->cmap_regs), reg[0], reg[1]);
 			return 0;
 		case FBIMSTT_GETCMAPREG:
 			if (copy_from_user(reg, (void *)arg, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
 				return -EFAULT;
-			reg[1] = in_le32(&((u_int *)p->cmap_regs)[reg[0]]);
+			reg[1] = read_reg_le32(((u_int *)par->cmap_regs), reg[0]);
 			if (copy_to_user((void *)(arg + 4), &reg[1], 4))
 				return -EFAULT;
 			return 0;
 		case FBIMSTT_SETIDXREG:
 			if (copy_from_user(idx, (void *)arg, 2))
 				return -EFAULT;
-			p->cmap_regs[PIDXHI] = 0;		eieio();
-			p->cmap_regs[PIDXLO] = idx[0];		eieio();
-			p->cmap_regs[PIDXDATA] = idx[1];	eieio();
+			par->cmap_regs[PIDXHI] = 0;		eieio();
+			par->cmap_regs[PIDXLO] = idx[0];	eieio();
+			par->cmap_regs[PIDXDATA] = idx[1];	eieio();
 			return 0;
 		case FBIMSTT_GETIDXREG:
 			if (copy_from_user(idx, (void *)arg, 1))
 				return -EFAULT;
-			p->cmap_regs[PIDXHI] = 0;		eieio();
-			p->cmap_regs[PIDXLO] = idx[0];		eieio();
-			idx[1] = p->cmap_regs[PIDXDATA];
+			par->cmap_regs[PIDXHI] = 0;		eieio();
+			par->cmap_regs[PIDXLO] = idx[0];	eieio();
+			idx[1] = par->cmap_regs[PIDXDATA];
 			if (copy_to_user((void *)(arg + 1), &idx[1], 1))
 				return -EFAULT;
 			return 0;
@@ -1593,107 +1334,53 @@
 };
 
 static struct fb_ops imsttfb_ops = {
-	.owner =	THIS_MODULE,
-	.fb_set_var =	imsttfb_set_var,
-	.fb_get_cmap =	imsttfb_get_cmap,
-	.fb_set_cmap =	gen_set_cmap,
-	.fb_setcolreg =	imsttfb_setcolreg,
-	.fb_pan_display =imsttfb_pan_display,
-	.fb_blank =	imsttfb_blank,
-	.fb_ioctl =	imsttfb_ioctl,
+	.owner 		= THIS_MODULE,
+	.fb_check_var	= imsttfb_check_var,
+	.fb_set_par 	= imsttfb_set_par,
+	.fb_setcolreg 	= imsttfb_setcolreg,
+	.fb_pan_display = imsttfb_pan_display,
+	.fb_blank 	= imsttfb_blank,
+	.fb_fillrect	= imsttfb_fillrect,
+	.fb_copyarea	= imsttfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
+	.fb_ioctl 	= imsttfb_ioctl,
 };
 
-static int
-imsttfbcon_switch (int con, struct fb_info *info)
-{
-	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
-	struct display *old = &fb_display[info->currcon], *new = &fb_display[con];
-
-	if (old->cmap.len)
-		fb_get_cmap(&old->cmap, 1, imsttfb_getcolreg, info);
-
-	if (old->conp && old->conp->vc_sw && old->conp->vc_sw->con_cursor)
-		old->conp->vc_sw->con_cursor(old->conp, CM_ERASE);
-
-	info->currcon = con;
-
-	if (old->var.xres != new->var.xres
-	    || old->var.yres != new->var.yres
-	    || old->var.bits_per_pixel != new->var.bits_per_pixel
-	    || old->var.green.length != new->var.green.length
-	    || old->var.accel_flags != new->var.accel_flags) {
-		set_dispsw(new, p);
-		if (!compute_imstt_regvals(p, new->var.xres, new->var.yres))
-			return -1;
-		if (new->var.bits_per_pixel == 16) {
-			if (new->var.green.length == 6)
-				set_565(p);
-			else
-				set_555(p);
-		}
-		set_imstt_regvals(p, new->var.bits_per_pixel);
-	}
-	set_offset(new, p);
-
-	imsttfbcon_set_font(new, fontwidth(new), fontheight(new));
-
-	do_install_cmap(con, info);
-
-	return 0;
-}
-
-static int
-imsttfbcon_updatevar (int con, struct fb_info *info)
-{
-	struct fb_info_imstt *p = (struct fb_info_imstt *)info;
-	struct display *disp = &fb_display[con];
-
-	if (con != info->currcon)
-		goto out;
-
-	if (p->ramdac == IBM)
-		imsttfbcon_cursor(disp, CM_ERASE, p->cursor.x, p->cursor.y);
-
-	set_offset(disp, p);
-
-out:
-	return 0;
-}
-
 static void __init 
-init_imstt(struct fb_info_imstt *p)
+init_imstt(struct fb_info *info)
 {
-	__u32 i, tmp;
-	__u32 *ip, *end;
+	struct imstt_par *par = (struct imstt_par *) info->par;
+	__u32 i, tmp, *ip, *end;
 
-	tmp = in_le32(&p->dc_regs[PRC]);
-	if (p->ramdac == IBM)
-		p->total_vram = (tmp & 0x0004) ? 0x400000 : 0x200000;
+	tmp = read_reg_le32(par->dc_regs, PRC);
+	if (par->ramdac == IBM)
+		info->fix.smem_len = (tmp & 0x0004) ? 0x400000 : 0x200000;
 	else
-		p->total_vram = 0x800000;
+		info->fix.smem_len = 0x800000;
 
-	ip = (__u32 *)p->frame_buffer;
-	end = (__u32 *)(p->frame_buffer + p->total_vram);
+	ip = (__u32 *)info->screen_base;
+	end = (__u32 *)(info->screen_base + info->fix.smem_len);
 	while (ip < end)
 		*ip++ = 0;
 
 	/* initialize the card */
-	tmp = in_le32(&p->dc_regs[STGCTL]);
-	out_le32(&p->dc_regs[STGCTL], tmp & ~0x1);
-	out_le32(&p->dc_regs[SSR], 0);
+	tmp = read_reg_le32(par->dc_regs, STGCTL);
+	write_reg_le32(par->dc_regs, STGCTL, tmp & ~0x1);
+	write_reg_le32(par->dc_regs, SSR, 0);
 
 	/* set default values for DAC registers */ 
-	if (p->ramdac == IBM) {
-		p->cmap_regs[PPMASK] = 0xff;	eieio();
-		p->cmap_regs[PIDXHI] = 0;	eieio();
+	if (par->ramdac == IBM) {
+		par->cmap_regs[PPMASK] = 0xff;	eieio();
+		par->cmap_regs[PIDXHI] = 0;	eieio();
 		for (i = 0; i < sizeof(ibm_initregs) / sizeof(*ibm_initregs); i++) {
-			p->cmap_regs[PIDXLO] = ibm_initregs[i].addr;	eieio();
-			p->cmap_regs[PIDXDATA] = ibm_initregs[i].value;	eieio();
+			par->cmap_regs[PIDXLO] = ibm_initregs[i].addr;	eieio();
+			par->cmap_regs[PIDXDATA] = ibm_initregs[i].value;	eieio();
 		}
 	} else {
 		for (i = 0; i < sizeof(tvp_initregs) / sizeof(*tvp_initregs); i++) {
-			p->cmap_regs[TVPADDRW] = tvp_initregs[i].addr;	eieio();
-			p->cmap_regs[TVPIDATA] = tvp_initregs[i].value;	eieio();
+			par->cmap_regs[TVPADDRW] = tvp_initregs[i].addr;	eieio();
+			par->cmap_regs[TVPIDATA] = tvp_initregs[i].value;	eieio();
 		}
 	}
 
@@ -1711,112 +1398,100 @@
 			if (cmode < CMODE_8 || cmode > CMODE_32)
 				cmode = CMODE_8;
 		}
-		if (mac_vmode_to_var(vmode, cmode, &p->disp.var)) {
-			p->disp.var.xres = p->disp.var.xres_virtual = INIT_XRES;
-			p->disp.var.yres = p->disp.var.yres_virtual = INIT_YRES;
-			p->disp.var.bits_per_pixel = INIT_BPP;
+		if (mac_vmode_to_var(vmode, cmode, &info->var)) {
+			info->var.xres = info->var.xres_virtual = INIT_XRES;
+			info->var.yres = info->var.yres_virtual = INIT_YRES;
+			info->var.bits_per_pixel = INIT_BPP;
 		}
 	}
 #else
-	p->disp.var.xres = p->disp.var.xres_virtual = INIT_XRES;
-	p->disp.var.yres = p->disp.var.yres_virtual = INIT_YRES;
-	p->disp.var.bits_per_pixel = INIT_BPP;
+	info->var.xres = info->var.xres_virtual = INIT_XRES;
+	info->var.yres = info->var.yres_virtual = INIT_YRES;
+	info->var.bits_per_pixel = INIT_BPP;
 #endif
 
-	if ((p->disp.var.xres * p->disp.var.yres) * (p->disp.var.bits_per_pixel >> 3) > p->total_vram
-	    || !(compute_imstt_regvals(p, p->disp.var.xres, p->disp.var.yres))) {
-		printk("imsttfb: %ux%ux%u not supported\n", p->disp.var.xres, p->disp.var.yres, p->disp.var.bits_per_pixel);
-		kfree(p);
+	if ((info->var.xres * info->var.yres) * (info->var.bits_per_pixel >> 3) > info->fix.smem_len
+	    || !(compute_imstt_regvals(par, info->var.xres, info->var.yres))) {
+		printk("imsttfb: %ux%ux%u not supported\n", info->var.xres, info->var.yres, info->var.bits_per_pixel);
+		kfree(info);
 		return;
 	}
 
-	sprintf(p->fix.id, "IMS TT (%s)", p->ramdac == IBM ? "IBM" : "TVP");
-	p->fix.smem_start = p->frame_buffer_phys;
-	p->fix.smem_len = p->total_vram;
-	p->fix.mmio_start = p->dc_regs_phys;
-	p->fix.mmio_len = 0x1000;
-	p->fix.accel = FB_ACCEL_IMS_TWINTURBO;
-	p->fix.type = FB_TYPE_PACKED_PIXELS;
-	p->fix.visual = p->disp.var.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR
+	sprintf(info->fix.id, "IMS TT (%s)", par->ramdac == IBM ? "IBM" : "TVP");
+	info->fix.mmio_len = 0x1000;
+	info->fix.accel = FB_ACCEL_IMS_TWINTURBO;
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.visual = info->var.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR
 							: FB_VISUAL_DIRECTCOLOR;
-	p->fix.line_length = p->disp.var.xres * (p->disp.var.bits_per_pixel >> 3);
-	p->fix.xpanstep = 8;
-	p->fix.ypanstep = 1;
-	p->fix.ywrapstep = 0;
-
-	p->disp.var.accel_flags = noaccel ? 0 : FB_ACCELF_TEXT;
-	set_disp(&p->disp, p);
-
-	if (!noaccel && p->ramdac == IBM)
-		imstt_cursor_init(p);
-	if (p->disp.var.green.length == 6)
-		set_565(p);
+	info->fix.line_length = info->var.xres * (info->var.bits_per_pixel >> 3);
+	info->fix.xpanstep = 8;
+	info->fix.ypanstep = 1;
+	info->fix.ywrapstep = 0;
+
+	info->var.accel_flags = FB_ACCELF_TEXT;
+
+//	if (par->ramdac == IBM)
+//		imstt_cursor_init(info);
+	if (info->var.green.length == 6)
+		set_565(par);
 	else
-		set_555(p);
-	set_imstt_regvals(p, p->disp.var.bits_per_pixel);
+		set_555(par);
+	set_imstt_regvals(info, info->var.bits_per_pixel);
 
-	p->disp.var.pixclock = 1000000 / getclkMHz(p);
+	info->var.pixclock = 1000000 / getclkMHz(par);
 
-	strcpy(p->info.modename, p->fix.id);
-	strcpy(p->info.fontname, fontname);
-	p->info.node = NODEV;
-	p->info.fbops = &imsttfb_ops;
-	p->info.disp = &p->disp;
-	p->info.screen_base = (__u8 *)p->frame_buffer;
-	p->info.currcon = -1;
-	p->info.changevar = 0;
-	p->info.switch_con = &imsttfbcon_switch;
-	p->info.updatevar = &imsttfbcon_updatevar;
-	p->info.flags = FBINFO_FLAG_DEFAULT;
-
-	for (i = 0; i < 16; i++) {
-		u_int j = color_table[i];
-		p->palette[i].red = default_red[j];
-		p->palette[i].green = default_grn[j];
-		p->palette[i].blue = default_blu[j];
-	}
+	info->node = NODEV;
+	info->fbops = &imsttfb_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
 
-	if (register_framebuffer(&p->info) < 0) {
-		kfree(p);
+	fb_alloc_cmap(&info->cmap, 0, 0);
+
+	if (register_framebuffer(info) < 0) {
+		kfree(info);
 		return;
 	}
 
-	i = GET_FB_IDX(p->info.node);
-	tmp = (in_le32(&p->dc_regs[SSTATUS]) & 0x0f00) >> 8;
+	tmp = (read_reg_le32(par->dc_regs, SSTATUS) & 0x0f00) >> 8;
 	printk("fb%u: %s frame buffer; %uMB vram; chip version %u\n",
-		i, p->fix.id, p->total_vram >> 20, tmp);
+		minor(info->node), info->fix.id, info->fix.smem_len >> 20, tmp);
 }
 
 static int __devinit
 imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	struct fb_info_imstt *p;
 	unsigned long addr, size;
+	struct imstt_par *par;
+	struct fb_info *info;
 
-	addr = pci_resource_start (pdev, 0);
-	size = pci_resource_len (pdev, 0);
+	size = sizeof(struct fb_info) + sizeof(struct imstt_par) +
+		sizeof(u32) * 16;
 
-	p = kmalloc(sizeof(struct fb_info_imstt), GFP_KERNEL);
+	info = kmalloc(size, GFP_KERNEL);
 
-	if (!p) {
+	if (!info) {
 		printk(KERN_ERR "imsttfb: Can't allocate memory\n");
 		return -ENOMEM;
 	}
 
-	memset(p, 0, sizeof(struct fb_info_imstt));
+	memset(info, 0, size);
+
+	par = (struct imstt_par *) (info + 1);
+
+	addr = pci_resource_start (pdev, 0);
+	size = pci_resource_len (pdev, 0);
 
 	if (!request_mem_region(addr, size, "imsttfb")) {
 		printk(KERN_ERR "imsttfb: Can't reserve memory region\n");
-		kfree(p);
+		kfree(info);
 		return -ENODEV;
 	}
 
 	switch (pdev->device) {
 		case PCI_DEVICE_ID_IMS_TT128: /* IMS,tt128mbA */
-			p->ramdac = IBM;
+			par->ramdac = IBM;
 			break;
 		case PCI_DEVICE_ID_IMS_TT3D:  /* IMS,tt3d */
-			p->ramdac = TVP;
+			par->ramdac = TVP;
 			break;
 		default:
 			printk(KERN_INFO "imsttfb: Device 0x%x unknown, "
@@ -1824,32 +1499,33 @@
 			return -ENODEV;
 	}
 
-	p->frame_buffer_phys = addr;
-	p->board_size = size;
-	p->frame_buffer = (__u8 *)ioremap(addr, p->ramdac == IBM ? 0x400000 : 0x800000);
-	p->dc_regs_phys = addr + 0x800000;
-	p->dc_regs = (__u32 *)ioremap(addr + 0x800000, 0x1000);
-	p->cmap_regs_phys = addr + 0x840000;
-	p->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000);
-
-	init_imstt(p);
-
-	pci_set_drvdata(pdev, p);
+	info->fix.smem_start = addr;
+	info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? 0x400000 : 0x800000);
+	info->fix.mmio_start = addr + 0x800000;
+	par->dc_regs = (__u32 *)ioremap(addr + 0x800000, 0x1000);
+	par->cmap_regs_phys = addr + 0x840000;
+	par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000);
+	info->par = par;
+	info->pseudo_palette = (void *) (par + 1);
+	init_imstt(info);
 
+	pci_set_drvdata(pdev, info);
 	return 0;
 }
 
 static void __devexit
 imsttfb_remove(struct pci_dev *pdev)
 {
-	struct fb_info_imstt *p = pci_get_drvdata(pdev);
-
-	unregister_framebuffer(&p->info);
-	iounmap(p->cmap_regs);
-	iounmap(p->dc_regs);
-	iounmap(p->frame_buffer);
-	release_mem_region(p->frame_buffer_phys, p->board_size);
-	kfree(p);
+	struct fb_info *info = pci_get_drvdata(pdev);
+	struct imstt_par *par = (struct imstt_par *) info->par;
+	int size = pci_resource_len(pdev, 0);
+
+	unregister_framebuffer(info);
+	iounmap(par->cmap_regs);
+	iounmap(par->dc_regs);
+	iounmap(info->screen_base);
+	release_mem_region(info->fix.smem_start, size);
+	kfree(info);
 }
 
 #ifndef MODULE
@@ -1872,10 +1548,6 @@
 					break;
 			memcpy(fontname, this_opt + 5, i);
 			fontname[i] = 0;
-		} else if (!strncmp(this_opt, "noblink", 7)) {
-			curblink = 0;
-		} else if (!strncmp(this_opt, "noaccel", 7)) {
-			noaccel = 1;
 		} else if (!strncmp(this_opt, "inverse", 7)) {
 			inverse = 1;
 			fb_invert_cmaps();
diff -Nru a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/Kconfig	Mon Feb 24 13:47:00 2003
@@ -0,0 +1,67 @@
+#
+# Logo configuration
+#
+
+menu "Logo configuration"
+
+config LOGO
+	bool "Bootup logo"
+	depends on FB || SGI_NEWPORT_CONSOLE
+
+config LOGO_LINUX_MONO
+	bool "Standard black and white Linux logo"
+	depends on LOGO
+	default y
+
+config LOGO_LINUX_VGA16
+	bool "Standard 16-color Linux logo"
+	depends on LOGO
+	default y
+
+config LOGO_LINUX_CLUT224
+	bool "Standard 224-color Linux logo"
+	depends on LOGO
+	default y
+
+config LOGO_DEC_CLUT224
+	bool "224-color Digital Equipment Corporation Linux logo"
+	depends on LOGO && DECSTATION
+	default y
+
+config LOGO_MAC_CLUT224
+	bool "224-color Macintosh Linux logo"
+	depends on LOGO && MAC
+	default y
+
+config LOGO_PARISC_CLUT224
+	bool "224-color PA-RISC Linux logo"
+	depends on LOGO && PARISC
+	default y
+
+config LOGO_SGI_CLUT224
+	bool "224-color SGI Linux logo"
+	depends on LOGO && (SGI_IP22 || SGI_IP27 || SGI_IP32)
+	default y
+
+config LOGO_SUN_CLUT224
+	bool "224-color Sun Linux logo"
+	depends on LOGO && (SPARC || SPARC64)
+	default y
+
+config LOGO_SUPERH_MONO
+	bool "Black and white SuperH Linux logo"
+	depends on LOGO && SUPERH
+	default y
+
+config LOGO_SUPERH_VGA16
+	bool "16-color SuperH Linux logo"
+	depends on LOGO && SUPERH
+	default y
+
+config LOGO_SUPERH_CLUT224
+	bool "224-color SuperH Linux logo"
+	depends on LOGO && SUPERH
+	default y
+
+endmenu
+
diff -Nru a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/Makefile	Thu Feb 13 18:50:31 2003
@@ -0,0 +1,27 @@
+# Makefile for the Linux logos
+
+obj-$(CONFIG_LOGO)			+= logo.o
+obj-$(CONFIG_LOGO_LINUX_MONO)		+= logo_linux_mono.o
+obj-$(CONFIG_LOGO_LINUX_VGA16)		+= logo_linux_vga16.o
+obj-$(CONFIG_LOGO_LINUX_CLUT224)	+= logo_linux_clut224.o
+obj-$(CONFIG_LOGO_DEC_CLUT224)		+= logo_dec_clut224.o
+obj-$(CONFIG_LOGO_MAC_CLUT224)		+= logo_mac_clut224.o
+obj-$(CONFIG_LOGO_PARISC_CLUT224)	+= logo_parisc_clut224.o
+obj-$(CONFIG_LOGO_SGI_CLUT224)		+= logo_sgi_clut224.o
+obj-$(CONFIG_LOGO_SUN_CLUT224)		+= logo_sun_clut224.o
+obj-$(CONFIG_LOGO_SUPERH_MONO)		+= logo_superh_mono.o
+obj-$(CONFIG_LOGO_SUPERH_VGA16)		+= logo_superh_vga16.o
+obj-$(CONFIG_LOGO_SUPERH_CLUT224)	+= logo_superh_clut224.o
+
+$(obj)/%_mono.c:	$(src)/%_mono.pbm
+		$(objtree)/scripts/pnmtologo -t mono -n $*_mono -o $@ $<
+
+$(obj)/%_vga16.c:	$(src)/%_vga16.ppm
+		$(objtree)/scripts/pnmtologo -t vga16 -n $*_vga16 -o $@ $<
+
+$(obj)/%_clut224.c:	$(src)/%_clut224.ppm
+		$(objtree)/scripts/pnmtologo -t clut224 -n $*_clut224 -o $@ $<
+
+$(obj)/%_gray256.c:	$(src)/%_gray256.pgm
+		$(objtree)/scripts/pnmtologo -t gray256 -n $*_gray256 -o $@ $<
+
diff -Nru a/drivers/video/logo/clut_vga16.ppm b/drivers/video/logo/clut_vga16.ppm
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/clut_vga16.ppm	Mon Feb 24 13:47:01 2003
@@ -0,0 +1,20 @@
+P3
+# Standard console colors
+16 1
+255
+  0   0   0
+  0   0 170
+  0 170   0
+  0 170 170
+170   0   0
+170   0 170
+170  85   0
+170 170 170
+ 85  85  85
+ 85  85 255
+ 85 255  85
+ 85 255 255
+255  85  85
+255  85 255
+255 255  85
+255 255 255
diff -Nru a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/logo.c	Thu Feb 13 18:50:33 2003
@@ -0,0 +1,100 @@
+
+/*
+ *  Linux logo to be displayed on boot
+ *
+ *  Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
+ *  Copyright (C) 1996,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ *  Copyright (C) 2001 Greg Banks <gnb@alphalink.com.au>
+ *  Copyright (C) 2001 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+ *  Copyright (C) 2003 Geert Uytterhoeven <geert@linux-m68k.org>
+ */
+
+#include <linux/config.h>
+#include <linux/linux_logo.h>
+
+#ifdef CONFIG_M68K
+#include <asm/setup.h>
+#endif
+
+#if defined(CONFIG_MIPS) || defined(CONFIG_MIPS64)
+#include <asm/bootinfo.h>
+#endif
+
+extern const struct linux_logo logo_linux_mono;
+extern const struct linux_logo logo_linux_vga16;
+extern const struct linux_logo logo_linux_clut224;
+extern const struct linux_logo logo_dec_clut224;
+extern const struct linux_logo logo_mac_clut224;
+extern const struct linux_logo logo_parisc_clut224;
+extern const struct linux_logo logo_sgi_clut224;
+extern const struct linux_logo logo_sun_clut224;
+extern const struct linux_logo logo_superh_mono;
+extern const struct linux_logo logo_superh_vga16;
+extern const struct linux_logo logo_superh_clut224;
+
+
+const struct linux_logo * __init fb_find_logo(int type)
+{
+	const struct linux_logo *logo = 0;
+
+	switch (type) {
+		case LINUX_LOGO_MONO:
+#ifdef CONFIG_LOGO_LINUX_MONO
+			/* Generic Linux logo */
+			logo = &logo_linux_mono;
+#endif
+#ifdef CONFIG_LOGO_SUPERH_MONO
+			/* SuperH Linux logo */
+			logo = &logo_superh_mono;
+#endif
+			break;
+
+		case LINUX_LOGO_VGA16:
+#ifdef CONFIG_LOGO_LINUX_VGA16
+			/* Generic Linux logo */
+			logo = &logo_linux_vga16;
+#endif
+#ifdef CONFIG_LOGO_SUPERH_VGA16
+			/* SuperH Linux logo */
+			logo = &logo_superh_vga16;
+#endif
+			break;
+
+		case LINUX_LOGO_CLUT224:
+#ifdef CONFIG_LOGO_LINUX_CLUT224
+			/* Generic Linux logo */
+			logo = &logo_linux_clut224;
+#endif
+#ifdef CONFIG_LOGO_DEC_CLUT224
+			/* DEC Linux logo on MIPS/MIPS64 */
+			if (mips_machgroup == MACH_GROUP_SGI)
+				logo = &logo_dec_clut224;
+#endif
+#ifdef CONFIG_LOGO_MAC_CLUT224
+			/* Macintosh Linux logo on m68k */
+			if (MACH_IS_MAC)
+				logo = &logo_mac_clut224;
+#endif
+#ifdef CONFIG_LOGO_PARISC_CLUT224
+			/* PA-RISC Linux logo */
+			logo = &logo_parisc_clut224;
+#endif
+#ifdef CONFIG_LOGO_SGI_CLUT224
+			/* SGI Linux logo on MIPS/MIPS64 */
+			if (mips_machgroup == MACH_GROUP_SGI)
+				logo = &logo_sgi_clut224;
+#endif
+#ifdef CONFIG_LOGO_SUN_CLUT224
+			/* Sun Linux logo */
+			logo = &logo_sun_clut224;
+#endif
+#ifdef CONFIG_LOGO_SUPERH_CLUT224
+			/* SuperH Linux logo */
+			logo = &logo_superh_clut224;
+#endif
+			break;
+
+	}
+	return logo;
+}
+
diff -Nru a/drivers/video/logo/logo_dec_clut224.ppm b/drivers/video/logo/logo_dec_clut224.ppm
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/logo_dec_clut224.ppm	Mon Feb 24 13:47:00 2003
@@ -0,0 +1,1604 @@
+P3
+# 224-color Digital Equipment Corporation Linux logo
+80 80
+255
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6   6   6   6  10  10  10  10  10  10
+ 10  10  10   6   6   6   6   6   6   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  10  10  10  14  14  14
+ 22  22  22  26  26  26  30  30  30  34  34  34
+ 30  30  30  30  30  30  26  26  26  18  18  18
+ 14  14  14  10  10  10   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  26  26  26  42  42  42
+ 54  54  54  66  66  66  78  78  78  78  78  78
+ 78  78  78  74  74  74  66  66  66  54  54  54
+ 42  42  42  26  26  26  18  18  18  10  10  10
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 22  22  22  42  42  42  66  66  66  86  86  86
+ 66  66  66  38  38  38  38  38  38  22  22  22
+ 26  26  26  34  34  34  54  54  54  66  66  66
+ 86  86  86  70  70  70  46  46  46  26  26  26
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  26  26  26
+ 50  50  50  82  82  82  58  58  58   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  54  54  54  86  86  86  66  66  66
+ 38  38  38  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  22  22  22  50  50  50
+ 78  78  78  34  34  34   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   6   6   6  70  70  70
+ 78  78  78  46  46  46  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  42  42  42  82  82  82
+ 26  26  26   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  14  14  14
+ 46  46  46  34  34  34   6   6   6   2   2   6
+ 42  42  42  78  78  78  42  42  42  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 10  10  10  30  30  30  66  66  66  58  58  58
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  26  26  26
+ 86  86  86 101 101 101  46  46  46  10  10  10
+  2   2   6  58  58  58  70  70  70  34  34  34
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 14  14  14  42  42  42  86  86  86  10  10  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  30  30  30
+ 94  94  94  94  94  94  58  58  58  26  26  26
+  2   2   6   6   6   6  78  78  78  54  54  54
+ 22  22  22   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 22  22  22  62  62  62  62  62  62   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  26  26  26
+ 54  54  54  38  38  38  18  18  18  10  10  10
+  2   2   6   2   2   6  34  34  34  82  82  82
+ 38  38  38  14  14  14   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 30  30  30  78  78  78  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 10  10  10   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  78  78  78
+ 50  50  50  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  14  14  14   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  54  54  54
+ 66  66  66  26  26  26   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  82  82  82   2   2   6   2   2   6
+  2   2   6   6   6   6  10  10  10   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 14  14  14  10  10  10   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  18  18  18
+ 82  82  82  34  34  34  10  10  10   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6   2   2   6
+  6   6   6   6   6   6  22  22  22  34  34  34
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  34  34  34
+ 10  10  10  50  50  50  22  22  22   2   2   6
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 86  86  86  42  42  42  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6   2   2   6
+ 38  38  38 116 116 116  94  94  94  22  22  22
+ 22  22  22   2   2   6   2   2   6   2   2   6
+ 14  14  14  86  86  86 138 138 138 162 162 162
+154 154 154  38  38  38  26  26  26   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 86  86  86  46  46  46  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6  14  14  14
+134 134 134 198 198 198 195 195 195 116 116 116
+ 10  10  10   2   2   6   2   2   6   6   6   6
+101  98  89 187 187 187 210 210 210 218 218 218
+214 214 214 134 134 134  14  14  14   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 86  86  86  50  50  50  18  18  18   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6  54  54  54
+218 218 218 195 195 195 226 226 226 246 246 246
+ 58  58  58   2   2   6   2   2   6  30  30  30
+210 210 210 253 253 253 174 174 174 123 123 123
+221 221 221 234 234 234  74  74  74   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  82  82  82   2   2   6 106 106 106
+170 170 170  26  26  26  86  86  86 226 226 226
+123 123 123  10  10  10  14  14  14  46  46  46
+231 231 231 190 190 190   6   6   6  70  70  70
+ 90  90  90 238 238 238 158 158 158   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  86  86  86   6   6   6 116 116 116
+106 106 106   6   6   6  70  70  70 149 149 149
+128 128 128  18  18  18  38  38  38  54  54  54
+221 221 221 106 106 106   2   2   6  14  14  14
+ 46  46  46 190 190 190 198 198 198   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  62  62  62  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  94  94  94  14  14  14 101 101 101
+128 128 128   2   2   6  18  18  18 116 116 116
+118  98  46 121  92   8 121  92   8  98  78  10
+162 162 162 106 106 106   2   2   6   2   2   6
+  2   2   6 195 195 195 195 195 195   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  62  62  62  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   1
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  90  90  90  14  14  14  58  58  58
+210 210 210  26  26  26  54  38   6 154 114  10
+226 170  11 236 186  11 225 175  15 184 144  12
+215 174  15 175 146  61  37  26   9   2   2   6
+ 70  70  70 246 246 246 138 138 138   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  66  66  66  26  26  26   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  14  14  14  10  10  10
+195 195 195 188 164 115 192 133   9 225 175  15
+239 182  13 234 190  10 232 195  16 232 200  30
+245 207  45 241 208  19 232 195  16 184 144  12
+218 194 134 211 206 186  42  42  42   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 50  50  50  74  74  74  30  30  30   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  86  86  86  14  14  14   2   2   6
+121  87  25 192 133   9 219 162  10 239 182  13
+236 186  11 232 195  16 241 208  19 244 214  54
+246 218  60 246 218  38 246 215  20 241 208  19
+241 208  19 226 184  13 121  87  25   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 50  50  50  82  82  82  34  34  34  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  82  82  82  30  30  30  61  42   6
+180 123   7 206 145  10 230 174  11 239 182  13
+234 190  10 238 202  15 241 208  19 246 218  74
+246 218  38 246 215  20 246 215  20 246 215  20
+226 184  13 215 174  15 184 144  12   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 26  26  26  94  94  94  42  42  42  14  14  14
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78  50  50  50 104  69   6
+192 133   9 216 158  10 236 178  12 236 186  11
+232 195  16 241 208  19 244 214  54 245 215  43
+246 215  20 246 215  20 241 208  19 198 155  10
+200 144  11 216 158  10 156 118  10   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  90  90  90  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78  46  46  46  22  22  22
+137  92   6 210 162  10 239 182  13 238 190  10
+238 202  15 241 208  19 246 215  20 246 215  20
+241 208  19 203 166  17 185 133  11 210 150  10
+216 158  10 210 150  10 102  78  10   2   2   6
+  6   6   6  54  54  54  14  14  14   2   2   6
+  2   2   6  62  62  62  74  74  74  30  30  30
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  78  78  78  50  50  50   6   6   6
+ 94  70  30 139 102  15 190 146  13 226 184  13
+232 200  30 232 195  16 215 174  15 190 146  13
+168 122  10 192 133   9 210 150  10 213 154  11
+202 150  34 182 157 106 101  98  89   2   2   6
+  2   2   6  78  78  78 116 116 116  58  58  58
+  2   2   6  22  22  22  90  90  90  46  46  46
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  50  50  50   6   6   6
+128 128 128 174 154 114 156 107  11 168 122  10
+198 155  10 184 144  12 197 138  11 200 144  11
+206 145  10 206 145  10 197 138  11 188 164 115
+195 195 195 198 198 198 174 174 174  14  14  14
+  2   2   6  22  22  22 116 116 116 116 116 116
+ 22  22  22   2   2   6  74  74  74  70  70  70
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 101 101 101  26  26  26  10  10  10
+138 138 138 190 190 190 174 154 114 156 107  11
+197 138  11 200 144  11 197 138  11 192 133   9
+180 123   7 190 142  34 190 178 144 187 187 187
+202 202 202 221 221 221 214 214 214  66  66  66
+  2   2   6   2   2   6  50  50  50  62  62  62
+  6   6   6   2   2   6  10  10  10  90  90  90
+ 50  50  50  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  34  34  34
+ 74  74  74  74  74  74   2   2   6   6   6   6
+144 144 144 198 198 198 190 190 190 178 166 146
+154 121  60 156 107  11 156 107  11 168 124  44
+174 154 114 187 187 187 190 190 190 210 210 210
+246 246 246 253 253 253 253 253 253 182 182 182
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  62  62  62
+ 74  74  74  34  34  34  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  10  10  10  22  22  22  54  54  54
+ 94  94  94  18  18  18   2   2   6  46  46  46
+234 234 234 221 221 221 190 190 190 190 190 190
+190 190 190 187 187 187 187 187 187 190 190 190
+190 190 190 195 195 195 214 214 214 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+ 82  82  82   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  14  14  14
+ 86  86  86  54  54  54  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  46  46  46  90  90  90
+ 46  46  46  18  18  18   6   6   6 182 182 182
+253 253 253 246 246 246 206 206 206 190 190 190
+190 190 190 190 190 190 190 190 190 190 190 190
+206 206 206 231 231 231 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+202 202 202  14  14  14   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 42  42  42  86  86  86  42  42  42  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 14  14  14  38  38  38  74  74  74  66  66  66
+  2   2   6   6   6   6  90  90  90 250 250 250
+253 253 253 253 253 253 238 238 238 198 198 198
+190 190 190 190 190 190 195 195 195 221 221 221
+246 246 246 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253  82  82  82   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  78  78  78  70  70  70  34  34  34
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 34  34  34  66  66  66  78  78  78   6   6   6
+  2   2   6  18  18  18 218 218 218 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+226 226 226 231 231 231 246 246 246 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 178 178 178   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  18  18  18  90  90  90  62  62  62
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  26  26  26
+ 58  58  58  90  90  90  18  18  18   2   2   6
+  2   2   6 110 110 110 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 231 231 231  18  18  18   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  94  94  94
+ 54  54  54  26  26  26  10  10  10   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  22  22  22  50  50  50
+ 90  90  90  26  26  26   2   2   6   2   2   6
+ 14  14  14 195 195 195 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 242 242 242  54  54  54   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+ 86  86  86  50  50  50  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  38  38  38  82  82  82
+ 34  34  34   2   2   6   2   2   6   2   2   6
+ 42  42  42 195 195 195 246 246 246 253 253 253
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 242 242 242 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 250 250 250 246 246 246 238 238 238
+226 226 226 231 231 231 101 101 101   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 38  38  38  82  82  82  42  42  42  14  14  14
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 10  10  10  26  26  26  62  62  62  66  66  66
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 70  70  70 170 170 170 206 206 206 234 234 234
+246 246 246 250 250 250 250 250 250 238 238 238
+226 226 226 231 231 231 238 238 238 250 250 250
+250 250 250 250 250 250 246 246 246 231 231 231
+214 214 214 206 206 206 202 202 202 202 202 202
+198 198 198 202 202 202 182 182 182  18  18  18
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  62  62  62  66  66  66  30  30  30
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 14  14  14  42  42  42  82  82  82  18  18  18
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 94  94  94 182 182 182 218 218 218 242 242 242
+250 250 250 253 253 253 253 253 253 250 250 250
+234 234 234 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+238 238 238 226 226 226 210 210 210 202 202 202
+195 195 195 195 195 195 210 210 210 158 158 158
+  6   6   6  14  14  14  50  50  50  14  14  14
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  86  86  86  46  46  46
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 22  22  22  54  54  54  70  70  70   2   2   6
+  2   2   6  10  10  10   2   2   6  22  22  22
+166 166 166 231 231 231 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+231 231 231 206 206 206 198 198 198 226 226 226
+ 94  94  94   2   2   6   6   6   6  38  38  38
+ 30  30  30   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  62  62  62  66  66  66
+ 26  26  26  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  74  74  74  50  50  50   2   2   6
+ 26  26  26  26  26  26   2   2   6 106 106 106
+238 238 238 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 246 246 246 218 218 218 202 202 202
+210 210 210  14  14  14   2   2   6   2   2   6
+ 30  30  30  22  22  22   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  86  86  86
+ 42  42  42  14  14  14   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  90  90  90  22  22  22   2   2   6
+ 42  42  42   2   2   6  18  18  18 218 218 218
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 250 250 250 221 221 221
+218 218 218 101 101 101   2   2   6  14  14  14
+ 18  18  18  38  38  38  10  10  10   2   2   6
+  2   2   6   2   2   6   2   2   6  78  78  78
+ 58  58  58  22  22  22   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 54  54  54  82  82  82   2   2   6  26  26  26
+ 22  22  22 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 253 253 253
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 253 253 253
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 253 253 253   6   6   6  38  38  38
+ 58  58  58  26  26  26  38  38  38   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+ 78  78  78  30  30  30  10  10  10   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  30  30  30
+ 74  74  74  58  58  58   2   2   6  42  42  42
+  2   2   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 253 253 253
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 253 253 253  46  46  46  38  38  38
+ 42  42  42  14  14  14  38  38  38  14  14  14
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 86  86  86  46  46  46  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  42  42  42
+ 90  90  90  18  18  18  18  18  18  26  26  26
+  2   2   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 253 253 253
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 253 253 253  94  94  94   6   6   6
+  2   2   6   2   2   6  10  10  10  34  34  34
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  10  10  10  26  26  26  66  66  66
+ 82  82  82   2   2   6  38  38  38   6   6   6
+ 14  14  14 175 118   6 175 118   6 175 118   6
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+253 253 253 175 118   6 175 118   6 253 253 253
+175 118   6 175 118   6 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 175 118   6
+175 118   6 253 253 253 144 144 144   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 42  42  42  74  74  74  30  30  30  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  42  42  42  90  90  90
+ 26  26  26   6   6   6  42  42  42   2   2   6
+ 74  74  74 175 118   6 175 118   6 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 175 118   6
+175 118   6 253 253 253 182 182 182   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 10  10  10  86  86  86  38  38  38  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 10  10  10  26  26  26  66  66  66  82  82  82
+  2   2   6  22  22  22  18  18  18   2   2   6
+149 149 149 175 118   6 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 253 253 253 175 118   6
+253 253 253 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 206 206 206   2   2   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  86  86  86  46  46  46  14  14  14
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 18  18  18  46  46  46  86  86  86  18  18  18
+  2   2   6  34  34  34  10  10  10   6   6   6
+210 210 210 175 118   6 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 253 253 253 175 118   6
+253 253 253 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 221 221 221   6   6   6
+  2   2   6   2   2   6   6   6   6  30  30  30
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  82  82  82  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 26  26  26  66  66  66  62  62  62   2   2   6
+  2   2   6  38  38  38  10  10  10  26  26  26
+238 238 238 175 118   6 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 231 231 231   6   6   6
+  2   2   6   2   2   6  10  10  10  30  30  30
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  58  58  58  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  78  78  78   6   6   6   2   2   6
+  2   2   6  46  46  46  14  14  14  42  42  42
+246 246 246 175 118   6 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 253 253 253 234 234 234  10  10  10
+  2   2   6   2   2   6  22  22  22  14  14  14
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  62  62  62  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50  74  74  74   2   2   6   2   2   6
+ 14  14  14  70  70  70  34  34  34  62  62  62
+250 250 250 175 118   6 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 253 253 253 175 118   6
+175 118   6 175 118   6 175 118   6 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 253 253 253 234 234 234  14  14  14
+  2   2   6   2   2   6  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  62  62  62  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 54  54  54  62  62  62   2   2   6   2   2   6
+  2   2   6  30  30  30  46  46  46  70  70  70
+250 250 250 175 118   6 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 253 253 253 175 118   6
+253 253 253 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 226 226 226  10  10  10
+  2   2   6   6   6   6  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  58  58  58  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 58  58  58  62  62  62   2   2   6   2   2   6
+  2   2   6   2   2   6  30  30  30  78  78  78
+250 250 250 175 118   6 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 253 253 253 175 118   6
+253 253 253 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 206 206 206   2   2   6
+ 22  22  22  34  34  34  18  14   6  22  22  22
+ 26  26  26  18  18  18   6   6   6   2   2   6
+  2   2   6  82  82  82  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  26  26  26
+ 62  62  62 106 106 106  74  54  14 185 133  11
+210 162  10 121  92   8   6   6   6  62  62  62
+238 238 238 175 118   6 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 253 253 253 175 118   6
+253 253 253 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+175 118   6 253 253 253 158 158 158  18  18  18
+ 14  14  14   2   2   6   2   2   6   2   2   6
+  6   6   6  18  18  18  66  66  66  38  38  38
+  6   6   6  94  94  94  50  50  50  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 10  10  10  10  10  10  18  18  18  38  38  38
+ 78  78  78 142 134 106 216 158  10 242 186  14
+246 190  14 246 190  14 156 118  10  10  10  10
+ 90  90  90 175 118   6 175 118   6 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+175 118   6 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+175 118   6 175 118   6 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 175 118   6
+175 118   6 253 253 253 181 142  44  37  26   9
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  38  38  38  46  46  46
+ 26  26  26 106 106 106  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  22  22  22
+ 30  30  30  38  38  38  50  50  50  70  70  70
+106 106 106 190 142  34 226 170  11 242 186  14
+246 190  14 246 190  14 246 190  14 154 114  10
+  6   6   6 175 118   6 175 118   6 175 118   6
+253 253 253 253 253 253 175 118   6 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+175 118   6 175 118   6 253 253 253 253 253 253
+253 253 253 253 253 253 175 118   6 253 253 253
+175 118   6 175 118   6 253 253 253 253 253 253
+253 253 253 253 253 253 175 118   6 175 118   6
+175 118   6 253 253 253 232 195  16  38  30  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  30  30  30  26  26  26
+203 166  17 154 142  90  66  66  66  26  26  26
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  38  38  38  58  58  58
+ 78  78  78  86  86  86 101 101 101 123 123 123
+175 146  61 210 150  10 234 174  13 246 186  14
+246 190  14 246 190  14 246 190  14 238 190  10
+102  78  10 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 253 253 253
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 253 253 253
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 253 253 253 210 166  10  22  18   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   6   6   6 121  92   8
+238 202  15 232 195  16  82  82  82  34  34  34
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 14  14  14  38  38  38  70  70  70 154 122  46
+190 142  34 200 144  11 197 138  11 197 138  11
+213 154  11 226 170  11 242 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+225 175  15 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 253 253 253
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 253 253 253
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 175 118   6 175 118   6 175 118   6
+175 118   6 253 253 253 213 154  11  46  32   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  61  42   6 225 175  15
+238 190  10 236 186  11 112 100  78  42  42  42
+ 14  14  14   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 22  22  22  54  54  54 154 122  46 213 154  11
+226 170  11 230 174  11 226 170  11 226 170  11
+236 178  12 242 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+241 196  14 184 144  12  10  10  10   2   2   6
+  6   6   6 116 116 116 242 242 242 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 231 231 231 198 198 198 214 170  54
+236 178  12 236 178  12 210 150  10 137  92   6
+ 18  14   6   2   2   6   2   2   6   2   2   6
+  6   6   6  70  47   6 200 144  11 236 178  12
+239 182  13 239 182  13 124 112  88  58  58  58
+ 22  22  22   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  70  70  70 180 133  36 226 170  11
+239 182  13 242 186  14 242 186  14 246 186  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 232 195  16  98  70   6   2   2   6
+  2   2   6   2   2   6  66  66  66 221 221 221
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 206 206 206 198 198 198 214 166  58
+230 174  11 230 174  11 216 158  10 192 133   9
+163 110   8 116  81   8 102  78  10 116  81   8
+167 114   7 197 138  11 226 170  11 239 182  13
+242 186  14 242 186  14 162 146  94  78  78  78
+ 34  34  34  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 30  30  30  78  78  78 190 142  34 226 170  11
+239 182  13 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 241 196  14 203 166  17  22  18   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+218 218 218 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 206 206 206 198 198 198 202 162  69
+226 170  11 236 178  12 224 166  10 210 150  10
+200 144  11 197 138  11 192 133   9 197 138  11
+210 150  10 226 170  11 242 186  14 246 190  14
+246 190  14 246 186  14 225 175  15 124 112  88
+ 62  62  62  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78 174 135  50 224 166  10
+239 182  13 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 241 196  14 139 102  15
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 78  78  78 250 250 250 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 214 214 214 198 198 198 190 150  46
+219 162  10 236 178  12 234 174  13 224 166  10
+216 158  10 213 154  11 213 154  11 216 158  10
+226 170  11 239 182  13 246 190  14 246 190  14
+246 190  14 246 190  14 242 186  14 206 162  42
+101 101 101  58  58  58  30  30  30  14  14  14
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  74  74  74 174 135  50 216 158  10
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 241 196  14 226 184  13
+ 61  42   6   2   2   6   2   2   6   2   2   6
+ 22  22  22 238 238 238 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 226 226 226 187 187 187 180 133  36
+216 158  10 236 178  12 239 182  13 236 178  12
+230 174  11 226 170  11 226 170  11 230 174  11
+236 178  12 242 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 186  14 239 182  13
+206 162  42 106 106 106  66  66  66  34  34  34
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 26  26  26  70  70  70 163 133  67 213 154  11
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 241 196  14
+190 146  13  18  14   6   2   2   6   2   2   6
+ 46  46  46 246 246 246 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 221 221 221  86  86  86 156 107  11
+216 158  10 236 178  12 242 186  14 246 186  14
+242 186  14 239 182  13 239 182  13 242 186  14
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+242 186  14 225 175  15 142 122  72  66  66  66
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 26  26  26  70  70  70 163 133  67 210 150  10
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+232 195  16 121  92   8  34  34  34 106 106 106
+221 221 221 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+242 242 242  82  82  82  18  14   6 163 110   8
+216 158  10 236 178  12 242 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 242 186  14 163 133  67
+ 46  46  46  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78 163 133  67 210 150  10
+236 178  12 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+241 196  14 215 174  15 190 178 144 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 218 218 218
+ 58  58  58   2   2   6  22  18   6 167 114   7
+216 158  10 236 178  12 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 186  14 242 186  14 190 150  46
+ 54  54  54  22  22  22   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 38  38  38  86  86  86 180 133  36 213 154  11
+236 178  12 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 232 195  16 190 146  13 214 214 214
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 250 250 250 170 170 170  26  26  26
+  2   2   6   2   2   6  37  26   9 163 110   8
+219 162  10 239 182  13 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 236 178  12 224 166  10 142 122  72
+ 46  46  46  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 109 106  95 192 133   9 224 166  10
+242 186  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+242 186  14 226 184  13 210 162  10 142 110  46
+226 226 226 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+198 198 198  66  66  66   2   2   6   2   2   6
+  2   2   6   2   2   6  50  34   6 156 107  11
+219 162  10 239 182  13 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 242 186  14
+234 174  13 213 154  11 154 122  46  66  66  66
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 58  58  58 154 121  60 206 145  10 234 174  13
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 236 178  12 210 162  10 163 110   8
+ 61  42   6 138 138 138 218 218 218 250 250 250
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 210 210 210 144 144 144  66  66  66
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  61  42   6 163 110   8
+216 158  10 236 178  12 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 239 182  13 230 174  11 216 158  10
+190 142  34 124 112  88  70  70  70  38  38  38
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 62  62  62 168 124  44 206 145  10 224 166  10
+236 178  12 239 182  13 242 186  14 242 186  14
+246 186  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 236 178  12 216 158  10 175 118   6
+ 80  54   7   2   2   6   6   6   6  30  30  30
+ 54  54  54  62  62  62  50  50  50  38  38  38
+ 14  14  14   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  80  54   7 167 114   7
+213 154  11 236 178  12 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 242 186  14 239 182  13 239 182  13
+230 174  11 210 150  10 174 135  50 124 112  88
+ 82  82  82  54  54  54  34  34  34  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 158 118  36 192 133   9 200 144  11
+216 158  10 219 162  10 224 166  10 226 170  11
+230 174  11 236 178  12 239 182  13 239 182  13
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 230 174  11 210 150  10 163 110   8
+104  69   6  10  10  10   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  91  60   6 167 114   7
+206 145  10 230 174  11 242 186  14 246 190  14
+246 190  14 246 190  14 246 186  14 242 186  14
+239 182  13 230 174  11 224 166  10 213 154  11
+180 133  36 124 112  88  86  86  86  58  58  58
+ 38  38  38  22  22  22  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 34  34  34  70  70  70 138 110  50 158 118  36
+167 114   7 180 123   7 192 133   9 197 138  11
+200 144  11 206 145  10 213 154  11 219 162  10
+224 166  10 230 174  11 239 182  13 242 186  14
+246 186  14 246 186  14 246 186  14 246 186  14
+239 182  13 216 158  10 185 133  11 152  99   6
+104  69   6  18  14   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  80  54   7 152  99   6
+192 133   9 219 162  10 236 178  12 239 182  13
+246 186  14 242 186  14 239 182  13 236 178  12
+224 166  10 206 145  10 192 133   9 154 121  60
+ 94  94  94  62  62  62  42  42  42  22  22  22
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 18  18  18  34  34  34  58  58  58  78  78  78
+101  98  89 124 112  88 142 110  46 156 107  11
+163 110   8 167 114   7 175 118   6 180 123   7
+185 133  11 197 138  11 210 150  10 219 162  10
+226 170  11 236 178  12 236 178  12 234 174  13
+219 162  10 197 138  11 163 110   8 130  83   6
+ 91  60   6  10  10  10   2   2   6   2   2   6
+ 18  18  18  38  38  38  38  38  38  38  38  38
+ 38  38  38  38  38  38  38  38  38  38  38  38
+ 38  38  38  38  38  38  26  26  26   2   2   6
+  2   2   6   6   6   6  70  47   6 137  92   6
+175 118   6 200 144  11 219 162  10 230 174  11
+234 174  13 230 174  11 219 162  10 210 150  10
+192 133   9 163 110   8 124 112  88  82  82  82
+ 50  50  50  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  22  22  22  34  34  34
+ 42  42  42  58  58  58  74  74  74  86  86  86
+101  98  89 122 102  70 130  98  46 121  87  25
+137  92   6 152  99   6 163 110   8 180 123   7
+185 133  11 197 138  11 206 145  10 200 144  11
+180 123   7 156 107  11 130  83   6 104  69   6
+ 50  34   6  54  54  54 110 110 110 101  98  89
+ 86  86  86  82  82  82  78  78  78  78  78  78
+ 78  78  78  78  78  78  78  78  78  78  78  78
+ 78  78  78  82  82  82  86  86  86  94  94  94
+106 106 106 101 101 101  86  66  34 124  80   6
+156 107  11 180 123   7 192 133   9 200 144  11
+206 145  10 200 144  11 192 133   9 175 118   6
+139 102  15 109 106  95  70  70  70  42  42  42
+ 22  22  22  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  10  10  10
+ 14  14  14  22  22  22  30  30  30  38  38  38
+ 50  50  50  62  62  62  74  74  74  90  90  90
+101  98  89 112 100  78 121  87  25 124  80   6
+137  92   6 152  99   6 152  99   6 152  99   6
+138  86   6 124  80   6  98  70   6  86  66  30
+101  98  89  82  82  82  58  58  58  46  46  46
+ 38  38  38  34  34  34  34  34  34  34  34  34
+ 34  34  34  34  34  34  34  34  34  34  34  34
+ 34  34  34  34  34  34  38  38  38  42  42  42
+ 54  54  54  82  82  82  94  86  76  91  60   6
+134  86   6 156 107  11 167 114   7 175 118   6
+175 118   6 167 114   7 152  99   6 121  87  25
+101  98  89  62  62  62  34  34  34  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6   6   6   6  10  10  10
+ 18  18  18  22  22  22  30  30  30  42  42  42
+ 50  50  50  66  66  66  86  86  86 101  98  89
+106  86  58  98  70   6 104  69   6 104  69   6
+104  69   6  91  60   6  82  62  34  90  90  90
+ 62  62  62  38  38  38  22  22  22  14  14  14
+ 10  10  10  10  10  10  10  10  10  10  10  10
+ 10  10  10  10  10  10   6   6   6  10  10  10
+ 10  10  10  10  10  10  10  10  10  14  14  14
+ 22  22  22  42  42  42  70  70  70  89  81  66
+ 80  54   7 104  69   6 124  80   6 137  92   6
+134  86   6 116  81   8 100  82  52  86  86  86
+ 58  58  58  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  10  10  10  14  14  14
+ 18  18  18  26  26  26  38  38  38  54  54  54
+ 70  70  70  86  86  86  94  86  76  89  81  66
+ 89  81  66  86  86  86  74  74  74  50  50  50
+ 30  30  30  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  34  34  34  58  58  58
+ 82  82  82  89  81  66  89  81  66  89  81  66
+ 94  86  66  94  86  76  74  74  74  50  50  50
+ 26  26  26  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6   6   6   6  14  14  14  18  18  18
+ 30  30  30  38  38  38  46  46  46  54  54  54
+ 50  50  50  42  42  42  30  30  30  18  18  18
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  26  26  26
+ 38  38  38  50  50  50  58  58  58  58  58  58
+ 54  54  54  42  42  42  30  30  30  18  18  18
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+  6   6   6  10  10  10  14  14  14  18  18  18
+ 18  18  18  14  14  14  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 14  14  14  18  18  18  22  22  22  22  22  22
+ 18  18  18  14  14  14  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
diff -Nru a/drivers/video/logo/logo_linux_clut224.ppm b/drivers/video/logo/logo_linux_clut224.ppm
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/logo_linux_clut224.ppm	Mon Feb 24 13:47:01 2003
@@ -0,0 +1,1604 @@
+P3
+# Standard 224-color Linux logo
+80 80
+255
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6   6   6   6  10  10  10  10  10  10
+ 10  10  10   6   6   6   6   6   6   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  10  10  10  14  14  14
+ 22  22  22  26  26  26  30  30  30  34  34  34
+ 30  30  30  30  30  30  26  26  26  18  18  18
+ 14  14  14  10  10  10   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  26  26  26  42  42  42
+ 54  54  54  66  66  66  78  78  78  78  78  78
+ 78  78  78  74  74  74  66  66  66  54  54  54
+ 42  42  42  26  26  26  18  18  18  10  10  10
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 22  22  22  42  42  42  66  66  66  86  86  86
+ 66  66  66  38  38  38  38  38  38  22  22  22
+ 26  26  26  34  34  34  54  54  54  66  66  66
+ 86  86  86  70  70  70  46  46  46  26  26  26
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  26  26  26
+ 50  50  50  82  82  82  58  58  58   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  54  54  54  86  86  86  66  66  66
+ 38  38  38  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  22  22  22  50  50  50
+ 78  78  78  34  34  34   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   6   6   6  70  70  70
+ 78  78  78  46  46  46  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  42  42  42  82  82  82
+ 26  26  26   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  14  14  14
+ 46  46  46  34  34  34   6   6   6   2   2   6
+ 42  42  42  78  78  78  42  42  42  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 10  10  10  30  30  30  66  66  66  58  58  58
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  26  26  26
+ 86  86  86 101 101 101  46  46  46  10  10  10
+  2   2   6  58  58  58  70  70  70  34  34  34
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 14  14  14  42  42  42  86  86  86  10  10  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  30  30  30
+ 94  94  94  94  94  94  58  58  58  26  26  26
+  2   2   6   6   6   6  78  78  78  54  54  54
+ 22  22  22   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 22  22  22  62  62  62  62  62  62   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  26  26  26
+ 54  54  54  38  38  38  18  18  18  10  10  10
+  2   2   6   2   2   6  34  34  34  82  82  82
+ 38  38  38  14  14  14   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 30  30  30  78  78  78  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 10  10  10   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  78  78  78
+ 50  50  50  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  14  14  14   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  54  54  54
+ 66  66  66  26  26  26   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  82  82  82   2   2   6   2   2   6
+  2   2   6   6   6   6  10  10  10   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 14  14  14  10  10  10   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  18  18  18
+ 82  82  82  34  34  34  10  10  10   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6   2   2   6
+  6   6   6   6   6   6  22  22  22  34  34  34
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  34  34  34
+ 10  10  10  50  50  50  22  22  22   2   2   6
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 86  86  86  42  42  42  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6   2   2   6
+ 38  38  38 116 116 116  94  94  94  22  22  22
+ 22  22  22   2   2   6   2   2   6   2   2   6
+ 14  14  14  86  86  86 138 138 138 162 162 162
+154 154 154  38  38  38  26  26  26   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 86  86  86  46  46  46  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6  14  14  14
+134 134 134 198 198 198 195 195 195 116 116 116
+ 10  10  10   2   2   6   2   2   6   6   6   6
+101  98  89 187 187 187 210 210 210 218 218 218
+214 214 214 134 134 134  14  14  14   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 86  86  86  50  50  50  18  18  18   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6  54  54  54
+218 218 218 195 195 195 226 226 226 246 246 246
+ 58  58  58   2   2   6   2   2   6  30  30  30
+210 210 210 253 253 253 174 174 174 123 123 123
+221 221 221 234 234 234  74  74  74   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  82  82  82   2   2   6 106 106 106
+170 170 170  26  26  26  86  86  86 226 226 226
+123 123 123  10  10  10  14  14  14  46  46  46
+231 231 231 190 190 190   6   6   6  70  70  70
+ 90  90  90 238 238 238 158 158 158   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  86  86  86   6   6   6 116 116 116
+106 106 106   6   6   6  70  70  70 149 149 149
+128 128 128  18  18  18  38  38  38  54  54  54
+221 221 221 106 106 106   2   2   6  14  14  14
+ 46  46  46 190 190 190 198 198 198   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  62  62  62  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  94  94  94  14  14  14 101 101 101
+128 128 128   2   2   6  18  18  18 116 116 116
+118  98  46 121  92   8 121  92   8  98  78  10
+162 162 162 106 106 106   2   2   6   2   2   6
+  2   2   6 195 195 195 195 195 195   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  62  62  62  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   1
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  90  90  90  14  14  14  58  58  58
+210 210 210  26  26  26  54  38   6 154 114  10
+226 170  11 236 186  11 225 175  15 184 144  12
+215 174  15 175 146  61  37  26   9   2   2   6
+ 70  70  70 246 246 246 138 138 138   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  66  66  66  26  26  26   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  14  14  14  10  10  10
+195 195 195 188 164 115 192 133   9 225 175  15
+239 182  13 234 190  10 232 195  16 232 200  30
+245 207  45 241 208  19 232 195  16 184 144  12
+218 194 134 211 206 186  42  42  42   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 50  50  50  74  74  74  30  30  30   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  86  86  86  14  14  14   2   2   6
+121  87  25 192 133   9 219 162  10 239 182  13
+236 186  11 232 195  16 241 208  19 244 214  54
+246 218  60 246 218  38 246 215  20 241 208  19
+241 208  19 226 184  13 121  87  25   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 50  50  50  82  82  82  34  34  34  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  82  82  82  30  30  30  61  42   6
+180 123   7 206 145  10 230 174  11 239 182  13
+234 190  10 238 202  15 241 208  19 246 218  74
+246 218  38 246 215  20 246 215  20 246 215  20
+226 184  13 215 174  15 184 144  12   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 26  26  26  94  94  94  42  42  42  14  14  14
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78  50  50  50 104  69   6
+192 133   9 216 158  10 236 178  12 236 186  11
+232 195  16 241 208  19 244 214  54 245 215  43
+246 215  20 246 215  20 241 208  19 198 155  10
+200 144  11 216 158  10 156 118  10   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  90  90  90  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78  46  46  46  22  22  22
+137  92   6 210 162  10 239 182  13 238 190  10
+238 202  15 241 208  19 246 215  20 246 215  20
+241 208  19 203 166  17 185 133  11 210 150  10
+216 158  10 210 150  10 102  78  10   2   2   6
+  6   6   6  54  54  54  14  14  14   2   2   6
+  2   2   6  62  62  62  74  74  74  30  30  30
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  78  78  78  50  50  50   6   6   6
+ 94  70  30 139 102  15 190 146  13 226 184  13
+232 200  30 232 195  16 215 174  15 190 146  13
+168 122  10 192 133   9 210 150  10 213 154  11
+202 150  34 182 157 106 101  98  89   2   2   6
+  2   2   6  78  78  78 116 116 116  58  58  58
+  2   2   6  22  22  22  90  90  90  46  46  46
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  50  50  50   6   6   6
+128 128 128 174 154 114 156 107  11 168 122  10
+198 155  10 184 144  12 197 138  11 200 144  11
+206 145  10 206 145  10 197 138  11 188 164 115
+195 195 195 198 198 198 174 174 174  14  14  14
+  2   2   6  22  22  22 116 116 116 116 116 116
+ 22  22  22   2   2   6  74  74  74  70  70  70
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 101 101 101  26  26  26  10  10  10
+138 138 138 190 190 190 174 154 114 156 107  11
+197 138  11 200 144  11 197 138  11 192 133   9
+180 123   7 190 142  34 190 178 144 187 187 187
+202 202 202 221 221 221 214 214 214  66  66  66
+  2   2   6   2   2   6  50  50  50  62  62  62
+  6   6   6   2   2   6  10  10  10  90  90  90
+ 50  50  50  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  34  34  34
+ 74  74  74  74  74  74   2   2   6   6   6   6
+144 144 144 198 198 198 190 190 190 178 166 146
+154 121  60 156 107  11 156 107  11 168 124  44
+174 154 114 187 187 187 190 190 190 210 210 210
+246 246 246 253 253 253 253 253 253 182 182 182
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  62  62  62
+ 74  74  74  34  34  34  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  10  10  10  22  22  22  54  54  54
+ 94  94  94  18  18  18   2   2   6  46  46  46
+234 234 234 221 221 221 190 190 190 190 190 190
+190 190 190 187 187 187 187 187 187 190 190 190
+190 190 190 195 195 195 214 214 214 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+ 82  82  82   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  14  14  14
+ 86  86  86  54  54  54  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  46  46  46  90  90  90
+ 46  46  46  18  18  18   6   6   6 182 182 182
+253 253 253 246 246 246 206 206 206 190 190 190
+190 190 190 190 190 190 190 190 190 190 190 190
+206 206 206 231 231 231 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+202 202 202  14  14  14   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 42  42  42  86  86  86  42  42  42  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 14  14  14  38  38  38  74  74  74  66  66  66
+  2   2   6   6   6   6  90  90  90 250 250 250
+253 253 253 253 253 253 238 238 238 198 198 198
+190 190 190 190 190 190 195 195 195 221 221 221
+246 246 246 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253  82  82  82   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  78  78  78  70  70  70  34  34  34
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 34  34  34  66  66  66  78  78  78   6   6   6
+  2   2   6  18  18  18 218 218 218 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+226 226 226 231 231 231 246 246 246 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 178 178 178   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  18  18  18  90  90  90  62  62  62
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  26  26  26
+ 58  58  58  90  90  90  18  18  18   2   2   6
+  2   2   6 110 110 110 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 231 231 231  18  18  18   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  94  94  94
+ 54  54  54  26  26  26  10  10  10   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  22  22  22  50  50  50
+ 90  90  90  26  26  26   2   2   6   2   2   6
+ 14  14  14 195 195 195 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 242 242 242  54  54  54   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+ 86  86  86  50  50  50  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  38  38  38  82  82  82
+ 34  34  34   2   2   6   2   2   6   2   2   6
+ 42  42  42 195 195 195 246 246 246 253 253 253
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 242 242 242 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 250 250 250 246 246 246 238 238 238
+226 226 226 231 231 231 101 101 101   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 38  38  38  82  82  82  42  42  42  14  14  14
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 10  10  10  26  26  26  62  62  62  66  66  66
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 70  70  70 170 170 170 206 206 206 234 234 234
+246 246 246 250 250 250 250 250 250 238 238 238
+226 226 226 231 231 231 238 238 238 250 250 250
+250 250 250 250 250 250 246 246 246 231 231 231
+214 214 214 206 206 206 202 202 202 202 202 202
+198 198 198 202 202 202 182 182 182  18  18  18
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  62  62  62  66  66  66  30  30  30
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 14  14  14  42  42  42  82  82  82  18  18  18
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 94  94  94 182 182 182 218 218 218 242 242 242
+250 250 250 253 253 253 253 253 253 250 250 250
+234 234 234 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+238 238 238 226 226 226 210 210 210 202 202 202
+195 195 195 195 195 195 210 210 210 158 158 158
+  6   6   6  14  14  14  50  50  50  14  14  14
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  86  86  86  46  46  46
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 22  22  22  54  54  54  70  70  70   2   2   6
+  2   2   6  10  10  10   2   2   6  22  22  22
+166 166 166 231 231 231 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+231 231 231 206 206 206 198 198 198 226 226 226
+ 94  94  94   2   2   6   6   6   6  38  38  38
+ 30  30  30   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  62  62  62  66  66  66
+ 26  26  26  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  74  74  74  50  50  50   2   2   6
+ 26  26  26  26  26  26   2   2   6 106 106 106
+238 238 238 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 246 246 246 218 218 218 202 202 202
+210 210 210  14  14  14   2   2   6   2   2   6
+ 30  30  30  22  22  22   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  86  86  86
+ 42  42  42  14  14  14   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  90  90  90  22  22  22   2   2   6
+ 42  42  42   2   2   6  18  18  18 218 218 218
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 250 250 250 221 221 221
+218 218 218 101 101 101   2   2   6  14  14  14
+ 18  18  18  38  38  38  10  10  10   2   2   6
+  2   2   6   2   2   6   2   2   6  78  78  78
+ 58  58  58  22  22  22   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 54  54  54  82  82  82   2   2   6  26  26  26
+ 22  22  22   2   2   6 123 123 123 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 250 250 250
+238 238 238 198 198 198   6   6   6  38  38  38
+ 58  58  58  26  26  26  38  38  38   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+ 78  78  78  30  30  30  10  10  10   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  30  30  30
+ 74  74  74  58  58  58   2   2   6  42  42  42
+  2   2   6  22  22  22 231 231 231 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 250 250 250
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 246 246 246  46  46  46  38  38  38
+ 42  42  42  14  14  14  38  38  38  14  14  14
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 86  86  86  46  46  46  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  42  42  42
+ 90  90  90  18  18  18  18  18  18  26  26  26
+  2   2   6 116 116 116 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 250 250 250 238 238 238
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253  94  94  94   6   6   6
+  2   2   6   2   2   6  10  10  10  34  34  34
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  10  10  10  26  26  26  66  66  66
+ 82  82  82   2   2   6  38  38  38   6   6   6
+ 14  14  14 210 210 210 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 246 246 246 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 144 144 144   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 42  42  42  74  74  74  30  30  30  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  42  42  42  90  90  90
+ 26  26  26   6   6   6  42  42  42   2   2   6
+ 74  74  74 250 250 250 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 242 242 242 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 182 182 182   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 10  10  10  86  86  86  38  38  38  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 10  10  10  26  26  26  66  66  66  82  82  82
+  2   2   6  22  22  22  18  18  18   2   2   6
+149 149 149 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 234 234 234 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 206 206 206   2   2   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  86  86  86  46  46  46  14  14  14
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 18  18  18  46  46  46  86  86  86  18  18  18
+  2   2   6  34  34  34  10  10  10   6   6   6
+210 210 210 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 234 234 234 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 221 221 221   6   6   6
+  2   2   6   2   2   6   6   6   6  30  30  30
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  82  82  82  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 26  26  26  66  66  66  62  62  62   2   2   6
+  2   2   6  38  38  38  10  10  10  26  26  26
+238 238 238 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 238 238 238
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231   6   6   6
+  2   2   6   2   2   6  10  10  10  30  30  30
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  58  58  58  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  78  78  78   6   6   6   2   2   6
+  2   2   6  46  46  46  14  14  14  42  42  42
+246 246 246 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 234 234 234  10  10  10
+  2   2   6   2   2   6  22  22  22  14  14  14
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  62  62  62  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50  74  74  74   2   2   6   2   2   6
+ 14  14  14  70  70  70  34  34  34  62  62  62
+250 250 250 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 246 246 246
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 234 234 234  14  14  14
+  2   2   6   2   2   6  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  62  62  62  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 54  54  54  62  62  62   2   2   6   2   2   6
+  2   2   6  30  30  30  46  46  46  70  70  70
+250 250 250 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 246 246 246
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 226 226 226  10  10  10
+  2   2   6   6   6   6  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  58  58  58  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 58  58  58  62  62  62   2   2   6   2   2   6
+  2   2   6   2   2   6  30  30  30  78  78  78
+250 250 250 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 246 246 246
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 206 206 206   2   2   6
+ 22  22  22  34  34  34  18  14   6  22  22  22
+ 26  26  26  18  18  18   6   6   6   2   2   6
+  2   2   6  82  82  82  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  26  26  26
+ 62  62  62 106 106 106  74  54  14 185 133  11
+210 162  10 121  92   8   6   6   6  62  62  62
+238 238 238 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 246 246 246
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 158 158 158  18  18  18
+ 14  14  14   2   2   6   2   2   6   2   2   6
+  6   6   6  18  18  18  66  66  66  38  38  38
+  6   6   6  94  94  94  50  50  50  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 10  10  10  10  10  10  18  18  18  38  38  38
+ 78  78  78 142 134 106 216 158  10 242 186  14
+246 190  14 246 190  14 156 118  10  10  10  10
+ 90  90  90 238 238 238 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 250 250 250
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 246 230 190
+238 204  91 238 204  91 181 142  44  37  26   9
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  38  38  38  46  46  46
+ 26  26  26 106 106 106  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  22  22  22
+ 30  30  30  38  38  38  50  50  50  70  70  70
+106 106 106 190 142  34 226 170  11 242 186  14
+246 190  14 246 190  14 246 190  14 154 114  10
+  6   6   6  74  74  74 226 226 226 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 250 250 250
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 228 184  62
+241 196  14 241 208  19 232 195  16  38  30  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  30  30  30  26  26  26
+203 166  17 154 142  90  66  66  66  26  26  26
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  38  38  38  58  58  58
+ 78  78  78  86  86  86 101 101 101 123 123 123
+175 146  61 210 150  10 234 174  13 246 186  14
+246 190  14 246 190  14 246 190  14 238 190  10
+102  78  10   2   2   6  46  46  46 198 198 198
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 234 234 234 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 224 178  62
+242 186  14 241 196  14 210 166  10  22  18   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   6   6   6 121  92   8
+238 202  15 232 195  16  82  82  82  34  34  34
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 14  14  14  38  38  38  70  70  70 154 122  46
+190 142  34 200 144  11 197 138  11 197 138  11
+213 154  11 226 170  11 242 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+225 175  15  46  32   6   2   2   6  22  22  22
+158 158 158 250 250 250 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 250 250 250 242 242 242 224 178  62
+239 182  13 236 186  11 213 154  11  46  32   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  61  42   6 225 175  15
+238 190  10 236 186  11 112 100  78  42  42  42
+ 14  14  14   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 22  22  22  54  54  54 154 122  46 213 154  11
+226 170  11 230 174  11 226 170  11 226 170  11
+236 178  12 242 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+241 196  14 184 144  12  10  10  10   2   2   6
+  6   6   6 116 116 116 242 242 242 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 231 231 231 198 198 198 214 170  54
+236 178  12 236 178  12 210 150  10 137  92   6
+ 18  14   6   2   2   6   2   2   6   2   2   6
+  6   6   6  70  47   6 200 144  11 236 178  12
+239 182  13 239 182  13 124 112  88  58  58  58
+ 22  22  22   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  70  70  70 180 133  36 226 170  11
+239 182  13 242 186  14 242 186  14 246 186  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 232 195  16  98  70   6   2   2   6
+  2   2   6   2   2   6  66  66  66 221 221 221
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 206 206 206 198 198 198 214 166  58
+230 174  11 230 174  11 216 158  10 192 133   9
+163 110   8 116  81   8 102  78  10 116  81   8
+167 114   7 197 138  11 226 170  11 239 182  13
+242 186  14 242 186  14 162 146  94  78  78  78
+ 34  34  34  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 30  30  30  78  78  78 190 142  34 226 170  11
+239 182  13 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 241 196  14 203 166  17  22  18   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+218 218 218 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 206 206 206 198 198 198 202 162  69
+226 170  11 236 178  12 224 166  10 210 150  10
+200 144  11 197 138  11 192 133   9 197 138  11
+210 150  10 226 170  11 242 186  14 246 190  14
+246 190  14 246 186  14 225 175  15 124 112  88
+ 62  62  62  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78 174 135  50 224 166  10
+239 182  13 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 241 196  14 139 102  15
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 78  78  78 250 250 250 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 214 214 214 198 198 198 190 150  46
+219 162  10 236 178  12 234 174  13 224 166  10
+216 158  10 213 154  11 213 154  11 216 158  10
+226 170  11 239 182  13 246 190  14 246 190  14
+246 190  14 246 190  14 242 186  14 206 162  42
+101 101 101  58  58  58  30  30  30  14  14  14
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  74  74  74 174 135  50 216 158  10
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 241 196  14 226 184  13
+ 61  42   6   2   2   6   2   2   6   2   2   6
+ 22  22  22 238 238 238 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 226 226 226 187 187 187 180 133  36
+216 158  10 236 178  12 239 182  13 236 178  12
+230 174  11 226 170  11 226 170  11 230 174  11
+236 178  12 242 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 186  14 239 182  13
+206 162  42 106 106 106  66  66  66  34  34  34
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 26  26  26  70  70  70 163 133  67 213 154  11
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 241 196  14
+190 146  13  18  14   6   2   2   6   2   2   6
+ 46  46  46 246 246 246 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 221 221 221  86  86  86 156 107  11
+216 158  10 236 178  12 242 186  14 246 186  14
+242 186  14 239 182  13 239 182  13 242 186  14
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+242 186  14 225 175  15 142 122  72  66  66  66
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 26  26  26  70  70  70 163 133  67 210 150  10
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+232 195  16 121  92   8  34  34  34 106 106 106
+221 221 221 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+242 242 242  82  82  82  18  14   6 163 110   8
+216 158  10 236 178  12 242 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 242 186  14 163 133  67
+ 46  46  46  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78 163 133  67 210 150  10
+236 178  12 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+241 196  14 215 174  15 190 178 144 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 218 218 218
+ 58  58  58   2   2   6  22  18   6 167 114   7
+216 158  10 236 178  12 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 186  14 242 186  14 190 150  46
+ 54  54  54  22  22  22   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 38  38  38  86  86  86 180 133  36 213 154  11
+236 178  12 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 232 195  16 190 146  13 214 214 214
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 250 250 250 170 170 170  26  26  26
+  2   2   6   2   2   6  37  26   9 163 110   8
+219 162  10 239 182  13 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 236 178  12 224 166  10 142 122  72
+ 46  46  46  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 109 106  95 192 133   9 224 166  10
+242 186  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+242 186  14 226 184  13 210 162  10 142 110  46
+226 226 226 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+198 198 198  66  66  66   2   2   6   2   2   6
+  2   2   6   2   2   6  50  34   6 156 107  11
+219 162  10 239 182  13 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 242 186  14
+234 174  13 213 154  11 154 122  46  66  66  66
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 58  58  58 154 121  60 206 145  10 234 174  13
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 236 178  12 210 162  10 163 110   8
+ 61  42   6 138 138 138 218 218 218 250 250 250
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 210 210 210 144 144 144  66  66  66
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  61  42   6 163 110   8
+216 158  10 236 178  12 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 239 182  13 230 174  11 216 158  10
+190 142  34 124 112  88  70  70  70  38  38  38
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 62  62  62 168 124  44 206 145  10 224 166  10
+236 178  12 239 182  13 242 186  14 242 186  14
+246 186  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 236 178  12 216 158  10 175 118   6
+ 80  54   7   2   2   6   6   6   6  30  30  30
+ 54  54  54  62  62  62  50  50  50  38  38  38
+ 14  14  14   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  80  54   7 167 114   7
+213 154  11 236 178  12 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 242 186  14 239 182  13 239 182  13
+230 174  11 210 150  10 174 135  50 124 112  88
+ 82  82  82  54  54  54  34  34  34  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 158 118  36 192 133   9 200 144  11
+216 158  10 219 162  10 224 166  10 226 170  11
+230 174  11 236 178  12 239 182  13 239 182  13
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 230 174  11 210 150  10 163 110   8
+104  69   6  10  10  10   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  91  60   6 167 114   7
+206 145  10 230 174  11 242 186  14 246 190  14
+246 190  14 246 190  14 246 186  14 242 186  14
+239 182  13 230 174  11 224 166  10 213 154  11
+180 133  36 124 112  88  86  86  86  58  58  58
+ 38  38  38  22  22  22  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 34  34  34  70  70  70 138 110  50 158 118  36
+167 114   7 180 123   7 192 133   9 197 138  11
+200 144  11 206 145  10 213 154  11 219 162  10
+224 166  10 230 174  11 239 182  13 242 186  14
+246 186  14 246 186  14 246 186  14 246 186  14
+239 182  13 216 158  10 185 133  11 152  99   6
+104  69   6  18  14   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  80  54   7 152  99   6
+192 133   9 219 162  10 236 178  12 239 182  13
+246 186  14 242 186  14 239 182  13 236 178  12
+224 166  10 206 145  10 192 133   9 154 121  60
+ 94  94  94  62  62  62  42  42  42  22  22  22
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 18  18  18  34  34  34  58  58  58  78  78  78
+101  98  89 124 112  88 142 110  46 156 107  11
+163 110   8 167 114   7 175 118   6 180 123   7
+185 133  11 197 138  11 210 150  10 219 162  10
+226 170  11 236 178  12 236 178  12 234 174  13
+219 162  10 197 138  11 163 110   8 130  83   6
+ 91  60   6  10  10  10   2   2   6   2   2   6
+ 18  18  18  38  38  38  38  38  38  38  38  38
+ 38  38  38  38  38  38  38  38  38  38  38  38
+ 38  38  38  38  38  38  26  26  26   2   2   6
+  2   2   6   6   6   6  70  47   6 137  92   6
+175 118   6 200 144  11 219 162  10 230 174  11
+234 174  13 230 174  11 219 162  10 210 150  10
+192 133   9 163 110   8 124 112  88  82  82  82
+ 50  50  50  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  22  22  22  34  34  34
+ 42  42  42  58  58  58  74  74  74  86  86  86
+101  98  89 122 102  70 130  98  46 121  87  25
+137  92   6 152  99   6 163 110   8 180 123   7
+185 133  11 197 138  11 206 145  10 200 144  11
+180 123   7 156 107  11 130  83   6 104  69   6
+ 50  34   6  54  54  54 110 110 110 101  98  89
+ 86  86  86  82  82  82  78  78  78  78  78  78
+ 78  78  78  78  78  78  78  78  78  78  78  78
+ 78  78  78  82  82  82  86  86  86  94  94  94
+106 106 106 101 101 101  86  66  34 124  80   6
+156 107  11 180 123   7 192 133   9 200 144  11
+206 145  10 200 144  11 192 133   9 175 118   6
+139 102  15 109 106  95  70  70  70  42  42  42
+ 22  22  22  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  10  10  10
+ 14  14  14  22  22  22  30  30  30  38  38  38
+ 50  50  50  62  62  62  74  74  74  90  90  90
+101  98  89 112 100  78 121  87  25 124  80   6
+137  92   6 152  99   6 152  99   6 152  99   6
+138  86   6 124  80   6  98  70   6  86  66  30
+101  98  89  82  82  82  58  58  58  46  46  46
+ 38  38  38  34  34  34  34  34  34  34  34  34
+ 34  34  34  34  34  34  34  34  34  34  34  34
+ 34  34  34  34  34  34  38  38  38  42  42  42
+ 54  54  54  82  82  82  94  86  76  91  60   6
+134  86   6 156 107  11 167 114   7 175 118   6
+175 118   6 167 114   7 152  99   6 121  87  25
+101  98  89  62  62  62  34  34  34  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6   6   6   6  10  10  10
+ 18  18  18  22  22  22  30  30  30  42  42  42
+ 50  50  50  66  66  66  86  86  86 101  98  89
+106  86  58  98  70   6 104  69   6 104  69   6
+104  69   6  91  60   6  82  62  34  90  90  90
+ 62  62  62  38  38  38  22  22  22  14  14  14
+ 10  10  10  10  10  10  10  10  10  10  10  10
+ 10  10  10  10  10  10   6   6   6  10  10  10
+ 10  10  10  10  10  10  10  10  10  14  14  14
+ 22  22  22  42  42  42  70  70  70  89  81  66
+ 80  54   7 104  69   6 124  80   6 137  92   6
+134  86   6 116  81   8 100  82  52  86  86  86
+ 58  58  58  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  10  10  10  14  14  14
+ 18  18  18  26  26  26  38  38  38  54  54  54
+ 70  70  70  86  86  86  94  86  76  89  81  66
+ 89  81  66  86  86  86  74  74  74  50  50  50
+ 30  30  30  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  34  34  34  58  58  58
+ 82  82  82  89  81  66  89  81  66  89  81  66
+ 94  86  66  94  86  76  74  74  74  50  50  50
+ 26  26  26  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6   6   6   6  14  14  14  18  18  18
+ 30  30  30  38  38  38  46  46  46  54  54  54
+ 50  50  50  42  42  42  30  30  30  18  18  18
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  26  26  26
+ 38  38  38  50  50  50  58  58  58  58  58  58
+ 54  54  54  42  42  42  30  30  30  18  18  18
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+  6   6   6  10  10  10  14  14  14  18  18  18
+ 18  18  18  14  14  14  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 14  14  14  18  18  18  22  22  22  22  22  22
+ 18  18  18  14  14  14  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
diff -Nru a/drivers/video/logo/logo_linux_mono.pbm b/drivers/video/logo/logo_linux_mono.pbm
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/logo_linux_mono.pbm	Mon Feb 24 13:47:01 2003
@@ -0,0 +1,203 @@
+P1
+# Standard black and white Linux logo
+80 80
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 0 0 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1
+1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1
+1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1
+1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+0 1 1 0 0 1 1 1 0 0 1 1 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 1 1 1 0 1 1 1 1 0 0 1
+1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 1 1 1 0 1 1 1 0 1 1 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
+1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+0 1 1 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 1 0 0 0 0 0 1 1 1
+1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1
+1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1
+1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 1 1 1 1 1 1 1 0 0 0 0 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1
+1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1
+0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0
+1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1
+0 0 0 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1
+1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 1
+0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1
+1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1
+1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1
+1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1
+1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1
+1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 1 0 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 1 1 1 1 0
+0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 1 0 0 0
+0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
+1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
+1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
diff -Nru a/drivers/video/logo/logo_linux_vga16.ppm b/drivers/video/logo/logo_linux_vga16.ppm
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/logo_linux_vga16.ppm	Mon Feb 24 13:47:01 2003
@@ -0,0 +1,1604 @@
+P3
+# Standard 16-color Linux logo
+80 80
+255
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85  85  85  85  85  85  85  85  85  85
+ 85  85  85  85  85  85  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+ 85  85  85  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85 170 170 170   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170 170 170 170 170 170  85  85  85   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170 170 170 170 170 170
+170 170 170   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+ 85  85  85 170 170 170 170 170 170 170 170 170
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 170 170 170 255 255 255 255 255 255
+255 255 255 170 170 170   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+170 170 170 170 170 170 255 255 255 255 255 255
+  0   0   0   0   0   0   0   0   0   0   0   0
+170 170 170 255 255 255 170 170 170 170 170 170
+255 255 255 170 170 170   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+170 170 170   0   0   0   0   0   0 255 255 255
+ 85  85  85   0   0   0   0   0   0   0   0   0
+255 255 255 170 170 170   0   0   0  85  85  85
+170 170 170 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+ 85  85  85   0   0   0   0   0   0 170 170 170
+ 85  85  85   0   0   0   0   0   0   0   0   0
+255 255 255  85  85  85   0   0   0   0   0   0
+ 85  85  85 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+170 170 170   0   0   0   0   0   0 170 170 170
+ 85  85  85  85  85  85  85  85  85  85  85  85
+255 255 255  85  85  85   0   0   0   0   0   0
+ 85  85  85 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+255 255 255   0   0   0   0   0   0 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+ 85  85  85 255 255 255   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+170 170 170 170 170 170 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170 170 170 170 170 170   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 170  85   0
+170  85   0 170  85   0  85  85  85   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+ 85  85  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0  85  85  85   0   0   0
+  0   0   0  85  85  85 170 170 170  85  85  85
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+ 85  85  85 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170 170 170 170 170 170 170 170 170   0   0   0
+  0   0   0   0   0   0 170 170 170 170 170 170
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+ 85  85  85 170 170 170 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170  85  85  85
+  0   0   0   0   0   0  85  85  85  85  85  85
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+ 85  85  85 170 170 170 170 170 170 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170 170 170 170 170 170 170 170 170 170 170 170
+255 255 255 255 255 255 255 255 255 170 170 170
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0 170 170 170
+255 255 255 255 255 255 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0  85  85  85 255 255 255
+255 255 255 255 255 255 255 255 255 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0  85  85  85 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+ 85  85  85 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85 170 170 170 170 170 170 170 170 170
+255 255 255 255 255 255 255 255 255 170 170 170
+170 170 170 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+170 170 170 170 170 170 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170  85  85  85
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 170 170 170
+  0   0   0   0   0   0   0   0   0  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+ 85  85  85   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 170 170 170
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0 170 170 170
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+  0   0   0   0   0   0  85  85  85 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170   0   0   0  85  85  85
+ 85  85  85   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+  0   0   0  85  85  85 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170   0   0   0  85  85  85
+ 85  85  85   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0  85  85  85
+  0   0   0 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0  85  85  85   0   0   0
+  0   0   0 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0  85  85  85   0   0   0
+ 85  85  85 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0  85  85  85   0   0   0   0   0   0
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+ 85  85  85  85  85  85  85  85  85  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+ 85  85  85 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0  85  85  85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+  0   0   0   0   0   0  85  85  85 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 170  85   0
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85   0   0   0   0   0   0   0   0   0
+ 85  85  85 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 255 255  85
+170  85   0 255 255  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85   0   0   0   0   0   0
+  0   0   0  85  85  85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0  85  85  85 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85   0   0   0   0   0   0   0   0   0
+ 85  85  85 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170  85  85  85 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85  85  85  85  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170  85  85  85  85  85  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 170 170 170
+ 85  85  85   0   0   0   0   0   0 170  85   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170  85  85  85
+  0   0   0   0   0   0   0   0   0 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170  85  85  85  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 170  85   0
+170  85   0 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85 170  85   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 170  85   0 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 170  85   0
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85 170  85   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 170  85   0 170  85   0 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 170  85   0
+170  85   0   0   0   0   0   0   0   0   0   0
+ 85  85  85  85  85  85  85  85  85  85  85  85
+ 85  85  85  85  85  85  85  85  85  85  85  85
+ 85  85  85  85  85  85  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+170  85   0 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+170  85   0 170  85   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 170  85   0 170  85   0
+ 85  85  85  85  85  85  85  85  85  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+ 85  85  85  85  85  85  85  85  85 170  85   0
+170  85   0 170  85   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 170  85   0
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
diff -Nru a/drivers/video/logo/logo_mac_clut224.ppm b/drivers/video/logo/logo_mac_clut224.ppm
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/logo_mac_clut224.ppm	Mon Feb 24 13:47:01 2003
@@ -0,0 +1,1604 @@
+P3
+# 224-color Macintosh Linux logo
+80 80
+255
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6   6   6   6  10  10  10  10  10  10
+ 10  10  10   6   6   6   6   6   6   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  10  10  10  14  14  14
+ 22  22  22  26  26  26  30  30  30  34  34  34
+ 30  30  30  30  30  30  26  26  26  18  18  18
+ 14  14  14  10  10  10   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  26  26  26  42  42  42
+ 54  54  54  66  66  66  78  78  78  78  78  78
+ 78  78  78  74  74  74  66  66  66  54  54  54
+ 42  42  42  26  26  26  18  18  18  10  10  10
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 22  22  22  42  42  42  66  66  66  86  86  86
+ 66  66  66  38  38  38  38  38  38  22  22  22
+ 26  26  26  34  34  34  54  54  54  66  66  66
+ 86  86  86  70  70  70  46  46  46  26  26  26
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  26  26  26
+ 50  50  50  82  82  82  58  58  58   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  54  54  54  86  86  86  66  66  66
+ 38  38  38  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  22  22  22  50  50  50
+ 78  78  78  34  34  34   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   6   6   6  70  70  70
+ 78  78  78  46  46  46  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 250 250 250
+250 250 250 250 250 250 250 250 250 242 242 242
+250 250 250 250 250 250 246 246 246 250 250 250
+246 246 246 242 242 242 246 246 246 231 231 231
+ 46  46  46   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  14  14  14
+ 46  46  46  34  34  34   6   6   6   2   2   6
+ 82  82  82 242 242 242 242 242 242 246 246 246
+242 242 242 250 250 250 242 242 242 246 246 246
+242 242 242 250 250 250 242 242 242 250 250 250
+250 250 250 250 250 250 250 250 250 250 250 250
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 242 242 242
+250 250 250 250 250 250 250 250 250 250 250 250
+242 242 242 246 246 246 250 250 250 250 250 250
+250 250 250 250 250 250 242 242 242 116 116 116
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  26  26  26
+ 86  86  86 101 101 101  46  46  46  10  10  10
+  2   2   6 123 123 123 242 242 242 250 250 250
+246 246 246 250 250 250 242 242 242 250 250 250
+246 246 246 250 250 250 242 242 242 250 250 250
+242 242 242 250 250 250 250 250 250 250 250 250
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 123 123 123
+234 234 234 231 231 231 234 234 234 234 234 234
+234 234 234 221 221 221 234 234 234 231 231 231
+234 234 234 234 234 234 214 214 214  10  10  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  30  30  30
+ 94  94  94  94  94  94  58  58  58  26  26  26
+  2   2   6  10  10  10 190 190 190 242 242 242
+242 242 242 250 250 250 250 250 250 242 242 242
+246 246 246 250 250 250 250 250 250 242 242 242
+250 250 250 242 242 242 242 242 242 231 231 231
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  90  90  90
+234 234 234 226 226 226 226 226 226 218 218 218
+226 226 226 214 214 214 231 231 231 221 221 221
+231 231 231 221 221 221 116 116 116   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  26  26  26
+ 54  54  54  38  38  38  18  18  18  10  10  10
+  2   2   6   2   2   6  58  58  58 242 242 242
+242 242 242 242 242 242 242 242 242 242 242 242
+242 242 242 242 242 242 242 242 242 242 242 242
+242 242 242 242 242 242 250 250 250 226 226 226
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  82  82  82
+234 234 234 231 231 231 242 242 242 242 242 242
+234 234 234 234 234 234 238 238 238 234 234 234
+238 238 238 238 238 238  50  50  50   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 10  10  10   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6 182 182 182
+242 242 242 250 250 250 250 250 250 250 250 250
+242 242 242 250 250 250 250 250 250 250 250 250
+242 242 242 242 242 242 250 250 250 206 206 206
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  50  50  50
+250 250 250 226 226 226 234 234 234  10  10  10
+ 78  78  78  66  66  66 101  98  89  90  90  90
+110 110 110 106 106 106  10  10  10   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6 101  98  89
+210 210 210 238 238 238 226 226 226 238 238 238
+210 210 210 242 242 242 226 226 226 242 242 242
+242 242 242 234 234 234 250 250 250 198 198 198
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  82  82  82
+234 234 234 234 234 234 231 231 231   2   2   6
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  82  82  82   2   2   6   2   2   6
+  2   2   6   6   6   6  10  10  10   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 14  14  14  10  10  10   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  18  18  18
+ 82  82  82  34  34  34  10  10  10   0   0   0
+  6   6   6   0   0   0   0   0   0   0   0   0
+144 144 144 250 250 250 242 242 242 202 202 202
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  82  82  82
+226 226 226 231 231 231 234 234 234  90  90  90
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6   2   2   6
+  6   6   6   6   6   6  22  22  22  34  34  34
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  34  34  34
+ 10  10  10  50  50  50  22  22  22   2   2   6
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 86  86  86  42  42  42  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+158 158 158 242 242 242 234 234 234 187 187 187
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  66  66  66
+231 231 231 226 226 226 226 226 226 178 178 178
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6   2   2   6
+ 38  38  38 116 116 116  94  94  94  22  22  22
+ 22  22  22   2   2   6   2   2   6   2   2   6
+ 14  14  14  86  86  86 138 138 138 162 162 162
+154 154 154  38  38  38  26  26  26   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 86  86  86  46  46  46  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+187 187 187 234 234 234 250 250 250 190 190 190
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  82  82  82
+226 226 226 218 218 218 234 234 234 218 218 218
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6  14  14  14
+134 134 134 198 198 198 195 195 195 116 116 116
+ 10  10  10   2   2   6   2   2   6   6   6   6
+101  98  89 187 187 187 210 210 210 218 218 218
+214 214 214 134 134 134  14  14  14   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 86  86  86  50  50  50  18  18  18   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+214 214 214 226 226 226 242 242 242 187 187 187
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  74  74  74
+226 226 226 214 214 214 226 226 226 190 190 190
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6  54  54  54
+218 218 218 195 195 195 226 226 226 246 246 246
+ 58  58  58   2   2   6   2   2   6  30  30  30
+210 210 210 253 253 253 174 174 174 123 123 123
+221 221 221 234 234 234  74  74  74   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+195 195 195 226 226 226 234 234 234 206 206 206
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  62  62  62
+226 226 226 218 218 218 234 234 234 226 226 226
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  82  82  82   2   2   6 106 106 106
+170 170 170  26  26  26  86  86  86 226 226 226
+123 123 123  10  10  10  14  14  14  46  46  46
+231 231 231 190 190 190   6   6   6  70  70  70
+ 90  90  90 238 238 238 158 158 158   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+182 182 182 234 234 234 242 242 242 158 158 158
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 101  98  89
+214 214 214 214 214 214 226 226 226 242 242 242
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  86  86  86   6   6   6 116 116 116
+106 106 106   6   6   6  70  70  70 149 149 149
+128 128 128  18  18  18  38  38  38  54  54  54
+221 221 221 106 106 106   2   2   6  14  14  14
+ 46  46  46 190 190 190 198 198 198   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  62  62  62  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+190 190 190 226 226 226 226 226 226 178 178 178
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  66  66  66
+210 210 210 214 214 214 210 210 210 250 250 250
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  94  94  94  14  14  14 101 101 101
+128 128 128   2   2   6  18  18  18 116 116 116
+118  98  46 121  92   8 121  92   8  98  78  10
+162 162 162 106 106 106   2   2   6   2   2   6
+  2   2   6 195 195 195 195 195 195   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  62  62  62  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+214 214 214 226 226 226 231 231 231 149 149 149
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   1
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  42  42  42
+226 226 226 218 218 218 210 210 210 231 231 231
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  90  90  90  14  14  14  58  58  58
+210 210 210  26  26  26  54  38   6 154 114  10
+226 170  11 236 186  11 225 175  15 184 144  12
+215 174  15 175 146  61  37  26   9   2   2   6
+ 70  70  70 246 246 246 138 138 138   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  66  66  66  26  26  26   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+178 178 178 218 218 218 226 226 226 162 162 162
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  42  42  42
+214 214 214 198 198 198 210 210 210 242 242 242
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  14  14  14  10  10  10
+195 195 195 188 164 115 192 133   9 225 175  15
+239 182  13 234 190  10 232 195  16 232 200  30
+245 207  45 241 208  19 232 195  16 184 144  12
+218 194 134 211 206 186  42  42  42   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 50  50  50  74  74  74  30  30  30   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+187 187 187 231 231 231 226 226 226 182 182 182
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  66  66  66
+218 218 218 210 210 210 210 210 210 242 242 242
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  86  86  86  14  14  14   2   2   6
+121  87  25 192 133   9 219 162  10 239 182  13
+236 186  11 232 195  16 241 208  19 244 214  54
+246 218  60 246 218  38 246 215  20 241 208  19
+241 208  19 226 184  13 121  87  25   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 50  50  50  82  82  82  34  34  34  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+162 162 162 226 226 226 226 226 226 162 162 162
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  62  62  62
+206 206 206 206 206 206 202 202 202 250 250 250
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  82  82  82  30  30  30  61  42   6
+180 123   7 206 145  10 230 174  11 239 182  13
+234 190  10 238 202  15 241 208  19 246 218  74
+246 218  38 246 215  20 246 215  20 246 215  20
+226 184  13 215 174  15 184 144  12   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 26  26  26  94  94  94  42  42  42  14  14  14
+  0   0   0   0   0   0   0   0   0   0   0   0
+166 166 166 226 226 226 214 214 214 170 170 170
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  66  66  66
+226 226 226 218 218 218 202 202 202 242 242 242
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78  50  50  50 104  69   6
+192 133   9 216 158  10 236 178  12 236 186  11
+232 195  16 241 208  19 244 214  54 245 215  43
+246 215  20 246 215  20 241 208  19 198 155  10
+200 144  11 216 158  10 156 118  10   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  90  90  90  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+178 178 178 226 226 226 226 226 226 158 158 158
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  62  62  62
+214 214 214 198 198 198 202 202 202 242 242 242
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78  46  46  46  22  22  22
+137  92   6 210 162  10 239 182  13 238 190  10
+238 202  15 241 208  19 246 215  20 246 215  20
+241 208  19 203 166  17 185 133  11 210 150  10
+216 158  10 210 150  10 102  78  10   2   2   6
+  6   6   6  54  54  54  14  14  14   2   2   6
+  2   2   6  62  62  62  74  74  74  30  30  30
+ 10  10  10   0   0   0   0   0   0   0   0   0
+190 190 190 214 214 214 242 242 242 158 158 158
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  66  66  66
+210 210 210 202 202 202 202 202 202 242 242 242
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  78  78  78  50  50  50   6   6   6
+ 94  70  30 139 102  15 190 146  13 226 184  13
+232 200  30 232 195  16 215 174  15 190 146  13
+168 122  10 192 133   9 210 150  10 213 154  11
+202 150  34 182 157 106 101  98  89   2   2   6
+  2   2   6  78  78  78 116 116 116  58  58  58
+  2   2   6  22  22  22  90  90  90  46  46  46
+ 18  18  18   6   6   6   0   0   0   0   0   0
+195 195 195 214 214 214 226 226 226 162 162 162
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  82  82  82
+198 198 198 190 190 190 187 187 187 242 242 242
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  50  50  50   6   6   6
+128 128 128 174 154 114 156 107  11 168 122  10
+198 155  10 184 144  12 197 138  11 200 144  11
+206 145  10 206 145  10 197 138  11 188 164 115
+195 195 195 198 198 198 174 174 174  14  14  14
+  2   2   6  22  22  22 116 116 116 116 116 116
+ 22  22  22   2   2   6  74  74  74  70  70  70
+ 30  30  30  10  10  10   0   0   0   0   0   0
+178 178 178 226 226 226 226 226 226 141 141 141
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  62  62  62
+195 195 195 195 195 195 195 195 195 250 250 250
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 101 101 101  26  26  26  10  10  10
+138 138 138 190 190 190 174 154 114 156 107  11
+197 138  11 200 144  11 197 138  11 192 133   9
+180 123   7 190 142  34 190 178 144 187 187 187
+202 202 202 221 221 221 214 214 214  66  66  66
+  2   2   6   2   2   6  50  50  50  62  62  62
+  6   6   6   2   2   6  10  10  10  90  90  90
+ 50  50  50  18  18  18   6   6   6   0   0   0
+190 190 190 226 226 226 250 250 250 202 202 202
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  42  42  42
+187 187 187 190 190 190 187 187 187 250 250 250
+  0   0   0   0   0   0  10  10  10  34  34  34
+ 74  74  74  74  74  74   2   2   6   6   6   6
+144 144 144 198 198 198 190 190 190 178 166 146
+154 121  60 156 107  11 156 107  11 168 124  44
+174 154 114 187 187 187 190 190 190 210 210 210
+246 246 246 253 253 253 253 253 253 182 182 182
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  62  62  62
+ 74  74  74  34  34  34  14  14  14   0   0   0
+174 174 174 206 206 206 242 242 242 158 158 158
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  42  42  42
+190 190 190 187 187 187 190 190 190 234 234 234
+  0   0   0  10  10  10  22  22  22  54  54  54
+ 94  94  94  18  18  18   2   2   6  46  46  46
+234 234 234 221 221 221 190 190 190 190 190 190
+190 190 190 187 187 187 187 187 187 190 190 190
+190 190 190 195 195 195 214 214 214 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+ 82  82  82   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  14  14  14
+ 86  86  86  54  54  54  22  22  22   6   6   6
+195 195 195 202 202 202 234 234 234 138 138 138
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  50  50  50
+182 182 182 187 187 187 178 178 178 242 242 242
+  6   6   6  18  18  18  46  46  46  90  90  90
+ 46  46  46  18  18  18   6   6   6 182 182 182
+253 253 253 246 246 246 206 206 206 190 190 190
+190 190 190 190 190 190 190 190 190 190 190 190
+206 206 206 231 231 231 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+202 202 202  14  14  14   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 42  42  42  86  86  86  42  42  42  18  18  18
+190 190 190 202 202 202 226 226 226 178 178 178
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  62  62  62
+195 195 195 182 182 182 187 187 187 250 250 250
+ 14  14  14  38  38  38  74  74  74  66  66  66
+  2   2   6   6   6   6  90  90  90 250 250 250
+253 253 253 253 253 253 238 238 238 198 198 198
+190 190 190 190 190 190 195 195 195 221 221 221
+246 246 246 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253  82  82  82   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  78  78  78  70  70  70  34  34  34
+202 202 202 182 182 182 242 242 242 158 158 158
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  26  26  26
+195 195 195 182 182 182 178 178 178 242 242 242
+ 34  34  34  66  66  66  78  78  78   6   6   6
+  2   2   6  18  18  18 218 218 218 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+226 226 226 231 231 231 246 246 246 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 178 178 178   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  18  18  18  90  90  90  62  62  62
+218 218 218 198 198 198 250 250 250 141 141 141
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  42  42  42
+182 182 182 178 178 178 174 174 174 250 250 250
+ 58  58  58  90  90  90  18  18  18   2   2   6
+  2   2   6 110 110 110 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 231 231 231  18  18  18   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  94  94  94
+206 206 206 198 198 198 242 242 242 162 162 162
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  42  42  42
+166 166 166 170 170 170 187 187 187 242 242 242
+ 90  90  90  26  26  26   2   2   6   2   2   6
+ 14  14  14 195 195 195 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 242 242 242  54  54  54   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+187 187 187 214 214 214 231 231 231 134 134 134
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  50  50  50
+187 187 187 182 182 182 166 166 166 234 234 234
+ 34  34  34   2   2   6   2   2   6   2   2   6
+ 42  42  42 195 195 195 246 246 246 253 253 253
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 242 242 242 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 250 250 250 246 246 246 238 238 238
+226 226 226 231 231 231 101 101 101   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+206 206 206 174 174 174 250 250 250 128 128 128
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  34  34  34
+178 178 178 144 144 144 170 170 170 226 226 226
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 70  70  70 170 170 170 206 206 206 234 234 234
+246 246 246 250 250 250 250 250 250 238 238 238
+226 226 226 231 231 231 238 238 238 250 250 250
+250 250 250 250 250 250 246 246 246 231 231 231
+214 214 214 206 206 206 202 202 202 202 202 202
+198 198 198 202 202 202 182 182 182  18  18  18
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+202 202 202 166 166 166 214 214 214 128 128 128
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  50  50  50
+178 178 178 158 158 158 134 134 134 242 242 242
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 94  94  94 182 182 182 218 218 218 242 242 242
+250 250 250 253 253 253 253 253 253 250 250 250
+234 234 234 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+238 238 238 226 226 226 210 210 210 202 202 202
+195 195 195 195 195 195 210 210 210 158 158 158
+  6   6   6  14  14  14  50  50  50  14  14  14
+  2   2   6   2   2   6   2   2   6   2   2   6
+198 198 198 187 187 187 246 246 246 116 116 116
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  50  50  50
+195 195 195 154 154 154 154 154 154 250 250 250
+250 250 250 250 250 250 242 242 242 242 242 242
+242 242 242 250 250 250 250 250 250 250 250 250
+250 250 250 250 250 250 242 242 242 250 250 250
+250 250 250 250 250 250 242 242 242 250 250 250
+250 250 250 250 250 250 250 250 250 246 246 246
+234 234 234 250 250 250 242 242 242 242 242 242
+242 242 242 250 250 250 242 242 242 242 242 242
+242 242 242 250 250 250 242 242 242 242 242 242
+250 250 250 242 242 242 242 242 242 250 250 250
+182 182 182 190 190 190 206 206 206 141 141 141
+ 26  26  26  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  50  50  50
+170 170 170 166 166 166 128 128 128 250 250 250
+242 242 242 250 250 250 250 250 250 242 242 242
+250 250 250 242 242 242 242 242 242 250 250 250
+242 242 242 250 250 250 250 250 250 250 250 250
+250 250 250 250 250 250 242 242 242 250 250 250
+242 242 242 250 250 250 242 242 242 250 250 250
+250 250 250 242 242 242 250 250 250 250 250 250
+242 242 242 250 250 250 250 250 250 250 250 250
+242 242 242 242 242 242 250 250 250 234 234 234
+250 250 250 242 242 242 242 242 242 250 250 250
+195 195 195 195 195 195 206 206 206 128 128 128
+ 42  42  42  14  14  14   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  50  50  50
+178 178 178 174 174 174 158 158 158 170 170 170
+162 162 162 170 170 170 170 170 170 162 162 162
+166 166 166 170 170 170 154 154 154 154 154 154
+178 178 178 162 162 162 166 166 166 166 166 166
+166 166 166 158 158 158 178 178 178 162 162 162
+170 170 170 174 174 174 178 178 178 178 178 178
+170 170 170 178 178 178 170 170 170 166 166 166
+170 170 170 182 182 182 187 187 187 178 178 178
+195 195 195 195 195 195 195 195 195 195 195 195
+187 187 187 195 195 195 178 178 178 195 195 195
+206 206 206 195 195 195 210 210 210 116 116 116
+ 58  58  58  22  22  22   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  50  50  50
+162 162 162 162 162 162 170 170 170 158 158 158
+162 162 162 158 158 158 162 162 162 166 166 166
+158 158 158 174 174 174 162 162 162 158 158 158
+170 170 170 166 166 166 166 166 166 174 174 174
+166 166 166 174 174 174 174 174 174 174 174 174
+174 174 174 182 182 182 166 166 166 187 187 187
+182 182 182 187 187 187 174 174 174 166 166 166
+166 166 166 187 187 187 182 182 182 158 158 158
+174 174 174 174 174 174 174 174 174 182 182 182
+182 182 182 182 182 182 178 178 178 195 195 195
+178 178 178 182 182 182 174 174 174  30  30  30
+ 78  78  78  30  30  30  10  10  10   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  34  34  34
+154 154 154 158 158 158 154 154 154 158 158 158
+154 154 154 166 166 166 162 162 162 178 178 178
+178 178 178 166 166 166 170 170 170 158 158 158
+170 170 170 178 178 178 178 178 178 187 187 187
+195 195 195 178 178 178 178 178 178 178 178 178
+162 162 162 187 187 187 166 166 166 178 178 178
+174 174 174 178 178 178 170 170 170 170 170 170
+174 174 174 170 170 170 187 187 187 178 178 178
+178 178 178 202 202 202 170 170 170 187 187 187
+178 178 178 182 182 182 174 174 174 190 190 190
+182 182 182 166 166 166 149 149 149   6   6   6
+ 86  86  86  46  46  46  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  50  50  50
+166 166 166 162 162 162 149 149 149 162 162 162
+158 158 158 170 170 170 158 158 158 158 158 158
+166 166 166 170 170 170 149 149 149 170 170 170
+158 158 158 174 174 174 166 166 166 166 166 166
+166 166 166 166 166 166 182 182 182 158 158 158
+158 158 158 174 174 174 170 170 170 158 158 158
+178 178 178 166 166 166 158 158 158 174 174 174
+170 170 170 166 166 166 174 174 174 166 166 166
+174 174 174 182 182 182 174 174 174 182 182 182
+174 174 174 178 178 178 187 187 187 206 206 206
+187 187 187 178 178 178 128 128 128   2   2   6
+ 74  74  74  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  10  10  10  26  26  26  42  42  42
+158 158 158 144 144 144 149 149 149 162 162 162
+149 149 149 170 170 170 170 170 170 170 170 170
+174 174 174 170 170 170 158 158 158 162 162 162
+170 170 170 162 162 162 170 170 170 170 170 170
+162 162 162 162 162 162 170 170 170 170 170 170
+170 170 170 166 166 166 154 154 154 166 166 166
+154 154 154 162 162 162 170 170 170 149 149 149
+170 170 170 144 144 144 187 187 187 170 170 170
+170 170 170 195 195 195 187 187 187 202 202 202
+198 198 198 182 182 182 202 202 202 210 210 210
+187 187 187 178 178 178 106 106 106   2   2   6
+ 42  42  42  74  74  74  30  30  30  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  42  42  42  42  42  42
+158 158 158 141 141 141 162 162 162 149 149 149
+154 154 154 158 158 158 166 166 166 174 174 174
+162 162 162 158 158 158 162 162 162 158 158 158
+158 158 158 158 158 158 166 166 166 166 166 166
+158 158 158 158 158 158 158 158 158 166 166 166
+166 166 166 170 170 170 182 182 182 187 187 187
+166 166 166 174 174 174 166 166 166 154 154 154
+174 174 174 174 174 174 166 166 166 190 190 190
+ 34  34  34   2   2   6  18  18  18   2   2   6
+ 34  34  34   2   2   6  18  18  18  78  78  78
+182 182 182 178 178 178  78  78  78   2   2   6
+ 10  10  10  86  86  86  38  38  38  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 10  10  10  26  26  26  66  66  66  30  30  30
+138 138 138 144 144 144 154 154 154 149 149 149
+154 154 154 154 154 154 154 154 154 166 166 166
+162 162 162 158 158 158 162 162 162 154 154 154
+170 170 170 154 154 154 178 178 178 162 162 162
+162 162 162 170 170 170 162 162 162 154 154 154
+  2   2   6   2   2   6  34  34  34  42  42  42
+ 42  42  42  34  34  34  22  18   6  34  34  34
+ 42  42  42  42  42  42  66  66  66  34  34  34
+128 128 128  10  10  10  10  10  10  18  18  18
+ 18  18  18  10  10  10  26  26  26 174 174 174
+187 187 187 138 138 138  34  34  34   2   2   6
+  6   6   6  86  86  86  46  46  46  14  14  14
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 18  18  18  46  46  46  86  86  86   6   6   6
+110 110 110 162 162 162 149 149 149 144 144 144
+149 149 149 166 166 166 149 149 149 162 162 162
+149 149 149 162 162 162 149 149 149 158 158 158
+166 166 166 158 158 158 158 158 158 166 166 166
+166 166 166 149 149 149 158 158 158 166 166 166
+128 128 128  18  18  18   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  22  18   6  26  26  26
+ 18  18  18   6   6   6  18  18  18 166 166 166
+174 174 174 110 110 110  18  18  18   2   2   6
+  2   2   6  82  82  82  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 26  26  26  66  66  66  62  62  62   2   2   6
+ 46  46  46 141 141 141 166 166 166 144 144 144
+154 154 154 170 170 170 158 158 158 162 162 162
+149 149 149 162 162 162 154 154 154 154 154 154
+162 162 162 144 144 144 162 162 162 154 154 154
+170 170 170 144 144 144 154 154 154 170 170 170
+116 116 116 144 144 144 110 110 110 116 116 116
+110 110 110 144 144 144 116 116 116 128 128 128
+134 134 134 116 116 116 134 134 134 149 149 149
+158 158 158 231 231 231 234 234 234 214 214 214
+202 202 202 195 195 195 166 166 166 144 144 144
+144 144 144  34  34  34   2   2   6   2   2   6
+  2   2   6  66  66  66  58  58  58  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  78  78  78   6   6   6   2   2   6
+ 14  14  14 123 123 123 138 138 138  90  90  90
+110 110 110 128 128 128 154 154 154 149 149 149
+144 144 144 149 149 149 158 158 158 149 149 149
+166 166 166 158 158 158 158 158 158 166 166 166
+158 158 158 158 158 158 158 158 158 158 158 158
+144 144 144 170 170 170 162 162 162 170 170 170
+187 187 187 174 174 174 170 170 170 170 170 170
+162 162 162 170 170 170 170 170 170 178 178 178
+187 187 187 190 190 190 170 170 170 149 149 149
+149 149 149 138 138 138 170 170 170 116 116 116
+ 18  18  18   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  62  62  62  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50  74  74  74   2   2   6   2   2   6
+ 14  14  14  94  94  94 134 134 134  74  74  74
+ 50  50  50 158 158 158 154 154 154 166 166 166
+162 162 162 170 170 170 162 162 162 178 178 178
+170 170 170 154 154 154 162 162 162 154 154 154
+154 154 154 154 154 154 170 170 170 141 141 141
+149 149 149 166 166 166 166 166 166 166 166 166
+178 178 178 174 174 174 158 158 158 174 174 174
+174 174 174 174 174 174 174 174 174 158 158 158
+166 166 166 166 166 166 170 170 170 170 170 170
+170 170 170 162 162 162  82  82  82  10  10  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  62  62  62  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 54  54  54  62  62  62   2   2   6   2   2   6
+  2   2   6  34  34  34 123 123 123  18  18  18
+ 22  18   6 128 128 128 149 149 149 154 154 154
+158 158 158 158 158 158 149 149 149 166 166 166
+166 166 166 158 158 158 158 158 158 182 182 182
+158 158 158 149 149 149 149 149 149 178 178 178
+162 162 162 170 170 170 170 170 170 170 170 170
+174 174 174 178 178 178 170 170 170 178 178 178
+170 170 170 178 178 178 178 178 178 162 162 162
+174 174 174 170 170 170 166 166 166 166 166 166
+141 141 141  50  50  50  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  58  58  58  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 58  58  58  62  62  62   2   2   6   2   2   6
+  2   2   6   2   2   6  38  38  38 144 144 144
+178 178 178 162 162 162 134 134 134 154 154 154
+154 154 154 154 154 154 154 154 154 170 170 170
+154 154 154 154 154 154 162 162 162 170 170 170
+162 162 162 154 154 154 158 158 158 174 174 174
+149 149 149 166 166 166 174 174 174 178 178 178
+174 174 174 174 174 174 166 166 166 174 174 174
+166 166 166 166 166 166 166 166 166 166 166 166
+170 170 170 170 170 170 166 166 166 138 138 138
+ 42  42  42  34  34  34  18  14   6  22  22  22
+ 26  26  26  18  18  18   6   6   6   2   2   6
+  2   2   6  82  82  82  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  26  26  26
+ 62  62  62 106 106 106  74  54  14 185 133  11
+210 162  10 121  92   8   6   6   6  78  78  78
+154 154 154 149 149 149 141 141 141 149 149 149
+149 149 149 149 149 149 158 158 158 141 141 141
+149 149 149 141 141 141 158 158 158 149 149 149
+149 149 149 149 149 149 162 162 162 170 170 170
+154 154 154 170 170 170 162 162 162 166 166 166
+170 170 170 170 170 170 170 170 170 162 162 162
+162 162 162 170 170 170 170 170 170 170 170 170
+170 170 170 162 162 162 162 162 162  38  38  38
+ 14  14  14   2   2   6   2   2   6   2   2   6
+  6   6   6  18  18  18  66  66  66  38  38  38
+  6   6   6  94  94  94  50  50  50  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 10  10  10  10  10  10  18  18  18  38  38  38
+ 78  78  78 142 134 106 216 158  10 242 186  14
+246 190  14 246 190  14 156 118  10  10  10  10
+116 116 116 182 182 182 138 138 138 154 154 154
+154 154 154 138 138 138 162 162 162 170 170 170
+178 178 178 138 138 138 162 162 162 162 162 162
+162 162 162 158 158 158 149 149 149 174 174 174
+134 134 134 174 174 174 170 170 170 158 158 158
+158 158 158 174 174 174 141 141 141 174 174 174
+149 149 149 166 166 166 158 158 158 174 174 174
+141 141 141 178 178 178 175 146  61  37  26   9
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  38  38  38  46  46  46
+ 26  26  26 106 106 106  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  22  22  22
+ 30  30  30  38  38  38  50  50  50  70  70  70
+106 106 106 190 142  34 226 170  11 242 186  14
+246 190  14 246 190  14 246 190  14 154 114  10
+  6   6   6  74  74  74 226 226 226 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 231 231 231 250 250 250
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 228 184  62
+241 196  14 241 208  19 232 195  16  38  30  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  30  30  30  26  26  26
+203 166  17 154 142  90  66  66  66  26  26  26
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  38  38  38  58  58  58
+ 78  78  78  86  86  86 101 101 101 123 123 123
+175 146  61 210 150  10 234 174  13 246 186  14
+246 190  14 246 190  14 246 190  14 238 190  10
+102  78  10   2   2   6  46  46  46 198 198 198
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 234 234 234 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 224 178  62
+242 186  14 241 196  14 210 166  10  22  18   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   6   6   6 121  92   8
+238 202  15 232 195  16  82  82  82  34  34  34
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 14  14  14  38  38  38  70  70  70 154 122  46
+190 142  34 200 144  11 197 138  11 197 138  11
+213 154  11 226 170  11 242 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+225 175  15  46  32   6   2   2   6  22  22  22
+158 158 158 250 250 250 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 250 250 250 242 242 242 224 178  62
+239 182  13 236 186  11 213 154  11  46  32   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  61  42   6 225 175  15
+238 190  10 236 186  11 112 100  78  42  42  42
+ 14  14  14   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 22  22  22  54  54  54 154 122  46 213 154  11
+226 170  11 230 174  11 226 170  11 226 170  11
+236 178  12 242 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+241 196  14 184 144  12  10  10  10   2   2   6
+  6   6   6 116 116 116 242 242 242 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 231 231 231 198 198 198 214 170  54
+236 178  12 236 178  12 210 150  10 137  92   6
+ 18  14   6   2   2   6   2   2   6   2   2   6
+  6   6   6  70  47   6 200 144  11 236 178  12
+239 182  13 239 182  13 124 112  88  58  58  58
+ 22  22  22   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  70  70  70 180 133  36 226 170  11
+239 182  13 242 186  14 242 186  14 246 186  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 232 195  16  98  70   6   2   2   6
+  2   2   6   2   2   6  66  66  66 221 221 221
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 206 206 206 198 198 198 214 166  58
+230 174  11 230 174  11 216 158  10 192 133   9
+163 110   8 116  81   8 102  78  10 116  81   8
+167 114   7 197 138  11 226 170  11 239 182  13
+242 186  14 242 186  14 162 146  94  78  78  78
+ 34  34  34  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 30  30  30  78  78  78 190 142  34 226 170  11
+239 182  13 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 241 196  14 203 166  17  22  18   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+218 218 218 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 206 206 206 198 198 198 202 162  69
+226 170  11 236 178  12 224 166  10 210 150  10
+200 144  11 197 138  11 192 133   9 197 138  11
+210 150  10 226 170  11 242 186  14 246 190  14
+246 190  14 246 186  14 225 175  15 124 112  88
+ 62  62  62  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78 174 135  50 224 166  10
+239 182  13 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 241 196  14 139 102  15
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 78  78  78 250 250 250 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 214 214 214 198 198 198 190 150  46
+219 162  10 236 178  12 234 174  13 224 166  10
+216 158  10 213 154  11 213 154  11 216 158  10
+226 170  11 239 182  13 246 190  14 246 190  14
+246 190  14 246 190  14 242 186  14 206 162  42
+101 101 101  58  58  58  30  30  30  14  14  14
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  74  74  74 174 135  50 216 158  10
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 241 196  14 226 184  13
+ 61  42   6   2   2   6   2   2   6   2   2   6
+ 22  22  22 238 238 238 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 226 226 226 187 187 187 180 133  36
+216 158  10 236 178  12 239 182  13 236 178  12
+230 174  11 226 170  11 226 170  11 230 174  11
+236 178  12 242 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 186  14 239 182  13
+206 162  42 106 106 106  66  66  66  34  34  34
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 26  26  26  70  70  70 163 133  67 213 154  11
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 241 196  14
+190 146  13  18  14   6   2   2   6   2   2   6
+ 46  46  46 246 246 246 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 221 221 221  86  86  86 156 107  11
+216 158  10 236 178  12 242 186  14 246 186  14
+242 186  14 239 182  13 239 182  13 242 186  14
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+242 186  14 225 175  15 142 122  72  66  66  66
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 26  26  26  70  70  70 163 133  67 210 150  10
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+232 195  16 121  92   8  34  34  34 106 106 106
+221 221 221 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+242 242 242  82  82  82  18  14   6 163 110   8
+216 158  10 236 178  12 242 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 242 186  14 163 133  67
+ 46  46  46  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78 163 133  67 210 150  10
+236 178  12 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+241 196  14 215 174  15 190 178 144 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 218 218 218
+ 58  58  58   2   2   6  22  18   6 167 114   7
+216 158  10 236 178  12 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 186  14 242 186  14 190 150  46
+ 54  54  54  22  22  22   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 38  38  38  86  86  86 180 133  36 213 154  11
+236 178  12 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 232 195  16 190 146  13 214 214 214
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 250 250 250 170 170 170  26  26  26
+  2   2   6   2   2   6  37  26   9 163 110   8
+219 162  10 239 182  13 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 236 178  12 224 166  10 142 122  72
+ 46  46  46  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 109 106  95 192 133   9 224 166  10
+242 186  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+242 186  14 226 184  13 210 162  10 142 110  46
+226 226 226 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+198 198 198  66  66  66   2   2   6   2   2   6
+  2   2   6   2   2   6  50  34   6 156 107  11
+219 162  10 239 182  13 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 242 186  14
+234 174  13 213 154  11 154 122  46  66  66  66
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 58  58  58 154 121  60 206 145  10 234 174  13
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 236 178  12 210 162  10 163 110   8
+ 61  42   6 138 138 138 218 218 218 250 250 250
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 210 210 210 144 144 144  66  66  66
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  61  42   6 163 110   8
+216 158  10 236 178  12 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 239 182  13 230 174  11 216 158  10
+190 142  34 124 112  88  70  70  70  38  38  38
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 62  62  62 168 124  44 206 145  10 224 166  10
+236 178  12 239 182  13 242 186  14 242 186  14
+246 186  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 236 178  12 216 158  10 175 118   6
+ 80  54   7   2   2   6   6   6   6  30  30  30
+ 54  54  54  62  62  62  50  50  50  38  38  38
+ 14  14  14   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  80  54   7 167 114   7
+213 154  11 236 178  12 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 242 186  14 239 182  13 239 182  13
+230 174  11 210 150  10 174 135  50 124 112  88
+ 82  82  82  54  54  54  34  34  34  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 158 118  36 192 133   9 200 144  11
+216 158  10 219 162  10 224 166  10 226 170  11
+230 174  11 236 178  12 239 182  13 239 182  13
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 230 174  11 210 150  10 163 110   8
+104  69   6  10  10  10   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  91  60   6 167 114   7
+206 145  10 230 174  11 242 186  14 246 190  14
+246 190  14 246 190  14 246 186  14 242 186  14
+239 182  13 230 174  11 224 166  10 213 154  11
+180 133  36 124 112  88  86  86  86  58  58  58
+ 38  38  38  22  22  22  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 34  34  34  70  70  70 138 110  50 158 118  36
+167 114   7 180 123   7 192 133   9 197 138  11
+200 144  11 206 145  10 213 154  11 219 162  10
+224 166  10 230 174  11 239 182  13 242 186  14
+246 186  14 246 186  14 246 186  14 246 186  14
+239 182  13 216 158  10 185 133  11 152  99   6
+104  69   6  18  14   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  80  54   7 152  99   6
+192 133   9 219 162  10 236 178  12 239 182  13
+246 186  14 242 186  14 239 182  13 236 178  12
+224 166  10 206 145  10 192 133   9 154 121  60
+ 94  94  94  62  62  62  42  42  42  22  22  22
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 18  18  18  34  34  34  58  58  58  78  78  78
+101  98  89 124 112  88 142 110  46 156 107  11
+163 110   8 167 114   7 175 118   6 180 123   7
+185 133  11 197 138  11 210 150  10 219 162  10
+226 170  11 236 178  12 236 178  12 234 174  13
+219 162  10 197 138  11 163 110   8 130  83   6
+ 91  60   6  10  10  10   2   2   6   2   2   6
+ 18  18  18  38  38  38  38  38  38  38  38  38
+ 38  38  38  38  38  38  38  38  38  38  38  38
+ 38  38  38  38  38  38  26  26  26   2   2   6
+  2   2   6   6   6   6  70  47   6 137  92   6
+175 118   6 200 144  11 219 162  10 230 174  11
+234 174  13 230 174  11 219 162  10 210 150  10
+192 133   9 163 110   8 124 112  88  82  82  82
+ 50  50  50  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  22  22  22  34  34  34
+ 42  42  42  58  58  58  74  74  74  86  86  86
+101  98  89 122 102  70 130  98  46 121  87  25
+137  92   6 152  99   6 163 110   8 180 123   7
+185 133  11 197 138  11 206 145  10 200 144  11
+180 123   7 156 107  11 130  83   6 104  69   6
+ 50  34   6  54  54  54 110 110 110 101  98  89
+ 86  86  86  82  82  82  78  78  78  78  78  78
+ 78  78  78  78  78  78  78  78  78  78  78  78
+ 78  78  78  82  82  82  86  86  86  94  94  94
+106 106 106 101 101 101  86  66  34 124  80   6
+156 107  11 180 123   7 192 133   9 200 144  11
+206 145  10 200 144  11 192 133   9 175 118   6
+139 102  15 109 106  95  70  70  70  42  42  42
+ 22  22  22  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  10  10  10
+ 14  14  14  22  22  22  30  30  30  38  38  38
+ 50  50  50  62  62  62  74  74  74  90  90  90
+101  98  89 112 100  78 121  87  25 124  80   6
+137  92   6 152  99   6 152  99   6 152  99   6
+138  86   6 124  80   6  98  70   6  86  66  30
+101  98  89  82  82  82  58  58  58  46  46  46
+ 38  38  38  34  34  34  34  34  34  34  34  34
+ 34  34  34  34  34  34  34  34  34  34  34  34
+ 34  34  34  34  34  34  38  38  38  42  42  42
+ 54  54  54  82  82  82  94  86  76  91  60   6
+134  86   6 156 107  11 167 114   7 175 118   6
+175 118   6 167 114   7 152  99   6 121  87  25
+101  98  89  62  62  62  34  34  34  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6   6   6   6  10  10  10
+ 18  18  18  22  22  22  30  30  30  42  42  42
+ 50  50  50  66  66  66  86  86  86 101  98  89
+106  86  58  98  70   6 104  69   6 104  69   6
+104  69   6  91  60   6  82  62  34  90  90  90
+ 62  62  62  38  38  38  22  22  22  14  14  14
+ 10  10  10  10  10  10  10  10  10  10  10  10
+ 10  10  10  10  10  10   6   6   6  10  10  10
+ 10  10  10  10  10  10  10  10  10  14  14  14
+ 22  22  22  42  42  42  70  70  70  89  81  66
+ 80  54   7 104  69   6 124  80   6 137  92   6
+134  86   6 116  81   8 100  82  52  86  86  86
+ 58  58  58  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  10  10  10  14  14  14
+ 18  18  18  26  26  26  38  38  38  54  54  54
+ 70  70  70  86  86  86  94  86  76  89  81  66
+ 89  81  66  86  86  86  74  74  74  50  50  50
+ 30  30  30  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  34  34  34  58  58  58
+ 82  82  82  89  81  66  89  81  66  89  81  66
+ 94  86  66  94  86  76  74  74  74  50  50  50
+ 26  26  26  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6   6   6   6  14  14  14  18  18  18
+ 30  30  30  38  38  38  46  46  46  54  54  54
+ 50  50  50  42  42  42  30  30  30  18  18  18
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  26  26  26
+ 38  38  38  50  50  50  58  58  58  58  58  58
+ 54  54  54  42  42  42  30  30  30  18  18  18
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+  6   6   6  10  10  10  14  14  14  18  18  18
+ 18  18  18  14  14  14  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 14  14  14  18  18  18  22  22  22  22  22  22
+ 18  18  18  14  14  14  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
diff -Nru a/drivers/video/logo/logo_parisc_clut224.ppm b/drivers/video/logo/logo_parisc_clut224.ppm
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/logo_parisc_clut224.ppm	Mon Feb 24 13:47:01 2003
@@ -0,0 +1,1604 @@
+P3
+# 224-color PA-RISC Linux logo
+80 80
+255
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   6   6   7   6   6   7
+   6   6   7   6   6   7   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   6   6   7  22  22  23
+  46  46  47  58  58  59  70  70  71  82  82  82
+  82  82  82  66  66  67  54  54  55  38  38  39
+  22  22  23   6   6   7   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   6   6   7  29  30  31  70  70  71 119 122 130
+ 166 166 167 191 191 190 198 198 200 206 206 206
+ 206 206 206 194 194 195 182 182 182 158 158 158
+ 119 119 118  70  70  71  29  30  31  10  10  11
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  14  14  15
+  54  54  55 126 126 127 191 191 190 226 226 226
+ 202 202 202 130 130 132 126 126 127 100 100 102
+ 100 100 102 119 122 130 163 162 161 202 202 202
+ 226 226 226 191 191 190 134 134 134  74  74  74
+  26  26  28   6   6   7   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  18  18  18  74  74  74
+ 158 158 158 222 222 223 182 182 182  63  62  63
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  63  62  63 166 166 167 230 230 231 191 191 190
+ 119 119 118  46  46  47  10  10  11   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2  10  10  11  66  66  67 166 166 167
+ 222 222 223 112 112 112   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  46  46  47 194 194 195
+ 214 214 215 140 140 141  54  54  55  10  10  11
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2  38  38  39 140 140 141 226 226 226
+  90  90  90   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  10  10  11
+  33  34  35  22  22  23   2   2   2   6   6   7
+ 140 140 141 222 222 223 140 140 141  42  42  43
+   6   6   7   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  14  14  15  86  86  86 202 202 202 146 146 146
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  26  26  28
+ 100 100 102 112 112 112  42  42  43   2   2   2
+   2   2   2 163 162 161 210 210 210 105 107 112
+  22  22  23   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  33  34  35 146 146 146 226 226 226  33  34  35
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  29  30  31
+ 119 119 118 130 130 132  70  70  71  26  26  28
+   2   2   2  10  10  11 206 206 206 178 177 177
+  63  62  63   6   6   7   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   6   6   7
+  70  70  71 191 191 190 163 162 161   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  29  30  31
+  78  78  79  63  62  63  29  30  31  18  18  18
+   2   2   2   2   2   2  86  86  86 222 222 223
+ 119 119 118  22  22  23   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  14  14  15
+ 100 100 102 218 218 219  70  70  71   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  10  10  11
+  14  14  15   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   6   6   7 198 198 200
+ 171 170 167  54  54  55   6   6   7   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  22  22  23
+ 126 126 127 230 230 231  22  22  23   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2 112 112 112
+ 206 206 206  86  86  86  10  10  11   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  29  30  31
+ 146 146 146 210 210 210   6   6   7   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  38  38  39
+ 226 226 226 119 119 118  18  18  18   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  33  34  35
+ 150 150 151 202 202 202   2   2   2   2   2   2
+   2   2   2   2   2   2  22  22  23  26  26  28
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   6   6   7  54  54  55   6   6   7   2   2   2
+   2   2   2   2   2   2   2   2   2  18  18  18
+ 226 226 226 140 140 141  26  26  28   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  33  34  35
+ 150 150 151 202 202 202   2   2   2   2   2   2
+  10  10  11  78  78  79  54  54  55  14  14  15
+  18  18  18   2   2   2   2   2   2   2   2   2
+   2   2   2  54  54  55 130 130 132 171 170 167
+ 130 130 132  14  14  15  29  30  31   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+ 198 198 200 155 153 152  33  34  35   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  33  34  35
+ 150 150 151 202 202 202   2   2   2   2   2   2
+ 134 134 134 222 222 223 214 214 215  90  90  90
+   2   2   2   2   2   2   2   2   2   2   2   2
+  70  70  71 182 182 182 218 218 219 237 238 239
+ 241 242 244 140 140 141   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+ 202 202 202 166 166 167  42  42  43   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  33  34  35
+ 150 150 151 202 202 202   2   2   2  38  38  39
+ 234 234 235 254 254 254 254 254 254 254 254 254
+  29  30  31   2   2   2   2   2   2   2   2  10
+ 218 218 219 254 254 254 254 254 254 210 210 210
+ 254 254 254 249 250 251  54  54  55   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+ 140 140 141 178 177 177  54  54  55   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  33  34  35
+ 150 150 151 202 202 202   2   2   2 105 107 112
+ 237 238 239  29  30  31 105 107 112 254 254 254
+ 119 122 130   2   2   2   2   2   2  29  30  31
+ 254 254 254 249 250 251   6   6   7  58  58  59
+ 112 112 112 254 254 254 166 166 167   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+ 140 140 141 182 182 182  54  54  55   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  29  30  31
+ 146 146 146 198 198 200   2   2   2 126 126 127
+ 126 126 127   2   2   2  78  78  79 178 182 190
+ 150 150 151   2   2  10  26  26  28  42  42  43
+ 254 254 254 119 122 130   2   2   2   2   2  10
+  54  54  55 226 226 226 230 230 231   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+ 140 140 141 182 182 182  54  54  55   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  26  26  28
+ 134 134 134 234 234 235  22  22  23 119 119 118
+ 130 130 132   2   2   2   6  10  24 122 126 140
+  86  86  86  42  30   2  45  26   2  23  14   2
+ 184 186 195 100 100 102   2   2   2   2   2   2
+   2   2   2 210 210 210 234 234 235   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+ 140 140 141 187 187 186  58  58  59   6   6   7
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  18  18  18
+ 119 119 118 230 230 231  22  22  23  70  70  71
+ 222 222 223   2   2   2   2   2   2 138  98  18
+ 236 174   8 254 198   2 246 190  13 202 152   2
+ 214 170  26 162 138  86   2   2   2   2   2   2
+  12  14  26 254 254 254 183 186 190   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+ 146 146 146 194 194 195  70  70  71   6   6   7
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  18  18  18
+ 112 112 112 226 226 226  22  22  23   6   6   7
+ 249 250 251 167 155 134 186 124   4 234 170   6
+ 254 198   2 253 202   2 253 207   3 238 198  14
+ 254 212  22 254 216  14 218 173   2 118  90   6
+ 210 210 210 254 254 254  63  62  63   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  82  82  82 206 206 206  82  82  82  10  10  11
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  18  18  18
+ 112 112 112 226 226 226  22  22  23   2   2   2
+ 122 106  82 207 143  12 234 170   6 254 194   2
+ 254 198   2 253 207   3 252 218   6 254 234  42
+ 254 234  66 254 234  42 254 233   7 254 226   4
+ 253 207   3 228 176  28  70  46   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  82  82  82 214 214 215  94  94  95  10  10  11
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  18  18  18
+ 112 112 112 226 226 226  38  38  39  23  14   2
+ 186 124   4 221 154   6 248 183   3 254 198   2
+ 253 202   2 250 214   3 254 222   7 254 230  70
+ 254 234  66 254 233   7 254 233   7 254 236  14
+ 254 226   4 254 212  22 214 162   3   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  54  54  55 226 226 226 119 119 118  22  22  23
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  10  10  11
+  94  94  95 214 214 215  86  86  86 100  63   4
+ 206 137   3 238 167   5 254 190  11 254 198   2
+ 253 207   3 252 218   6 254 226  46 254 232  58
+ 254 233   7 254 233   7 254 233   7 226 190   2
+ 202 152   2 231 166   7 175 127   3   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  10  10  11 222 222 223 163 162 161  46  46  47
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  10  10  11
+  82  82  82 210 210 210  86  86  86  42  30   2
+ 174 119   4 248 183   3 254 194   2 253 202   2
+ 253 207   3 254 222   7 254 226  46 254 226   4
+ 254 222   7 238 202   2 190 145   2 207 143  12
+ 226 160   6 238 167   5 138  98  18   2   2   2
+   2   2   2  22  22  23   2   2   2   2   2   2
+   2   2   2 130 130 132 202 202 202  82  82  82
+  10  10  11   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  10  10  11
+  82  82  82 210 210 210  86  86  86   2   2   2
+  89  59   3 156 110   2 241 183   7 253 207   3
+ 253 224  28 254 222   7 250 214   3 218 173   2
+ 175 127   3 166 110  10 211 145   3 226 160   6
+ 221 154   6 204 154  50  63  62  63   2   2   2
+   2   2   2  94  94  95 100 100 102  33  34  35
+   2   2   2  50  50  51 230 230 231 140 140 141
+  33  34  35   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  14  14  15
+  94  94  95 214 214 215  86  86  86   2   2   2
+ 119 122 130 162 138  86 142  90   5 174 119   4
+ 190 145   2 175 127   3 170 112   4 186 124   4
+ 202 130   2 206 137   3 202 130   2 187 145  53
+ 194 186 174 204 208 219 178 177 177   2   2   2
+   2   2   2  18  18  18 140 140 141 130 130 132
+  14  14  15   2   2   2 178 177 177 198 198 200
+  86  86  86  14  14  15   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  33  34  35
+ 134 134 134 230 230 231  54  54  55   2   2   2
+ 146 146 146 202 202 202 164 124  56 156 101   3
+ 213 150   7 211 145   3 206 137   3 198 126   2
+ 180 114   4 182 118   3 182 158 114 188 190 198
+ 204 208 219 230 230 231 214 214 215  33  34  35
+   2   2   2   2   2   2  78  78  79  94  94  95
+   6   6   7   2   2   2  29  30  31 226 226 226
+ 150 150 151  42  42  43   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  14  14  15  82  82  82
+ 194 194 195 187 187 186   6   6   7   2   2   2
+ 140 140 141 204 208 219 194 194 195 163 143 109
+ 148  89   3 148  89   3 148  89   3 148  89   3
+ 164 124  56 184 176 158 184 186 195 204 208 219
+ 254 254 254 254 254 254 254 254 254 158 158 158
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2 140 140 141
+ 206 206 206 100 100 102  18  18  18   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   6   6   7  54  54  55 158 158 158
+ 226 226 226  50  50  51   2   2   2   2   2   2
+ 234 234 235 230 234 235 198 198 200 190 194 210
+ 184 186 195 174 162 150 174 162 150 178 177 177
+ 183 186 190 188 190 198 204 208 219 245 246 248
+ 254 254 254 254 254 254 254 254 254 254 254 254
+  38  38  39   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  29  30  31
+ 218 218 219 171 170 167  58  58  59   6   6   7
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   6   6   7  38  38  39 134 134 134 222 222 223
+ 120 112 108   2   2   2   2   2   2 150 150 151
+ 254 254 254 254 254 254 210 210 210 188 190 198
+ 188 190 198 184 186 195 183 186 190 183 186 190
+ 194 194 195 222 222 223 249 250 251 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 194 194 195   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+ 100 100 102 222 222 223 119 122 130  29  30  31
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  26  26  28 112 112 112 206 206 206 171 170 167
+   6   6   7   2   2   2  46  46  47 254 254 254
+ 254 254 254 254 254 254 241 242 244 188 190 198
+ 187 187 186 183 186 190 183 186 190 206 206 206
+ 241 242 244 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254  46  46  47   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   6   6   7 194 194 195 194 194 195  90  90  90
+  18  18  18   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  18  18  18
+  86  86  86 191 191 190 206 206 206  26  26  28
+   2   2   2   2   2   2 206 206 206 254 254 254
+ 254 254 254 254 254 254 254 254 254 245 246 248
+ 218 218 219 218 218 219 234 234 235 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 171 170 167   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2  46  46  47 226 226 226 178 177 177
+  74  74  74  14  14  15   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  14  14  15  70  70  71
+ 171 170 167 226 226 226  46  46  47   2   2   2
+   2   2   2  74  74  74 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 249 250 251   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  63  62  63 234 234 235
+ 163 162 161  66  66  67  14  14  15   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   6   6   7  54  54  55 155 153 152
+ 230 230 231  82  82  82   2   2   2   2   2   2
+   2   2   2 194 194 195 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254  26  26  28   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2 112 112 112
+ 230 230 231 155 153 152  58  58  59   6   6   7
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2  29  30  31 126 126 127 222 222 223
+ 112 112 112   2   2   2   2   2   2   2   2   2
+  14  14  15 218 218 219 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 249 250 251 249 250 251 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 250 254 254 254  90  90  90   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+ 112 112 112 222 222 223 134 134 134  38  38  39
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  10  10  11  74  74  74 191 191 190 182 182 182
+   6   6   7   2   2   2   2   2   2   2   2   2
+  46  46  47 182 182 182 234 234 235 254 254 254
+ 254 254 254 254 254 254 254 254 254 234 234 235
+ 222 222 223 222 222 223 237 238 239 249 250 251
+ 249 250 251 249 250 251 249 250 251 230 230 231
+ 222 222 223 218 218 219 214 214 215 210 210 210
+ 210 210 210 222 222 223 163 162 161   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   6   6   7 163 162 161 202 202 202  90  90  90
+  14  14  15   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  29  30  31 134 134 134 230 230 231  50  50  51
+   2   2   2   2   2   2   2   2   2   2   2   2
+  78  78  79 178 177 177 214 214 215 241 242 244
+ 254 254 254 254 254 254 254 254 254 254 254 250
+ 226 226 226 245 246 248 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 250 241 242 244
+ 222 222 223 206 206 206 198 198 200 194 194 195
+ 194 194 195 198 198 200 234 234 235 119 119 118
+   2   2   2   2   2   2  29  30  31   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2  26  26  28 222 222 223 150 150 151
+  38  38  39   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   6   6   7
+  58  58  59 178 177 177 171 170 167   2   2   2
+   2   2   2   2   2   2   2   2   2   6   6   7
+ 150 150 151 234 234 235 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 250
+ 237 238 239 254 254 254 254 254 250 254 254 250
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 237 238 239
+ 222 222 223 206 206 206 210 210 210 249 250 251
+  46  46  47   2   2   2   2   2   2  38  38  39
+  10  10  11   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2 150 150 151 198 198 200
+  82  82  82  10  10  11   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  10  10  11
+  86  86  86 210 210 210 112 112 112   2   2   2
+   2   2   2  18  18  18   2   2   2 112 112 112
+ 241 242 244 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 250 254 254 250 254 254 250 254 254 250
+ 254 254 250 254 254 250 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 234 234 235 226 226 226
+ 214 214 215   2   2   2   2   2   2   2   2   2
+  42  42  43  10  10  11   2   2   2   2   2   2
+   2   2   2   2   2   2  46  46  47 230 230 231
+ 134 134 134  29  30  31   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  26  26  28
+ 126 126 127 230 230 231  50  50  51   2   2   2
+  33  34  35   2   2   2  14  14  15 194 194 195
+ 254 254 254 254 254 254 245 246 248 254 254 254
+ 254 254 254 230 234 235 206 206 206 206 206 206
+ 206 206 206 206 206 206 154 206 206 154 206 206
+ 154 206 206 154 206 206 154 206 206 154 206 206
+ 154 206 206 102 154 154 102 154 154 166 174 186
+ 226 226 226 254 254 254 245 246 248 245 246 248
+ 245 246 248  70  70  71   2   2   2   2   2   2
+   2   2   2  38  38  39   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2 178 177 177
+ 178 177 177  58  58  59   6   6   7   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  50  50  51
+ 166 166 167 210 210 210   6   6   7   6   6   7
+  14  14  15   2   2   2 134 134 134 237 238 239
+ 249 250 251 254 254 254 254 254 254 254 254 254
+ 254 254 254 102 154 154   2 102 102   2 102 154
+   2 102 102   2 102 102   2 102 102   2 102 102
+   2 102 102   2 102 102   2 102 102   2 102 102
+   2 102 102   2 102 102   2 102 102  50 154 154
+ 234 234 235 254 254 254 254 254 254 254 254 254
+ 249 250 251 198 198 200   2   2   2  18  18  18
+  50  50  51  22  22  23  29  30  31   2   2   2
+   2   2   2   2   2   2   2   2   2 105 107 112
+ 214 214 215 100 100 102  14  14  15   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  10  10  11  86  86  86
+ 206 206 206 126 126 127   2   2   2  38  38  39
+   2   2   2   6   6   7 230 230 231 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 102 154 154   2 102 102   2 102 102
+   2 154 154  50 154 154 102 206 206 154 206 206
+ 206 206 206 230 234 235 206 206 206 154 206 206
+ 102 154 154   2 102 154   2 102 102  50 154 154
+ 245 246 248 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254  14  14  15  29  30  31
+  50  50  51  10  10  11  42  42  43   2   2   2
+   2   2   2   2   2   2   2   2   2  10  10  11
+ 226 226 226 150 150 151  33  34  35   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  29  30  31 134 134 134
+ 230 230 231  46  46  47   2   2   2  22  22  23
+   2   2   2  78  78  79 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254  50 154 154  50 154 154 154 206 206
+ 230 234 235 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 154 206 206   2 102 154   2 154 154
+ 241 242 244 254 254 254 249 250 251 254 254 254
+ 254 254 254 254 254 254  74  74  74   2   2   2
+   2   2   2   2   2   2  10  10  11  38  38  39
+   2   2   2   2   2   2   2   2   2   2   2   2
+ 166 166 167 191 191 190  66  66  67   6   6   7
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   6   6   7  66  66  67 182 182 182
+ 182 182 182   2   2   2  29  30  31   2   2   2
+   2   2   2 202 202 202 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 230 234 235
+ 102 154 154 154 206 206 230 234 235 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254  50 154 154   2 102 102
+ 206 206 206 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 140 140 141   2   2   2
+   2   2   2   2   2   2   2   2   2  46  46  47
+   2   2   2   2   2   2   2   2   2   2   2   2
+  90  90  90 214 214 215 100 100 102  14  14  15
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2  26  26  28 119 122 130 222 222 223
+  78  78  79   2   2   2  33  34  35   2   2   2
+  33  34  35 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 230 234 235 102 154 154
+ 206 206 206 254 254 254 254 254 254 254 254 254
+ 230 234 235 154 206 206 102 154 154  50 154 154
+  50 154 154  50 154 154  50 154 154 154 206 206
+ 230 234 235 254 254 254  50 154 154   2 102 102
+ 154 206 206 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 191 191 190   2   2   2
+   2   2   2   2   2   2   2   2   2  50  50  51
+   2   2   2   2   2   2   2   2   2   2   2   2
+  26  26  28 230 230 231 126 126 127  22  22  23
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  10  10  11  74  74  74 187 187 186 194 194 195
+   6   6   7   2   2   2  10  10  11   2   2   2
+ 130 130 132 254 254 254 254 254 254 254 254 254
+ 254 254 254 230 234 235 154 206 206 230 234 235
+ 254 254 254 254 254 254 154 206 206  50 154 154
+   2 102 154   2 102 154  50 154 154  50 154 154
+  50 154 154  50 154 154   2 102 102   2 102 102
+  50 154 154 206 206 206  50 154 154   2 102 102
+ 102 206 206 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 226 226 226   2   2   2
+   2   2   2   2   2   2   2   2   2  42  42  43
+   2   2   2   2   2   2   2   2   2   2   2   2
+   6   6   7 214 214 215 150 150 151  33  34  35
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  38  38  39 140 140 141 230 230 231  63  62  63
+   2   2   2  22  22  23   2   2   2   2   2   2
+ 210 210 210 254 254 254 254 254 254 254 254 254
+ 254 254 254 206 206 206 254 254 254 254 254 254
+ 154 206 206  50 154 154  50 154 154 102 154 206
+ 206 206 206 230 234 235 254 254 254 254 254 254
+ 254 254 254 230 234 235 206 206 206 102 154 154
+   2 102 102   2 102 154   2 102 154   2 102 102
+ 102 154 154 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 245 246 248   2   2   2
+   2   2   2   2   2   2   2   2   2  33  34  35
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2 194 194 195 171 170 167  46  46  47
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  14  14  15
+  90  90  90 202 202 202 150 150 151   2   2   2
+   2   2   2  29  30  31   2   2   2   2   2   2
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 230 234 235 102 154 154
+  50 154 154 154 206 206 230 234 235 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 102 154 206   2 102 102   2 102 154   2 102 102
+  50 154 154 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254   2   2   2
+   2   2   2   2   2   2   2   2   2  29  30  31
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2 134 134 134 187 187 186  58  58  59
+   6   6   7   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  29  30  31
+ 140 140 141 222 222 223  26  26  28   2   2   2
+   2   2   2  33  34  35   2   2   2  12  14  26
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 230 234 235 102 154 154 154 206 206
+ 254 254 254 254 254 254 230 234 235 254 254 254
+ 254 254 254 254 254 254 230 234 235 230 234 235
+ 230 234 235 254 254 254 254 254 254 254 254 254
+ 230 234 235   2 102 154   2 102 154   2 102 102
+  50 154 154 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254   2   2   2
+   2   2   2   2   2   2   6   6   7  18  18  18
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2 134 134 134 187 187 186  58  58  59
+   6   6   7   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  46  46  47
+ 171 170 167 194 194 195   2   2   2   2   2   2
+   2   2   2  58  58  59   6  10  24  33  34  35
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 230 234 235 102 154 206 230 234 235 254 254 254
+ 254 254 254 254 254 254 154 206 206 102 154 206
+  50 154 154  50 154 154   2 102 154   2 102 154
+   2 154 154  50 154 154 154 206 206 254 254 254
+ 230 234 235   2 154 154   2 102 154   2 102 154
+   2 154 154 230 234 235 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254   2   2   2
+   2   2   2   2   2   2  26  26  28   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2 134 134 134 187 187 186  58  58  59
+   6   6   7   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  58  58  59
+ 187 187 186 134 134 134   2   2   2   2   2   2
+   2   2   2  33  34  35  26  26  28  54  54  55
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 206 206 206 254 254 254 254 254 254 254 254 254
+ 154 206 206  50 154 154   2 102 154  50 154 154
+  50 154 154 102 154 154 102 154 154 102 154 154
+  50 154 154   2 102 102   2 102 102  50 154 154
+ 154 206 206   2 102 154   2 102 154   2 102 154
+   2 102 154 230 234 235 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254   2   2   2
+   2   2   2   2   2   2  26  26  28   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2 134 134 134 187 187 186  58  58  59
+   6   6   7   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   6   6   7  58  58  59
+ 187 187 186 134 134 134   2   2   2   2   2   2
+   2   2   2   2   2   2  12  14  26  54  54  55
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 154 206 206 102 154 154
+ 102 154 154 154 206 206 206 206 206 230 234 235
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 206 206 206  50 154 154   2 102 102
+   2 102 154   2 102 154   2 102 154   2 102 154
+   2 102 154 154 206 206 254 254 254 254 254 254
+ 254 254 254 254 254 254 237 238 239   2   2   2
+   2   2   2  26  26  28  14  14  15  14  14  15
+  12  14  26   2   2   2   2   2   2   2   2   2
+   2   2   2 163 162 161 182 182 182  54  54  55
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  54  54  55
+ 182 182 182 194 194 195  18   6   2 130  88   2
+ 162 122   2  55  34   3   2   2   2  62  66  80
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 230 234 235 102 154 154 102 154 154 230 234 235
+ 254 254 254 254 254 254 230 234 235 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254  50 154 154
+   2 102 102   2 102 102   2 102 102   2 102 102
+   2 102 102 102 206 206 254 254 254 254 254 254
+ 254 254 254 254 254 254 188 190 198   2   2   2
+   6   6   7   2   2   2   2   2   2   2   2   2
+   2   2  10  29  30  31  66  66  67  22  22  23
+   2   2   2 202 202 202 163 162 161  42  42  43
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   6   6   7
+  10  10  11  10  10  11  18  18  18  74  74  74
+ 194 194 195 222 222 223 226 162  16 254 212  22
+ 253 207   3 253 202   2  87  61  13   2   2   2
+ 130 130 132 254 254 254 254 254 254 230 234 235
+ 102 154 154 206 206 206 254 254 254 254 254 254
+ 254 254 254 254 254 254 230 234 235 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 206 206 206
+ 102 154 154 102 154 154 102 154 154  50 154 154
+  50 154 154 102 154 154 254 254 254 254 254 242
+ 254 230 154 254 234 162 150 126  70   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  38  38  39  62  66  80
+  10  10  11 241 242 244 158 158 158  42  42  43
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2  10  10  11  29  30  31  63  62  63
+  86  86  86  94  94  95 100 100 102 158 158 158
+ 230 230 231 186 150  74 248 183   3 254 202  13
+ 253 207   3 253 207   3 254 198   2  89  59   3
+   2   2   2 105 107 112 254 254 254 154 206 206
+ 230 234 235 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 230 234 235 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 230 234 235 230 234 235 254 254 254 242 190  58
+ 253 207   3 254 226   4 250 214   3  23  14   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  33  34  35  14  14  15
+ 170 142  50 218 218 219 194 194 195  78  78  79
+  10  10  11   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  10  10  11  58  58  59 134 134 134 187 187 186
+ 210 210 210 214 214 215 218 218 219 234 234 235
+ 184 176 158 218 159   3 254 186   7 254 202  13
+ 253 207   3 253 202   2 253 202   2 246 190  13
+  38  22   2   2   2   2  62  66  80 245 246 248
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 230 230 231 241 242 244
+ 254 254 254 254 254 254 254 254 250 254 254 250
+ 254 254 250 254 254 250 254 254 250 254 254 250
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 228 176  28
+ 254 186   7 253 207   3 234 190   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2  10  87  61  13
+ 254 236  14 238 230  54 230 230 231 130 130 132
+  26  26  28   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  42  42  43 146 146 146 226 226 226 184 176 158
+ 182 158 114 196 157  72 186 150  74 187 145  53
+ 213 150   7 236 174   8 254 194  14 254 202  13
+ 254 202  13 253 202   2 254 198   2 254 198   2
+ 214 162   3   2   2   2   2   2   2  12  14  26
+ 214 214 215 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 250
+ 254 254 250 254 254 250 254 254 250 254 254 250
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 226 174  56
+ 254 186   7 254 194   2 218 159   3   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   6   6   7 241 183   7
+ 254 222   7 254 222   7 194 194 195 155 153 152
+  33  34  35   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  10  10  11
+  86  86  86 206 206 206 179 164 133 234 170   6
+ 254 186   7 248 184  12 242 177   7 236 174   8
+ 248 184  12 254 190  11 254 198  13 254 198  13
+ 254 198  13 254 198   6 254 198   6 254 198   2
+ 253 207   3 142 102   2   2   2   2   2   2   2
+   2   2   2 166 166 167 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 250
+ 254 254 250 254 254 250 254 254 250 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 241 242 244 204 208 219 213 163  50
+ 248 183   3 254 186   7 221 154   6 100  63   4
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2 175 127   3 254 202  13
+ 254 212  22 254 212  22 194 194 195 166 166 167
+  42  42  43   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  18  18  18
+ 119 119 118 230 230 231 213 163  50 254 186   7
+ 254 202  13 254 202  13 254 198  13 254 194  14
+ 254 198  13 254 198  13 254 198  13 254 198  13
+ 254 198  13 254 198  13 254 198   6 254 194   9
+ 254 198   2 242 198   2  38  22   2   2   2   2
+   2   2   2   2   2   2 100 100 102 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 250
+ 254 254 250 254 254 250 254 254 250 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 204 208 219 190 194 210 213 163  50
+ 242 177   7 242 177   7 226 160   6 186 124   4
+ 118  76   2  55  34   3  45  26   2  55  34   3
+ 118  76   2 194 134  10 242 177   7 254 198  13
+ 254 206  18 254 206  18 191 191 190 198 198 200
+  86  86  86  18  18  18   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  18  18  18
+ 119 122 130 230 230 231 219 155  20 254 190  11
+ 254 202  13 254 206  18 254 202  13 254 202  13
+ 254 198  13 254 198  13 254 194  14 250 194  13
+ 250 194  13 254 194   9 254 194   9 254 198   6
+ 254 198   6 253 207   3 190 145   2   2   2   2
+   2   2   2   2   2   2   2   2   2  50  50  51
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 250
+ 254 254 250 254 254 250 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 204 208 219 190 198 214 204 154  50
+ 234 170   6 248 183   3 234 170   6 211 145   3
+ 206 137   3 194 131   6 194 131   6 194 134  10
+ 211 145   3 234 170   6 254 198  13 254 206  18
+ 254 206  18 254 206  18 222 182  66 222 222 223
+ 166 166 167  70  70  71  14  14  15   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  14  14  15
+ 105 107 112 222 222 223 196 157  72 248 183   3
+ 254 198  13 254 206  18 254 202  13 254 198  13
+ 254 194  14 250 194  13 250 194  13 250 194  13
+ 250 194  13 250 194  13 254 194   9 254 194   9
+ 254 198   6 254 198   6 253 207   3  82  58   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  86  86  86 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 214 214 215 190 198 214 187 145  53
+ 226 160   6 241 183   7 241 183   7 231 166   7
+ 218 159   3 221 154   6 221 154   6 218 159   3
+ 236 174   8 250 190  11 254 202  13 254 202  13
+ 254 206  18 254 202  13 254 202  13 190 167 108
+ 230 230 231 163 162 161  74  74  74  22  22  23
+   6   6   7   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  10  10  11
+  90  90  90 214 214 215 188 154  82 240 174  22
+ 254 194  14 254 202  13 254 198  13 254 198  13
+ 250 194  13 250 194  13 246 190  13 246 190  13
+ 246 190  13 250 190  11 250 194  13 254 194   9
+ 254 198  13 254 198   6 253 202   2 218 173   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2 249 250 251 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 230 234 235 190 198 214 174 134  38
+ 221 154   6 248 183   3 250 190  11 241 183   7
+ 236 174   8 236 174   8 234 170   6 236 174   8
+ 241 183   7 254 194  14 254 198  13 254 198  13
+ 254 202  13 254 202  13 254 202  13 254 198  13
+ 190 167 108 234 234 235 182 182 182 112 112 112
+  50  50  51  10  10  11   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   6   6   7
+  74  74  74 202 202 202 179 164 133 231 166   7
+ 254 190  11 254 202  13 254 198  13 254 194  14
+ 250 194  13 246 190  13 246 190  13 246 190  13
+ 246 190  13 246 190  13 250 194  13 250 194  13
+ 254 194   9 254 198  13 254 198   6 253 207   3
+ 156 110   2   2   2   2   2   2   2   2   2   2
+   2   2   2 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 241 242 244 105 107 112 142  90   5
+ 221 154   6 241 183   7 254 194   9 254 190  11
+ 254 186   7 241 183   7 241 183   7 248 184  12
+ 250 190  11 254 194  14 254 198  13 254 198  13
+ 254 198  13 254 202  13 254 202  13 254 206  18
+ 254 206  18 218 182  78 214 214 215 214 214 215
+ 140 140 141  38  38  39   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   6   6   7
+  66  66  67 194 194 195 174 162 150 226 162  16
+ 250 190  11 254 198  13 254 198  13 250 194  13
+ 250 194  13 246 190  13 246 190  13 246 190  13
+ 246 190  13 246 190  13 250 190  11 250 194  13
+ 254 194   9 254 194   9 254 198   6 253 202   2
+ 253 202   2  62  39   2   2   2   2   6  10  24
+ 178 182 190 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 122 126 140   2   2   2 142  90   5
+ 218 159   3 248 183   3 254 194   9 254 198  13
+ 254 198  13 254 194   9 250 194  13 250 194  13
+ 250 194  13 250 194  13 254 194  14 254 198  13
+ 254 198  13 254 202  13 254 202  13 254 206  18
+ 254 212  22 254 216  14 254 206  18 194 178 146
+ 198 198 200  74  74  74   6   6   7   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  10  10  11
+  78  78  79 202 202 202 179 164 133 226 162  16
+ 250 190  11 254 198  13 254 198  13 250 194  13
+ 250 194  13 246 190  13 246 190  13 246 190  13
+ 246 190  13 246 190  13 246 190  13 250 194  13
+ 250 194  13 254 194   9 254 198   6 254 194   9
+ 253 207   3 214 162   3 171 170 167 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 100 100 102   2   2   2   2   2   2 156 101   3
+ 226 160   6 248 184  12 254 194   9 254 198  13
+ 254 194   9 250 194  13 250 194  13 250 194  13
+ 250 194  13 250 194  13 250 194  13 254 194  14
+ 254 198  13 254 202  13 254 202  13 254 206  18
+ 254 212  22 254 216  14 254 216  14 226 190  78
+ 214 214 215  90  90  90  10  10  11   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  18  18  18
+ 112 112 112 222 222 223 186 150  74 226 162  16
+ 254 194  14 254 198  13 254 198  13 254 194  14
+ 250 194  13 250 190  11 246 190  13 246 190  13
+ 246 190  13 246 190  13 246 190  13 250 194  13
+ 250 194  13 254 194   9 254 194   9 254 194   9
+ 254 198   2 242 198   2 182 138  22 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 241 242 244  46  46  47
+   2   2   2   2   2   2   2   2   2 156 101   3
+ 226 160   6 254 186   7 254 194   9 254 198  13
+ 254 194   9 250 194  13 250 194  13 250 194  13
+ 250 194  13 250 194  13 254 194  14 254 198  13
+ 254 198  13 254 202  13 254 206  18 254 206  18
+ 254 212  22 254 206  18 254 198  13 194 178 146
+ 206 206 206  82  82  82  10  10  11   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  42  42  43
+ 158 158 158 226 226 226 211 145   3 236 174   8
+ 254 198  13 254 202  13 254 198  13 254 198  13
+ 254 194  14 250 194  13 250 194  13 250 194  13
+ 250 194  13 250 190  11 250 194  13 250 194  13
+ 250 194  13 254 194   9 254 194   9 254 194   9
+ 254 194   9 242 198   2 214 162   3 146 122  78
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 130 130 132   2   2   2   2   2   2
+   2   2   2   2   2   2  18   6   2 156 101   3
+ 231 166   7 250 190  11 254 198  13 254 198  13
+ 254 194   9 250 194  13 250 194  13 250 194  13
+ 250 194  13 254 194  14 254 198  13 254 198  13
+ 254 202  13 254 202  13 254 206  18 254 206  18
+ 254 202  13 248 184  12 226 174  56 222 222 223
+ 158 158 158  50  50  51   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   6   6   7  70  70  71
+ 198 198 200 182 170 146 226 160   6 254 194   9
+ 254 206  18 254 202  13 254 202  13 254 198  13
+ 254 198  13 254 198  13 254 194  14 250 194  13
+ 250 194  13 250 194  13 250 194  13 250 194  13
+ 250 194  13 254 194   9 254 198  13 254 198   6
+ 254 198   6 241 183   7 231 166   7 142  90   5
+  63  62  63 214 214 215 254 254 254 254 254 254
+ 254 254 254 254 254 254 254 254 254 254 254 254
+ 254 254 254 254 254 254 230 230 231 134 134 134
+   6   6   7   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  38  22   2 166 110  10
+ 231 166   7 250 190  11 254 198  13 254 198  13
+ 254 198  13 254 194  14 254 194  14 254 194  14
+ 254 198  13 254 198  13 254 198  13 254 202  13
+ 254 202  13 254 202  13 254 194  14 248 184  12
+ 240 174  22 179 164 133 234 234 235 178 177 177
+  82  82  82  14  14  15   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  10  10  11  90  90  90
+ 214 214 215 196 157  72 231 166   7 254 190  11
+ 254 202  13 254 202  13 254 202  13 254 198  13
+ 254 198  13 254 198  13 254 198  13 254 198  13
+ 254 198  13 254 198  13 254 198  13 254 198  13
+ 254 198  13 254 194   9 254 198  13 254 198  13
+ 254 198   6 254 186   7 231 166   7 170 112   4
+  45  26   2   2   2   2  12  14  26  78  78  79
+ 119 119 118 126 126 127 112 112 112  94  94  95
+  54  54  55   6   6   7   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  55  34   3 170 112   4
+ 231 166   7 254 190  11 254 202  13 254 202  13
+ 254 198  13 254 198  13 254 198  13 254 198  13
+ 254 198  13 254 198  13 254 194  14 254 198  13
+ 254 194  14 240 174  22 219 155  20 179 164 133
+ 214 214 215 210 210 210 150 150 151  74  74  74
+  18  18  18   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  10  10  11  90  90  90
+ 210 210 210 196 157  72 221 154   6 234 170   6
+ 248 183   3 248 184  12 250 190  11 250 190  11
+ 254 190  11 254 194  14 254 198  13 254 198  13
+ 254 198  13 254 198  13 254 198  13 254 198  13
+ 254 198  13 254 198  13 254 202  13 254 202  13
+ 254 202  13 250 190  11 226 160   6 170 112   4
+  90  52   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  82  51   7 182 118   3
+ 226 162  16 250 190  11 254 202  13 254 202  13
+ 254 202  13 254 202  13 254 198  13 254 198  13
+ 254 198  13 250 190  11 248 184  12 236 174   8
+ 213 150   7 167 155 134 226 226 226 210 210 210
+ 163 162 161 100 100 102  46  46  47  10  10  11
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   6   6   7  66  66  67
+ 187 187 186 202 202 202 198 146  54 194 131   6
+ 206 137   3 207 143  12 213 150   7 221 154   6
+ 226 162  16 231 166   7 236 174   8 241 183   7
+ 248 184  12 250 190  11 254 198  13 254 198  13
+ 254 202  13 254 202  13 254 202  13 254 202  13
+ 254 198  13 242 177   7 207 143  12 156 101   3
+ 100  63   4   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  82  51   7 170 112   4
+ 213 150   7 242 177   7 254 198  13 254 198  13
+ 254 202  13 254 198  13 254 198  13 254 194  14
+ 241 183   7 231 166   7 221 154   6 187 145  53
+ 206 206 206 218 218 219 163 162 161 100 100 102
+  46  46  47  18  18  18   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  26  26  28
+ 105 107 112 187 187 186 226 226 226 226 226 226
+ 182 182 182 163 143 109 174 126  38 180 114   4
+ 186 124   4 186 124   4 194 131   6 194 134  10
+ 207 143  12 221 154   6 234 170   6 241 183   7
+ 254 190  11 254 194  14 254 198  13 254 194  14
+ 248 183   3 221 154   6 182 118   3 142  90   5
+  90  52   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2  70  46   2 156 101   3
+ 194 134  10 226 162  16 248 183   3 254 194  14
+ 254 194  14 254 194  14 248 183   3 234 170   6
+ 221 154   6 186 124   4 163 143 109 234 234 235
+ 187 187 186 119 119 118  54  54  55  14  14  15
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   6   6   7
+  26  26  28  74  74  74 112 112 112 150 150 151
+ 182 182 182 210 210 210 230 230 231 202 202 202
+ 171 170 167 146 122  78 146  98  22 142  90   5
+ 156 101   3 166 110  10 186 124   4 206 137   3
+ 211 145   3 218 159   3 231 166   7 226 162  16
+ 211 145   3 182 118   3 148  89   3 111  67   3
+  55  34   3  50  50  51 182 182 182 182 182 182
+ 202 202 202 237 238 239 234 234 235 234 234 235
+ 234 234 235 234 234 235 234 234 235 234 234 235
+ 234 234 235 234 234 235 218 218 219 182 182 182
+ 178 177 177 126 126 127  78  58  26 130  88   2
+ 182 118   3 206 137   3 221 154   6 231 166   7
+ 231 166   7 226 162  16 211 145   3 194 134  10
+ 166 110  10 174 162 150 226 226 226 163 162 161
+  78  78  79  26  26  28   6   6   7   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   6   6   7  18  18  18  33  34  35
+  58  58  59  90  90  90 130 130 132 163 162 161
+ 194 194 195 218 218 219 234 234 235 202 202 202
+ 167 155 134 130 114  86 118  76   2 142  90   5
+ 156 101   3 166 110  10 170 112   4 170 112   4
+ 156 101   3 134  82   2 111  67   3  89  59   3
+ 146 146 146 218 218 219 206 206 206 171 170 167
+ 155 153 152 140 140 141 130 130 132 126 126 127
+ 126 126 127 126 126 127 126 126 127 126 126 127
+ 126 126 127 134 134 134 150 150 151 166 166 167
+ 191 191 190 234 234 235 130 130 132 100  63   4
+ 156 101   3 182 118   3 186 124   4 194 131   6
+ 194 131   6 186 124   4 170 112   4 142  90   5
+ 171 170 167 218 218 219 146 146 146  63  62  63
+  14  14  15   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   6   6   7  10  10  11  26  26  28  42  42  43
+  66  66  67 100 100 102 134 134 134 166 166 167
+ 194 194 195 222 222 223 230 230 231 155 153 152
+ 110  86  42 111  67   3 111  67   3 118  76   2
+ 111  67   3 100  63   4  82  51   7 182 182 182
+ 218 218 219 158 158 158  94  94  95  50  50  51
+  33  34  35  26  26  28  22  22  23  22  22  23
+  22  22  23  22  22  23  22  22  23  22  22  23
+  22  22  23  26  26  28  33  34  35  42  42  43
+  78  78  79 166 166 167 226 226 226 120 112 108
+  89  59   3 134  82   2 148  89   3 156 101   3
+ 156 101   3 142  90   5 120  78  12 171 170 167
+ 218 218 219 134 134 134  50  50  51  10  10  11
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   6   6   7  14  14  15  26  26  28  46  46  47
+  70  70  71 112 112 112 155 153 152 198 198 200
+ 230 230 231 202 202 202 140 140 141 110  94  70
+ 110  94  70 155 153 152 218 218 219 202 202 202
+ 126 126 127  50  50  51  14  14  15   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+  14  14  15  74  74  74 163 162 161 222 222 223
+ 191 191 190 119 119 118 106  92  68 110  94  70
+ 118 106  86 150 150 151 226 226 226 202 202 202
+ 130 130 132  46  46  47   6   6   7   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   6   6   7  18  18  18  42  42  43  78  78  79
+ 126 126 127 171 170 167 198 198 200 214 214 215
+ 214 214 215 194 194 195 155 153 152 100 100 102
+  33  34  35   6   6   7   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2  14  14  15  58  58  59 126 126 127
+ 178 177 177 206 206 206 214 214 215 214 214 215
+ 210 210 210 194 194 195 150 150 151  90  90  90
+  38  38  39   6   6   7   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2  10  10  11
+  26  26  28  46  46  47  74  74  74  90  90  90
+  90  90  90  70  70  71  38  38  39  14  14  15
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   6   6   7  26  26  28
+  54  54  55  82  82  82  90  90  90  94  94  95
+  86  86  86  66  66  67  38  38  39  14  14  15
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
+   2   2   2   2   2   2   2   2   2   2   2   2
diff -Nru a/drivers/video/logo/logo_sgi_clut224.ppm b/drivers/video/logo/logo_sgi_clut224.ppm
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/logo_sgi_clut224.ppm	Mon Feb 24 13:47:01 2003
@@ -0,0 +1,1604 @@
+P3
+# 224-color SGI Linux logo
+80 80
+255
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6   6   6   6  10  10  10  10  10  10
+ 10  10  10   6   6   6   6   6   6   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  10  10  10  14  14  14
+ 22  22  22  26  26  26  30  30  30  34  34  34
+ 30  30  30  30  30  30  26  26  26  18  18  18
+ 14  14  14  10  10  10   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  26  26  26  42  42  42
+ 54  54  54  66  66  66  78  78  78  78  78  78
+ 78  78  78  74  74  74  66  66  66  54  54  54
+ 42  42  42  26  26  26  18  18  18  10  10  10
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 22  22  22  42  42  42  66  66  66  86  86  86
+ 66  66  66  38  38  38  38  38  38  22  22  22
+ 26  26  26  34  34  34  54  54  54  66  66  66
+ 86  86  86  70  70  70  46  46  46  26  26  26
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  26  26  26
+ 50  50  50  82  82  82  58  58  58   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  54  54  54  86  86  86  66  66  66
+ 38  38  38  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  22  22  22  50  50  50
+ 78  78  78  34  34  34   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   6   6   6  70  70  70
+ 78  78  78  46  46  46  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  42  42  42  82  82  82
+ 26  26  26   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  14  14  14
+ 46  46  46  34  34  34   6   6   6   2   2   6
+ 42  42  42  78  78  78  42  42  42  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 10  10  10  30  30  30  66  66  66  58  58  58
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  26  26  26
+ 86  86  86 101 101 101  46  46  46  10  10  10
+  2   2   6  58  58  58  70  70  70  34  34  34
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 14  14  14  42  42  42  86  86  86  10  10  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  30  30  30
+ 94  94  94  94  94  94  58  58  58  26  26  26
+  2   2   6   6   6   6  78  78  78  54  54  54
+ 22  22  22   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 22  22  22  62  62  62  62  62  62   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  26  26  26
+ 54  54  54  38  38  38  18  18  18  10  10  10
+  2   2   6   2   2   6  34  34  34  82  82  82
+ 38  38  38  14  14  14   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 30  30  30  78  78  78  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 10  10  10   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  78  78  78
+ 50  50  50  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  14  14  14   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  54  54  54
+ 66  66  66  26  26  26   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  82  82  82   2   2   6   2   2   6
+  2   2   6   6   6   6  10  10  10   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 14  14  14  10  10  10   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  18  18  18
+ 82  82  82  34  34  34  10  10  10   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6   2   2   6
+  6   6   6   6   6   6  22  22  22  34  34  34
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  34  34  34
+ 10  10  10  50  50  50  22  22  22   2   2   6
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 86  86  86  42  42  42  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6   2   2   6
+ 38  38  38 116 116 116  94  94  94  22  22  22
+ 22  22  22   2   2   6   2   2   6   2   2   6
+ 14  14  14  86  86  86 138 138 138 162 162 162
+154 154 154  38  38  38  26  26  26   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 86  86  86  46  46  46  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6  14  14  14
+134 134 134 198 198 198 195 195 195 116 116 116
+ 10  10  10   2   2   6   2   2   6   6   6   6
+101  98  89 187 187 187 210 210 210 218 218 218
+214 214 214 134 134 134  14  14  14   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 86  86  86  50  50  50  18  18  18   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  86  86  86   2   2   6  54  54  54
+218 218 218 195 195 195 226 226 226 246 246 246
+ 58  58  58   2   2   6   2   2   6  30  30  30
+210 210 210 253 253 253 174 174 174 123 123 123
+221 221 221 234 234 234  74  74  74   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 46  46  46  82  82  82   2   2   6 106 106 106
+170 170 170  26  26  26  86  86  86 226 226 226
+123 123 123  10  10  10  14  14  14  46  46  46
+231 231 231 190 190 190   6   6   6  70  70  70
+ 90  90  90 238 238 238 158 158 158   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   1   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  86  86  86   6   6   6 116 116 116
+106 106 106   6   6   6  70  70  70 149 149 149
+128 128 128  18  18  18  38  38  38  54  54  54
+221 221 221 106 106 106   2   2   6  14  14  14
+ 46  46  46 190 190 190 198 198 198   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  62  62  62  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   0
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  94  94  94  14  14  14 101 101 101
+128 128 128   2   2   6  18  18  18 116 116 116
+118  98  46 121  92   8 121  92   8  98  78  10
+162 162 162 106 106 106   2   2   6   2   2   6
+  2   2   6 195 195 195 195 195 195   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  62  62  62  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   1   0   0   1
+  0   0   1   0   0   0   0   0   1   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  90  90  90  14  14  14  58  58  58
+210 210 210  26  26  26  54  38   6 154 114  10
+226 170  11 236 186  11 225 175  15 184 144  12
+215 174  15 175 146  61  37  26   9   2   2   6
+ 70  70  70 246 246 246 138 138 138   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  66  66  66  26  26  26   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  14  14  14  10  10  10
+195 195 195 188 164 115 192 133   9 225 175  15
+239 182  13 234 190  10 232 195  16 232 200  30
+245 207  45 241 208  19 232 195  16 184 144  12
+218 194 134 211 206 186  42  42  42   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 50  50  50  74  74  74  30  30  30   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  86  86  86  14  14  14   2   2   6
+121  87  25 192 133   9 219 162  10 239 182  13
+236 186  11 232 195  16 241 208  19 244 214  54
+246 218  60 246 218  38 246 215  20 241 208  19
+241 208  19 226 184  13 121  87  25   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 50  50  50  82  82  82  34  34  34  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  82  82  82  30  30  30  61  42   6
+180 123   7 206 145  10 230 174  11 239 182  13
+234 190  10 238 202  15 241 208  19 246 218  74
+246 218  38 246 215  20 246 215  20 246 215  20
+226 184  13 215 174  15 184 144  12   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 26  26  26  94  94  94  42  42  42  14  14  14
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78  50  50  50 104  69   6
+192 133   9 216 158  10 236 178  12 236 186  11
+232 195  16 241 208  19 244 214  54 245 215  43
+246 215  20 246 215  20 241 208  19 198 155  10
+200 144  11 216 158  10 156 118  10   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  90  90  90  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78  46  46  46  22  22  22
+137  92   6 210 162  10 239 182  13 238 190  10
+238 202  15 241 208  19 246 215  20 246 215  20
+241 208  19 203 166  17 185 133  11 210 150  10
+216 158  10 210 150  10 102  78  10   2   2   6
+  6   6   6  54  54  54  14  14  14   2   2   6
+  2   2   6  62  62  62  74  74  74  30  30  30
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 34  34  34  78  78  78  50  50  50   6   6   6
+ 94  70  30 139 102  15 190 146  13 226 184  13
+232 200  30 232 195  16 215 174  15 190 146  13
+168 122  10 192 133   9 210 150  10 213 154  11
+202 150  34 182 157 106 101  98  89   2   2   6
+  2   2   6  78  78  78 116 116 116  58  58  58
+  2   2   6  22  22  22  90  90  90  46  46  46
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  86  86  86  50  50  50   6   6   6
+128 128 128 174 154 114 156 107  11 168 122  10
+198 155  10 184 144  12 197 138  11 200 144  11
+206 145  10 206 145  10 197 138  11 188 164 115
+195 195 195 198 198 198 174 174 174  14  14  14
+  2   2   6  22  22  22 116 116 116 116 116 116
+ 22  22  22   2   2   6  74  74  74  70  70  70
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 101 101 101  26  26  26  10  10  10
+138 138 138 190 190 190 174 154 114 156 107  11
+197 138  11 200 144  11 197 138  11 192 133   9
+180 123   7 190 142  34 190 178 144 187 187 187
+202 202 202 221 221 221 214 214 214  66  66  66
+  2   2   6   2   2   6  50  50  50  62  62  62
+  6   6   6   2   2   6  10  10  10  90  90  90
+ 50  50  50  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  34  34  34
+ 74  74  74  74  74  74   2   2   6   6   6   6
+144 144 144 198 198 198 190 190 190 178 166 146
+154 121  60 156 107  11 156 107  11 168 124  44
+174 154 114 187 187 187 190 190 190 210 210 210
+246 246 246 253 253 253 253 253 253 182 182 182
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  62  62  62
+ 74  74  74  34  34  34  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  10  10  10  22  22  22  54  54  54
+ 94  94  94  18  18  18   2   2   6  46  46  46
+234 234 234 221 221 221 190 190 190 190 190 190
+190 190 190 187 187 187 187 187 187 190 190 190
+190 190 190 195 195 195 214 214 214 242 242 242
+253 253 253 253 253 253 253 253 253 253 253 253
+ 82  82  82   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  14  14  14
+ 86  86  86  54  54  54  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  46  46  46  90  90  90
+ 46  46  46  18  18  18   6   6   6 182 182 182
+253 253 253 246 246 246 206 206 206 190 190 190
+190 190 190 190 190 190 190 190 190 190 190 190
+206 206 206 231 231 231 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+202 202 202  14  14  14   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 42  42  42  86  86  86  42  42  42  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 14  14  14  38  38  38  74  74  74  66  66  66
+  2   2   6   6   6   6  90  90  90 250 250 250
+253 253 253 253 253 253 238 238 238 198 198 198
+190 190 190 190 190 190 195 195 195 221 221 221
+246 246 246 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253  82  82  82   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  78  78  78  70  70  70  34  34  34
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 34  34  34  66  66  66  78  78  78   6   6   6
+  2   2   6  18  18  18 218 218 218 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+226 226 226 231 231 231 246 246 246 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 178 178 178   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  18  18  18  90  90  90  62  62  62
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  26  26  26
+ 58  58  58  90  90  90  18  18  18   2   2   6
+  2   2   6 110 110 110 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 231 231 231  18  18  18   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  94  94  94
+ 54  54  54  26  26  26  10  10  10   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  22  22  22  50  50  50
+ 90  90  90  26  26  26   2   2   6   2   2   6
+ 14  14  14 195 195 195 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+250 250 250 242 242 242  54  54  54   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+ 86  86  86  50  50  50  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  38  38  38  82  82  82
+ 34  34  34   2   2   6   2   2   6   2   2   6
+ 42  42  42 195 195 195 246 246 246 253 253 253
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 242 242 242 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 250 250 250 246 246 246 238 238 238
+226 226 226 231 231 231 101 101 101   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 38  38  38  82  82  82  42  42  42  14  14  14
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 10  10  10  26  26  26  62  62  62  66  66  66
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 70  70  70 170 170 170 206 206 206 234 234 234
+246 246 246 250 250 250 250 250 250 238 238 238
+226 226 226 231 231 231 238 238 238 250 250 250
+250 250 250 250 250 250 246 246 246 231 231 231
+214 214 214 206 206 206 202 202 202 202 202 202
+198 198 198 202 202 202 182 182 182  18  18  18
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  62  62  62  66  66  66  30  30  30
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 14  14  14  42  42  42  82  82  82  18  18  18
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 94  94  94 182 182 182 218 218 218 242 242 242
+250 250 250 253 253 253 253 253 253 250 250 250
+234 234 234 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+238 238 238 226 226 226 210 210 210 202 202 202
+195 195 195 195 195 195 210 210 210 158 158 158
+  6   6   6  14  14  14  50  50  50  14  14  14
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  86  86  86  46  46  46
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 22  22  22  54  54  54  70  70  70   2   2   6
+  2   2   6  10  10  10   2   2   6  22  22  22
+166 166 166 231 231 231 250 250 250 253 253 253
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 246 246 246
+231 231 231 206 206 206 198 198 198 226 226 226
+ 94  94  94   2   2   6   6   6   6  38  38  38
+ 30  30  30   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  62  62  62  66  66  66
+ 26  26  26  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  74  74  74  50  50  50   2   2   6
+ 26  26  26  26  26  26   2   2   6 106 106 106
+238 238 238 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 231 231 231
+134 134 134 106 106 106 174 174 174 253 253 253
+182 182 182  54  54  54 128 128 128 231 231 231
+250 250 250 253 253 253 253 253 253 253 253 253
+253 253 253 246 246 246 218 218 218 202 202 202
+210 210 210  14  14  14   2   2   6   2   2   6
+ 30  30  30  22  22  22   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  86  86  86
+ 42  42  42  14  14  14   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 42  42  42  90  90  90  22  22  22   2   2   6
+ 42  42  42   2   2   6  18  18  18 218 218 218
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 231 231 231 149 149 149  94  94  94
+154 154 154 182 182 182 101 101 101 250 250 250
+116 116 116  10  10  10  14  14  14  42  42  42
+128 128 128 231 231 231 253 253 253 253 253 253
+253 253 253 253 253 253 250 250 250 221 221 221
+218 218 218 101 101 101   2   2   6  14  14  14
+ 18  18  18  38  38  38  10  10  10   2   2   6
+  2   2   6   2   2   6   2   2   6  78  78  78
+ 58  58  58  22  22  22   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 54  54  54  82  82  82   2   2   6  26  26  26
+ 22  22  22   2   2   6 123 123 123 253 253 253
+253 253 253 253 253 253 253 253 253 238 238 238
+158 158 158 101 101 101 149 149 149 182 182 182
+128 128 128  94  94  94  94  94  94 246 246 246
+123 123 123  78  78  78  38  38  38  14  14  14
+ 18  18  18  62  62  62 158 158 158 238 238 238
+253 253 253 253 253 253 253 253 253 250 250 250
+238 238 238 198 198 198   6   6   6  38  38  38
+ 58  58  58  26  26  26  38  38  38   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+ 78  78  78  30  30  30  10  10  10   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  10  10  10  30  30  30
+ 74  74  74  58  58  58   2   2   6  42  42  42
+  2   2   6  22  22  22 231 231 231 253 253 253
+253 253 253 250 250 250 128 128 128  62  62  62
+128 128 128 158 158 158 116 116 116 128 128 128
+116 116 116  90  90  90  90  90  90 246 246 246
+128 128 128 116 116 116 106 106 106 101 101 101
+ 38  38  38  10  10  10  22  22  22  54  54  54
+149 149 149 250 250 250 253 253 253 253 253 253
+253 253 253 246 246 246  46  46  46  38  38  38
+ 42  42  42  14  14  14  38  38  38  14  14  14
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 86  86  86  46  46  46  14  14  14   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  42  42  42
+ 90  90  90  18  18  18  18  18  18  26  26  26
+  2   2   6 116 116 116 253 253 253 253 253 253
+253 253 253 231 231 231  30  30  30  14  14  14
+ 30  30  30  62  62  62 134 134 134 210 210 210
+174 174 174 101 101 101  86  86  86 250 250 250
+128 128 128 116 116 116 149 149 149 210 210 210
+134 134 134  38  38  38  46  46  46 154 154 154
+174 174 174 198 198 198 253 253 253 253 253 253
+253 253 253 253 253 253  94  94  94   6   6   6
+  2   2   6   2   2   6  10  10  10  34  34  34
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  58  58  58  22  22  22   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  10  10  10  26  26  26  66  66  66
+ 82  82  82   2   2   6  38  38  38   6   6   6
+ 14  14  14 210 210 210 253 253 253 253 253 253
+253 253 253 246 246 246 138 138 138  46  46  46
+  6   6   6  18  18  18  54  54  54 166 166 166
+174 174 174 101 101 101  74  74  74 238 238 238
+123 123 123 101 101 101 166 166 166 182 182 182
+ 90  90  90 116 116 116 202 202 202 149 149 149
+128 128 128 231 231 231 253 253 253 253 253 253
+253 253 253 253 253 253 144 144 144   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 42  42  42  74  74  74  30  30  30  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  42  42  42  90  90  90
+ 26  26  26   6   6   6  42  42  42   2   2   6
+ 74  74  74 250 250 250 253 253 253 253 253 253
+238 238 238 221 221 221 238 238 238 166 166 166
+ 90  90  90  38  38  38  10  10  10  18  18  18
+ 46  46  46  46  46  46  62  62  62 246 246 246
+101 101 101  42  42  42  62  62  62 116 116 116
+190 190 190 141 141 141 116 116 116 141 141 141
+221 221 221 250 250 250 253 253 253 253 253 253
+253 253 253 253 253 253 182 182 182   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 10  10  10  86  86  86  38  38  38  10  10  10
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 10  10  10  26  26  26  66  66  66  82  82  82
+  2   2   6  22  22  22  18  18  18   2   2   6
+149 149 149 253 253 253 253 253 253 214 214 214
+ 38  38  38  38  38  38 166 166 166 238 238 238
+214 214 214 116 116 116  70  70  70  26  26  26
+ 10  10  10  26  26  26  42  42  42 182 182 182
+ 62  62  62  86  86  86 187 187 187 174 174 174
+123 123 123 138 138 138 190 190 190 246 246 246
+210 210 210 110 110 110 138 138 138 221 221 221
+253 253 253 253 253 253 206 206 206   2   2   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  86  86  86  46  46  46  14  14  14
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 18  18  18  46  46  46  86  86  86  18  18  18
+  2   2   6  34  34  34  10  10  10   6   6   6
+210 210 210 253 253 253 253 253 253 190 190 190
+ 38  38  38  14  14  14  26  26  26  86  86  86
+198 198 198 238 238 238 174 174 174  90  90  90
+ 62  62  62  26  26  26  22  22  22  54  54  54
+166 166 166 187 187 187 134 134 134 128 128 128
+166 166 166 231 231 231 231 231 231 149 149 149
+123 123 123 166 166 166 174 174 174 190 190 190
+253 253 253 253 253 253 221 221 221   6   6   6
+  2   2   6   2   2   6   6   6   6  30  30  30
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  82  82  82  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 26  26  26  66  66  66  62  62  62   2   2   6
+  2   2   6  38  38  38  10  10  10  26  26  26
+238 238 238 253 253 253 253 253 253 214 214 214
+116 116 116  90  90  90  30  30  30  14  14  14
+ 38  38  38 110 110 110 214 214 214 195 195 195
+116 116 116  62  62  62  54  54  54  54  54  54
+138 138 138 116 116 116 128 128 128 221 221 221
+246 246 246 166 166 166 116 116 116 174 174 174
+166 166 166 141 141 141 138 138 138 206 206 206
+253 253 253 253 253 253 231 231 231   6   6   6
+  2   2   6   2   2   6  10  10  10  30  30  30
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  58  58  58  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 38  38  38  78  78  78   6   6   6   2   2   6
+  2   2   6  46  46  46  14  14  14  42  42  42
+246 246 246 253 253 253 253 253 253 210 210 210
+134 134 134 116 116 116 110 110 110  54  54  54
+ 14  14  14  26  26  26  62  62  62 106 106 106
+ 54  54  54  70  70  70  78  78  78 110 110 110
+ 82  82  82  74  74  74  86  86  86 166 166 166
+116 116 116 128 128 128 198 198 198 141 141 141
+141 141 141 134 134 134 128 128 128 210 210 210
+253 253 253 253 253 253 234 234 234  10  10  10
+  2   2   6   2   2   6  22  22  22  14  14  14
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  62  62  62  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50  74  74  74   2   2   6   2   2   6
+ 14  14  14  70  70  70  34  34  34  62  62  62
+250 250 250 253 253 253 253 253 253 231 231 231
+134 134 134 106 106 106 128 128 128 166 166 166
+ 90  90  90  22  22  22  14  14  14  30  30  30
+ 46  46  46  66  66  66 138 138 138 221 221 221
+128 128 128  46  46  46  54  54  54 101 101 101
+182 182 182 166 166 166 134 134 134 166 166 166
+128 128 128 101 101 101 134 134 134 221 221 221
+253 253 253 253 253 253 234 234 234  14  14  14
+  2   2   6   2   2   6  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  62  62  62  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 54  54  54  62  62  62   2   2   6   2   2   6
+  2   2   6  30  30  30  46  46  46  70  70  70
+250 250 250 253 253 253 253 253 253 231 231 231
+128 128 128 116 116 116 158 158 158 158 158 158
+ 74  74  74 110 110 110  82  82  82  18  18  18
+ 18  18  18 101 101 101 182 182 182 214 214 214
+134 134 134  54  54  54 174 174 174 166 166 166
+138 138 138 134 134 134  78  78  78 211 206 186
+123 123 123 116 116 116 138 138 138 231 231 231
+253 253 253 253 253 253 226 226 226  10  10  10
+  2   2   6   6   6   6  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  58  58  58  22  22  22
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 58  58  58  62  62  62   2   2   6   2   2   6
+  2   2   6   2   2   6  30  30  30  78  78  78
+250 250 250 253 253 253 253 253 253 246 246 246
+138 138 138 116 116 116  86  86  86 101 101 101
+174 174 174  94  94  94  94  94  94 116 116 116
+ 54  54  54  70  70  70  90  90  90  46  46  46
+ 54  54  54  30  30  30 101 101 101 141 141 141
+128 128 128  46  46  46  30  30  30  54  54  54
+ 78  78  78 110 110 110 138 138 138 238 238 238
+253 253 253 253 253 253 206 206 206   2   2   6
+ 22  22  22  34  34  34  18  14   6  22  22  22
+ 26  26  26  18  18  18   6   6   6   2   2   6
+  2   2   6  82  82  82  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  26  26  26
+ 62  62  62 106 106 106  74  54  14 185 133  11
+210 162  10 121  92   8   6   6   6  62  62  62
+238 238 238 253 253 253 253 253 253 246 246 246
+141 141 141 123 123 123 106 106 106 128 128 128
+101 101 101 141 141 141 214 214 214 166 166 166
+134 134 134 149 149 149 106 106 106  78  78  78
+ 90  90  90 138 138 138 154 154 154 195 195 195
+190 190 190  86  86  86  46  46  46  14  14  14
+ 42  42  42 116 116 116 149 149 149 246 246 246
+253 253 253 253 253 253 158 158 158  18  18  18
+ 14  14  14   2   2   6   2   2   6   2   2   6
+  6   6   6  18  18  18  66  66  66  38  38  38
+  6   6   6  94  94  94  50  50  50  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 10  10  10  10  10  10  18  18  18  38  38  38
+ 78  78  78 142 134 106 216 158  10 242 186  14
+246 190  14 246 190  14 156 118  10  10  10  10
+ 90  90  90 238 238 238 253 253 253 250 250 250
+138 138 138 116 116 116  86  86  86 149 149 149
+198 198 198 221 221 221 138 138 138  82  82  82
+134 134 134 128 128 128  82  82  82 106 106 106
+ 82  82  82 138 138 138 138 138 138 128 128 128
+187 187 187 221 221 221 166 166 166  70  70  70
+ 54  54  54 116 116 116 166 166 166 246 246 246
+238 204  91 238 204  91 181 142  44  37  26   9
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  38  38  38  46  46  46
+ 26  26  26 106 106 106  54  54  54  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  22  22  22
+ 30  30  30  38  38  38  50  50  50  70  70  70
+106 106 106 190 142  34 226 170  11 242 186  14
+246 190  14 246 190  14 246 190  14 154 114  10
+  6   6   6  74  74  74 226 226 226 253 253 253
+206 206 206 138 138 138 187 187 187 246 246 246
+187 187 187 110 110 110 101 101 101  62  62  62
+123 123 123 134 134 134 116 116 116 238 238 238
+ 94  94  94 134 134 134 134 134 134  54  54  54
+ 26  26  26 101 101 101 231 231 231 231 231 231
+128 128 128 128 128 128 214 214 214 228 184  62
+241 196  14 241 208  19 232 195  16  38  30  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  30  30  30  26  26  26
+203 166  17 154 142  90  66  66  66  26  26  26
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  38  38  38  58  58  58
+ 78  78  78  86  86  86 101 101 101 123 123 123
+175 146  61 210 150  10 234 174  13 246 186  14
+246 190  14 246 190  14 246 190  14 238 190  10
+102  78  10   2   2   6  46  46  46 198 198 198
+253 253 253 246 246 246 221 221 221 123 123 123
+110 110 110 128 128 128  86  86  86  90  90  90
+116 116 116 138 138 138 128 128 128 250 250 250
+106 106 106 138 138 138 128 128 128  62  62  62
+ 22  22  22  18  18  18  46  46  46 166 166 166
+246 246 246 246 246 246 253 253 253 224 178  62
+242 186  14 241 196  14 210 166  10  22  18   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   6   6   6 121  92   8
+238 202  15 232 195  16  82  82  82  34  34  34
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 14  14  14  38  38  38  70  70  70 154 122  46
+190 142  34 200 144  11 197 138  11 197 138  11
+213 154  11 226 170  11 242 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+225 175  15  46  32   6   2   2   6  22  22  22
+158 158 158 246 246 246 101 101 101  38  38  38
+ 46  46  46  74  74  74 182 182 182 198 198 198
+116 116 116 134 134 134 123 123 123 246 246 246
+110 110 110 134 134 134 149 149 149 195 195 195
+128 128 128  38  38  38  38  38  38 123 123 123
+211 206 186 250 250 250 242 242 242 224 178  62
+239 182  13 236 186  11 213 154  11  46  32   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  61  42   6 225 175  15
+238 190  10 236 186  11 112 100  78  42  42  42
+ 14  14  14   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 22  22  22  54  54  54 154 122  46 213 154  11
+226 170  11 230 174  11 226 170  11 226 170  11
+236 178  12 242 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+241 196  14 184 144  12  10  10  10   2   2   6
+  6   6   6 116 116 116 154 154 154  38  38  38
+ 10  10  10  18  18  18 116 116 116 218 218 218
+123 123 123 134 134 134 134 134 134 250 250 250
+110 110 110 134 134 134 166 166 166 221 221 221
+128 128 128  74  74  74 187 187 187 141 141 141
+202 202 202 231 231 231 198 198 198 214 170  54
+236 178  12 236 178  12 210 150  10 137  92   6
+ 18  14   6   2   2   6   2   2   6   2   2   6
+  6   6   6  70  47   6 200 144  11 236 178  12
+239 182  13 239 182  13 124 112  88  58  58  58
+ 22  22  22   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  70  70  70 180 133  36 226 170  11
+239 182  13 242 186  14 242 186  14 246 186  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 232 195  16  98  70   6   2   2   6
+  2   2   6   2   2   6  66  66  66 149 149 149
+ 70  70  70  14  14  14  30  30  30  66  66  66
+116 116 116 138 138 138 128 128 128 246 246 246
+101 101 101 138 138 138 138 138 138  94  94  94
+123 123 123 182 182 182 128 128 128 182 182 182
+246 246 246 206 206 206 198 198 198 214 166  58
+230 174  11 230 174  11 216 158  10 192 133   9
+163 110   8 116  81   8 102  78  10 116  81   8
+167 114   7 197 138  11 226 170  11 239 182  13
+242 186  14 242 186  14 162 146  94  78  78  78
+ 34  34  34  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 30  30  30  78  78  78 190 142  34 226 170  11
+239 182  13 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 241 196  14 203 166  17  22  18   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+182 182 182 101 101 101  38  38  38  30  30  30
+110 110 110 134 134 134 141 141 141 250 250 250
+101 101 101 138 138 138 138 138 138 158 158 158
+158 158 158 154 154 154 221 221 221 253 253 253
+250 250 250 206 206 206 198 198 198 202 162  69
+226 170  11 236 178  12 224 166  10 210 150  10
+200 144  11 197 138  11 192 133   9 197 138  11
+210 150  10 226 170  11 242 186  14 246 190  14
+246 190  14 246 186  14 225 175  15 124 112  88
+ 62  62  62  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78 174 135  50 224 166  10
+239 182  13 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 241 196  14 139 102  15
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 78  78  78 198 198 198 138 138 138  70  70  70
+106 106 106 134 134 134 141 141 141 246 246 246
+ 94  94  94 138 138 138 134 134 134 134 134 134
+182 182 182 238 238 238 253 253 253 253 253 253
+250 250 250 214 214 214 198 198 198 190 150  46
+219 162  10 236 178  12 234 174  13 224 166  10
+216 158  10 213 154  11 213 154  11 216 158  10
+226 170  11 239 182  13 246 190  14 246 190  14
+246 190  14 246 190  14 242 186  14 206 162  42
+101 101 101  58  58  58  30  30  30  14  14  14
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  74  74  74 174 135  50 216 158  10
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 241 196  14 226 184  13
+ 61  42   6   2   2   6   2   2   6   2   2   6
+ 22  22  22 238 238 238 246 246 246 174 174 174
+116 116 116 128 128 128 182 182 182 246 246 246
+110 110 110 134 134 134 149 149 149 214 214 214
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 226 226 226 187 187 187 180 133  36
+216 158  10 236 178  12 239 182  13 236 178  12
+230 174  11 226 170  11 226 170  11 230 174  11
+236 178  12 242 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 186  14 239 182  13
+206 162  42 106 106 106  66  66  66  34  34  34
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 26  26  26  70  70  70 163 133  67 213 154  11
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 241 196  14
+190 146  13  18  14   6   2   2   6   2   2   6
+ 46  46  46 246 246 246 253 253 253 250 250 250
+206 206 206 198 198 198 246 246 246 253 253 253
+221 221 221 195 195 195 231 231 231 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 221 221 221  86  86  86 156 107  11
+216 158  10 236 178  12 242 186  14 246 186  14
+242 186  14 239 182  13 239 182  13 242 186  14
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+242 186  14 225 175  15 142 122  72  66  66  66
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 26  26  26  70  70  70 163 133  67 210 150  10
+236 178  12 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+232 195  16 121  92   8  34  34  34 106 106 106
+221 221 221 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+242 242 242  82  82  82  18  14   6 163 110   8
+216 158  10 236 178  12 242 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 242 186  14 163 133  67
+ 46  46  46  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  10  10  10
+ 30  30  30  78  78  78 163 133  67 210 150  10
+236 178  12 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+241 196  14 215 174  15 190 178 144 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 218 218 218
+ 58  58  58   2   2   6  22  18   6 167 114   7
+216 158  10 236 178  12 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 186  14 242 186  14 190 150  46
+ 54  54  54  22  22  22   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 38  38  38  86  86  86 180 133  36 213 154  11
+236 178  12 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 232 195  16 190 146  13 214 214 214
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 250 250 250 170 170 170  26  26  26
+  2   2   6   2   2   6  37  26   9 163 110   8
+219 162  10 239 182  13 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 236 178  12 224 166  10 142 122  72
+ 46  46  46  18  18  18   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 109 106  95 192 133   9 224 166  10
+242 186  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+242 186  14 226 184  13 210 162  10 142 110  46
+226 226 226 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+253 253 253 253 253 253 253 253 253 253 253 253
+198 198 198  66  66  66   2   2   6   2   2   6
+  2   2   6   2   2   6  50  34   6 156 107  11
+219 162  10 239 182  13 246 186  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 242 186  14
+234 174  13 213 154  11 154 122  46  66  66  66
+ 30  30  30  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 58  58  58 154 121  60 206 145  10 234 174  13
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 236 178  12 210 162  10 163 110   8
+ 61  42   6 138 138 138 218 218 218 250 250 250
+253 253 253 253 253 253 253 253 253 250 250 250
+242 242 242 210 210 210 144 144 144  66  66  66
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  61  42   6 163 110   8
+216 158  10 236 178  12 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 239 182  13 230 174  11 216 158  10
+190 142  34 124 112  88  70  70  70  38  38  38
+ 18  18  18   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  22  22  22
+ 62  62  62 168 124  44 206 145  10 224 166  10
+236 178  12 239 182  13 242 186  14 242 186  14
+246 186  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 236 178  12 216 158  10 175 118   6
+ 80  54   7   2   2   6   6   6   6  30  30  30
+ 54  54  54  62  62  62  50  50  50  38  38  38
+ 14  14  14   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  80  54   7 167 114   7
+213 154  11 236 178  12 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 242 186  14 239 182  13 239 182  13
+230 174  11 210 150  10 174 135  50 124 112  88
+ 82  82  82  54  54  54  34  34  34  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  18  18  18
+ 50  50  50 158 118  36 192 133   9 200 144  11
+216 158  10 219 162  10 224 166  10 226 170  11
+230 174  11 236 178  12 239 182  13 239 182  13
+242 186  14 246 186  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 186  14 230 174  11 210 150  10 163 110   8
+104  69   6  10  10  10   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  91  60   6 167 114   7
+206 145  10 230 174  11 242 186  14 246 190  14
+246 190  14 246 190  14 246 186  14 242 186  14
+239 182  13 230 174  11 224 166  10 213 154  11
+180 133  36 124 112  88  86  86  86  58  58  58
+ 38  38  38  22  22  22  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  14  14  14
+ 34  34  34  70  70  70 138 110  50 158 118  36
+167 114   7 180 123   7 192 133   9 197 138  11
+200 144  11 206 145  10 213 154  11 219 162  10
+224 166  10 230 174  11 239 182  13 242 186  14
+246 186  14 246 186  14 246 186  14 246 186  14
+239 182  13 216 158  10 185 133  11 152  99   6
+104  69   6  18  14   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  80  54   7 152  99   6
+192 133   9 219 162  10 236 178  12 239 182  13
+246 186  14 242 186  14 239 182  13 236 178  12
+224 166  10 206 145  10 192 133   9 154 121  60
+ 94  94  94  62  62  62  42  42  42  22  22  22
+ 14  14  14   6   6   6   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 18  18  18  34  34  34  58  58  58  78  78  78
+101  98  89 124 112  88 142 110  46 156 107  11
+163 110   8 167 114   7 175 118   6 180 123   7
+185 133  11 197 138  11 210 150  10 219 162  10
+226 170  11 236 178  12 236 178  12 234 174  13
+219 162  10 197 138  11 163 110   8 130  83   6
+ 91  60   6  10  10  10   2   2   6   2   2   6
+ 18  18  18  38  38  38  38  38  38  38  38  38
+ 38  38  38  38  38  38  38  38  38  38  38  38
+ 38  38  38  38  38  38  26  26  26   2   2   6
+  2   2   6   6   6   6  70  47   6 137  92   6
+175 118   6 200 144  11 219 162  10 230 174  11
+234 174  13 230 174  11 219 162  10 210 150  10
+192 133   9 163 110   8 124 112  88  82  82  82
+ 50  50  50  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  14  14  14  22  22  22  34  34  34
+ 42  42  42  58  58  58  74  74  74  86  86  86
+101  98  89 122 102  70 130  98  46 121  87  25
+137  92   6 152  99   6 163 110   8 180 123   7
+185 133  11 197 138  11 206 145  10 200 144  11
+180 123   7 156 107  11 130  83   6 104  69   6
+ 50  34   6  54  54  54 110 110 110 101  98  89
+ 86  86  86  82  82  82  78  78  78  78  78  78
+ 78  78  78  78  78  78  78  78  78  78  78  78
+ 78  78  78  82  82  82  86  86  86  94  94  94
+106 106 106 101 101 101  86  66  34 124  80   6
+156 107  11 180 123   7 192 133   9 200 144  11
+206 145  10 200 144  11 192 133   9 175 118   6
+139 102  15 109 106  95  70  70  70  42  42  42
+ 22  22  22  10  10  10   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   6   6   6  10  10  10
+ 14  14  14  22  22  22  30  30  30  38  38  38
+ 50  50  50  62  62  62  74  74  74  90  90  90
+101  98  89 112 100  78 121  87  25 124  80   6
+137  92   6 152  99   6 152  99   6 152  99   6
+138  86   6 124  80   6  98  70   6  86  66  30
+101  98  89  82  82  82  58  58  58  46  46  46
+ 38  38  38  34  34  34  34  34  34  34  34  34
+ 34  34  34  34  34  34  34  34  34  34  34  34
+ 34  34  34  34  34  34  38  38  38  42  42  42
+ 54  54  54  82  82  82  94  86  76  91  60   6
+134  86   6 156 107  11 167 114   7 175 118   6
+175 118   6 167 114   7 152  99   6 121  87  25
+101  98  89  62  62  62  34  34  34  18  18  18
+  6   6   6   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6   6   6   6  10  10  10
+ 18  18  18  22  22  22  30  30  30  42  42  42
+ 50  50  50  66  66  66  86  86  86 101  98  89
+106  86  58  98  70   6 104  69   6 104  69   6
+104  69   6  91  60   6  82  62  34  90  90  90
+ 62  62  62  38  38  38  22  22  22  14  14  14
+ 10  10  10  10  10  10  10  10  10  10  10  10
+ 10  10  10  10  10  10   6   6   6  10  10  10
+ 10  10  10  10  10  10  10  10  10  14  14  14
+ 22  22  22  42  42  42  70  70  70  89  81  66
+ 80  54   7 104  69   6 124  80   6 137  92   6
+134  86   6 116  81   8 100  82  52  86  86  86
+ 58  58  58  30  30  30  14  14  14   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  10  10  10  14  14  14
+ 18  18  18  26  26  26  38  38  38  54  54  54
+ 70  70  70  86  86  86  94  86  76  89  81  66
+ 89  81  66  86  86  86  74  74  74  50  50  50
+ 30  30  30  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6  18  18  18  34  34  34  58  58  58
+ 82  82  82  89  81  66  89  81  66  89  81  66
+ 94  86  66  94  86  76  74  74  74  50  50  50
+ 26  26  26  14  14  14   6   6   6   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  6   6   6   6   6   6  14  14  14  18  18  18
+ 30  30  30  38  38  38  46  46  46  54  54  54
+ 50  50  50  42  42  42  30  30  30  18  18  18
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   6   6   6  14  14  14  26  26  26
+ 38  38  38  50  50  50  58  58  58  58  58  58
+ 54  54  54  42  42  42  30  30  30  18  18  18
+ 10  10  10   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+  6   6   6  10  10  10  14  14  14  18  18  18
+ 18  18  18  14  14  14  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   6   6   6
+ 14  14  14  18  18  18  22  22  22  22  22  22
+ 18  18  18  14  14  14  10  10  10   6   6   6
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
diff -Nru a/drivers/video/logo/logo_sun_clut224.ppm b/drivers/video/logo/logo_sun_clut224.ppm
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/logo_sun_clut224.ppm	Mon Feb 24 13:47:01 2003
@@ -0,0 +1,1604 @@
+P3
+# 224-color Sun Linux logo
+80 80
+255
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   6   6   6   6   6   6  10  10  10  10  10  10
+  10  10  10   6   6   6   6   6   6   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   6   6   6  10  10  10  14  14  14
+  22  22  22  26  26  26  30  30  30  34  34  34
+  30  30  30  30  30  30  26  26  26  18  18  18
+  14  14  14  10  10  10   6   6   6   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   1   0   0   1   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   6   6   6  14  14  14  26  26  26  42  42  42
+  54  54  54  66  66  66  78  78  78  78  78  78
+  78  78  78  74  74  74  66  66  66  54  54  54
+  42  42  42  26  26  26  18  18  18  10  10  10
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   1   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  22  22  22  42  42  42  66  66  66  86  86  86
+  66  66  66  38  38  38  38  38  38  22  22  22
+  26  26  26  34  34  34  54  54  54  66  66  66
+  86  86  86  70  70  70  46  46  46  26  26  26
+  14  14  14   6   6   6   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   1   0   0   1   0   0   1   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0  10  10  10  26  26  26
+  50  50  50  82  82  82  58  58  58   6   6   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   6   6   6  54  54  54  86  86  86  66  66  66
+  38  38  38  18  18  18   6   6   6   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   6   6   6  22  22  22  50  50  50
+  78  78  78  34  34  34   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   6   6   6  70  70  70
+  78  78  78  46  46  46  22  22  22   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   1   0   0   1   0   0   1   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   6   6   6  18  18  18  42  42  42  82  82  82
+  26  26  26   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6  14  14  14
+  46  46  46  34  34  34   6   6   6   2   2   6
+  42  42  42  78  78  78  42  42  42  18  18  18
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   1   0   0   0   0   0   1   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+  10  10  10  30  30  30  66  66  66  58  58  58
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6  26  26  26
+  86  86  86 101 101 101  46  46  46  10  10  10
+   2   2   6  58  58  58  70  70  70  34  34  34
+  10  10  10   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   1   0   0   1   0   0   1   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+  14  14  14  42  42  42  86  86  86  10  10  10
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6  30  30  30
+  94  94  94  94  94  94  58  58  58  26  26  26
+   2   2   6   6   6   6  78  78  78  54  54  54
+  22  22  22   6   6   6   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   6   6   6
+  22  22  22  62  62  62  62  62  62   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6  26  26  26
+  54  54  54  38  38  38  18  18  18  10  10  10
+   2   2   6   2   2   6  34  34  34  82  82  82
+  38  38  38  14  14  14   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   1   0   0   1   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   6   6   6
+  30  30  30  78  78  78  30  30  30   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6  10  10  10
+  10  10  10   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6  78  78  78
+  50  50  50  18  18  18   6   6   6   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   1   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  38  38  38  86  86  86  14  14  14   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6  54  54  54
+  66  66  66  26  26  26   6   6   6   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   1   0   0   1   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  14  14  14
+  42  42  42  82  82  82   2   2   6   2   2   6
+   2   2   6   6   6   6  10  10  10   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   6   6   6
+  14  14  14  10  10  10   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6  18  18  18
+  82  82  82  34  34  34  10  10  10   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   1   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  14  14  14
+  46  46  46  86  86  86   2   2   6   2   2   6
+   6   6   6   6   6   6  22  22  22  34  34  34
+   6   6   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6  18  18  18  34  34  34
+  10  10  10  50  50  50  22  22  22   2   2   6
+   2   2   6   2   2   6   2   2   6  10  10  10
+  86  86  86  42  42  42  14  14  14   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   1   0   0   1   0   0   1   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  14  14  14
+  46  46  46  86  86  86   2   2   6   2   2   6
+  38  38  38 116 116 116  94  94  94  22  22  22
+  22  22  22   2   2   6   2   2   6   2   2   6
+  14  14  14  86  86  86 138 138 138 162 162 162
+ 154 154 154  38  38  38  26  26  26   6   6   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+  86  86  86  46  46  46  14  14  14   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  14  14  14
+  46  46  46  86  86  86   2   2   6  14  14  14
+ 134 134 134 198 198 198 195 195 195 116 116 116
+  10  10  10   2   2   6   2   2   6   6   6   6
+ 101  98  89 187 187 187 210 210 210 218 218 218
+ 214 214 214 134 134 134  14  14  14   6   6   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+  86  86  86  50  50  50  18  18  18   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   1   0   0   0
+   0   0   1   0   0   1   0   0   1   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  14  14  14
+  46  46  46  86  86  86   2   2   6  54  54  54
+ 218 218 218 195 195 195 226 226 226 246 246 246
+  58  58  58   2   2   6   2   2   6  30  30  30
+ 210 210 210 253 253 253 174 174 174 123 123 123
+ 221 221 221 234 234 234  74  74  74   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+  70  70  70  58  58  58  22  22  22   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  14  14  14
+  46  46  46  82  82  82   2   2   6 106 106 106
+ 170 170 170  26  26  26  86  86  86 226 226 226
+ 123 123 123  10  10  10  14  14  14  46  46  46
+ 231 231 231 190 190 190   6   6   6  70  70  70
+  90  90  90 238 238 238 158 158 158   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+  70  70  70  58  58  58  22  22  22   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   1   0   0   0
+   0   0   1   0   0   1   0   0   1   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  14  14  14
+  42  42  42  86  86  86   6   6   6 116 116 116
+ 106 106 106   6   6   6  70  70  70 149 149 149
+ 128 128 128  18  18  18  38  38  38  54  54  54
+ 221 221 221 106 106 106   2   2   6  14  14  14
+  46  46  46 190 190 190 198 198 198   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+  74  74  74  62  62  62  22  22  22   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   1   0   0   0
+   0   0   1   0   0   0   0   0   1   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  14  14  14
+  42  42  42  94  94  94  14  14  14 101 101 101
+ 128 128 128   2   2   6  18  18  18 116 116 116
+ 118  98  46 121  92   8 121  92   8  98  78  10
+ 162 162 162 106 106 106   2   2   6   2   2   6
+   2   2   6 195 195 195 195 195 195   6   6   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+  74  74  74  62  62  62  22  22  22   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   1   0   0   1
+   0   0   1   0   0   0   0   0   1   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  38  38  38  90  90  90  14  14  14  58  58  58
+ 210 210 210  26  26  26  54  38   6 154 114  10
+ 226 170  11 236 186  11 225 175  15 184 144  12
+ 215 174  15 175 146  61  37  26   9   2   2   6
+  70  70  70 246 246 246 138 138 138   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+  70  70  70  66  66  66  26  26  26   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  38  38  38  86  86  86  14  14  14  10  10  10
+ 195 195 195 188 164 115 192 133   9 225 175  15
+ 239 182  13 234 190  10 232 195  16 232 200  30
+ 245 207  45 241 208  19 232 195  16 184 144  12
+ 218 194 134 211 206 186  42  42  42   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+  50  50  50  74  74  74  30  30  30   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  34  34  34  86  86  86  14  14  14   2   2   6
+ 121  87  25 192 133   9 219 162  10 239 182  13
+ 236 186  11 232 195  16 241 208  19 244 214  54
+ 246 218  60 246 218  38 246 215  20 241 208  19
+ 241 208  19 226 184  13 121  87  25   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+  50  50  50  82  82  82  34  34  34  10  10  10
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  34  34  34  82  82  82  30  30  30  61  42   6
+ 180 123   7 206 145  10 230 174  11 239 182  13
+ 234 190  10 238 202  15 241 208  19 246 218  74
+ 246 218  38 246 215  20 246 215  20 246 215  20
+ 226 184  13 215 174  15 184 144  12   6   6   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+  26  26  26  94  94  94  42  42  42  14  14  14
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  30  30  30  78  78  78  50  50  50 104  69   6
+ 192 133   9 216 158  10 236 178  12 236 186  11
+ 232 195  16 241 208  19 244 214  54 245 215  43
+ 246 215  20 246 215  20 241 208  19 198 155  10
+ 200 144  11 216 158  10 156 118  10   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   6   6   6  90  90  90  54  54  54  18  18  18
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  30  30  30  78  78  78  46  46  46  22  22  22
+ 137  92   6 210 162  10 239 182  13 238 190  10
+ 238 202  15 241 208  19 246 215  20 246 215  20
+ 241 208  19 203 166  17 185 133  11 210 150  10
+ 216 158  10 210 150  10 102  78  10   2   2   6
+   6   6   6  54  54  54  14  14  14   2   2   6
+   2   2   6  62  62  62  74  74  74  30  30  30
+  10  10  10   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  34  34  34  78  78  78  50  50  50   6   6   6
+  94  70  30 139 102  15 190 146  13 226 184  13
+ 232 200  30 232 195  16 215 174  15 190 146  13
+ 168 122  10 192 133   9 210 150  10 213 154  11
+ 202 150  34 182 157 106 101  98  89   2   2   6
+   2   2   6  78  78  78 116 116 116  58  58  58
+   2   2   6  22  22  22  90  90  90  46  46  46
+  18  18  18   6   6   6   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  38  38  38  86  86  86  50  50  50   6   6   6
+ 128 128 128 174 154 114 156 107  11 168 122  10
+ 198 155  10 184 144  12 197 138  11 200 144  11
+ 206 145  10 206 145  10 197 138  11 188 164 115
+ 195 195 195 198 198 198 174 174 174  14  14  14
+   2   2   6  22  22  22 116 116 116 116 116 116
+  22  22  22   2   2   6  74  74  74  70  70  70
+  30  30  30  10  10  10   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   6   6   6  18  18  18
+  50  50  50 101 101 101  26  26  26  10  10  10
+ 138 138 138 190 190 190 174 154 114 156 107  11
+ 197 138  11 200 144  11 197 138  11 192 133   9
+ 180 123   7 190 142  34 190 178 144 187 187 187
+ 202 202 202 221 221 221 214 214 214  66  66  66
+   2   2   6   2   2   6  50  50  50  62  62  62
+   6   6   6   2   2   6  10  10  10  90  90  90
+  50  50  50  18  18  18   6   6   6   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0  10  10  10  34  34  34
+  74  74  74  74  74  74   2   2   6   6   6   6
+ 144 144 144 198 198 198 190 190 190 178 166 146
+ 154 121  60 156 107  11 156 107  11 168 124  44
+ 174 154 114 187 187 187 190 190 190 210 210 210
+ 246 246 246 253 253 253 253 253 253 182 182 182
+   6   6   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6  62  62  62
+  74  74  74  34  34  34  14  14  14   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0  10  10  10  22  22  22  54  54  54
+  94  94  94  18  18  18   2   2   6  46  46  46
+ 234 234 234 221 221 221 190 190 190 190 190 190
+ 190 190 190 187 187 187 187 187 187 190 190 190
+ 190 190 190 195 195 195 214 214 214 242 242 242
+ 253 253 253 253 253 253 253 253 253 253 253 253
+  82  82  82   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6  14  14  14
+  86  86  86  54  54  54  22  22  22   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   6   6   6  18  18  18  46  46  46  90  90  90
+  46  46  46  18  18  18   6   6   6 182 182 182
+ 253 253 253 246 246 246 206 206 206 190 190 190
+ 190 190 190 190 190 190 190 190 190 190 190 190
+ 206 206 206 231 231 231 250 250 250 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 202 202 202  14  14  14   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+  42  42  42  86  86  86  42  42  42  18  18  18
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   6   6   6
+  14  14  14  38  38  38  74  74  74  66  66  66
+   2   2   6   6   6   6  90  90  90 250 250 250
+ 253 253 253 253 253 253 238 238 238 198 198 198
+ 190 190 190 190 190 190 195 195 195 221 221 221
+ 246 246 246 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253  82  82  82   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6  78  78  78  70  70  70  34  34  34
+  14  14  14   6   6   6   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  14  14  14
+  34  34  34  66  66  66  78  78  78   6   6   6
+   2   2   6  18  18  18 218 218 218 253 253 253
+ 253 253 253 253 253 253 253 253 253 246 246 246
+ 226 226 226 231 231 231 246 246 246 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 178 178 178   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6  18  18  18  90  90  90  62  62  62
+  30  30  30  10  10  10   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0  10  10  10  26  26  26
+  58  58  58  90  90  90  18  18  18   2   2   6
+   2   2   6 110 110 110 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 250 250 250 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 231 231 231  18  18  18   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6  18  18  18  94  94  94
+  54  54  54  26  26  26  10  10  10   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   6   6   6  22  22  22  50  50  50
+  90  90  90  26  26  26   2   2   6   2   2   6
+  14  14  14 195 195 195 250 250 250 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 250 250 250 242 242 242  54  54  54   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6  38  38  38
+  86  86  86  50  50  50  22  22  22   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   6   6   6  14  14  14  38  38  38  82  82  82
+  34  34  34   2   2   6   2   2   6   2   2   6
+  42  42  42 195 195 195 246 246 246 253 253 253
+ 253 253 253 253 253 253 253 253 253 250 250 250
+ 242 242 242 242 242 242 250 250 250 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 250 250 250 246 246 246 238 238 238
+ 226 226 226 231 231 231 101 101 101   6   6   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+  38  38  38  82  82  82  42  42  42  14  14  14
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+  10  10  10  26  26  26  62  62  62  66  66  66
+   2   2   6   2   2   6   2   2   6   6   6   6
+  70  70  70 170 170 170 206 206 206 234 234 234
+ 246 246 246 250 250 250 250 250 250 238 238 238
+ 226 226 226 231 231 231 238 238 238 250 250 250
+ 250 250 250 250 250 250 246 246 246 231 231 231
+ 214 214 214 206 206 206 202 202 202 202 202 202
+ 198 198 198 202 202 202 182 182 182  18  18  18
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6  62  62  62  66  66  66  30  30  30
+  10  10  10   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+  14  14  14  42  42  42  82  82  82  18  18  18
+   2   2   6   2   2   6   2   2   6  10  10  10
+  94  94  94 182 182 182 218 218 218 242 242 242
+ 250 250 250 253 253 253 253 253 253 250 250 250
+ 234 234 234 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 246 246 246
+ 238 238 238 226 226 226 210 210 210 202 202 202
+ 195 195 195 195 195 195 210 210 210 158 158 158
+   6   6   6  14  14  14  50  50  50  14  14  14
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   6   6   6  86  86  86  46  46  46
+  18  18  18   6   6   6   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   6   6   6
+  22  22  22  54  54  54  70  70  70   2   2   6
+   2   2   6  10  10  10   2   2   6  22  22  22
+ 166 166 166 231 231 231 250 250 250 253 253 253
+ 253 253 253 253 253 253 253 253 253 250 250 250
+ 242 242 242 254 250 234 238 238 238 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 246 246 246
+ 231 231 231 206 206 206 198 198 198 226 226 226
+  94  94  94   2   2   6   6   6   6  38  38  38
+  30  30  30   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6  62  62  62  66  66  66
+  26  26  26  10  10  10   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  30  30  30  74  74  74  50  50  50   2   2   6
+  26  26  26  26  26  26   2   2   6 106 106 106
+ 238 238 238 253 253 253 253 253 253 253 253 253
+ 246 246 246 254 250 234 253 253 253 253 253 253
+ 253 253 253 246 234 182 236 215 124 254 246 218
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 246 246 246 218 218 218 202 202 202
+ 210 210 210  14  14  14   2   2   6   2   2   6
+  30  30  30  22  22  22   2   2   6   2   2   6
+   2   2   6   2   2   6  18  18  18  86  86  86
+  42  42  42  14  14  14   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  14  14  14
+  42  42  42  90  90  90  22  22  22   2   2   6
+  42  42  42   2   2   6  18  18  18 218 218 218
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 210 188 142 234 218 166 253 253 253 253 253 253
+ 254 250 234 245 222 135 242 218 102 254 250 234
+ 253 253 253 253 253 253 253 253 253 254 246 218
+ 242 230 182 246 246 246 253 253 253 253 253 253
+ 253 253 253 253 253 253 250 250 250 221 221 221
+ 218 218 218 101 101 101   2   2   6  14  14  14
+  18  18  18  38  38  38  10  10  10   2   2   6
+   2   2   6   2   2   6   2   2   6  78  78  78
+  58  58  58  22  22  22   6   6   6   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   6   6   6  18  18  18
+  54  54  54  82  82  82   2   2   6  26  26  26
+  22  22  22   2   2   6 123 123 123 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 233 202 129 236 215 124 253 253 253 253 253 253
+ 254 250 234 238 216 106 242 218 102 254 250 234
+ 253 253 253 253 253 253 246 234 198 236 215 124
+ 245 222 135 254 250 234 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 250 250 250
+ 238 238 238 198 198 198   6   6   6  38  38  38
+  58  58  58  26  26  26  38  38  38   2   2   6
+   2   2   6   2   2   6   2   2   6  46  46  46
+  78  78  78  30  30  30  10  10  10   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0  10  10  10  30  30  30
+  74  74  74  58  58  58   2   2   6  42  42  42
+   2   2   6  22  22  22 231 231 231 253 253 253
+ 238 238 238 238 238 238 253 253 253 253 253 253
+ 242 224 154 238 204  91 246 234 182 253 253 253
+ 246 242 210 242 218 102 242 218 102 254 250 234
+ 253 253 253 254 246 218 238 216 106 242 218 102
+ 254 246 218 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 246 246 246  46  46  46  38  38  38
+  42  42  42  14  14  14  38  38  38  14  14  14
+   2   2   6   2   2   6   2   2   6   6   6   6
+  86  86  86  46  46  46  14  14  14   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   6   6   6  14  14  14  42  42  42
+  90  90  90  18  18  18  18  18  18  26  26  26
+   2   2   6 116 116 116 253 253 253 253 253 253
+ 218 206 182 212 178 106 253 253 253 253 253 253
+ 246 242 210 238 204  91 236 215 124 254 250 234
+ 254 246 218 238 216 106 238 216 106 254 246 218
+ 253 253 253 242 224 154 246 218  74 242 230 182
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 254 250 234 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253  94  94  94   6   6   6
+   2   2   6   2   2   6  10  10  10  34  34  34
+   2   2   6   2   2   6   2   2   6   2   2   6
+  74  74  74  58  58  58  22  22  22   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0  10  10  10  26  26  26  66  66  66
+  82  82  82   2   2   6  38  38  38   6   6   6
+  14  14  14 210 210 210 253 253 253 253 253 253
+ 250 238 202 202 162  69 242 214 146 254 250 234
+ 253 253 253 246 230 178 245 222 135 246 230 178
+ 242 224 154 238 216 106 238 216 106 246 230 178
+ 254 246 202 238 216 106 242 215  82 250 238 202
+ 253 253 253 253 253 253 246 234 182 245 222 135
+ 236 215 124 246 242 210 253 253 253 253 253 253
+ 253 253 253 253 253 253 144 144 144   2   2   6
+   2   2   6   2   2   6   2   2   6  46  46  46
+   2   2   6   2   2   6   2   2   6   2   2   6
+  42  42  42  74  74  74  30  30  30  10  10  10
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   6   6   6  14  14  14  42  42  42  90  90  90
+  26  26  26   6   6   6  42  42  42   2   2   6
+  74  74  74 250 250 250 253 253 253 253 253 253
+ 253 253 253 218 197 138 228 184  62 234 218 166
+ 254 246 218 242 230 182 242 215  82 246 218  74
+ 246 218  60 246 218  60 244 214  54 246 218  60
+ 238 216 106 242 215  82 242 224 154 253 253 253
+ 254 250 234 242 224 154 238 216 106 236 215 124
+ 246 234 198 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 182 182 182   2   2   6
+   2   2   6   2   2   6   2   2   6  46  46  46
+   2   2   6   2   2   6   2   2   6   2   2   6
+  10  10  10  86  86  86  38  38  38  10  10  10
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+  10  10  10  26  26  26  66  66  66  82  82  82
+   2   2   6  22  22  22  18  18  18   2   2   6
+ 149 149 149 253 253 253 253 253 253 253 253 253
+ 253 253 253 254 246 218 233 202 129 236 215 124
+ 245 222 135 242 218 102 244 214  54 244 214  54
+ 246 218  60 246 218  60 246 218  60 246 218  60
+ 246 218  60 246 218  74 245 222 135 246 234 182
+ 246 234 182 246 218  74 242 218 102 254 246 218
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 206 206 206   2   2   6
+   2   2   6   2   2   6   2   2   6  38  38  38
+   2   2   6   2   2   6   2   2   6   2   2   6
+   6   6   6  86  86  86  46  46  46  14  14  14
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   6   6   6
+  18  18  18  46  46  46  86  86  86  18  18  18
+   2   2   6  34  34  34  10  10  10   6   6   6
+ 210 210 210 253 253 253 221 221 221 254 246 218
+ 254 250 234 253 253 253 254 246 218 236 215 124
+ 246 198  46 244 214  54 244 214  54 242 215  82
+ 246 218  74 246 218  60 246 218  74 246 218  74
+ 244 214  54 246 218  60 246 218  74 242 215  82
+ 242 218 102 236 215 124 246 234 182 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 221 221 221   6   6   6
+   2   2   6   2   2   6   6   6   6  30  30  30
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6  82  82  82  54  54  54  18  18  18
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  26  26  26  66  66  66  62  62  62   2   2   6
+   2   2   6  38  38  38  10  10  10  26  26  26
+ 238 238 238 253 253 253 210 188 142 202 162  69
+ 218 197 138 246 230 178 246 234 198 238 204  91
+ 245 207  45 245 207  45 244 214  54 246 218  60
+ 246 218  60 246 218  60 246 218  60 246 218  60
+ 246 218  74 246 218  60 246 218  60 242 215  82
+ 242 218 102 254 246 202 253 253 253 254 250 234
+ 254 246 202 254 246 202 254 246 218 254 250 234
+ 253 253 253 253 253 253 231 231 231   6   6   6
+   2   2   6   2   2   6  10  10  10  30  30  30
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6  66  66  66  58  58  58  22  22  22
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  38  38  38  78  78  78   6   6   6   2   2   6
+   2   2   6  46  46  46  14  14  14  42  42  42
+ 246 246 246 253 253 253 254 246 218 218 197 138
+ 212 178 106 221 185 102 242 206 102 245 207  45
+ 244 214  54 244 214  54 246 218  60 246 218  60
+ 246 218  60 246 218  60 246 218  60 246 218  74
+ 246 218  60 246 218  60 242 218 102 246 218  60
+ 242 215  82 246 234 182 246 234 198 242 218 102
+ 242 218 102 238 216 106 242 214 146 246 230 178
+ 253 253 253 253 253 253 234 234 234  10  10  10
+   2   2   6   2   2   6  22  22  22  14  14  14
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6  66  66  66  62  62  62  22  22  22
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   6   6   6  18  18  18
+  50  50  50  74  74  74   2   2   6   2   2   6
+  14  14  14  70  70  70  34  34  34  62  62  62
+ 250 250 250 253 253 253 253 253 253 253 253 253
+ 250 238 202 250 238 202 242 206 102 246 198  46
+ 245 207  45 245 207  45 241 208  19 246 218  74
+ 246 218  60 242 215  82 246 218  60 242 215  82
+ 246 218  74 246 218  74 246 218  74 246 218  74
+ 246 218  74 245 222 135 238 222 174 238 216 106
+ 245 222 135 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 234 234 234  14  14  14
+   2   2   6   2   2   6  30  30  30   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6  66  66  66  62  62  62  22  22  22
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   6   6   6  18  18  18
+  54  54  54  62  62  62   2   2   6   2   2   6
+   2   2   6  30  30  30  46  46  46  70  70  70
+ 250 250 250 253 253 253 253 253 253 253 253 253
+ 253 253 253 254 250 234 238 204  91 245 207  45
+ 250 206  62 244 214  54 244 214  54 244 214  54
+ 242 215  82 246 218  60 244 214  54 246 218  60
+ 246 218  60 246 218  74 246 218  74 242 215  82
+ 242 215  82 245 222 135 254 250 234 254 250 234
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 226 226 226  10  10  10
+   2   2   6   6   6   6  30  30  30   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6  66  66  66  58  58  58  22  22  22
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   6   6   6  22  22  22
+  58  58  58  62  62  62   2   2   6   2   2   6
+   2   2   6   2   2   6  30  30  30  78  78  78
+ 250 250 250 253 253 253 253 253 253 250 238 202
+ 246 234 198 246 230 178 240 198  71 246 198  46
+ 246 198  46 245 207  45 244 214  54 244 214  54
+ 242 215  82 246 218  60 246 218  74 244 214  54
+ 246 218  74 246 218  60 246 218  74 246 218  74
+ 242 215  82 238 216 106 254 246 218 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 206 206 206   2   2   6
+  22  22  22  34  34  34  18  14   6  22  22  22
+  26  26  26  18  18  18   6   6   6   2   2   6
+   2   2   6  82  82  82  54  54  54  18  18  18
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   6   6   6  26  26  26
+  62  62  62 106 106 106  74  54  14 185 133  11
+ 210 162  10 121  92   8   6   6   6  62  62  62
+ 238 238 238 253 253 253 253 253 253 188 164 115
+ 202 162  69 214 174  82 242 190  54 242 190  54
+ 246 198  46 246 198  46 245 207  45 250 206  62
+ 244 214  54 244 214  54 244 214  54 246 218  74
+ 246 218  74 246 218  74 246 218  74 244 214  54
+ 246 218  74 238 216 106 246 234 182 242 224 154
+ 246 230 178 254 246 218 253 253 253 253 253 253
+ 253 253 253 253 253 253 158 158 158  18  18  18
+  14  14  14   2   2   6   2   2   6   2   2   6
+   6   6   6  18  18  18  66  66  66  38  38  38
+   6   6   6  94  94  94  50  50  50  18  18  18
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   6   6   6
+  10  10  10  10  10  10  18  18  18  38  38  38
+  78  78  78 142 134 106 216 158  10 242 186  14
+ 246 190  14 246 190  14 156 118  10  10  10  10
+  90  90  90 238 238 238 253 253 253 253 253 253
+ 250 238 202 246 234 198 233 202 129 240 198  71
+ 245 207  45 246 198  46 246 198  46 245 207  45
+ 245 207  45 244 214  54 244 214  54 246 218  60
+ 244 214  54 244 214  54 242 215  82 244 214  54
+ 246 218  74 242 224 154 242 224 154 242 215  82
+ 246 218  74 242 218 102 246 230 178 246 230 190
+ 238 204  91 238 204  91 181 142  44  37  26   9
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6  38  38  38  46  46  46
+  26  26  26 106 106 106  54  54  54  18  18  18
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   6   6   6  14  14  14  22  22  22
+  30  30  30  38  38  38  50  50  50  70  70  70
+ 106 106 106 190 142  34 226 170  11 242 186  14
+ 246 190  14 246 190  14 246 190  14 154 114  10
+   6   6   6  74  74  74 226 226 226 253 253 253
+ 253 253 253 253 253 253 250 238 202 239 182  13
+ 242 190  54 246 198  46 246 198  46 246 198  46
+ 245 207  45 246 215  20 244 214  54 244 214  54
+ 246 218  60 246 215  20 246 218  60 246 218  60
+ 242 218 102 246 234 182 254 250 234 254 246 202
+ 254 246 202 246 234 182 236 215 124 228 184  62
+ 241 196  14 241 208  19 232 195  16  38  30  10
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   6   6   6  30  30  30  26  26  26
+ 203 166  17 154 142  90  66  66  66  26  26  26
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   6   6   6  18  18  18  38  38  38  58  58  58
+  78  78  78  86  86  86 101 101 101 123 123 123
+ 175 146  61 210 150  10 234 174  13 246 186  14
+ 246 190  14 246 190  14 246 190  14 238 190  10
+ 102  78  10   2   2   6  46  46  46 198 198 198
+ 254 246 218 234 218 166 233 202 129 238 216 106
+ 246 198  46 246 198  46 246 198  46 246 198  46
+ 245 207  45 244 214  54 244 214  54 244 214  54
+ 244 214  54 246 215  20 246 218  60 246 215  20
+ 242 218 102 254 246 202 254 250 234 254 250 234
+ 253 253 253 253 253 253 253 253 253 224 178  62
+ 242 186  14 241 196  14 210 166  10  22  18   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   6   6   6 121  92   8
+ 238 202  15 232 195  16  82  82  82  34  34  34
+  10  10  10   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+  14  14  14  38  38  38  70  70  70 154 122  46
+ 190 142  34 200 144  11 197 138  11 197 138  11
+ 213 154  11 226 170  11 242 186  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 225 175  15  46  32   6   2   2   6  22  22  22
+ 210 198 158 202 162  69 212 178 106 246 234 198
+ 242 206 102 246 198  46 245 207  45 245 207  45
+ 245 207  45 246 215  20 244 214  54 244 214  54
+ 244 214  54 246 218  60 244 214  54 246 218  74
+ 236 215 124 238 216 106 236 215 124 250 238 202
+ 254 250 234 250 250 250 242 242 242 224 178  62
+ 239 182  13 236 186  11 213 154  11  46  32   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6  61  42   6 225 175  15
+ 238 190  10 236 186  11 112 100  78  42  42  42
+  14  14  14   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   6   6   6
+  22  22  22  54  54  54 154 122  46 213 154  11
+ 226 170  11 230 174  11 226 170  11 226 170  11
+ 236 178  12 242 186  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 241 196  14 184 144  12  10  10  10   2   2   6
+   6   6   6 116 116 116 242 242 242 253 253 253
+ 254 246 218 233 202 129 228 184  62 242 190  54
+ 246 198  46 245 207  45 245 207  45 250 206  62
+ 245 207  45 244 214  54 242 215  82 254 246 202
+ 254 246 202 242 224 154 242 215  82 236 215 124
+ 250 238 202 231 231 231 198 198 198 214 170  54
+ 236 178  12 236 178  12 210 150  10 137  92   6
+  18  14   6   2   2   6   2   2   6   2   2   6
+   6   6   6  70  47   6 200 144  11 236 178  12
+ 239 182  13 239 182  13 124 112  88  58  58  58
+  22  22  22   6   6   6   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  30  30  30  70  70  70 180 133  36 226 170  11
+ 239 182  13 242 186  14 242 186  14 246 186  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 232 195  16  98  70   6   2   2   6
+   2   2   6   2   2   6  66  66  66 221 221 221
+ 218 206 158 238 214 174 246 230 178 233 202 129
+ 240 198  71 240 198  71 240 198  71 240 198  71
+ 238 216 106 242 224 154 246 230 178 245 222 135
+ 254 246 218 254 250 234 254 246 218 236 215 124
+ 218 194 134 206 206 206 198 198 198 214 166  58
+ 230 174  11 230 174  11 216 158  10 192 133   9
+ 163 110   8 116  81   8 102  78  10 116  81   8
+ 167 114   7 197 138  11 226 170  11 239 182  13
+ 242 186  14 242 186  14 162 146  94  78  78  78
+  34  34  34  14  14  14   6   6   6   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   6   6   6
+  30  30  30  78  78  78 190 142  34 226 170  11
+ 239 182  13 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 241 196  14 203 166  17  22  18   6
+   2   2   6   2   2   6   2   2   6  38  38  38
+ 202 162  69 238 214 174 253 253 253 236 215 124
+ 242 214 146 250 238 202 250 238 202 246 230 178
+ 254 246 218 253 253 253 242 230 182 240 198  71
+ 238 216 106 254 246 218 253 253 253 254 250 234
+ 246 234 198 206 206 206 198 198 198 202 162  69
+ 226 170  11 236 178  12 224 166  10 210 150  10
+ 200 144  11 197 138  11 192 133   9 197 138  11
+ 210 150  10 226 170  11 242 186  14 246 190  14
+ 246 190  14 246 186  14 225 175  15 124 112  88
+  62  62  62  30  30  30  14  14  14   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  30  30  30  78  78  78 174 135  50 224 166  10
+ 239 182  13 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 241 196  14 139 102  15
+   2   2   6   2   2   6   2   2   6   2   2   6
+  78  78  78 250 250 250 253 253 253 221 185 102
+ 212 178 106 254 246 218 254 246 218 221 185 102
+ 233 202 129 254 250 234 253 253 253 242 230 182
+ 228 184  62 238 214 174 253 253 253 253 253 253
+ 250 250 250 214 214 214 198 198 198 190 150  46
+ 219 162  10 236 178  12 234 174  13 224 166  10
+ 216 158  10 213 154  11 213 154  11 216 158  10
+ 226 170  11 239 182  13 246 190  14 246 190  14
+ 246 190  14 246 190  14 242 186  14 206 162  42
+ 101 101 101  58  58  58  30  30  30  14  14  14
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  30  30  30  74  74  74 174 135  50 216 158  10
+ 236 178  12 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 241 196  14 226 184  13
+  61  42   6   2   2   6   2   2   6   2   2   6
+  22  22  22 238 238 238 253 253 253 210 188 142
+ 212 178 106 254 250 234 253 253 253 218 197 138
+ 212 178 106 254 246 218 253 253 253 254 250 234
+ 226 214 178 218 206 158 253 253 253 253 253 253
+ 253 253 253 226 226 226 187 187 187 180 133  36
+ 216 158  10 236 178  12 239 182  13 236 178  12
+ 230 174  11 226 170  11 226 170  11 230 174  11
+ 236 178  12 242 186  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 186  14 239 182  13
+ 206 162  42 106 106 106  66  66  66  34  34  34
+  14  14  14   6   6   6   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   6   6   6
+  26  26  26  70  70  70 163 133  67 213 154  11
+ 236 178  12 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 241 196  14
+ 190 146  13  18  14   6   2   2   6   2   2   6
+  46  46  46 246 246 246 253 253 253 231 231 231
+ 246 234 182 253 253 253 253 253 253 226 214 178
+ 190 178 144 254 250 234 253 253 253 254 250 234
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 221 221 221  86  86  86 156 107  11
+ 216 158  10 236 178  12 242 186  14 246 186  14
+ 242 186  14 239 182  13 239 182  13 242 186  14
+ 242 186  14 246 186  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 242 186  14 225 175  15 142 122  72  66  66  66
+  30  30  30  10  10  10   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   6   6   6
+  26  26  26  70  70  70 163 133  67 210 150  10
+ 236 178  12 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 232 195  16 121  92   8  34  34  34 106 106 106
+ 221 221 221 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 242 242 242  82  82  82  18  14   6 163 110   8
+ 216 158  10 236 178  12 242 186  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 242 186  14 163 133  67
+  46  46  46  18  18  18   6   6   6   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  10  10  10
+  30  30  30  78  78  78 163 133  67 210 150  10
+ 236 178  12 246 186  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 241 196  14 215 174  15 190 178 144 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 218 218 218
+  58  58  58   2   2   6  22  18   6 167 114   7
+ 216 158  10 236 178  12 246 186  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 186  14 242 186  14 190 150  46
+  54  54  54  22  22  22   6   6   6   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  14  14  14
+  38  38  38  86  86  86 180 133  36 213 154  11
+ 236 178  12 246 186  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 232 195  16 190 146  13 214 214 214
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 250 250 250 170 170 170  26  26  26
+   2   2   6   2   2   6  37  26   9 163 110   8
+ 219 162  10 239 182  13 246 186  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 186  14 236 178  12 224 166  10 142 122  72
+  46  46  46  18  18  18   6   6   6   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   6   6   6  18  18  18
+  50  50  50 109 106  95 192 133   9 224 166  10
+ 242 186  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 242 186  14 226 184  13 210 162  10 142 110  46
+ 226 226 226 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 253 253 253 253 253 253 253 253 253 253 253 253
+ 198 198 198  66  66  66   2   2   6   2   2   6
+   2   2   6   2   2   6  50  34   6 156 107  11
+ 219 162  10 239 182  13 246 186  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 242 186  14
+ 234 174  13 213 154  11 154 122  46  66  66  66
+  30  30  30  10  10  10   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   6   6   6  22  22  22
+  58  58  58 154 121  60 206 145  10 234 174  13
+ 242 186  14 246 186  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 186  14 236 178  12 210 162  10 163 110   8
+  61  42   6 138 138 138 218 218 218 250 250 250
+ 253 253 253 253 253 253 253 253 253 250 250 250
+ 242 242 242 210 210 210 144 144 144  66  66  66
+   6   6   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6  61  42   6 163 110   8
+ 216 158  10 236 178  12 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 239 182  13 230 174  11 216 158  10
+ 190 142  34 124 112  88  70  70  70  38  38  38
+  18  18  18   6   6   6   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   6   6   6  22  22  22
+  62  62  62 168 124  44 206 145  10 224 166  10
+ 236 178  12 239 182  13 242 186  14 242 186  14
+ 246 186  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 236 178  12 216 158  10 175 118   6
+  80  54   7   2   2   6   6   6   6  30  30  30
+  54  54  54  62  62  62  50  50  50  38  38  38
+  14  14  14   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   6   6   6  80  54   7 167 114   7
+ 213 154  11 236 178  12 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 190  14 242 186  14 239 182  13 239 182  13
+ 230 174  11 210 150  10 174 135  50 124 112  88
+  82  82  82  54  54  54  34  34  34  18  18  18
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   6   6   6  18  18  18
+  50  50  50 158 118  36 192 133   9 200 144  11
+ 216 158  10 219 162  10 224 166  10 226 170  11
+ 230 174  11 236 178  12 239 182  13 239 182  13
+ 242 186  14 246 186  14 246 190  14 246 190  14
+ 246 190  14 246 190  14 246 190  14 246 190  14
+ 246 186  14 230 174  11 210 150  10 163 110   8
+ 104  69   6  10  10  10   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   6   6   6  91  60   6 167 114   7
+ 206 145  10 230 174  11 242 186  14 246 190  14
+ 246 190  14 246 190  14 246 186  14 242 186  14
+ 239 182  13 230 174  11 224 166  10 213 154  11
+ 180 133  36 124 112  88  86  86  86  58  58  58
+  38  38  38  22  22  22  10  10  10   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0  14  14  14
+  34  34  34  70  70  70 138 110  50 158 118  36
+ 167 114   7 180 123   7 192 133   9 197 138  11
+ 200 144  11 206 145  10 213 154  11 219 162  10
+ 224 166  10 230 174  11 239 182  13 242 186  14
+ 246 186  14 246 186  14 246 186  14 246 186  14
+ 239 182  13 216 158  10 185 133  11 152  99   6
+ 104  69   6  18  14   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   2   2   6   2   2   6   2   2   6
+   2   2   6   6   6   6  80  54   7 152  99   6
+ 192 133   9 219 162  10 236 178  12 239 182  13
+ 246 186  14 242 186  14 239 182  13 236 178  12
+ 224 166  10 206 145  10 192 133   9 154 121  60
+  94  94  94  62  62  62  42  42  42  22  22  22
+  14  14  14   6   6   6   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   6   6   6
+  18  18  18  34  34  34  58  58  58  78  78  78
+ 101  98  89 124 112  88 142 110  46 156 107  11
+ 163 110   8 167 114   7 175 118   6 180 123   7
+ 185 133  11 197 138  11 210 150  10 219 162  10
+ 226 170  11 236 178  12 236 178  12 234 174  13
+ 219 162  10 197 138  11 163 110   8 130  83   6
+  91  60   6  10  10  10   2   2   6   2   2   6
+  18  18  18  38  38  38  38  38  38  38  38  38
+  38  38  38  38  38  38  38  38  38  38  38  38
+  38  38  38  38  38  38  26  26  26   2   2   6
+   2   2   6   6   6   6  70  47   6 137  92   6
+ 175 118   6 200 144  11 219 162  10 230 174  11
+ 234 174  13 230 174  11 219 162  10 210 150  10
+ 192 133   9 163 110   8 124 112  88  82  82  82
+  50  50  50  30  30  30  14  14  14   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   6   6   6  14  14  14  22  22  22  34  34  34
+  42  42  42  58  58  58  74  74  74  86  86  86
+ 101  98  89 122 102  70 130  98  46 121  87  25
+ 137  92   6 152  99   6 163 110   8 180 123   7
+ 185 133  11 197 138  11 206 145  10 200 144  11
+ 180 123   7 156 107  11 130  83   6 104  69   6
+  50  34   6  54  54  54 110 110 110 101  98  89
+  86  86  86  82  82  82  78  78  78  78  78  78
+  78  78  78  78  78  78  78  78  78  78  78  78
+  78  78  78  82  82  82  86  86  86  94  94  94
+ 106 106 106 101 101 101  86  66  34 124  80   6
+ 156 107  11 180 123   7 192 133   9 200 144  11
+ 206 145  10 200 144  11 192 133   9 175 118   6
+ 139 102  15 109 106  95  70  70  70  42  42  42
+  22  22  22  10  10  10   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   6   6   6  10  10  10
+  14  14  14  22  22  22  30  30  30  38  38  38
+  50  50  50  62  62  62  74  74  74  90  90  90
+ 101  98  89 112 100  78 121  87  25 124  80   6
+ 137  92   6 152  99   6 152  99   6 152  99   6
+ 138  86   6 124  80   6  98  70   6  86  66  30
+ 101  98  89  82  82  82  58  58  58  46  46  46
+  38  38  38  34  34  34  34  34  34  34  34  34
+  34  34  34  34  34  34  34  34  34  34  34  34
+  34  34  34  34  34  34  38  38  38  42  42  42
+  54  54  54  82  82  82  94  86  76  91  60   6
+ 134  86   6 156 107  11 167 114   7 175 118   6
+ 175 118   6 167 114   7 152  99   6 121  87  25
+ 101  98  89  62  62  62  34  34  34  18  18  18
+   6   6   6   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   6   6   6   6   6   6  10  10  10
+  18  18  18  22  22  22  30  30  30  42  42  42
+  50  50  50  66  66  66  86  86  86 101  98  89
+ 106  86  58  98  70   6 104  69   6 104  69   6
+ 104  69   6  91  60   6  82  62  34  90  90  90
+  62  62  62  38  38  38  22  22  22  14  14  14
+  10  10  10  10  10  10  10  10  10  10  10  10
+  10  10  10  10  10  10   6   6   6  10  10  10
+  10  10  10  10  10  10  10  10  10  14  14  14
+  22  22  22  42  42  42  70  70  70  89  81  66
+  80  54   7 104  69   6 124  80   6 137  92   6
+ 134  86   6 116  81   8 100  82  52  86  86  86
+  58  58  58  30  30  30  14  14  14   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   6   6   6  10  10  10  14  14  14
+  18  18  18  26  26  26  38  38  38  54  54  54
+  70  70  70  86  86  86  94  86  76  89  81  66
+  89  81  66  86  86  86  74  74  74  50  50  50
+  30  30  30  14  14  14   6   6   6   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   6   6   6  18  18  18  34  34  34  58  58  58
+  82  82  82  89  81  66  89  81  66  89  81  66
+  94  86  66  94  86  76  74  74  74  50  50  50
+  26  26  26  14  14  14   6   6   6   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   6   6   6   6   6   6  14  14  14  18  18  18
+  30  30  30  38  38  38  46  46  46  54  54  54
+  50  50  50  42  42  42  30  30  30  18  18  18
+  10  10  10   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   6   6   6  14  14  14  26  26  26
+  38  38  38  50  50  50  58  58  58  58  58  58
+  54  54  54  42  42  42  30  30  30  18  18  18
+  10  10  10   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   6   6   6
+   6   6   6  10  10  10  14  14  14  18  18  18
+  18  18  18  14  14  14  10  10  10   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   6   6   6
+  14  14  14  18  18  18  22  22  22  22  22  22
+  18  18  18  14  14  14  10  10  10   6   6   6
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
+   0   0   0   0   0   0   0   0   0   0   0   0
diff -Nru a/drivers/video/logo/logo_superh_clut224.ppm b/drivers/video/logo/logo_superh_clut224.ppm
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/logo_superh_clut224.ppm	Mon Feb 24 13:47:01 2003
@@ -0,0 +1,1604 @@
+P3
+# 224-color SuperH Linux logo
+80 80
+255
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  6   6   6   6   6   6  10  10  10  10  10  10
+ 10  10  10   6   6   6   6   6   6   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   6   6   6  10  10  10  14  14  13
+ 22  22  22  26  26  26  30  30  30  34  34  34
+ 30  30  30  30  30  30  26  26  26  18  18  18
+ 14  14  13  10  10  10   6   6   6   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  6   6   6  14  14  13  26  26  26  42  42  43
+ 54  54  54  66  66  66  78  78  78  78  78  78
+ 78  78  78  74  74  74  66  66  66  54  54  54
+ 42  42  43  26  26  26  18  18  18  10  10  10
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 22  22  22  42  42  43  66  66  66  86  86  86
+ 66  66  66  38  38  38  38  38  38  22  22  22
+ 26  26  26  34  34  34  54  54  54  66  66  66
+ 86  86  86  70  70  70  46  46  46  26  26  26
+ 14  14  13   6   6   6   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2  10  10  10  26  26  26
+ 50  50  50  82  82  82  58  58  58   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  54  54  54  86  86  86  66  66  66
+ 38  38  38  18  18  18   6   6   6   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   6   6   6  22  22  22  50  50  50
+ 78  78  78  34  34  34   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   6   6   6  70  70  70
+ 78  78  78  46  46  46  22  22  22   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  6   6   6  18  18  18  42  42  43  82  82  82
+ 26  26  26   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  14  14  13
+ 46  46  46  34  34  34   6   6   6   2   2   6
+ 42  42  43  78  78  78  42  42  43  18  18  18
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+ 10  10  10  30  30  30  66  66  66  58  58  58
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  26  26  26
+ 86  86  86 102 102 102  46  46  46  10  10  10
+  2   2   6  58  58  58  70  70  70  34  34  34
+ 10  10  10   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+ 14  14  13  42  42  43  86  86  86  10  10  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  30  30  30
+ 94  94  93  94  94  93  58  58  58  26  26  26
+  2   2   6   6   6   6  78  78  78  54  54  54
+ 22  22  22   6   6   6   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   6   6   6
+ 22  22  22  62  62  62  62  62  62   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  26  26  26
+ 54  54  54  38  38  38  18  18  18  10  10  10
+  2   2   6   2   2   6  34  34  34  82  82  82
+ 38  38  38  14  14  13   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   6   6   6
+ 30  30  30  78  78  78  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 10  10  10   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  78  78  78
+ 50  50  50  18  18  18   6   6   6   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 38  38  38  86  86  86  14  14  13   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  54  54  54
+ 66  66  66  26  26  26   6   6   6   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  14  14  13
+ 42  42  43  82  82  82   2   2   6   2   2   6
+  2   2   6   6   6   6  10  10  10   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 14  14  13  10  10  10   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  18  18  18
+ 82  82  82  34  34  34  10  10  10   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  14  14  13
+ 46  46  46  86  86  86   2   2   6   2   2   6
+  6   6   6   6   6   6  22  22  22  34  34  34
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  34  34  34
+ 10  10  10  50  50  50  22  22  22   2   2   6
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 86  86  86  42  42  43  14  14  13   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  14  14  13
+ 46  46  46  86  86  86   2   2   6   2   2   6
+ 38  38  38 118 118 118  94  94  93  22  22  22
+ 22  22  22   2   2   6   2   2   6   2   2   6
+ 14  14  13  86  86  86 138 138 142 163 163 163
+154 154 154  38  38  38  26  26  26   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 86  86  86  46  46  46  14  14  13   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  14  14  13
+ 46  46  46  86  86  86   2   2   6  14  14  13
+134 134 134 198 198 196 194 194 194 118 118 118
+ 10  10  10   2   2   6   2   2   6   6   6   6
+102  98  90 186 186 186 210 210 210 218 218 218
+214 214 214 134 134 134  14  14  13   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 86  86  86  50  50  50  18  18  18   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  14  14  13
+ 46  46  46  86  86  86   2   2   6  54  54  54
+218 218 218 194 194 194 226 226 226 246 246 246
+ 58  58  58   2   2   6   2   2   6  30  30  30
+210 210 210 254 254 254 174 174 174 122 122 122
+223 222 222 234 234 234  74  74  74   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  58  58  58  22  22  22   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  14  14  13
+ 46  46  46  82  82  82   2   2   6 106 106 105
+170 170 170  26  26  26  86  86  86 226 226 226
+122 122 122  10  10  10  14  14  13  46  46  46
+230 230 228 190 190 187   6   6   6  70  70  70
+ 89  90  90 238 238 238 158 158 158   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  58  58  58  22  22  22   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  14  14  13
+ 42  42  43  86  86  86   6   6   6 118 118 118
+106 106 105   6   6   6  70  70  70 150 150 150
+130 130 130  18  18  18  38  38  38  54  54  54
+223 222 222 106 106 105   2   2   6  14  14  13
+ 46  46  46 190 190 187 198 198 196   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  62  62  62  22  22  22   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  14  14  13
+ 42  42  43  94  94  93  14  14  13 102 102 102
+130 130 130   2   2   6  18  18  18 118 118 118
+122 100  66 122  94  10 122  94  10 104  78  10
+163 163 163 106 106 105   2   2   6   2   2   6
+  2   2   6 194 194 194 194 194 194   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  62  62  62  22  22  22   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 38  38  38  89  90  90  14  14  13  58  58  58
+210 210 210  26  26  26  60  40   9 154 114  10
+226 170  10 241 186  13 229 174  11 186 146  17
+214 174  14 178 147  70  38  26  10   2   2   6
+ 70  70  70 246 246 246 138 138 142   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 70  70  70  66  66  66  26  26  26   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 38  38  38  86  86  86  14  14  13  10  10  10
+194 194 194 190 166 114 195 134  10 229 174  11
+238 182  14 234 190  10 234 196  18 238 202  21
+246 206  46 244 212  20 234 196  18 186 146  17
+218 194 134 206 206 194  42  42  43   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 50  50  50  74  74  74  30  30  30   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 34  34  34  86  86  86  14  14  13   2   2   6
+122  86  26 195 134  10 220 162  10 238 182  14
+241 186  13 234 196  18 244 212  20 246 217  53
+246 217  53 246 217  39 244 212  20 244 212  20
+244 212  20 224 188  14 122  86  26   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 50  50  50  82  82  82  34  34  34  10  10  10
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 34  34  34  82  82  82  30  30  30  60  40   9
+181 122   9 204 146  11 229 174  11 238 182  14
+234 190  10 238 202  21 244 212  20 246 218  74
+246 217  39 244 212  20 244 212  20 244 212  20
+224 188  14 214 174  14 186 146  17   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 26  26  26  94  94  93  42  42  43  14  14  13
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 30  30  30  78  78  78  50  50  50 105  70   7
+195 134  10 219 158  11 238 178  14 241 186  13
+234 196  18 244 212  20 246 217  53 241 214  34
+244 212  20 244 212  20 244 212  20 197 151  13
+204 146  11 219 158  11 158 118  10   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  89  90  90  54  54  54  18  18  18
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 30  30  30  78  78  78  46  46  46  22  22  22
+138  94   6 210 162  12 238 182  14 238 190  10
+238 202  21 244 212  20 244 212  20 244 212  20
+244 212  20 202 164  20 186 134  10 211 150  11
+219 158  11 211 150  11 104  78  10   2   2   6
+  6   6   6  54  54  54  14  14  13   2   2   6
+  2   2   6  62  62  62  74  74  74  30  30  30
+ 10  10  10   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 34  34  34  78  78  78  50  50  50   6   6   6
+ 92  69  26 138 102  14 190 146  14 224 188  14
+238 202  21 234 196  18 214 174  14 190 146  14
+170 122  12 195 134  10 211 150  11 214 154  10
+202 147  31 182 158 106 102  98  90   2   2   6
+  2   2   6  78  78  78 118 118 118  58  58  58
+  2   2   6  22  22  22  89  90  90  46  46  46
+ 18  18  18   6   6   6   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 38  38  38  86  86  86  50  50  50   6   6   6
+130 130 130 173 154 115 158 106   9 170 122  12
+197 151  13 186 146  17 197 139  12 204 146  11
+204 146  11 204 146  11 197 139  12 190 166 114
+194 194 194 198 198 196 174 174 174  14  14  13
+  2   2   6  22  22  22 118 118 118 118 118 118
+ 22  22  22   2   2   6  74  74  74  70  70  70
+ 30  30  30  10  10  10   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   6   6   6  18  18  18
+ 50  50  50 102 102 102  26  26  26  10  10  10
+138 138 142 190 190 187 173 154 115 158 106   9
+197 139  12 204 146  11 197 139  12 195 134  10
+181 122   9 188 140  34 191 178 145 186 186 186
+201 202 203 223 222 222 214 214 214  66  66  66
+  2   2   6   2   2   6  50  50  50  62  62  62
+  6   6   6   2   2   6  10  10  10  89  90  90
+ 50  50  50  18  18  18   6   6   6   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2  10  10  10  34  34  34
+ 74  74  74  74  74  74   2   2   6   6   6   6
+146 146 146 198 198 196 190 190 187 178 166 146
+154 122  54 158 106   9 158 106   9 170 126  38
+173 154 115 186 186 186 190 190 187 210 210 210
+246 246 246 254 254 254 254 254 254 182 182 182
+  6   6   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  62  62  62
+ 74  74  74  34  34  34  14  14  13   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2  10  10  10  22  22  22  54  54  54
+ 94  94  93  18  18  18   2   2   6  46  46  46
+234 234 234 223 222 222 190 190 187 190 190 187
+190 190 187 186 186 186 186 186 186 190 190 187
+190 190 187 194 194 194 214 214 214 242 242 242
+254 254 254 254 254 254 254 254 254 254 254 254
+ 82  82  82   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  14  14  13
+ 86  86  86  54  54  54  22  22  22   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  6   6   6  18  18  18  46  46  46  89  90  90
+ 46  46  46  18  18  18   6   6   6 182 182 182
+254 254 254 246 246 246 206 206 206 190 190 187
+190 190 187 190 190 187 190 190 187 190 190 187
+206 206 206 230 230 228 250 250 250 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+201 202 203  14  14  13   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 42  42  43  86  86  86  42  42  43  18  18  18
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   6   6   6
+ 14  14  13  38  38  38  74  74  74  66  66  66
+  2   2   6   6   6   6  89  90  90 250 250 250
+254 254 254 254 254 254 238 238 238 198 198 196
+190 190 187 190 190 187 194 194 194 223 222 222
+246 246 246 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254  82  82  82   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  78  78  78  70  70  70  34  34  34
+ 14  14  13   6   6   6   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  14  14  13
+ 34  34  34  66  66  66  78  78  78   6   6   6
+  2   2   6  18  18  18 218 218 218 254 254 254
+254 254 254 254 254 254 254 254 254 246 246 246
+226 226 226 230 230 228 246 246 246 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 174 174 174   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  18  18  18  89  90  90  62  62  62
+ 30  30  30  10  10  10   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2  10  10  10  26  26  26
+ 58  58  58  89  90  90  18  18  18   2   2   6
+  2   2   6 110 110 110 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+250 250 250 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 230 230 228  18  18  18   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  94  94  93
+ 54  54  54  26  26  26  10  10  10   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   6   6   6  22  22  22  50  50  50
+ 89  90  90  26  26  26   2   2   6   2   2   6
+ 14  14  13 194 194 194 250 250 250 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+250 250 250 242 242 242  54  54  54   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+ 86  86  86  50  50  50  22  22  22   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  6   6   6  14  14  13  38  38  38  82  82  82
+ 34  34  34   2   2   6   2   2   6   2   2   6
+ 42  42  43 194 194 194 246 246 246 254 254 254
+254 254 254 254 254 254 254 254 254 250 250 250
+242 242 242 242 242 242 250 250 250 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 250 250 250 246 246 246 238 238 238
+226 226 226 230 230 228 102 102 102   6   6   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 38  38  38  82  82  82  42  42  43  14  14  13
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+ 10  10  10  26  26  26  62  62  62  66  66  66
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 70  70  70 170 170 170 206 206 206 234 234 234
+246 246 246 250 250 250 250 250 250 238 238 238
+226 226 226 230 230 228 238 238 238 250 250 250
+250 250 250 250 250 250 246 246 246 230 230 228
+214 214 214 206 206 206 201 202 203 201 202 203
+198 198 196 201 202 203 182 182 182  18  18  18
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  62  62  62  66  66  66  30  30  30
+ 10  10  10   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+ 14  14  13  42  42  43  82  82  82  18  18  18
+  2   2   6   2   2   6   2   2   6  10  10  10
+ 94  94  93 182 182 182 218 218 218 242 242 242
+250 250 250 254 254 254 254 254 254 250 250 250
+234 234 234 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 246 246 246
+238 238 238 226 226 226 210 210 210 201 202 203
+194 194 194 194 194 194 210 210 210 158 158 158
+  6   6   6  14  14  13  50  50  50  14  14  13
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  86  86  86  46  46  46
+ 18  18  18   6   6   6   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   6   6   6
+ 22  22  22  54  54  54  70  70  70   2   2   6
+  2   2   6  10  10  10   2   2   6  22  22  22
+166 166 166 230 230 228 250 250 250 254 254 254
+254 254 254 254 254 254 254 254 254 250 250 250
+242 242 242 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 246 246 246
+230 230 228 206 206 206 198 198 196 226 226 226
+ 94  94  93   2   2   6   6   6   6  38  38  38
+ 30  30  30   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  62  62  62  66  66  66
+ 26  26  26  10  10  10   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 30  30  30  74  74  74  50  50  50   2   2   6
+ 26  26  26  26  26  26   2   2   6 106 106 105
+238 238 238 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 246 246 246 218 218 218 201 202 203
+210 210 210  14  14  13   2   2   6   2   2   6
+ 30  30  30  22  22  22   2   2   6   2   2   6
+  2   2   6   2   2   6  18  18  18  86  86  86
+ 42  42  43  14  14  13   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  14  14  13
+ 42  42  43  89  90  90  22  22  22   2   2   6
+ 42  42  43   2   2   6  18  18  18 218 218 218
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 250 250 250 223 222 222
+218 218 218 102 102 102   2   2   6  14  14  13
+ 18  18  18  38  38  38  10  10  10   2   2   6
+  2   2   6   2   2   6   2   2   6  78  78  78
+ 58  58  58  22  22  22   6   6   6   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   6   6   6  18  18  18
+ 54  54  54  82  82  82   2   2   6  26  26  26
+ 22  22  22   2   2   6 122 122 122 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 250 250 250
+238 238 238 198 198 196   6   6   6  38  38  38
+ 58  58  58  26  26  26  38  38  38   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+ 78  78  78  30  30  30  10  10  10   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2  10  10  10  30  30  30
+ 74  74  74  58  58  58   2   2   6  42  42  43
+  2   2   6  22  22  22 230 230 228 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 250 250 250
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 246 246 246  46  46  46  38  38  38
+ 42  42  43  14  14  13  38  38  38  14  14  13
+  2   2   6   2   2   6   2   2   6   6   6   6
+ 86  86  86  46  46  46  14  14  13   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   6   6   6  14  14  13  42  42  43
+ 89  90  90  18  18  18  18  18  18  26  26  26
+  2   2   6 118 118 118 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 250 250 250 238 238 238
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254  94  94  93   6   6   6
+  2   2   6   2   2   6  10  10  10  34  34  34
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 74  74  74  58  58  58  22  22  22   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2  10  10  10  26  26  26  66  66  66
+ 82  82  82   2   2   6  38  38  38   6   6   6
+ 14  14  13 210 210 210 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 246 246 246 242 242 242
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 146 146 146   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 42  42  43  74  74  74  30  30  30  10  10  10
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  6   6   6  14  14  13  42  42  43  89  90  90
+ 26  26  26   6   6   6  42  42  43   2   2   6
+ 74  74  74 250 250 250 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 242 242 242 242 242 242
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 182 182 182   2   2   6
+  2   2   6   2   2   6   2   2   6  46  46  46
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 10  10  10  86  86  86  38  38  38  10  10  10
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+ 10  10  10  26  26  26  66  66  66  82  82  82
+  2   2   6  22  22  22  18  18  18   2   2   6
+150 150 150 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 234 234 234 242 242 242
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 206 206 206   2   2   6
+  2   2   6   2   2   6   2   2   6  38  38  38
+  2   2   6   2   2   6   2   2   6   2   2   6
+  6   6   6  86  86  86  46  46  46  14  14  13
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   6   6   6
+ 18  18  18  46  46  46  86  86  86  18  18  18
+  2   2   6  34  34  34  10  10  10   6   6   6
+210 210 210 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 234 234 234 242 242 242
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 223 222 222   6   6   6
+  2   2   6   2   2   6   6   6   6  30  30  30
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  82  82  82  54  54  54  18  18  18
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 26  26  26  66  66  66  62  62  62   2   2   6
+  2   2   6  38  38  38  10  10  10  26  26  26
+238 238 238 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 230 230 228 238 238 238
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 230 230 228   6   6   6
+  2   2   6   2   2   6  10  10  10  30  30  30
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  58  58  58  22  22  22
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 38  38  38  78  78  78   6   6   6   2   2   6
+  2   2   6  46  46  46  14  14  13  42  42  43
+246 246 246 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 230 230 228 242 242 242
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 234 234 234  10  10  10
+  2   2   6   2   2   6  22  22  22  14  14  13
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  62  62  62  22  22  22
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   6   6   6  18  18  18
+ 50  50  50  74  74  74   2   2   6   2   2   6
+ 14  14  13  70  70  70  34  34  34  62  62  62
+250 250 250 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 230 230 228 246 246 246
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 234 234 234  14  14  13
+  2   2   6   2   2   6  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  62  62  62  22  22  22
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   6   6   6  18  18  18
+ 54  54  54  62  62  62   2   2   6   2   2   6
+  2   2   6  30  30  30  46  46  46  70  70  70
+250 250 250 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 230 230 228 246 246 246
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 226 226 226  10  10  10
+  2   2   6   6   6   6  30  30  30   2   2   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6  66  66  66  58  58  58  22  22  22
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   6   6   6  22  22  22
+ 58  58  58  62  62  62   2   2   6   2   2   6
+  2   2   6   2   2   6  30  30  30  78  78  78
+250 250 250 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 230 230 228 246 246 246
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 206 206 206   2   2   6
+ 22  22  22  34  34  34  18  14   6  22  22  22
+ 26  26  26  18  18  18   6   6   6   2   2   6
+  2   2   6  82  82  82  54  54  54  18  18  18
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   6   6   6  26  26  26
+ 62  62  62 106 106 105  74  51  11 186 134  10
+210 162  12 122  94  10   6   6   6  62  62  62
+238 238 238 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 230 230 228 246 246 246
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 158 158 158  18  18  18
+ 14  14  13   2   2   6   2   2   6   2   2   6
+  6   6   6  18  18  18  66  66  66  38  38  38
+  6   6   6  94  94  93  50  50  50  18  18  18
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   6   6   6
+ 10  10  10  10  10  10  18  18  18  38  38  38
+ 78  78  78 142 134 106 219 158  11 241 186  13
+246 190  14 246 190  14 158 118  10  10  10  10
+ 89  90  90 238 238 238 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 230 230 228 250 250 250
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 246 230 190
+238 206  90 238 206  90 188 140  34  38  26  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  38  38  38  46  46  46
+ 26  26  26 106 106 105  54  54  54  18  18  18
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   6   6   6  14  14  13  22  22  22
+ 30  30  30  38  38  38  50  50  50  70  70  70
+106 106 105 188 140  34 226 170  10 241 186  13
+246 190  14 246 190  14 246 190  14 154 114  10
+  6   6   6  74  74  74 226 226 226 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 230 230 228 250 250 250
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 233 188  64
+240 198  14 244 212  20 234 196  18  38  30  10
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   6   6   6  30  30  30  26  26  26
+202 164  20 154 142  90  66  66  66  26  26  26
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  6   6   6  18  18  18  38  38  38  58  58  58
+ 78  78  78  86  86  86 102 102 102 122 122 122
+178 147  70 211 150  11 234 174  12 246 186  14
+246 190  14 246 190  14 246 190  14 238 190  10
+104  78  10   2   2   6  46  46  46 198 198 196
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 234 234 234 242 242 242
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 222 175  59
+241 186  13 240 198  14 210 162  12  18  18  18
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6   6   6   6 122  94  10
+238 202  21 234 196  18  82  82  82  34  34  34
+ 10  10  10   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+ 14  14  13  38  38  38  70  70  70 154 122  54
+188 140  34 204 146  11 197 139  12 197 139  12
+214 154  10 226 170  10 241 186  13 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+229 174  11  49  35   6   2   2   6  22  22  22
+158 158 158 250 250 250 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 250 250 250 242 242 242 222 175  59
+238 182  14 241 186  13 214 154  10  49  35   6
+  2   2   6   2   2   6   2   2   6   2   2   6
+  2   2   6   2   2   6  60  40   9 229 174  11
+238 190  10 241 186  13 114 102  78  42  42  43
+ 14  14  13   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   6   6   6
+ 22  22  22  54  54  54 154 122  54 214 154  10
+226 170  10 229 174  11 226 170  10 226 170  10
+238 178  14 241 186  13 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+240 198  14 186 146  17  10  10  10   2   2   6
+  6   6   6 118 118 118 242 242 242 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 230 230 228 198 198 196 206 170  74
+238 178  14 238 178  14 211 150  11 138  94   6
+ 18  14   6   2   2   6   2   2   6   2   2   6
+  6   6   6  70  46   6 204 146  11 238 178  14
+238 182  14 238 182  14 126 114  90  58  58  58
+ 22  22  22   6   6   6   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 30  30  30  70  70  70 182 134  38 226 170  10
+238 182  14 241 186  13 241 186  13 246 186  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 234 196  18  98  70   6   2   2   6
+  2   2   6   2   2   6  66  66  66 223 222 222
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 206 206 206 198 198 196 207 165  68
+229 174  11 229 174  11 219 158  11 195 134  10
+163 110  10 118  82  10 104  78  10 118  82  10
+164 114   8 197 139  12 226 170  10 238 182  14
+241 186  13 241 186  13 162 146  94  78  78  78
+ 34  34  34  14  14  13   6   6   6   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   6   6   6
+ 30  30  30  78  78  78 188 140  34 226 170  10
+238 182  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 240 198  14 202 164  20  18  18  18
+  2   2   6   2   2   6   2   2   6  38  38  38
+218 218 218 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+250 250 250 206 206 206 198 198 196 207 165  68
+226 170  10 238 178  14 226 166  13 211 150  11
+204 146  11 197 139  12 195 134  10 197 139  12
+211 150  11 226 170  10 241 186  13 246 190  14
+246 190  14 246 186  14 229 174  11 126 114  90
+ 62  62  62  30  30  30  14  14  13   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 30  30  30  78  78  78 174 134  50 226 166  13
+238 182  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 240 198  14 138 102  14
+  2   2   6   2   2   6   2   2   6   2   2   6
+ 78  78  78 250 250 250 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+250 250 250 214 214 214 198 198 196 192 148  44
+220 162  10 238 178  14 234 174  12 226 166  13
+219 158  11 214 154  10 214 154  10 219 158  11
+226 170  10 238 182  14 246 190  14 246 190  14
+246 190  14 246 190  14 241 186  13 206 160  36
+102 102 102  58  58  58  30  30  30  14  14  13
+  6   6   6   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2  10  10  10  86  86  86 150 150 150
+170 170 170 186 186 186 226 210 207 231 220 218
+246 230 190 246 230 190 246 230 190 246 230 190
+238 206  90 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 246 190  14 246 190  14
+246 190  14 246 190  14 240 198  14 224 188  14
+ 60  40   9   2   2   6   6   6   6   2   2   6
+ 22  22  22 238 238 238 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 226 226 226 186 186 186 182 134  38
+219 158  11 238 178  14 238 182  14 238 178  14
+229 174  11 226 170  10 226 170  10 229 174  11
+238 178  14 241 186  13 246 190  14 246 190  14
+246 190  14 240 198  14 246 230 190 246 230 190
+226 210 207 186 186 186 110 110 110  38  38  38
+ 26  26  26 122 122 122 138 138 142 138 138 142
+138 138 142 102  98  90   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+ 14  14  13 154 154 154 246 246 246 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+246 230 190 238 206  90 240 198  14 240 198  14
+240 198  14 240 198  14 246 190  14 246 190  14
+246 190  14 240 198  14 240 198  14 238 202  21
+206 160  36  18  18  18  22  22  22  30  30  30
+ 70  70  70 246 246 246 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 254 254 254 254 254 254 254 254 254
+254 254 254 230 230 228 118 118 118 170 126  38
+220 162  10 238 178  14 241 186  13 246 190  14
+234 196  18 246 190  14 246 190  14 234 196  18
+246 190  14 246 206  46 238 206  90 246 206  46
+240 198  14 246 230 190 254 254 254 254 254 254
+254 254 254 252 251 251 205 195 190 110 110 110
+134 134 134 242 242 242 250 250 250 254 254 254
+250 250 250 138 138 142 102  98  90   2   2   2
+  2   2   2   2   2   2   3   3   3  18  14   6
+150 150 150 242 242 242 239 159 153 249 100  93
+249 100  93 249 100  93 249 100  93 249 100  93
+249 100  93 249 100  93 249 100  93 249 100  93
+239 159 153 246 218  74 246 246 246 246 246 246
+246 246 246 246 246 246 238 206  90 246 190  14
+246 230 190 246 246 246 246 246 246 246 246 246
+246 230 190 138 102  14 182 182 182 242 242 242
+252 251 251 252 251 251 252 251 251 252 251 251
+252 251 251 252 251 251 254 254 254 252 251 251
+252 251 251 252 251 251 246 246 246 252 251 251
+254 254 254 252 251 251 252 251 251 254 254 254
+254 254 254 252 251 251 242 242 242 238 238 238
+238 206  90 238 178  14 241 186  13 246 230 190
+246 246 246 246 246 246 246 246 246 246 230 190
+246 230 190 246 246 246 252 251 251 246 230 190
+246 230 190 246 230 190 249 100  93 249 100  93
+249 100  93 249 100  93 218 194 134 218 194 134
+234 234 234 212 132  53 249 100  93 249 100  93
+249 100  93 239 159 153 138 138 142 102  98  90
+  2   2   2   2   2   2  10  10  10 150 150 150
+242 242 242 249 100  93 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+239 159 153 246 246 246 246 230 190 246 230 190
+246 230 190 246 230 190 246 230 190 246 230 190
+246 230 190 246 230 190 246 230 190 246 230 190
+246 230 190 246 230 190 238 238 238 246 230 190
+246 230 190 246 230 190 246 230 190 246 246 246
+231 220 218 218 194 134 218 194 134 226 210 207
+246 246 246 246 246 246 246 246 246 252 251 251
+246 246 246 226 210 207 218 194 134 218 194 134
+239 159 153 218 194 134 226 210 207 246 230 190
+246 246 246 238 206  90 246 230 190 246 230 190
+246 230 190 246 230 190 246 230 190 246 230 190
+246 246 246 226 210 207 239 159 153 226 210 207
+246 246 246 239 159 153 254   3   3 254   3   3
+254   3   3 254   3   3 218 194 134 246 246 246
+231 220 218 254  21  21 254   3   3 254   3   3
+254   3   3 212 132  53 250 250 250 122 122 122
+  2   2   2   2   2   2  89  90  90 246 246 246
+239 159 153 254   3   3 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 254  21  21
+226 210 207 226 210 207 254  21  21 254  21  21
+254  21  21 254  21  21 239 159 153 252 251 251
+249 100  93 254  21  21 254  21  21 254  21  21
+249 100  93 246 246 246 249 100  93 254  21  21
+254  21  21 254  21  21 249 100  93 249 100  93
+254  21  21 254   3   3 254   3   3 254  21  21
+212 132  53 246 246 246 252 251 251 226 210 207
+254  56  56 254  21  21 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 254  21  21
+249 100  93 242 242 242 246 246 246 249 100  93
+254  21  21 254  21  21 254  21  21 249 100  93
+249 100  93 254   3   3 254   3   3 254  56  56
+246 246 246 249 100  93 254   3   3 254   3   3
+254   3   3 254  21  21 246 230 190 252 251 251
+239 159 153 254   3   3 254   3   3 254   3   3
+254   3   3 218 194 134 246 246 246  58  58  58
+  2   2   2   6   6   6 182 182 182 252 251 251
+254  56  56 254   3   3 254   3   3 254   3   3
+254   3   3 249 100  93 239 159 153 239 159 153
+239 159 153 212 132  53 249 100  93 249 100  93
+246 246 246 212 132  53 254   3   3 254   3   3
+254   3   3 254  21  21 238 238 238 246 230 190
+254  21  21 254   3   3 254   3   3 254   3   3
+239 159 153 246 230 190 254  21  21 254   3   3
+254   3   3 254   3   3 254  21  21 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+254  21  21 246 246 246 231 220 218 254  21  21
+254   3   3 254   3   3 254   3   3 254   3   3
+254  21  21 254  21  21 254   3   3 254   3   3
+254   3   3 239 159 153 246 230 190 254  21  21
+254   3   3 254   3   3 254   3   3 254  56  56
+254   3   3 254   3   3 254   3   3 212 132  53
+246 246 246 254  21  21 254   3   3 254   3   3
+254   3   3 249 100  93 246 246 246 246 246 246
+249 100  93 254   3   3 254   3   3 254   3   3
+254  21  21 242 242 242 214 214 214  14  14  13
+  2   2   2   6   6   6 210 210 210 252 251 251
+254  56  56 254   3   3 254   3   3 254   3   3
+254   3   3 249 100  93 239 159 153 239 159 153
+239 159 153 239 159 153 238 238 238 246 246 246
+246 246 246 254  56  56 254   3   3 254   3   3
+254   3   3 249 100  93 246 246 246 239 159 153
+254   3   3 254   3   3 254   3   3 254   3   3
+246 230 190 239 159 153 254   3   3 254   3   3
+254   3   3 254   3   3 254  21  21 254  21  21
+254   3   3 254   3   3 254   3   3 254   3   3
+254   3   3 246 246 246 249 100  93 254   3   3
+254   3   3 254   3   3 254  21  21 218 194 134
+242 242 242 239 159 153 254   3   3 254   3   3
+254   3   3 249 100  93 239 159 153 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 218 194 134
+226 210 207 254   3   3 254   3   3 254   3   3
+254   3   3 254  21  21 254  21  21 254  21  21
+254   3   3 254   3   3 254   3   3 254   3   3
+249 100  93 254 254 254 158 158 158   2   2   2
+  2   2   2  10  10  10 186 186 186 246 246 246
+254  56  56 254   3   3 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+254   3   3 254   3   3 254  56  56 252 251 251
+246 230 190 254  21  21 254   3   3 254   3   3
+254   3   3 239 159 153 252 251 251 249 100  93
+254   3   3 254   3   3 254   3   3 254  56  56
+252 251 251 249 100  93 254   3   3 254   3   3
+254   3   3 254  21  21 218 194 134 226 210 207
+254  56  56 254   3   3 254   3   3 254   3   3
+254  56  56 231 220 218 254  21  21 254   3   3
+254   3   3 254   3   3 254  21  21 254  56  56
+254  56  56 254  56  56 254   3   3 254   3   3
+254   3   3 239 159 153 249 100  93 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+254   3   3 254   3   3 254  21  21 246 246 246
+212 132  53 254   3   3 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+239 159 153 252 251 251  89  90  90   2   2   2
+  2   2   2   6   6   6  50  50  50 206 206 206
+226 210 207 249 100  93 254  56  56 254  21  21
+254  21  21 254  21  21 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 238 238 238
+239 159 153 254   3   3 254   3   3 254   3   3
+254  21  21 226 210 207 238 238 238 254  21  21
+254   3   3 254   3   3 254   3   3 212 132  53
+238 238 238 254  56  56 254   3   3 254   3   3
+254   3   3 239 159 153 246 246 246 246 246 246
+254  56  56 254   3   3 254   3   3 254   3   3
+249 100  93 239 159 153 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+254  21  21 226 210 207 254  56  56 254   3   3
+254   3   3 254   3   3 254  21  21 249 100  93
+239 159 153 239 159 153 239 159 153 246 246 246
+254  56  56 254   3   3 254   3   3 254   3   3
+254   3   3 254  21  21 254  21  21 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+246 230 190 242 242 242  26  26  26   2   2   2
+  6   6   6  50  50  50 206 206 206 226 210 207
+231 220 218 231 220 218 231 220 218 246 230 190
+246 230 190 239 159 153 254   3   3 254   3   3
+254   3   3 254   3   3 254  21  21 246 246 246
+249 100  93 254   3   3 254   3   3 254   3   3
+254  21  21 231 220 218 239 159 153 254   3   3
+254   3   3 254   3   3 254   3   3 218 194 134
+218 194 134 254   3   3 254   3   3 254   3   3
+254   3   3 239 159 153 246 230 190 239 159 153
+254   3   3 254   3   3 254   3   3 254   3   3
+239 159 153 212 132  53 254   3   3 254   3   3
+254   3   3 254  21  21 218 194 134 231 220 218
+231 220 218 231 220 218 226 210 207 218 194 134
+226 210 207 231 220 218 254   3   3 254   3   3
+254   3   3 254   3   3 212 132  53 246 246 246
+252 251 251 252 251 251 242 242 242 231 220 218
+254  21  21 254   3   3 254   3   3 254   3   3
+249 100  93 242 242 242 238 238 238 254  56  56
+254   3   3 254   3   3 254   3   3 254  56  56
+246 246 246 194 194 194   6   6   6   2   2   2
+ 22  22  22 210 210 210 246 230 190 254  56  56
+254  21  21 254  21  21 254  21  21 254  21  21
+254  21  21 254  21  21 254   3   3 254   3   3
+254   3   3 254   3   3 249 100  93 246 246 246
+254  56  56 254   3   3 254   3   3 254   3   3
+254   3   3 254  21  21 254  21  21 254   3   3
+254   3   3 254   3   3 254  56  56 242 242 242
+212 132  53 254   3   3 254   3   3 254   3   3
+254   3   3 254  21  21 254  21  21 254   3   3
+254   3   3 254   3   3 254   3   3 254  56  56
+238 238 238 212 132  53 254   3   3 254   3   3
+254   3   3 254   3   3 254  56  56 249 100  93
+249 100  93 249 100  93 254  56  56 254  56  56
+246 246 246 239 159 153 254   3   3 254   3   3
+254   3   3 254  21  21 231 220 218 246 246 246
+206 170  74 182 158 106 246 246 246 239 159 153
+254   3   3 254   3   3 254   3   3 254   3   3
+218 194 134 242 242 242 246 230 190 254  21  21
+254   3   3 254   3   3 254   3   3 212 132  53
+252 251 251 131 126 116   6   6   6   2   2   2
+ 89  90  90 246 246 246 239 159 153 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+254   3   3 254  21  21 226 210 207 246 246 246
+249 100  93 254   3   3 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+254   3   3 254  56  56 226 210 207 252 251 251
+254  56  56 254   3   3 254   3   3 254   3   3
+254  56  56 254  21  21 254   3   3 254   3   3
+254   3   3 254   3   3 254  21  21 218 194 134
+238 238 238 226 210 207 254  21  21 254   3   3
+254   3   3 254   3   3 254   3   3 254   3   3
+254   3   3 254   3   3 254   3   3 239 159 153
+252 251 251 249 100  93 254   3   3 254   3   3
+254   3   3 254  56  56 246 246 246 231 220 218
+138 102  14 198 198 196 252 251 251 249 100  93
+254   3   3 254   3   3 254   3   3 254  21  21
+246 230 190 252 251 251 239 159 153 254   3   3
+254   3   3 254   3   3 254   3   3 218 194 134
+242 242 242  62  62  62   6   6   6   2   2   2
+ 58  58  58 122 122 122 218 194 134 212 132  53
+249 100  93 249 100  93 254  56  56 254  56  56
+254  56  56 254  56  56 254  56  56 249 100  93
+212 132  53 246 230 190 214 214 214 146 146 146
+242 242 242 239 159 153 249 100  93 254  56  56
+254  56  56 254  56  56 254  56  56 249 100  93
+239 159 153 246 230 190 246 246 246 246 230 190
+254  21  21 254   3   3 254   3   3 254   3   3
+239 159 153 218 194 134 249 100  93 254  56  56
+254  56  56 249 100  93 226 210 207 230 230 228
+ 89  90  90 231 220 218 226 210 207 249 100  93
+249 100  93 254  56  56 254  56  56 254  56  56
+249 100  93 249 100  93 239 159 153 238 238 238
+218 194 134 239 159 153 212 132  53 249 100  93
+249 100  93 239 159 153 231 220 218 154 142  90
+102 102 102 146 146 146 170 170 170 239 159 153
+249 100  93 249 100  93 249 100  93 239 159 153
+218 218 218 130 130 130 239 159 153 249 100  93
+249 100  93 249 100  93 212 132  53 246 230 190
+118 118 118  18  14   6   6   6   6   2   2   2
+  2   2   2  58  58  58 118 118 118 242 242 242
+254 254 254 250 250 250 246 246 246 246 246 246
+246 246 246 246 246 246 246 246 246 252 251 251
+252 251 251 214 214 214  50  50  50  18  18  18
+138 138 142 246 246 246 252 251 251 246 246 246
+246 246 246 246 246 246 246 246 246 252 251 251
+252 251 251 231 220 218 252 251 251 239 159 153
+254   3   3 254   3   3 254   3   3 254  21  21
+231 220 218 238 238 238 252 251 251 242 242 242
+252 251 251 252 251 251 230 230 228  74  74  74
+ 18  18  18  62  62  62 226 226 226 254 254 254
+252 251 251 246 246 246 246 246 246 252 251 251
+252 251 251 252 251 251 250 250 250 150 150 150
+162 146  94 205 195 190 252 251 251 252 251 251
+252 251 251 226 210 207 142 134 106  86  86  86
+ 58  58  58  34  34  34 122 122 122 163 163 163
+252 251 251 254 254 254 250 250 250 223 222 222
+102  98  90  78  78  78 130 130 130 254 254 254
+254 254 254 254 254 254 246 246 246 118 118 118
+ 18  14   6   3   3   3   2   2   2   2   2   2
+  2   2   2   2   2   2  58  58  58 122 122 122
+150 150 150 170 170 170 182 182 182 190 190 187
+201 202 203 201 202 203 190 190 187 170 170 170
+118 118 118  30  30  30   6   6   6   6   6   6
+ 10  10  10  86  86  86 150 150 150 182 182 182
+201 202 203 201 202 203 190 190 187 174 174 174
+134 134 134 146 146 146 190 190 187 239 159 153
+249 100  93 249 100  93 249 100  93 249 100  93
+234 234 234 138 138 142 166 166 166 198 198 196
+190 190 187 138 138 142  42  42  43   6   6   6
+  3   3   3   6   6   6  50  50  50 138 138 142
+174 174 174 198 198 196 198 198 196 182 182 182
+163 163 163 138 138 142 102  98  90  70  70  70
+ 94  86  75 158 158 158 178 166 146 170 170 170
+174 174 174 138 138 142  74  74  74  50  50  50
+ 26  26  26  14  14  13  10  10  10 118 118 118
+130 130 130 130 130 130 130 130 130 102  98  90
+  6   6   6   3   3   3  78  78  78 130 130 130
+130 130 130 130 130 130 118 118 118  18  14   6
+  3   3   3   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   6   6   6   6   6   6
+ 10  10  10  10  10  10   6   6   6   2   2   2
+  2   2   2   2   2   2   2   2   2   6   6   6
+  6   6   6   6   6   6   6   6   6   6   6   6
+ 14  14  13  14  14  13  22  22  22  22  22  22
+ 34  34  34  42  42  43 122 122 122 174 174 174
+254 254 254 254 254 254 254 254 254 238 238 238
+138 138 142   6   6   6   6   6   6  10  10  10
+  6   6   6   2   2   2   2   2   2   6   6   6
+  6   6   6   6   6   6   6   6   6   2   2   2
+  6   6   6  10  10  10  10  10  10   6   6   6
+  2   2   2   6   6   6  14  14  13  30  30  30
+ 42  42  43  54  54  54  62  62  62  62  62  62
+ 54  54  54  42  42  43  30  30  30  18  18  18
+ 10  10  10   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  6   6   6   2   2   2   6   6   6   2   2   2
+  2   2   2   2   2   2   2   2   2  10  10  10
+ 10  10  10  10  10  10  14  14  13 106 106 105
+163 163 163 170 170 170 166 166 166 138 138 142
+  6   6   6   6   6   6   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  6   6   6   6   6   6   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   6   6   6
+ 18  18  18  22  22  22  22  22  22  22  22  22
+ 18  18  18  14  14  13  10  10  10   6   6   6
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
+  2   2   2   2   2   2   2   2   2   2   2   2
diff -Nru a/drivers/video/logo/logo_superh_mono.pbm b/drivers/video/logo/logo_superh_mono.pbm
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/logo_superh_mono.pbm	Mon Feb 24 13:47:01 2003
@@ -0,0 +1,203 @@
+P1
+# Black and white SuperH Linux logo
+80 80
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 0 0 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1
+1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1
+1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1
+1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+0 1 1 0 0 1 1 1 0 0 1 1 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 1 1 1 0 1 1 1 1 0 0 1
+1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 1 1 1 0 1 1 1 0 1 1 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
+1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+0 1 1 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 1 0 0 0 0 0 1 1 1
+1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1
+1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1
+1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 1 1 1 1 1 1 1 0 0 0 0 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1
+1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1
+0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0
+1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1
+0 0 0 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1
+1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 1
+0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1
+1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1
+1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1
+1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1
+1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1
+1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 1 0 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 1 1 1 1 0
+0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 1 0 0 0
+0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1
+1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 1 1 1 0 1
+1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 1 1 1 1 0 0 0 1 1 1 1 1 0 0 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1
+0 0 1 1 1 1 1 0 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1
+1 1 1 0 0 0 0 1 1 1 0 0 1 1 1 1 0 1 1 1 1 1 0 0 0 1 1 1 1 0 0 1
+1 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 1 1 1 0 1 1
+1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1
+0 1 1 1 1 0 0 0 1 1 1 1 1 0 0 1 1 1 0 0 1 1 1 1 1 1 1 1 1 0 0 0
+0 1 1 1 1 1 0 0 0 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0
+0 1 1 1 1 0 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
+1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0 1 1 1 1 0 1 1 1
+1 1 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0
+1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0
+0 1 1 1 1 0 0 0 1 1 1 1 0 1 1 1 1 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1
+1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1
+1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1
+1 0 0 0 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0
+1 1 1 1 1 0 0 0 1 1 1 1 0 0 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0
+1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1
+1 1 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1 1 1 1 0 0 0 1 1 1 1 1 0 0 1 1
+1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1
+1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 1 0 0 1
+1 1 1 1 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0
+0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0 1 1 1 1 1
+1 1 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 1 1 1 0 0 0 1 1 1 1 0 0 1 1 1
+1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0
+0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0
+0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1
+1 1 0 0 0 0 0 0 1 1 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0
+0 0 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
+0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
diff -Nru a/drivers/video/logo/logo_superh_vga16.ppm b/drivers/video/logo/logo_superh_vga16.ppm
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/logo/logo_superh_vga16.ppm	Mon Feb 24 13:47:01 2003
@@ -0,0 +1,1604 @@
+P3
+# 16-color SuperH Linux logo
+80 80
+255
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85  85  85  85  85  85  85  85  85  85
+ 85  85  85  85  85  85  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+ 85  85  85  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85 170 170 170   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170 170 170 170 170 170  85  85  85   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170 170 170 170 170 170
+170 170 170   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+ 85  85  85 170 170 170 170 170 170 170 170 170
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 170 170 170 255 255 255 255 255 255
+255 255 255 170 170 170   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+170 170 170 170 170 170 255 255 255 255 255 255
+  0   0   0   0   0   0   0   0   0   0   0   0
+170 170 170 255 255 255 170 170 170 170 170 170
+255 255 255 170 170 170   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+170 170 170   0   0   0   0   0   0 255 255 255
+ 85  85  85   0   0   0   0   0   0   0   0   0
+255 255 255 170 170 170   0   0   0  85  85  85
+170 170 170 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+ 85  85  85   0   0   0   0   0   0 170 170 170
+ 85  85  85   0   0   0   0   0   0   0   0   0
+255 255 255  85  85  85   0   0   0   0   0   0
+ 85  85  85 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+170 170 170   0   0   0   0   0   0 170 170 170
+ 85  85  85  85  85  85  85  85  85  85  85  85
+255 255 255  85  85  85   0   0   0   0   0   0
+ 85  85  85 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+255 255 255   0   0   0   0   0   0 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+ 85  85  85 255 255 255   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+170 170 170 170 170 170 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170 170 170 170 170 170   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 170  85   0
+170  85   0 170  85   0  85  85  85   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+ 85  85  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0  85  85  85   0   0   0
+  0   0   0  85  85  85 170 170 170  85  85  85
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+ 85  85  85 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170 170 170 170 170 170 170 170 170   0   0   0
+  0   0   0   0   0   0 170 170 170 170 170 170
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+ 85  85  85 170 170 170 170  85   0 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170  85   0 170  85   0 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170  85  85  85
+  0   0   0   0   0   0  85  85  85  85  85  85
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+ 85  85  85 170 170 170 170 170 170 170  85   0
+170  85   0 170  85   0 170  85   0 170  85   0
+170 170 170 170 170 170 170 170 170 170 170 170
+255 255 255 255 255 255 255 255 255 170 170 170
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0 170 170 170
+255 255 255 255 255 255 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0  85  85  85 255 255 255
+255 255 255 255 255 255 255 255 255 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0  85  85  85 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+ 85  85  85 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85 170 170 170 170 170 170 170 170 170
+255 255 255 255 255 255 255 255 255 170 170 170
+170 170 170 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+170 170 170 170 170 170 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170  85  85  85
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 170 170 170
+  0   0   0   0   0   0   0   0   0  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+ 85  85  85   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 170 170 170
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0 170 170 170
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+170 170 170  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+  0   0   0   0   0   0  85  85  85 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170   0   0   0  85  85  85
+ 85  85  85   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+  0   0   0  85  85  85 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170   0   0   0  85  85  85
+ 85  85  85   0   0   0  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0  85  85  85
+  0   0   0 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0  85  85  85   0   0   0
+  0   0   0 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0  85  85  85   0   0   0
+ 85  85  85 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0  85  85  85   0   0   0   0   0   0
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255   0   0   0
+ 85  85  85  85  85  85  85  85  85  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85   0   0   0 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+ 85  85  85 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255  85  85  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85  85  85  85   0   0   0
+  0   0   0  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0  85  85  85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85  85  85  85
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+  0   0   0   0   0   0  85  85  85 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 170  85   0
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85   0   0   0   0   0   0   0   0   0
+ 85  85  85 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 255 255  85
+170  85   0 255 255  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85   0   0   0   0   0   0
+  0   0   0  85  85  85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0  85  85  85 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85 170 170 170
+170 170 170 170 170 170 170 170 170 255 255 255
+170 170 170 255 255 255 170 170 170 255 255  85
+170 170 170 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0   0   0   0   0   0   0   0   0   0
+  0   0   0 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255 255 170 170 170
+255 255  85 170 170 170  85  85  85   0   0   0
+  0   0   0  85  85  85 170 170 170  85  85  85
+170 170 170  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0 170 170 170 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255  85 170 170 170 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85 170  85   0 255 255  85 170  85   0
+255 255  85   0   0   0   0   0   0   0   0   0
+ 85  85  85 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170  85   0 255 255  85
+170  85   0 255 255  85 170 170 170 255 255  85
+170  85   0 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255  85  85  85  85  85  85
+ 85  85  85 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+170 170 170 255 255 255 170 170 170 255  85  85
+255  85  85 255  85  85 255  85  85 255  85  85
+255  85  85 255  85  85 255  85  85 255  85  85
+170 170 170 255 255  85 255 255 255 255 255 255
+255 255 255 255 255 255 170 170 170 255 255  85
+170 170 170 255 255 255 255 255 255 255 255 255
+170 170 170 255 255  85 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170  85   0 255 255  85 170 170 170
+255 255 255 255 255 255 255 255 255 170 170 170
+255 255  85 255 255 255 255 255 255 255 255 255
+255 255  85 255 255 255 255  85  85 255  85  85
+255  85  85 255  85  85 170 170 170 170 170 170
+255 255 255 170 170 170 255  85  85 255  85  85
+255  85  85 170 170 170 170 170 170  85  85  85
+  0   0   0   0   0   0   0   0   0 170 170 170
+255 255 255 255  85  85 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170 170 170 255 255 255 170 170 170 255 255 255
+255 255 255 170 170 170 255 255 255 170 170 170
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 255 255 255 255 255 255
+255 255 255 170 170 170 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 255 255 255
+255 255 255 255 255  85 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 170 170 170 170 170 170 170 170 170
+255 255 255 170 170 170 170   0   0 255  85  85
+170   0   0 255  85  85 170 170 170 255 255 255
+170 170 170 170   0   0 170   0   0 170   0   0
+170   0   0 255  85  85 255 255 255  85  85  85
+  0   0   0   0   0   0  85  85  85 255 255 255
+170 170 170 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170 170 170 255 255 255 170   0   0 170   0   0
+170   0   0 170   0   0 170 170 170 255 255 255
+255  85  85 170   0   0 170   0   0 170   0   0
+255  85  85 255 255 255 255  85  85 170   0   0
+170   0   0 170   0   0 255  85  85 255  85  85
+170   0   0 170   0   0 170   0   0 170   0   0
+255  85  85 255 255 255 255 255 255 170 170 170
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+255  85  85 255 255 255 255 255 255 255  85  85
+170   0   0 170   0   0 170   0   0 255  85  85
+255  85  85 170   0   0 170   0   0 255  85  85
+255 255 255 255  85  85 170   0   0 170   0   0
+170   0   0 255  85  85 255 255 255 255 255 255
+170 170 170 170   0   0 170   0   0 170   0   0
+255  85  85 170 170 170 255 255 255  85  85  85
+  0   0   0   0   0   0 170 170 170 255 255 255
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 255  85  85 170 170 170 170 170 170
+170 170 170 255  85  85 255  85  85 170 170 170
+255 255 255 255  85  85 170   0   0 170   0   0
+170   0   0 255  85  85 255 255 255 170 170 170
+170   0   0 170   0   0 170   0   0 170   0   0
+170 170 170 255 255 255 170   0   0 170   0   0
+170   0   0 170   0   0 255  85  85 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 255 255 255 255 255 255 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 170 170 170 255 255 255 170   0   0
+170   0   0 170   0   0 170   0   0 255  85  85
+170   0   0 170   0   0 170   0   0 255  85  85
+255 255 255 170   0   0 170   0   0 170   0   0
+170   0   0 255  85  85 255 255 255 255 255 255
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 255 255 255 255 255 255   0   0   0
+  0   0   0   0   0   0 170 170 170 255 255 255
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 255  85  85 255  85  85 170 170 170
+170 170 170 170 170 170 255 255 255 255 255 255
+255 255 255 255  85  85 170   0   0 170   0   0
+170   0   0 255  85  85 255 255 255 170 170 170
+170   0   0 170   0   0 170   0   0 170   0   0
+255 255 255 170 170 170 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 255 255 255 255  85  85 170   0   0
+170   0   0 170   0   0 170   0   0 170 170 170
+255 255 255 170 170 170 170   0   0 170   0   0
+170   0   0 255  85  85 170 170 170 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170 170 170
+255 255 255 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+255  85  85 255 255 255 170 170 170   0   0   0
+  0   0   0   0   0   0 170 170 170 255 255 255
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 255  85  85 255 255 255
+255 255 255 170   0   0 170   0   0 170   0   0
+170   0   0 255  85  85 255 255 255 255  85  85
+170   0   0 170   0   0 170   0   0 255  85  85
+255 255 255 255  85  85 170   0   0 170   0   0
+170   0   0 255  85  85 170 170 170 255 255 255
+170   0   0 170   0   0 170   0   0 170   0   0
+255  85  85 170 170 170 255  85  85 170   0   0
+170   0   0 170   0   0 255  85  85 255  85  85
+255  85  85 255  85  85 170   0   0 170   0   0
+170   0   0 170 170 170 255  85  85 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 255  85  85 255 255 255
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170 170 170 255 255 255  85  85  85   0   0   0
+  0   0   0   0   0   0   0   0   0 255 255 255
+170 170 170 255  85  85 255  85  85 170   0   0
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 255 255 255
+170 170 170 170   0   0 170   0   0 170   0   0
+255  85  85 170 170 170 255 255 255 255  85  85
+170   0   0 170   0   0 170   0   0 255  85  85
+255 255 255 255  85  85 170   0   0 170   0   0
+170   0   0 255  85  85 255 255 255 255 255 255
+255  85  85 170   0   0 170   0   0 170   0   0
+255  85  85 170 170 170 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 255 255 255 255  85  85 170   0   0
+170   0   0 170   0   0 170   0   0 255  85  85
+170 170 170 255  85  85 170 170 170 255 255 255
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 255  85  85 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+255 255 255 255 255 255   0   0   0   0   0   0
+  0   0   0  85  85  85 170 170 170 170 170 170
+255 255 255 255 255 255 170 170 170 255 255 255
+255 255 255 170 170 170 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 255 255 255
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 255 255 255 170 170 170 170   0   0
+170   0   0 170   0   0 170   0   0 170 170 170
+170 170 170 170   0   0 170   0   0 170   0   0
+170   0   0 170 170 170 255 255 255 255  85  85
+170   0   0 170   0   0 170   0   0 170   0   0
+170 170 170 255  85  85 170   0   0 170   0   0
+170   0   0 170   0   0 255 255 255 170 170 170
+255 255 255 255 255 255 170 170 170 255 255 255
+170 170 170 255 255 255 170   0   0 170   0   0
+170   0   0 170   0   0 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 170 170 170
+170   0   0 170   0   0 170   0   0 170   0   0
+170 170 170 255 255 255 255 255 255 255  85  85
+170   0   0 170   0   0 170   0   0 255  85  85
+255 255 255 170 170 170   0   0   0   0   0   0
+  0   0   0 255 255 255 255 255 255 255  85  85
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 255  85  85 255 255 255
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 255  85  85 255 255 255
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 255  85  85 170   0   0
+170   0   0 170   0   0 170   0   0 255  85  85
+255 255 255 170 170 170 170   0   0 170   0   0
+170   0   0 170   0   0 255  85  85 255  85  85
+255  85  85 255  85  85 170   0   0 255  85  85
+255 255 255 170 170 170 170   0   0 170   0   0
+170   0   0 170   0   0 255 255 255 255 255 255
+255  85  85 170 170 170 255 255 255 170 170 170
+170   0   0 170   0   0 170   0   0 170   0   0
+170 170 170 170 170 170 255 255 255 170   0   0
+170   0   0 170   0   0 170   0   0 255  85  85
+255 255 255 170 170 170   0   0   0   0   0   0
+ 85  85  85 255 255 255 255  85  85 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 255  85  85 170 170 170 255 255 255
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 255  85  85 170 170 170 255 255 255
+255  85  85 170   0   0 170   0   0 170   0   0
+255  85  85 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170 170 170
+255 255 255 170 170 170 255  85  85 170   0   0
+170   0   0 170   0   0 170   0   0 170   0   0
+170   0   0 170   0   0 170   0   0 170 170 170
+255 255 255 255  85  85 170   0   0 170   0   0
+170   0   0 255  85  85 255 255 255 170 170 170
+170  85   0 170 170 170 255 255 255 255  85  85
+170   0   0 170   0   0 170   0   0 255  85  85
+255 255 255 255 255 255 170 170 170 170   0   0
+170   0   0 170   0   0 170   0   0 170 170 170
+255 255 255  85  85  85   0   0   0   0   0   0
+ 85  85  85 170 170 170 170 170 170 170 170 170
+255  85  85 255  85  85 255  85  85 255  85  85
+255  85  85 255  85  85 255  85  85 255  85  85
+255  85  85 255 255 255 170 170 170 170 170 170
+255 255 255 170 170 170 255  85  85 255  85  85
+255  85  85 255  85  85 255  85  85 255  85  85
+255  85  85 255 255 255 255 255 255 255 255 255
+170   0   0 170   0   0 170   0   0 170   0   0
+170 170 170 170 170 170 255  85  85 255  85  85
+255  85  85 255  85  85 170 170 170 255 255 255
+ 85  85  85 170 170 170 255 255 255 255  85  85
+255  85  85 255  85  85 255  85  85 255  85  85
+255  85  85 255  85  85 170 170 170 255 255 255
+170 170 170 255  85  85 170 170 170 255  85  85
+255  85  85 170 170 170 255 255  85 170 170 170
+  0   0   0  85  85  85 170 170 170 255  85  85
+170 170 170 255  85  85 255  85  85 255  85  85
+255 255 255 255  85  85 170 170 170 255  85  85
+170 170 170 255  85  85 170 170 170 255 255 255
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85 170  85   0 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255   0   0   0   0   0   0
+170 170 170 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255 255  85  85
+170   0   0 170   0   0 170   0   0 170   0   0
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255  85  85  85
+  0   0   0  85  85  85 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 255 255 255
+255 255 255 255 255 255 255 255 255  85  85  85
+170 170 170 255 255  85 255 255 255 255 255 255
+255 255 255 255 255 255 255  85  85   0   0   0
+  0   0   0   0   0   0 170 170 170 170 170 170
+255 255 255 255 255 255 255 255 255 255 255 255
+ 85  85  85  85  85  85 170 170 170 255 255 255
+255 255 255 255 255 255 255 255 255 170  85   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85  85  85  85
+170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0  85  85  85 170 170 170 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170
+ 85  85  85  85  85  85 170 170 170 170 170 170
+255  85  85 255  85  85 255  85  85 255  85  85
+255 255 255 170  85   0 170 170 170 170 170 170
+170 170 170 170 170 170   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0 170 170 170
+170 170 170 170 170 170 170 170 170 170 170 170
+170 170 170  85  85  85 170  85   0   0   0   0
+  0   0   0  85  85  85  85  85  85 170 170 170
+ 85  85  85  85  85  85   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+170 170 170  85  85  85 170 170 170  85  85  85
+  0   0   0   0   0   0  85  85  85  85  85  85
+170 170 170  85  85  85 170 170 170   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0  85  85  85 170 170 170
+255 255 255 255 255 255 255 255 255 255 255 255
+ 85  85  85   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0  85  85  85
+170 170 170 170 170 170 170 170 170 170 170 170
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
+  0   0   0   0   0   0   0   0   0   0   0   0
diff -Nru a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c
--- a/drivers/video/maxinefb.c	Tue Nov 26 16:03:45 2002
+++ b/drivers/video/maxinefb.c	Thu Feb 13 18:50:30 2003
@@ -34,7 +34,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
-#include "maxinefb.h"
+#include <video/maxinefb.h>
 
 /* bootinfo.h defines the machine type values, needed when checking */
 /* whether are really running on a maxine, KM                       */
diff -Nru a/drivers/video/maxinefb.h b/drivers/video/maxinefb.h
--- a/drivers/video/maxinefb.h	Tue Feb  5 10:13:06 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,37 +0,0 @@
-/*
- *      linux/drivers/video/maxinefb.h
- *
- *      DECstation 5000/xx onboard framebuffer support, Copyright (C) 1999 by
- *      Michael Engel <engel@unix-ag.org> and Karsten Merker <merker@guug.de>
- *      This file is subject to the terms and conditions of the GNU General
- *      Public License.  See the file COPYING in the main directory of this
- *      archive for more details.
- */
-
-
-/*
- * IMS332 video controller register base address
- */
-#define MAXINEFB_IMS332_ADDRESS                  0xbc140000
-
-/*
- * Begin of DECstation 5000/xx onboard framebuffer memory, default resolution
- * is 1024x768x8
- */
-#define DS5000_xx_ONBOARD_FBMEM_START	0xaa000000
-
-/*
- *      The IMS 332 video controller used in the DECstation 5000/xx series
- *      uses 32 bits wide registers; the following defines declare the
- *      register numbers, to get the real offset, these have to be multiplied
- *      by four.
- */
-
-#define IMS332_REG_CURSOR_RAM           0x200	/* hardware cursor bitmap */
-
-/*
- * The color palette entries have the form 0x00BBGGRR
- */
-#define IMS332_REG_COLOR_PALETTE        0x100	/* color palette, 256 entries */
-#define IMS332_REG_CURSOR_COLOR_PALETTE	0x0a1	/* cursor color palette, */
-						/* 3 entries             */
diff -Nru a/drivers/video/modedb.c b/drivers/video/modedb.c
--- a/drivers/video/modedb.c	Sat Oct 12 12:51:48 2002
+++ b/drivers/video/modedb.c	Sun Jan 26 14:03:25 2003
@@ -129,6 +129,14 @@
 	NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
 	0, FB_VMODE_NONINTERLACED   	
     }, {
+	/* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
+	"LCD_XGA_75", 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3,
+	FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+    }, {
+	/* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
+	"LCD_XGA_60", 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
+	FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+    }, {
 	/* 1024x768 @ 85 Hz, 70.24 kHz hsync */
 	NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
 	0, FB_VMODE_NONINTERLACED
diff -Nru a/drivers/video/neofb.c b/drivers/video/neofb.c
--- a/drivers/video/neofb.c	Sat Nov 23 12:33:40 2002
+++ b/drivers/video/neofb.c	Mon Mar  3 19:41:18 2003
@@ -1143,7 +1143,6 @@
 		VGAwCR(0x70, par->VerticalExt);
 	}
 
-
 	vgaHWProtect(0);	/* Turn on screen */
 
 	/* Calling this also locks offset registers required in update_start */
@@ -1152,8 +1151,16 @@
 	info->fix.line_length =
 	    info->var.xres_virtual * (info->var.bits_per_pixel >> 3);
 
-	if (info->var.accel_flags & FB_ACCELF_TEXT)
-		neo2200_accel_init(info, &info->var);
+	switch (info->fix.accel) {
+		case FB_ACCEL_NEOMAGIC_NM2200:
+		case FB_ACCEL_NEOMAGIC_NM2230: 
+		case FB_ACCEL_NEOMAGIC_NM2360: 
+		case FB_ACCEL_NEOMAGIC_NM2380: 
+			neo2200_accel_init(info, &info->var);
+			break;
+		default:
+			break;
+	}	
 	return 0;
 }
 
@@ -1318,7 +1325,7 @@
 }
 
 static void
-neo2200_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+neo2200_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
 	struct neofb_par *par = (struct neofb_par *) info->par;
 	u_long dst, rop;
@@ -1352,33 +1359,30 @@
 }
 
 static void
-neo2200_copyarea(struct fb_info *info, struct fb_copyarea *area)
+neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
 	struct neofb_par *par = (struct neofb_par *) info->par;
+	u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
 	u_long src, dst, bltCntl;
 
 	bltCntl = NEO_BC3_FIFO_EN | NEO_BC3_SKIP_MAPPING | 0x0C0000;
 
-	if (area->sy < area->dy) {
-		area->sy += (area->height - 1);
-		area->dy += (area->height - 1);
+	if (sy < dy) {
+		sy += (area->height - 1);
+		dy += (area->height - 1);
 
 		bltCntl |= NEO_BC0_DST_Y_DEC | NEO_BC0_SRC_Y_DEC;
 	}
 
 	if (area->sx < area->dx) {
-		area->sx += (area->width - 1);
-		area->dx += (area->width - 1);
+		sx += (area->width - 1);
+		dx += (area->width - 1);
 
 		bltCntl |= NEO_BC0_X_DEC;
 	}
 
-	src =
-	    area->sx * (info->var.bits_per_pixel >> 3) +
-	    area->sy * info->fix.line_length;
-	dst =
-	    area->dx * (info->var.bits_per_pixel >> 3) +
-	    area->dy * info->fix.line_length;
+	src = sx * (info->var.bits_per_pixel >> 3) + sy*info->fix.line_length;
+	dst = dx * (info->var.bits_per_pixel >> 3) + dy*info->fix.line_length;
 
 	neo2200_wait_fifo(info, 4);
 
@@ -1392,7 +1396,7 @@
 }
 
 static void
-neo2200_imageblit(struct fb_info *info, struct fb_image *image)
+neo2200_imageblit(struct fb_info *info, const struct fb_image *image)
 {
 	struct neofb_par *par = (struct neofb_par *) info->par;
 
@@ -1429,32 +1433,69 @@
 }
 
 static void
-neofb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+neofb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
-	if (info->var.accel_flags == FB_ACCELF_TEXT)
-		neo2200_fillrect(info, rect);	
-	else
-		cfb_fillrect(info, rect);
+	switch (info->fix.accel) {
+		case FB_ACCEL_NEOMAGIC_NM2200:
+		case FB_ACCEL_NEOMAGIC_NM2230: 
+		case FB_ACCEL_NEOMAGIC_NM2360: 
+		case FB_ACCEL_NEOMAGIC_NM2380: 
+			neo2200_fillrect(info, rect);
+			break;
+		default:
+			cfb_fillrect(info, rect);
+			break;
+	}	
 }
 
 static void
-neofb_copyarea(struct fb_info *info, struct fb_copyarea *area)
+neofb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
-	if (info->var.accel_flags == FB_ACCELF_TEXT)
-		neo2200_copyarea(info, area);	
-	else
-		cfb_copyarea(info, area);	
+	switch (info->fix.accel) {
+		case FB_ACCEL_NEOMAGIC_NM2200:
+		case FB_ACCEL_NEOMAGIC_NM2230: 
+		case FB_ACCEL_NEOMAGIC_NM2360: 
+		case FB_ACCEL_NEOMAGIC_NM2380: 
+			neo2200_copyarea(info, area);
+			break;
+		default:
+			cfb_copyarea(info, area);
+			break;
+	}	
 }
 
 static void
-neofb_imageblit(struct fb_info *info, struct fb_image *image)
+neofb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
-	if (info->var.accel_flags == FB_ACCELF_TEXT)
-		neo2200_imageblit(info, image);	
-	else
-		cfb_imageblit(info, image);	
+	switch (info->fix.accel) {
+		case FB_ACCEL_NEOMAGIC_NM2200:
+		case FB_ACCEL_NEOMAGIC_NM2230: 
+		case FB_ACCEL_NEOMAGIC_NM2360: 
+		case FB_ACCEL_NEOMAGIC_NM2380: 
+			neo2200_imageblit(info, image);
+			break;
+		default:
+			cfb_imageblit(info, image);
+			break;
+	}
 }	
-	
+
+static int 
+neofb_sync(struct fb_info *info)
+{
+	switch (info->fix.accel) {
+		case FB_ACCEL_NEOMAGIC_NM2200:
+		case FB_ACCEL_NEOMAGIC_NM2230: 
+		case FB_ACCEL_NEOMAGIC_NM2360: 
+		case FB_ACCEL_NEOMAGIC_NM2380: 
+			neo2200_sync(info);
+			break;
+		default:
+			break;
+	}
+	return 0;		
+}
+
 static struct fb_ops neofb_ops = {
 	.owner		= THIS_MODULE,
 	.fb_check_var	= neofb_check_var,
@@ -1462,7 +1503,7 @@
 	.fb_setcolreg	= neofb_setcolreg,
 	.fb_pan_display	= neofb_pan_display,
 	.fb_blank	= neofb_blank,
-	.fb_sync	= neo2200_sync,
+	.fb_sync	= neofb_sync,
 	.fb_fillrect	= neofb_fillrect,
 	.fb_copyarea	= neofb_copyarea,
 	.fb_imageblit	= neofb_imageblit,
diff -Nru a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
--- a/drivers/video/platinumfb.c	Wed Nov 13 16:08:15 2002
+++ b/drivers/video/platinumfb.c	Thu Mar 20 06:36:41 2003
@@ -29,7 +29,6 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/fb.h>
-#include <linux/selection.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/nvram.h>
@@ -37,15 +36,8 @@
 #include <asm/prom.h>
 #include <asm/pgtable.h>
 
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb32.h>
-#include <video/macmodes.h>
-
 #include "platinumfb.h"
-
-static char fontname[40] __initdata = { 0 };
+#include "macmodes.h"
 
 static int default_vmode = VMODE_NVRAM;
 static int default_cmode = CMODE_NVRAM;
@@ -59,7 +51,6 @@
 
 struct fb_info_platinum {
 	struct fb_info			info;
-	struct display			display; /* Will disappear */
 	struct fb_par_platinum		par;
 
 	struct {
@@ -118,16 +109,14 @@
 
 static struct fb_ops platinumfb_ops = {
 	.owner =	THIS_MODULE,
-	.fb_set_var	= gen_set_var,
 	.fb_check_var	= platinumfb_check_var,
 	.fb_set_par	= platinumfb_set_par,
-	.fb_get_cmap	= gen_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
 	.fb_setcolreg	= platinumfb_setcolreg,
 	.fb_blank	= platinumfb_blank,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
 };
 
 /*
@@ -338,22 +327,12 @@
 static void __init platinum_init_info(struct fb_info *info, struct fb_info_platinum *p)
 {
 	/* Fill fb_info */
-	strcpy(info->modename, "platinum");
-	info->currcon = -1;
 	info->par = &p->par;
 	info->node = NODEV;
 	info->fbops = &platinumfb_ops;
-	info->disp = &p->display;
 	info->pseudo_palette = p->pseudo_palette;
         info->flags = FBINFO_FLAG_DEFAULT;
-        strncpy (info->fontname, fontname, sizeof (info->fontname));
-        info->fontname[sizeof (info->fontname) - 1] = 0;
-	info->changevar = NULL;
-        info->display_fg = NULL;
 	info->screen_base = (char *) p->frame_buffer + 0x20;
-	info->changevar  = NULL;
-	info->switch_con = gen_switch;
-	info->updatevar  = gen_update_var;
 
 	fb_alloc_cmap(&info->cmap, 256, 0);
 
diff -Nru a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
--- a/drivers/video/pm2fb.c	Fri Dec  6 12:36:20 2002
+++ b/drivers/video/pm2fb.c	Sun Feb 16 10:36:47 2003
@@ -46,7 +46,7 @@
 #include <video/fbcon-cfb16.h>
 #include <video/fbcon-cfb24.h>
 #include <video/fbcon-cfb32.h>
-#include "pm2fb.h"
+#include <video/pm2fb.h>
 #include "cvisionppc.h"
 #ifdef __sparc__
 #include <asm/pbm.h>
diff -Nru a/drivers/video/pm2fb.h b/drivers/video/pm2fb.h
--- a/drivers/video/pm2fb.h	Tue Feb  5 09:40:16 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,218 +0,0 @@
-/*
- * Permedia2 framebuffer driver definitions.
- * Copyright (c) 1998-1999 Ilario Nardinocchi (nardinoc@CS.UniBO.IT)
- * --------------------------------------------------------------------------
- * $Id: pm2fb.h,v 1.21 1999/01/28 13:18:07 illo Exp $
- * --------------------------------------------------------------------------
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-#ifndef PM2FB_H
-#define PM2FB_H
-
-#define PM2_REFERENCE_CLOCK	14318			/* in KHz */
-#define PM2_MAX_PIXCLOCK	230000			/* in KHz */
-#define PM2_REGS_SIZE		0x10000
-
-#define PM2TAG(r) (u32 )(((r)-0x8000)>>3)
-
-/*****************************************************************************
- * Permedia2 registers used in the framebuffer
- *****************************************************************************/
- 
-#define PM2R_RESET_STATUS				0x0000
-#define PM2R_IN_FIFO_SPACE				0x0018
-#define PM2R_OUT_FIFO_WORDS				0x0020
-#define PM2R_APERTURE_ONE				0x0050
-#define PM2R_APERTURE_TWO				0x0058
-#define PM2R_FIFO_DISCON				0x0068
-#define PM2R_CHIP_CONFIG				0x0070
-
-#define PM2R_REBOOT					0x1000
-#define PM2R_MEM_CONTROL				0x1040
-#define PM2R_BOOT_ADDRESS				0x1080
-#define PM2R_MEM_CONFIG					0x10c0
-#define PM2R_BYPASS_WRITE_MASK				0x1100
-#define PM2R_FRAMEBUFFER_WRITE_MASK			0x1140
-
-#define PM2R_OUT_FIFO					0x2000
-
-#define PM2R_SCREEN_BASE				0x3000
-#define PM2R_SCREEN_STRIDE				0x3008
-#define PM2R_H_TOTAL					0x3010
-#define PM2R_HG_END					0x3018
-#define PM2R_HB_END					0x3020
-#define PM2R_HS_START					0x3028
-#define PM2R_HS_END					0x3030
-#define PM2R_V_TOTAL					0x3038
-#define PM2R_VB_END					0x3040
-#define PM2R_VS_START					0x3048
-#define PM2R_VS_END					0x3050
-#define PM2R_VIDEO_CONTROL				0x3058
-#define PM2R_LINE_COUNT					0x3070
-#define PM2R_FIFO_CONTROL				0x3078
-
-#define PM2R_RD_PALETTE_WRITE_ADDRESS			0x4000
-#define PM2R_RD_PALETTE_DATA				0x4008
-#define PM2R_RD_PALETTE_READ_ADDRESS			0x4018
-#define PM2R_RD_INDEXED_DATA				0x4050
-
-#define PM2R_START_X_DOM				0x8000
-#define PM2R_D_X_DOM					0x8008
-#define PM2R_START_X_SUB				0x8010
-#define PM2R_D_X_SUB					0x8018
-#define PM2R_START_Y					0x8020
-#define PM2R_D_Y					0x8028
-#define PM2R_COUNT					0x8030
-#define PM2R_RENDER					0x8038
-#define PM2R_RECTANGLE_ORIGIN				0x80d0
-#define PM2R_RECTANGLE_SIZE				0x80d8
-#define PM2R_PACKED_DATA_LIMITS				0x8150
-#define PM2R_SCISSOR_MODE				0x8180
-#define PM2R_SCREEN_SIZE				0x8198
-#define PM2R_AREA_STIPPLE_MODE				0x81a0
-#define PM2R_WINDOW_ORIGIN				0x81c8
-#define PM2R_TEXTURE_ADDRESS_MODE			0x8380
-#define PM2R_TEXTURE_MAP_FORMAT				0x8588
-#define PM2R_TEXTURE_DATA_FORMAT			0x8590
-#define PM2R_TEXTURE_READ_MODE				0x8670
-#define PM2R_TEXEL_LUT_MODE				0x8678
-#define PM2R_TEXTURE_COLOR_MODE				0x8680
-#define PM2R_FOG_MODE					0x8690
-#define PM2R_COLOR_DDA_MODE				0x87e0
-#define PM2R_ALPHA_BLEND_MODE				0x8810
-#define PM2R_DITHER_MODE				0x8818
-#define PM2R_FB_SOFT_WRITE_MASK				0x8820
-#define PM2R_LOGICAL_OP_MODE				0x8828
-#define PM2R_LB_READ_MODE				0x8880
-#define PM2R_LB_READ_FORMAT				0x8888
-#define PM2R_LB_SOURCE_OFFSET				0x8890
-#define PM2R_LB_WINDOW_BASE				0x88b8
-#define PM2R_LB_WRITE_FORMAT				0x88c8
-#define PM2R_STENCIL_MODE				0x8988
-#define PM2R_DEPTH_MODE					0x89a0
-#define PM2R_FB_READ_MODE				0x8a80
-#define PM2R_FB_SOURCE_OFFSET				0x8a88
-#define PM2R_FB_PIXEL_OFFSET				0x8a90
-#define PM2R_FB_WINDOW_BASE				0x8ab0
-#define PM2R_FB_WRITE_MODE				0x8ab8
-#define PM2R_FB_HARD_WRITE_MASK				0x8ac0
-#define PM2R_FB_BLOCK_COLOR				0x8ac8
-#define PM2R_FB_READ_PIXEL				0x8ad0
-#define PM2R_FILTER_MODE				0x8c00
-#define PM2R_SYNC					0x8c40
-#define PM2R_YUV_MODE					0x8f00
-#define PM2R_STATISTICS_MODE				0x8c08
-#define PM2R_FB_SOURCE_DELTA				0x8d88
-#define PM2R_CONFIG					0x8d90
-
-/* Permedia2v */
-#define PM2VR_RD_INDEX_LOW				0x4020
-#define PM2VR_RD_INDEX_HIGH				0x4028
-#define PM2VR_RD_INDEXED_DATA				0x4030
-
-/* Permedia2 RAMDAC indexed registers */
-#define PM2I_RD_CURSOR_CONTROL				0x06
-#define PM2I_RD_COLOR_MODE				0x18
-#define PM2I_RD_MODE_CONTROL				0x19
-#define PM2I_RD_MISC_CONTROL				0x1e
-#define PM2I_RD_PIXEL_CLOCK_A1				0x20
-#define PM2I_RD_PIXEL_CLOCK_A2				0x21
-#define PM2I_RD_PIXEL_CLOCK_A3				0x22
-#define PM2I_RD_PIXEL_CLOCK_STATUS			0x29
-#define PM2I_RD_MEMORY_CLOCK_1				0x30
-#define PM2I_RD_MEMORY_CLOCK_2				0x31
-#define PM2I_RD_MEMORY_CLOCK_3				0x32
-#define PM2I_RD_MEMORY_CLOCK_STATUS			0x33
-#define PM2I_RD_COLOR_KEY_CONTROL			0x40
-#define PM2I_RD_OVERLAY_KEY				0x41
-#define PM2I_RD_RED_KEY					0x42
-#define PM2I_RD_GREEN_KEY				0x43
-#define PM2I_RD_BLUE_KEY				0x44
-
-/* Permedia2v extensions */
-#define PM2VI_RD_MISC_CONTROL				0x000
-#define PM2VI_RD_SYNC_CONTROL				0x001
-#define PM2VI_RD_DAC_CONTROL				0x002
-#define PM2VI_RD_PIXEL_SIZE				0x003
-#define PM2VI_RD_COLOR_FORMAT				0x004
-#define PM2VI_RD_CURSOR_MODE				0x005
-#define PM2VI_RD_CURSOR_X_LOW				0x007
-#define PM2VI_RD_CURSOR_X_HIGH				0x008
-#define PM2VI_RD_CURSOR_Y_LOW				0x009
-#define PM2VI_RD_CURSOR_Y_HIGH				0x00A
-#define PM2VI_RD_CURSOR_X_HOT				0x00B
-#define PM2VI_RD_CURSOR_Y_HOT				0x00C
-#define PM2VI_RD_CLK0_PRESCALE				0x201
-#define PM2VI_RD_CLK0_FEEDBACK				0x202
-#define PM2VI_RD_CLK0_POSTSCALE				0x203
-#define PM2VI_RD_CLK1_PRESCALE				0x204
-#define PM2VI_RD_CLK1_FEEDBACK				0x205
-#define PM2VI_RD_CLK1_POSTSCALE				0x206
-#define PM2VI_RD_CURSOR_PALETTE				0x303
-#define PM2VI_RD_CURSOR_PATTERN				0x400
-
-/* Fields and flags */
-#define PM2F_RENDER_AREASTIPPLE				(1L<<0)
-#define PM2F_RENDER_FASTFILL				(1L<<3)
-#define PM2F_RENDER_PRIMITIVE_MASK			(3L<<6)
-#define PM2F_RENDER_LINE				0
-#define PM2F_RENDER_TRAPEZOID				(1L<<6)
-#define PM2F_RENDER_POINT				(2L<<6)
-#define PM2F_RENDER_RECTANGLE				(3L<<6)
-#define PM2F_SYNCHRONIZATION				(1L<<10)
-#define PM2F_PLL_LOCKED					0x10
-#define PM2F_BEING_RESET				(1L<<31)
-#define PM2F_DATATYPE_COLOR				0x8000
-#define PM2F_VGA_ENABLE					0x02
-#define PM2F_VGA_FIXED					0x04
-#define PM2F_FB_WRITE_ENABLE				0x01
-#define PM2F_FB_READ_SOURCE_ENABLE			0x0200
-#define PM2F_RD_PALETTE_WIDTH_8				0x02
-#define PM2F_PART_PROD_MASK				0x01ff
-#define PM2F_SCREEN_SCISSOR_ENABLE			0x02
-#define PM2F_DATA_64_ENABLE				0x00010000
-#define PM2F_BLANK_LOW					0x02
-#define PM2F_HSYNC_MASK					0x18
-#define PM2F_VSYNC_MASK					0x60
-#define PM2F_HSYNC_ACT_HIGH				0x08
-#define PM2F_HSYNC_FORCED_LOW				0x10
-#define PM2F_HSYNC_ACT_LOW				0x18
-#define PM2F_VSYNC_ACT_HIGH				0x20
-#define PM2F_VSYNC_FORCED_LOW				0x40
-#define PM2F_VSYNC_ACT_LOW				0x60
-#define PM2F_LINE_DOUBLE				0x04
-#define PM2F_VIDEO_ENABLE				0x01
-#define PM2F_RD_GUI_ACTIVE				0x10
-#define PM2F_RD_COLOR_MODE_RGB				0x20
-#define PM2F_RD_TRUECOLOR				0x80
-#define PM2F_NO_ALPHA_BUFFER				0x10
-#define PM2F_TEXTEL_SIZE_16				0x00080000
-#define PM2F_TEXTEL_SIZE_32				0x00100000
-#define PM2F_TEXTEL_SIZE_4				0x00180000
-#define PM2F_TEXTEL_SIZE_24				0x00200000
-#define PM2F_INCREASE_X					(1L<<21)
-#define PM2F_INCREASE_Y					(1L<<22)
-#define PM2F_CONFIG_FB_WRITE_ENABLE			(1L<<3)
-#define PM2F_CONFIG_FB_PACKED_DATA			(1L<<2)
-#define PM2F_CONFIG_FB_READ_DEST_ENABLE			(1L<<1)
-#define PM2F_CONFIG_FB_READ_SOURCE_ENABLE		(1L<<0)
-#define PM2F_COLOR_KEY_TEST_OFF				(1L<<4)
-#define PM2F_MEM_CONFIG_RAM_MASK			(3L<<29)
-#define PM2F_MEM_BANKS_1				0L
-#define PM2F_MEM_BANKS_2				(1L<<29)
-#define PM2F_MEM_BANKS_3				(2L<<29)
-#define PM2F_MEM_BANKS_4				(3L<<29)
-
-typedef enum {
-	PM2_TYPE_PERMEDIA2,
-	PM2_TYPE_PERMEDIA2V
-} pm2type_t;
-
-#endif /* PM2FB_H */
-
-/*****************************************************************************
- * That's all folks!
- *****************************************************************************/
diff -Nru a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
--- a/drivers/video/pm3fb.c	Tue Feb 18 10:50:38 2003
+++ b/drivers/video/pm3fb.c	Wed Feb 19 16:35:24 2003
@@ -77,6 +77,7 @@
 #include <video/fbcon-cfb16.h>
 #include <video/fbcon-cfb24.h>
 #include <video/fbcon-cfb32.h>
+#include <video/pm3fb.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -84,8 +85,6 @@
 #ifdef CONFIG_FB_OF
 #include <asm/prom.h>
 #endif
-
-#include "pm3fb.h"
 
 /* ************************************* */
 /* ***** The various "global" data ***** */
diff -Nru a/drivers/video/pm3fb.h b/drivers/video/pm3fb.h
--- a/drivers/video/pm3fb.h	Mon Aug  5 23:12:39 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1284 +0,0 @@
-/*
- *  linux/drivers/video/pm3fb.h -- 3DLabs Permedia3 frame buffer device
- *  
- *  Copyright (C) 2001 Romain Dolbeau <dolbeau@irisa.fr>
- *  Copyright (C) 2001 Sven Luther, <luther@dpt-info.u-strasbg.fr>
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License. See the file COPYING in the main directory of this archive for
- *  more details.
- *
- *  $Header: /cvsroot/linux/drivers/video/pm3fb.h,v 1.1 2002/02/25 19:11:06 marcelo Exp $
- *
- */
-
-#ifndef PM3FB_H
-#define PM3FB_H
-
-/**********************************************
-*  GLINT Permedia3 Control Status registers   *
-***********************************************/
-/* Control Status Registers */
-#define PM3ResetStatus						0x0000
-#define PM3IntEnable						0x0008
-#define PM3IntFlags						0x0010
-#define PM3InFIFOSpace						0x0018
-#define PM3OutFIFOWords						0x0020
-#define PM3DMAAddress						0x0028
-#define PM3DMACount						0x0030
-#define PM3ErrorFlags						0x0038
-#define PM3VClkCtl						0x0040
-#define PM3TestRegister						0x0048
-#define PM3Aperture0						0x0050
-#define PM3Aperture1						0x0058
-#define PM3DMAControl						0x0060
-#define PM3FIFODis						0x0068
-#define PM3ChipConfig						0x0070
-#define PM3AGPControl						0x0078
-
-#define PM3GPOutDMAAddress					0x0080
-#define PM3PCIFeedbackCount					0x0088
-#define PM3PCIAbortStatus					0x0090
-#define PM3PCIAbortAddress					0x0098
-
-#define PM3PCIPLLStatus						0x00f0
-
-#define PM3HostTextureAddress					0x0100
-#define PM3TextureDownloadControl				0x0108
-#define PM3TextureOperation					0x0110
-#define PM3LogicalTexturePage					0x0118
-#define PM3TexDMAAddress					0x0120
-#define PM3TexFIFOSpace						0x0128
-
-/**********************************************
-*  GLINT Permedia3 Region 0 Bypass Controls   *
-***********************************************/
-#define PM3ByAperture1Mode					0x0300
-	#define PM3ByApertureMode_BYTESWAP_ABCD			(0<<0)
-	#define PM3ByApertureMode_BYTESWAP_BADC			(1<<0)
-	#define PM3ByApertureMode_BYTESWAP_CDAB			(2<<0)
-	#define PM3ByApertureMode_BYTESWAP_DCBA			(3<<0)
-	#define PM3ByApertureMode_PATCH_DISABLE			(0<<2)
-	#define PM3ByApertureMode_PATCH_ENABLE			(1<<2)
-	#define PM3ByApertureMode_FORMAT_RAW			(0<<3)
-	#define PM3ByApertureMode_FORMAT_YUYV			(1<<3)
-	#define PM3ByApertureMode_FORMAT_UYVY			(2<<3)
-	#define PM3ByApertureMode_PIXELSIZE_8BIT		(0<<5)
-	#define PM3ByApertureMode_PIXELSIZE_16BIT		(1<<5)
-	#define PM3ByApertureMode_PIXELSIZE_32BIT		(2<<5)
-                #define PM3ByApertureMode_PIXELSIZE_MASK        (3<<5)
-	#define PM3ByApertureMode_EFFECTIVE_STRIDE_1024		(0<<7)
-	#define PM3ByApertureMode_EFFECTIVE_STRIDE_2048		(1<<7)
-	#define PM3ByApertureMode_EFFECTIVE_STRIDE_4096		(2<<7)
-	#define PM3ByApertureMode_EFFECTIVE_STRIDE_8192		(3<<7)
-	#define PM3ByApertureMode_PATCH_OFFSET_X(off)	(((off)&7f)<<9)
-	#define PM3ByApertureMode_PATCH_OFFSET_Y(off)	(((off)&7f)<<16)
-	#define PM3ByApertureMode_FRAMEBUFFER			(0<<21)
-	#define PM3ByApertureMode_LOCALBUFFER			(1<<21)
-	#define PM3ByApertureMode_DOUBLE_WRITE_OFF		(0<<22)
-	#define PM3ByApertureMode_DOUBLE_WRITE_1MB		(1<<22)
-	#define PM3ByApertureMode_DOUBLE_WRITE_2MB		(2<<22)
-	#define PM3ByApertureMode_DOUBLE_WRITE_4MB		(3<<22)
-	#define PM3ByApertureMode_DOUBLE_WRITE_8MB		(4<<22)
-	#define PM3ByApertureMode_DOUBLE_WRITE_16MB		(5<<22)
-	#define PM3ByApertureMode_DOUBLE_WRITE_32MB		(6<<22)
-
-#define PM3ByAperture2Mode					0x0328
-	
-/**********************************************
-*  GLINT Permedia3 Memory Control (0x1000)    *
-***********************************************/
-#define PM3MemCounter						0x1000
-#define PM3MemBypassWriteMask					0x1008
-#define PM3MemScratch						0x1010
-#define PM3LocalMemCaps						0x1018
-        #define PM3LocalMemCaps_NoWriteMask                     (1 << 28)
-#define PM3LocalMemTimings					0x1020
-#define PM3LocalMemControl					0x1028
-#define PM3LocalMemRefresh					0x1030
-#define PM3LocalMemPowerDown					0x1038
-#define PM3RemoteMemControl					0x1100
-
-/**********************************************
-*  GLINT Permedia3 Video Control (0x3000)     *
-***********************************************/
-
-#define PM3ScreenBase						0x3000
-#define PM3ScreenStride						0x3008
-#define PM3HTotal						0x3010
-#define PM3HgEnd						0x3018
-#define PM3HbEnd						0x3020
-#define PM3HsStart						0x3028
-#define PM3HsEnd						0x3030
-#define PM3VTotal						0x3038
-#define PM3VbEnd						0x3040
-#define PM3VsStart						0x3048
-#define PM3VsEnd						0x3050
-#define PM3VideoControl						0x3058
-	#define PM3VideoControl_DISABLE				(0<<0)
-	#define PM3VideoControl_ENABLE				(1<<0)
-	#define PM3VideoControl_BLANK_ACTIVE_HIGH		(0<<1)
-	#define PM3VideoControl_BLANK_ACTIVE_LOW		(1<<1)
-	#define PM3VideoControl_LINE_DOUBLE_OFF			(0<<2)
-	#define PM3VideoControl_LINE_DOUBLE_ON			(1<<2)
-	#define PM3VideoControl_HSYNC_FORCE_HIGH		(0<<3)
-	#define PM3VideoControl_HSYNC_ACTIVE_HIGH		(1<<3)
-	#define PM3VideoControl_HSYNC_FORCE_LOW			(2<<3)
-	#define PM3VideoControl_HSYNC_ACTIVE_LOW		(3<<3)
-        #define PM3VideoControl_HSYNC_MASK          (3<<3)
-	#define PM3VideoControl_VSYNC_FORCE_HIGH		(0<<5)
-	#define PM3VideoControl_VSYNC_ACTIVE_HIGH		(1<<5)
-	#define PM3VideoControl_VSYNC_FORCE_LOW			(2<<5)
-	#define PM3VideoControl_VSYNC_ACTIVE_LOW		(3<<5)
-        #define PM3VideoControl_VSYNC_MASK          (3<<5)
-	#define PM3VideoControl_BYTE_DOUBLE_OFF			(0<<7)
-	#define PM3VideoControl_BYTE_DOUBLE_ON			(1<<7)
-	#define PM3VideoControl_BUFFER_SWAP_SYNCON_FRAMEBLANK	(0<<9)
-	#define PM3VideoControl_BUFFER_SWAP_FREE_RUNNING	(1<<9)
-	#define PM3VideoControl_BUFFER_SWAP_LIMITETO_FRAMERATE	(2<<9)
-	#define PM3VideoControl_STEREO_DISABLE			(0<<11)
-	#define PM3VideoControl_STEREO_ENABLE			(1<<11)
-	#define PM3VideoControl_RIGHT_EYE_ACTIVE_HIGH		(0<<12)
-	#define PM3VideoControl_RIGHT_EYE_ACTIVE_LOW		(1<<12)
-	#define PM3VideoControl_VIDEO_EXT_LOW			(0<<14)
-	#define PM3VideoControl_VIDEO_EXT_HIGH			(1<<14)
-	#define PM3VideoControl_SYNC_MODE_INDEPENDENT		(0<<16)
-	#define PM3VideoControl_SYNC_MODE_SYNCTO_VSA		(1<<16)
-	#define PM3VideoControl_SYNC_MODE_SYNCTO_VSB		(2<<16)
-	#define PM3VideoControl_PATCH_DISABLE			(0<<18)
-	#define PM3VideoControl_PATCH_ENABLE			(1<<18)
-	#define PM3VideoControl_PIXELSIZE_8BIT			(0<<19)
-	#define PM3VideoControl_PIXELSIZE_16BIT			(1<<19)
-	#define PM3VideoControl_PIXELSIZE_32BIT			(2<<19)
-	#define PM3VideoControl_DISPLAY_DISABLE			(0<<21)
-	#define PM3VideoControl_DISPLAY_ENABLE			(1<<21)
-	#define PM3VideoControl_PATCH_OFFSET_X(off)	(((off)&0x3f)<<22)
-	#define PM3VideoControl_PATCH_OFFSET_Y(off)	(((off)&0x3f)<<28)
-#define PM3InterruptLine					0x3060
-#define PM3DisplayData						0x3068
-#define PM3VerticalLineCount					0x3070
-#define PM3FifoControl						0x3078
-#define PM3ScreenBaseRight					0x3080
-#define PM3MiscControl						0x3088
-
-#define PM3VideoOverlayUpdate					0x3100
-        #define PM3VideoOverlayUpdate_DISABLE                   (0<<0)
-        #define PM3VideoOverlayUpdate_ENABLE                    (1<<0)
-#define PM3VideoOverlayMode					0x3108
-	#define PM3VideoOverlayMode_DISABLE			(0<<0)
-	#define PM3VideoOverlayMode_ENABLE			(1<<0)
-        #define PM3VideoOverlayMode_BUFFERSYNC_MANUAL           (0<<1)
-        #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMA     (1<<1)
-        #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMB     (2<<1)
-        #define PM3VideoOverlayMode_FIELDPOLARITY_NORMAL        (0<<4)
-        #define PM3VideoOverlayMode_FIELDPOLARITY_INVERT        (1<<4)
-        #define PM3VideoOverlayMode_PIXELSIZE_8BIT              (0<<5)
-        #define PM3VideoOverlayMode_PIXELSIZE_16BIT             (1<<5)
-        #define PM3VideoOverlayMode_PIXELSIZE_32BIT             (2<<5)
-        #define PM3VideoOverlayMode_COLORFORMAT_RGB8888 ((0<<7)|(1<<12)|(2<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_RGB4444 ((1<<7)|(1<<12)|(1<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_RGB5551 ((2<<7)|(1<<12)|(1<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_RGB565  ((3<<7)|(1<<12)|(1<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_RGB332  ((4<<7)|(1<<12)|(0<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_BGR8888 ((0<<7)|(2<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_BGR4444 ((1<<7)|(1<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_BGR5551 ((2<<7)|(1<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_BGR565  ((3<<7)|(1<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_BGR332  ((4<<7)|(0<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_CI8     ((5<<7)|(1<<12)|(0<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_VUY444  ((2<<10)|(1<<12)|(2<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_YUV444  ((2<<10)|(2<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_VUY422  ((1<<10)|(1<<12)|(1<<5))
-        #define PM3VideoOverlayMode_COLORFORMAT_YUV422  ((1<<10)|(1<<5))
-        #define PM3VideoOverlayMode_COLORORDER_BGR              (0<<12)
-        #define PM3VideoOverlayMode_COLORORDER_RGB              (1<<12)
-        #define PM3VideoOverlayMode_LINEARCOLOREXT_OFF          (0<<13)
-        #define PM3VideoOverlayMode_LINEARCOLOREXT_ON           (1<<13)
-        #define PM3VideoOverlayMode_FILTER_MASK                 (3<<14)
-        #define PM3VideoOverlayMode_FILTER_OFF                  (0<<14)
-        #define PM3VideoOverlayMode_FILTER_FULL                 (1<<14)
-        #define PM3VideoOverlayMode_FILTER_PARTIAL              (2<<14)
-        #define PM3VideoOverlayMode_DEINTERLACE_OFF             (0<<16)
-        #define PM3VideoOverlayMode_DEINTERLACE_BOB             (1<<16)
-        #define PM3VideoOverlayMode_PATCHMODE_OFF               (0<<18)
-        #define PM3VideoOverlayMode_PATCHMODE_ON                (1<<18)
-        #define PM3VideoOverlayMode_FLIP_VIDEO                  (0<<20)
-        #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMA           (1<<20)
-        #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMB           (2<<20)
-        #define PM3VideoOverlayMode_MIRROR_MASK                 (3<<23)
-        #define PM3VideoOverlayMode_MIRRORX_OFF                 (0<<23)
-        #define PM3VideoOverlayMode_MIRRORX_ON                  (1<<23)
-        #define PM3VideoOverlayMode_MIRRORY_OFF                 (0<<24)
-        #define PM3VideoOverlayMode_MIRRORY_ON                  (1<<24)
-#define PM3VideoOverlayFifoControl				0x3110
-#define PM3VideoOverlayIndex					0x3118
-#define PM3VideoOverlayBase0					0x3120
-#define PM3VideoOverlayBase1					0x3128
-#define PM3VideoOverlayBase2					0x3130
-#define PM3VideoOverlayStride					0x3138
-        #define PM3VideoOverlayStride_STRIDE(s)         (((s)&0xfff)<<0)
-#define PM3VideoOverlayWidth                                    0x3140
-        #define PM3VideoOverlayWidth_WIDTH(w)           (((w)&0xfff)<<0)
-#define PM3VideoOverlayHeight                                   0x3148
-        #define PM3VideoOverlayHeight_HEIGHT(h)         (((h)&0xfff)<<0)
-#define PM3VideoOverlayOrigin                                   0x3150
-        #define PM3VideoOverlayOrigin_XORIGIN(x)        (((x)&0xfff)<<0)
-        #define PM3VideoOverlayOrigin_YORIGIN(y)        (((y)&0xfff)<<16)
-#define PM3VideoOverlayShrinkXDelta                             0x3158
-        #define PM3VideoOverlayShrinkXDelta_NONE                (1<<16)
-        #define PM3VideoOverlayShrinkXDelta_DELTA(s,d)          \
-                ((((s)<<16)/(d))&0x0ffffff0)
-#define PM3VideoOverlayZoomXDelta                               0x3160
-        #define PM3VideoOverlayZoomXDelta_NONE                  (1<<16)
-        #define PM3VideoOverlayZoomXDelta_DELTA(s,d)            \
-                ((((s)<<16)/(d))&0x0001fff0)
-#define PM3VideoOverlayYDelta                                   0x3168
-        #define PM3VideoOverlayYDelta_NONE                      (1<<16)
-        #define PM3VideoOverlayYDelta_DELTA(s,d)                        \
-                ((((s)<<16)/(d))&0x0ffffff0)
-#define PM3VideoOverlayFieldOffset				0x3170
-#define PM3VideoOverlayStatus					0x3178
-
-/**********************************************
-*  GLINT Permedia3 RAMDAC Registers (0x4000)  *
-***********************************************/
-/* Direct Registers */
-#define PM3RD_PaletteWriteAddress				0x4000
-#define PM3RD_PaletteData					0x4008
-#define PM3RD_PixelMask						0x4010
-#define PM3RD_PaletteReadAddress				0x4018
-
-#define PM3RD_IndexLow						0x4020
-#define PM3RD_IndexHigh						0x4028
-#define PM3RD_IndexedData					0x4030
-#define PM3RD_IndexControl					0x4038
-	#define PM3RD_IndexControl_AUTOINCREMENT_ENABLE		(1<<0)
-	#define PM3RD_IndexControl_AUTOINCREMENT_DISABLE	(0<<0)
-
-/* Indirect Registers */
-#define PM3RD_MiscControl					0x000
-	#define PM3RD_MiscControl_HIGHCOLOR_RES_DISABLE		(0<<0)
-	#define PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE		(1<<0)
-	#define PM3RD_MiscControl_PIXELDOUBLE_DISABLE		(0<<1)
-	#define PM3RD_MiscControl_PIXELDOUBLE_ENABLE		(1<<1)
-	#define PM3RD_MiscControl_LASTREAD_ADDR_DISABLE		(0<<2)
-	#define PM3RD_MiscControl_LASTREAD_ADDR_ENABLE		(1<<2)
-	#define PM3RD_MiscControl_DIRECTCOLOR_DISABLE		(0<<3)
-	#define PM3RD_MiscControl_DIRECTCOLOR_ENABLE		(1<<3)
-	#define PM3RD_MiscControl_OVERLAY_DISABLE		(0<<4)
-	#define PM3RD_MiscControl_OVERLAY_ENABLE		(1<<4)
-	#define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_DISABLE	(0<<5)
-	#define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_ENABLE	(1<<5)
-	#define PM3RD_MiscControl_VSB_OUTPUT_DISABLE		(0<<6)
-	#define PM3RD_MiscControl_VSB_OUTPUT_ENABLE		(1<<6)
-	#define PM3RD_MiscControl_STEREODOUBLE_BUFFER_DISABLE	(0<<7)
-	#define PM3RD_MiscControl_STEREODOUBLE_BUFFER_ENABLE	(1<<7)
-#define PM3RD_SyncControl					0x001
-	#define PM3RD_SyncControl_HSYNC_ACTIVE_LOW		(0<<0)
-	#define PM3RD_SyncControl_HSYNC_ACTIVE_HIGH		(1<<0)
-	#define PM3RD_SyncControl_HSYNC_FORCE_ACTIVE		(3<<0)
-	#define PM3RD_SyncControl_HSYNC_FORCE_INACTIVE		(4<<0)
-	#define PM3RD_SyncControl_HSYNC_TRI_STATE		(2<<0)
-	#define PM3RD_SyncControl_VSYNC_ACTIVE_LOW		(0<<3)
-	#define PM3RD_SyncControl_VSYNC_ACTIVE_HIGH		(1<<3)
-	#define PM3RD_SyncControl_VSYNC_TRI_STATE		(2<<3)
-	#define PM3RD_SyncControl_VSYNC_FORCE_ACTIVE		(3<<3)
-	#define PM3RD_SyncControl_VSYNC_FORCE_INACTIVE		(4<<3)
-	#define PM3RD_SyncControl_HSYNC_OVERRIDE_SETBY_HSYNC	(0<<6)
-	#define PM3RD_SyncControl_HSYNC_OVERRIDE_FORCE_HIGH	(1<<6)
-	#define PM3RD_SyncControl_VSYNC_OVERRIDE_SETBY_VSYNC	(0<<7)
-	#define PM3RD_SyncControl_VSYNC_OVERRIDE_FORCE_HIGH	(1<<7)
-#define PM3RD_DACControl					0x002
-	#define PM3RD_DACControl_DAC_POWER_ON			(0<<0)
-	#define PM3RD_DACControl_DAC_POWER_OFF			(1<<0)
-	#define PM3RD_DACControl_SYNC_ON_GREEN_DISABLE		(0<<3)
-	#define PM3RD_DACControl_SYNC_ON_GREEN_ENABLE		(1<<3)
-	#define PM3RD_DACControl_BLANK_RED_DAC_DISABLE		(0<<4)
-	#define PM3RD_DACControl_BLANK_RED_DAC_ENABLE		(1<<4)
-	#define PM3RD_DACControl_BLANK_GREEN_DAC_DISABLE	(0<<5)
-	#define PM3RD_DACControl_BLANK_GREEN_DAC_ENABLE		(1<<5)
-	#define PM3RD_DACControl_BLANK_BLUE_DAC_DISABLE		(0<<6)
-	#define PM3RD_DACControl_BLANK_BLUE_DAC_ENABLE		(1<<6)
-	#define PM3RD_DACControl_BLANK_PEDESTAL_DISABLE		(0<<7)
-	#define PM3RD_DACControl_BLANK_PEDESTAL_ENABLE		(1<<7)
-#define PM3RD_PixelSize						0x003
-	#define PM3RD_PixelSize_24_BIT_PIXELS			(4<<0)
-	#define PM3RD_PixelSize_32_BIT_PIXELS			(2<<0)
-	#define PM3RD_PixelSize_16_BIT_PIXELS			(1<<0)
-	#define PM3RD_PixelSize_8_BIT_PIXELS			(0<<0)
-#define PM3RD_ColorFormat					0x004
-	#define PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE	(1<<6)
-	#define PM3RD_ColorFormat_LINEAR_COLOR_EXT_DISABLE	(0<<6)
-	#define PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW		(1<<5)
-	#define PM3RD_ColorFormat_COLOR_ORDER_RED_LOW		(0<<5)
-	#define PM3RD_ColorFormat_COLOR_FORMAT_MASK		(0x1f<<0)
-	#define PM3RD_ColorFormat_8888_COLOR			(0<<0)
-	#define PM3RD_ColorFormat_5551_FRONT_COLOR		(1<<0)
-	#define PM3RD_ColorFormat_4444_COLOR			(2<<0)
-	#define PM3RD_ColorFormat_332_FRONT_COLOR		(5<<0)
-	#define PM3RD_ColorFormat_332_BACK_COLOR		(6<<0)
-	#define PM3RD_ColorFormat_2321_FRONT_COLOR		(9<<0)
-	#define PM3RD_ColorFormat_2321_BACK_COLOR		(10<<0)
-	#define PM3RD_ColorFormat_232_FRONTOFF_COLOR		(11<<0)
-	#define PM3RD_ColorFormat_232_BACKOFF_COLOR		(12<<0)
-	#define PM3RD_ColorFormat_5551_BACK_COLOR		(13<<0)
-	#define PM3RD_ColorFormat_CI8_COLOR			(14<<0)
-	#define PM3RD_ColorFormat_565_FRONT_COLOR		(16<<0)
-	#define PM3RD_ColorFormat_565_BACK_COLOR		(17<<0)
-#define PM3RD_CursorMode					0x005
-	#define PM3RD_CursorMode_CURSOR_DISABLE			(0<<0)
-	#define PM3RD_CursorMode_CURSOR_ENABLE			(1<<0)
-	#define PM3RD_CursorMode_FORMAT_64x64_2BPE_P0123	(0<<2)
-	#define PM3RD_CursorMode_FORMAT_32x32_2BPE_P0		(1<<2)
-	#define PM3RD_CursorMode_FORMAT_32x32_2BPE_P1		(2<<2)
-	#define PM3RD_CursorMode_FORMAT_32x32_2BPE_P2		(3<<2)
-	#define PM3RD_CursorMode_FORMAT_32x32_2BPE_P3		(4<<2)
-	#define PM3RD_CursorMode_FORMAT_32x32_4BPE_P01		(5<<2)
-	#define PM3RD_CursorMode_FORMAT_32x32_4BPE_P23		(6<<2)
-	#define PM3RD_CursorMode_TYPE_MS			(0<<4)
-	#define PM3RD_CursorMode_TYPE_X				(1<<4)
-	#define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_DISABLE	(0<<6)
-	#define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_ENABLE	(1<<6)
-	#define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_3_COLOR	(2<<6)
-	#define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_15_COLOR	(3<<6)
-#define PM3RD_CursorControl					0x006
-	#define PM3RD_CursorControl_DOUBLE_X_DISABLED		(0<<0)
-	#define PM3RD_CursorControl_DOUBLE_X_ENABLED		(1<<0)
-	#define PM3RD_CursorControl_DOUBLE_Y_DISABLED		(0<<1)
-	#define PM3RD_CursorControl_DOUBLE_Y_ENABLED		(1<<1)
-	#define PM3RD_CursorControl_READBACK_POS_DISABLED	(0<<2)
-	#define PM3RD_CursorControl_READBACK_POS_ENABLED	(1<<2)
-
-#define PM3RD_CursorXLow					0x007
-#define PM3RD_CursorXHigh					0x008
-#define PM3RD_CursorYLow					0x009
-#define PM3RD_CursorYHigh					0x00a
-#define PM3RD_CursorHotSpotX					0x00b
-#define PM3RD_CursorHotSpotY					0x00c
-#define PM3RD_OverlayKey					0x00d
-#define PM3RD_Pan						0x00e
-	#define PM3RD_Pan_DISABLE				(0<<0)
-	#define PM3RD_Pan_ENABLE				(1<<0)
-	#define PM3RD_Pan_GATE_DISABLE				(0<<1)
-	#define PM3RD_Pan_GATE_ENABLE				(1<<1)
-#define PM3RD_Sense						0x00f
-
-#define PM3RD_CheckControl					0x018
-	#define PM3RD_CheckControl_PIXEL_DISABLED		(0<<0)
-	#define PM3RD_CheckControl_PIXEL_ENABLED		(1<<0)
-	#define PM3RD_CheckControl_LUT_DISABLED			(0<<1)
-	#define PM3RD_CheckControl_LUT_ENABLED			(1<<1)
-#define PM3RD_CheckPixelRed					0x019
-#define PM3RD_CheckPixelGreen					0x01a
-#define PM3RD_CheckPixelBlue					0x01b
-#define PM3RD_CheckLUTRed					0x01c
-#define PM3RD_CheckLUTGreen					0x01d
-#define PM3RD_CheckLUTBlue					0x01e
-#define PM3RD_Scratch						0x01f
-
-#define PM3RD_VideoOverlayControl				0x020
-        #define PM3RD_VideoOverlayControl_DISABLE               (0<<0)
-        #define PM3RD_VideoOverlayControl_ENABLE                (1<<0)
-        #define PM3RD_VideoOverlayControl_MODE_MASK             (3<<1)
-        #define PM3RD_VideoOverlayControl_MODE_MAINKEY          (0<<1)
-        #define PM3RD_VideoOverlayControl_MODE_OVERLAYKEY       (1<<1)
-        #define PM3RD_VideoOverlayControl_MODE_ALWAYS           (2<<1)
-        #define PM3RD_VideoOverlayControl_MODE_BLEND            (3<<1)
-        #define PM3RD_VideoOverlayControl_DIRECTCOLOR_DISABLED  (0<<3)
-        #define PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED   (1<<3)
-        #define PM3RD_VideoOverlayControl_BLENDSRC_MAIN         (0<<4)
-        #define PM3RD_VideoOverlayControl_BLENDSRC_REGISTER     (1<<4)
-        #define PM3RD_VideoOverlayControl_KEY_COLOR             (0<<5)
-        #define PM3RD_VideoOverlayControl_KEY_ALPHA             (1<<5)
-#define PM3RD_VideoOverlayXStartLow				0x021
-#define PM3RD_VideoOverlayXStartHigh				0x022
-#define PM3RD_VideoOverlayYStartLow				0x023
-#define PM3RD_VideoOverlayYStartHigh				0x024
-#define PM3RD_VideoOverlayXEndLow				0x025
-#define PM3RD_VideoOverlayXEndHigh				0x026
-#define PM3RD_VideoOverlayYEndLow				0x027
-#define PM3RD_VideoOverlayYEndHigh				0x028
-#define PM3RD_VideoOverlayKeyR					0x029
-#define PM3RD_VideoOverlayKeyG					0x02a
-#define PM3RD_VideoOverlayKeyB					0x02b
-#define PM3RD_VideoOverlayBlend					0x02c
-        #define PM3RD_VideoOverlayBlend_FACTOR_0_PERCENT        (0<<6)
-        #define PM3RD_VideoOverlayBlend_FACTOR_25_PERCENT       (1<<6)
-        #define PM3RD_VideoOverlayBlend_FACTOR_75_PERCENT       (2<<6)
-        #define PM3RD_VideoOverlayBlend_FACTOR_100_PERCENT      (3<<6)
-
-#define PM3RD_DClkSetup1					0x1f0
-#define PM3RD_DClkSetup2					0x1f1
-#define PM3RD_KClkSetup1					0x1f2
-#define PM3RD_KClkSetup2					0x1f3
-
-#define PM3RD_DClkControl					0x200
-	#define PM3RD_DClkControl_SOURCE_PLL			(0<<4)
-	#define PM3RD_DClkControl_SOURCE_VSA			(1<<4)
-	#define PM3RD_DClkControl_SOURCE_VSB			(2<<4)
-	#define PM3RD_DClkControl_SOURCE_EXT			(3<<4)
-	#define PM3RD_DClkControl_STATE_RUN			(2<<2)
-	#define PM3RD_DClkControl_STATE_HIGH			(1<<2)
-	#define PM3RD_DClkControl_STATE_LOW			(0<<2)
-	#define PM3RD_DClkControl_LOCKED			(1<<1)
-	#define PM3RD_DClkControl_NOT_LOCKED			(0<<1)
-	#define PM3RD_DClkControl_ENABLE			(1<<0)
-	#define PM3RD_DClkControl_DISABLE			(0<<0)
-#define PM3RD_DClk0PreScale					0x201
-#define PM3RD_DClk0FeedbackScale				0x202
-#define PM3RD_DClk0PostScale					0x203
-        #define PM3_REF_CLOCK                                   14318
-#define PM3RD_DClk1PreScale					0x204
-#define PM3RD_DClk1FeedbackScale				0x205
-#define PM3RD_DClk1PostScale					0x206
-#define PM3RD_DClk2PreScale					0x207
-#define PM3RD_DClk2FeedbackScale				0x208
-#define PM3RD_DClk2PostScale					0x209
-#define PM3RD_DClk3PreScale					0x20a
-#define PM3RD_DClk3FeedbackScale				0x20b
-#define PM3RD_DClk3PostScale					0x20c
-#define PM3RD_KClkControl					0x20d
-	#define PM3RD_KClkControl_DISABLE			(0<<0)
-	#define PM3RD_KClkControl_ENABLE			(1<<0)
-	#define PM3RD_KClkControl_NOT_LOCKED			(0<<1)
-	#define PM3RD_KClkControl_LOCKED			(1<<1)
-	#define PM3RD_KClkControl_STATE_LOW			(0<<2)
-	#define PM3RD_KClkControl_STATE_HIGH			(1<<2)
-	#define PM3RD_KClkControl_STATE_RUN			(2<<2)
-	#define PM3RD_KClkControl_STATE_LOW_POWER		(3<<2)
-	#define PM3RD_KClkControl_SOURCE_PCLK			(0<<4)
-	#define PM3RD_KClkControl_SOURCE_HALF_PCLK		(1<<4)
-	#define PM3RD_KClkControl_SOURCE_PLL			(2<<4)
-#define PM3RD_KClkPreScale					0x20e
-#define PM3RD_KClkFeedbackScale					0x20f
-#define PM3RD_KClkPostScale					0x210
-#define PM3RD_MClkControl					0x211
-	#define PM3RD_MClkControl_DISABLE			(0<<0)
-	#define PM3RD_MClkControl_ENABLE			(1<<0)
-	#define PM3RD_MClkControl_NOT_LOCKED			(0<<1)
-	#define PM3RD_MClkControl_LOCKED			(1<<1)
-	#define PM3RD_MClkControl_STATE_LOW			(0<<2)
-	#define PM3RD_MClkControl_STATE_HIGH			(1<<2)
-	#define PM3RD_MClkControl_STATE_RUN			(2<<2)
-	#define PM3RD_MClkControl_STATE_LOW_POWER		(3<<2)
-	#define PM3RD_MClkControl_SOURCE_PCLK			(0<<4)
-	#define PM3RD_MClkControl_SOURCE_HALF_PCLK		(1<<4)
-	#define PM3RD_MClkControl_SOURCE_HALF_EXT		(3<<4)
-	#define PM3RD_MClkControl_SOURCE_EXT			(4<<4)
-	#define PM3RD_MClkControl_SOURCE_HALF_KCLK		(5<<4)
-	#define PM3RD_MClkControl_SOURCE_KCLK			(6<<4)
-#define PM3RD_MClkPreScale					0x212
-#define PM3RD_MClkFeedbackScale					0x213
-#define PM3RD_MClkPostScale					0x214
-#define PM3RD_SClkControl					0x215
-	#define PM3RD_SClkControl_DISABLE			(0<<0)
-	#define PM3RD_SClkControl_ENABLE			(1<<0)
-	#define PM3RD_SClkControl_NOT_LOCKED			(0<<1)
-	#define PM3RD_SClkControl_LOCKED			(1<<1)
-	#define PM3RD_SClkControl_STATE_LOW			(0<<2)
-	#define PM3RD_SClkControl_STATE_HIGH			(1<<2)
-	#define PM3RD_SClkControl_STATE_RUN			(2<<2)
-	#define PM3RD_SClkControl_STATE_LOW_POWER		(3<<2)
-	#define PM3RD_SClkControl_SOURCE_PCLK			(0<<4)
-	#define PM3RD_SClkControl_SOURCE_HALF_PCLK		(1<<4)
-	#define PM3RD_SClkControl_SOURCE_HALF_EXT		(3<<4)
-	#define PM3RD_SClkControl_SOURCE_EXT			(4<<4)
-	#define PM3RD_SClkControl_SOURCE_HALF_KCLK		(5<<4)
-	#define PM3RD_SClkControl_SOURCE_KCLK			(6<<4)
-#define PM3RD_SClkPreScale					0x216
-#define PM3RD_SClkFeedbackScale					0x217
-#define PM3RD_SClkPostScale					0x218
-
-#define PM3RD_CursorPalette(p)					(0x303+(p))
-#define PM3RD_CursorPattern(p)					(0x400+(p))
-/******************************************************
-*  GLINT Permedia3 Video Streaming Registers (0x5000) *
-*******************************************************/
-
-#define PM3VSConfiguration					0x5800
-
-/**********************************************
-*  GLINT Permedia3 Core Registers (0x8000+)   *
-***********************************************/
-#define PM3AALineWidth						0x94c0
-#define PM3AAPointsize						0x94a0
-#define PM3AlphaBlendAlphaMode					0xafa8
-#define PM3AlphaBlendAlphaModeAnd				0xad30
-#define PM3AlphaBlendAlphaModeOr				0xad38
-#define PM3AlphaBlendColorMode					0xafa0
-#define PM3AlphaBlendColorModeAnd				0xacb0
-#define PM3AlphaBlendColorModeOr				0xacb8
-#define PM3AlphaDestColor					0xaf88
-#define PM3AlphaSourceColor					0xaf80
-#define PM3AlphaTestMode					0x8800
-#define PM3AlphaTestModeAnd					0xabf0
-#define PM3AlphaTestModeOr					0xabf8
-#define PM3AntialiasMode					0x8808
-#define PM3AntialiasModeAnd					0xac00
-#define PM3AntialiasModeOr					0xac08
-/* ... */
-#define PM3BackgroundColor					0xb0c8
-/* ... */
-#define PM3ColorDDAMode						0x87e0
-#define PM3ColorDDAModeAnd					0xabe0
-#define PM3ColorDDAModeOr					0xabe8
-#define PM3CommandInterrupt					0xa990
-#define PM3ConstantColorDDA					0xafb0
-	#define PM3ConstantColorDDA_R(r)		((r)&0xff)
-	#define PM3ConstantColorDDA_G(g)		(((g)&0xff)<<8)
-	#define PM3ConstantColorDDA_B(b)		(((b)&0xff)<<16)
-	#define PM3ConstantColorDDA_A(a)		(((a)&0xff)<<24)
-#define PM3ContextData						0x8dd0
-#define PM3ContextDump						0x8dc0
-#define PM3ContextRestore					0x8dc8
-#define PM3Continue						0x8058
-#define PM3ContinueNewDom					0x8048
-#define PM3ContinueNewLine					0x8040
-#define PM3ContinueNewSub					0x8050
-#define PM3Count						0x8030
-/* ... */
-#define PM3DeltaControl						0x9350
-#define PM3DeltaControlAnd					0xab20
-#define PM3DeltaControlOr					0xab28
-#define PM3DeltaMode						0x9300
-#define PM3DeltaModeAnd						0xaad0
-#define PM3DeltaModeOr						0xaad8
-/* ... */
-#define PM3DitherMode						0x8818
-#define PM3DitherModeAnd					0xacd0
-#define PM3DitherModeOr						0xacd8
-/* ... */
-#define PM3dXDom						0x8008
-#define PM3dXSub						0x8018
-#define PM3dY							0x8028
-/* ... */
-#define PM3FBBlockColor						0x8ac8
-#define PM3FBBlockColor0					0xb060
-#define PM3FBBlockColor1					0xb068
-#define PM3FBBlockColor2					0xb070
-#define PM3FBBlockColor3					0xb078
-#define PM3FBBlockColorBack					0xb0a0
-#define PM3FBBlockColorBack0					0xb080
-#define PM3FBBlockColorBack1					0xb088
-#define PM3FBBlockColorBack2					0xb090
-#define PM3FBBlockColorBack3					0xb098
-#define PM3FBColor						0x8a98
-#define PM3FBDestReadBufferAddr0				0xae80
-#define PM3FBDestReadBufferAddr1				0xae88
-#define PM3FBDestReadBufferAddr2				0xae90
-#define PM3FBDestReadBufferAddr3				0xae98
-#define PM3FBDestReadBufferOffset0				0xaea0
-#define PM3FBDestReadBufferOffset1				0xaea8
-#define PM3FBDestReadBufferOffset2				0xaeb0
-#define PM3FBDestReadBufferOffset3				0xaeb8
-	#define PM3FBDestReadBufferOffset_XOffset(x)	((x)&0xffff)
-	#define PM3FBDestReadBufferOffset_YOffset(y)	(((y)&0xffff)<<16)
-#define PM3FBDestReadBufferWidth0				0xaec0
-#define PM3FBDestReadBufferWidth1				0xaec8
-#define PM3FBDestReadBufferWidth2				0xaed0
-#define PM3FBDestReadBufferWidth3				0xaed8
-	#define PM3FBDestReadBufferWidth_Width(w)	((w)&0x0fff)
-
-#define PM3FBDestReadEnables					0xaee8
-#define PM3FBDestReadEnablesAnd					0xad20
-#define PM3FBDestReadEnablesOr					0xad28
-	#define PM3FBDestReadEnables_E(e)		((e)&0xff)
-	#define PM3FBDestReadEnables_E0				1<<0
-	#define PM3FBDestReadEnables_E1				1<<1
-	#define PM3FBDestReadEnables_E2				1<<2
-	#define PM3FBDestReadEnables_E3				1<<3
-	#define PM3FBDestReadEnables_E4				1<<4
-	#define PM3FBDestReadEnables_E5				1<<5
-	#define PM3FBDestReadEnables_E6				1<<6
-	#define PM3FBDestReadEnables_E7				1<<7
-	#define PM3FBDestReadEnables_R(r)		(((r)&0xff)<<8)
-	#define PM3FBDestReadEnables_R0				1<<8
-	#define PM3FBDestReadEnables_R1				1<<9
-	#define PM3FBDestReadEnables_R2				1<<10
-	#define PM3FBDestReadEnables_R3				1<<11
-	#define PM3FBDestReadEnables_R4				1<<12
-	#define PM3FBDestReadEnables_R5				1<<13
-	#define PM3FBDestReadEnables_R6				1<<14
-	#define PM3FBDestReadEnables_R7				1<<15
-	#define PM3FBDestReadEnables_ReferenceAlpha(a)	(((a)&0xff)<<24)
-
-#define PM3FBDestReadMode					0xaee0
-#define PM3FBDestReadModeAnd					0xac90
-#define PM3FBDestReadModeOr					0xac98
-	#define PM3FBDestReadMode_ReadDisable			0<<0
-	#define PM3FBDestReadMode_ReadEnable			1<<0
-	#define PM3FBDestReadMode_StripePitch(sp)	(((sp)&0x7)<<2
-	#define PM3FBDestReadMode_StripeHeight(sh)	(((sh)&0x7)<<7
-	#define PM3FBDestReadMode_Enable0			1<<8
-	#define PM3FBDestReadMode_Enable1			1<<9
-	#define PM3FBDestReadMode_Enable2			1<<10
-	#define PM3FBDestReadMode_Enable3			1<<11
-	#define PM3FBDestReadMode_Layout0(l)		(((l)&0x3)<<12
-	#define PM3FBDestReadMode_Layout1(l)		(((l)&0x3)<<14
-	#define PM3FBDestReadMode_Layout2(l)		(((l)&0x3)<<16
-	#define PM3FBDestReadMode_Layout3(l)		(((l)&0x3)<<18
-	#define PM3FBDestReadMode_Origin0			1<<20
-	#define PM3FBDestReadMode_Origin1			1<<21
-	#define PM3FBDestReadMode_Origin2			1<<22
-	#define PM3FBDestReadMode_Origin3			1<<23
-	#define PM3FBDestReadMode_Blocking			1<<24
-	#define PM3FBDestReadMode_UseReadEnabled		1<<26
-	#define PM3FBDestReadMode_AlphaFiltering		1<<27
-
-#define PM3FBHardwareWriteMask					0x8ac0
-#define PM3FBSoftwareWriteMask					0x8820
-#define PM3FBData						0x8aa0
-#define PM3FBSourceData						0x8aa8
-#define PM3FBSourceReadBufferAddr				0xaf08
-#define PM3FBSourceReadBufferOffset				0xaf10
-	#define PM3FBSourceReadBufferOffset_XOffset(x)	((x)&0xffff)
-	#define PM3FBSourceReadBufferOffset_YOffset(y)	(((y)&0xffff)<<16)
-#define PM3FBSourceReadBufferWidth				0xaf18
-	#define PM3FBSourceReadBufferWidth_Width(w)	((w)&0x0fff)
-#define PM3FBSourceReadMode					0xaf00
-#define PM3FBSourceReadModeAnd					0xaca0
-#define PM3FBSourceReadModeOr					0xaca8
-	#define PM3FBSourceReadMode_ReadDisable			(0<<0)
-	#define PM3FBSourceReadMode_ReadEnable			(1<<0)
-	#define PM3FBSourceReadMode_StripePitch(sp)	(((sp)&0x7)<<2
-	#define PM3FBSourceReadMode_StripeHeight(sh)	(((sh)&0x7)<<7
-	#define PM3FBSourceReadMode_Layout(l)		(((l)&0x3)<<8
-	#define PM3FBSourceReadMode_Origin			1<<10
-	#define PM3FBSourceReadMode_Blocking			1<<11
-	#define PM3FBSourceReadMode_UserTexelCoord		1<<13
-	#define PM3FBSourceReadMode_WrapXEnable			1<<14
-	#define PM3FBSourceReadMode_WrapYEnable			1<<15
-	#define PM3FBSourceReadMode_WrapX(w)		(((w)&0xf)<<16
-	#define PM3FBSourceReadMode_WrapY(w)		(((w)&0xf)<<20
-	#define PM3FBSourceReadMode_ExternalSourceData		1<<24
-#define PM3FBWriteBufferAddr0                                   0xb000
-#define PM3FBWriteBufferAddr1                                   0xb008
-#define PM3FBWriteBufferAddr2                                   0xb010
-#define PM3FBWriteBufferAddr3                                   0xb018
-
-#define PM3FBWriteBufferOffset0                                 0xb020
-#define PM3FBWriteBufferOffset1                                 0xb028
-#define PM3FBWriteBufferOffset2                                 0xb030
-#define PM3FBWriteBufferOffset3                                 0xb038
-	#define PM3FBWriteBufferOffset_XOffset(x)		((x)&0xffff)
-	#define PM3FBWriteBufferOffset_YOffset(y)		(((y)&0xffff)<<16)
-
-#define PM3FBWriteBufferWidth0                                  0xb040
-#define PM3FBWriteBufferWidth1                                  0xb048
-#define PM3FBWriteBufferWidth2                                  0xb050
-#define PM3FBWriteBufferWidth3                                  0xb058
-	#define PM3FBWriteBufferWidth_Width(w)			((w)&0x0fff)
-
-#define PM3FBWriteMode                                          0x8ab8
-#define PM3FBWriteModeAnd                                       0xacf0
-#define PM3FBWriteModeOr                                        0xacf8
-	#define PM3FBWriteMode_WriteDisable                     0<<0
-	#define PM3FBWriteMode_WriteEnable                      1<<0
-	#define PM3FBWriteMode_Replicate                        1<<4
-	#define PM3FBWriteMode_OpaqueSpan                       1<<5
-	#define PM3FBWriteMode_StripePitch(p)            (((p)&0x7)<<6)
-	#define PM3FBWriteMode_StripeHeight(h)           (((h)&0x7)<<9)
-	#define PM3FBWriteMode_Enable0                          1<<12
-	#define PM3FBWriteMode_Enable1                          1<<13
-	#define PM3FBWriteMode_Enable2                          1<<14
-	#define PM3FBWriteMode_Enable3                          1<<15
-	#define PM3FBWriteMode_Layout0(l)               (((l)&0x3)<<16)
-	#define PM3FBWriteMode_Layout1(l)               (((l)&0x3)<<18)
-	#define PM3FBWriteMode_Layout2(l)               (((l)&0x3)<<20)
-	#define PM3FBWriteMode_Layout3(l)               (((l)&0x3)<<22)
-	#define PM3FBWriteMode_Origin0                          1<<24
-	#define PM3FBWriteMode_Origin1                          1<<25
-	#define PM3FBWriteMode_Origin2                          1<<26
-	#define PM3FBWriteMode_Origin3                          1<<27
-#define PM3ForegroundColor					0xb0c0
-/* ... */
-#define PM3GIDMode						0xb538
-#define PM3GIDModeAnd						0xb5b0
-#define PM3GIDModeOr						0xb5b8
-/* ... */
-#define PM3LBDestReadBufferAddr					0xb510
-#define PM3LBDestReadBufferOffset				0xb518
-#define PM3LBDestReadEnables					0xb508
-#define PM3LBDestReadEnablesAnd					0xb590
-#define PM3LBDestReadEnablesOr					0xb598
-#define PM3LBDestReadMode					0xb500
-#define PM3LBDestReadModeAnd					0xb580
-#define PM3LBDestReadModeOr					0xb588
-	#define PM3LBDestReadMode_Disable			0<<0
-	#define PM3LBDestReadMode_Enable			1<<0
-	#define PM3LBDestReadMode_StripePitch(p)		(((p)&0x7)<<2)
-	#define PM3LBDestReadMode_StripeHeight(h)		(((h)&0x7)<<5)
-	#define PM3LBDestReadMode_Layout			1<<8
-	#define PM3LBDestReadMode_Origin			1<<9
-	#define PM3LBDestReadMode_UserReadEnables		1<<10
-	#define PM3LBDestReadMode_Packed16			1<<11
-	#define PM3LBDestReadMode_Width(w)			(((w)&0xfff)<<12)
-#define PM3LBReadFormat						0x8888
-	#define PM3LBReadFormat_DepthWidth(w)			(((w)&0x3)<<0)
-	#define PM3LBReadFormat_StencilWidth(w)			(((w)&0xf)<<2)
-	#define PM3LBReadFormat_StencilPosition(p)		(((p)&0x1f)<<6)
-	#define PM3LBReadFormat_FCPWidth(w)			(((w)&0xf)<<11)
-	#define PM3LBReadFormat_FCPPosition(p)			(((p)&0x1f)<<15)
-	#define PM3LBReadFormat_GIDWidth(w)			(((w)&0x7)<<20)
-	#define PM3LBReadFormat_GIDPosition(p)			(((p)&0x1f)<<23)
-#define PM3LBSourceReadBufferAddr				0xb528
-#define PM3LBSourceReadBufferOffset				0xb530
-#define PM3LBSourceReadMode					0xb520
-#define PM3LBSourceReadModeAnd					0xb5a0
-#define PM3LBSourceReadModeOr					0xb5a8
-	#define PM3LBSourceReadMode_Enable			1<<0
-	#define PM3LBSourceReadMode_StripePitch(p)		(((p)&0x7)<<2)
-	#define PM3LBSourceReadMode_StripeHeight(h)		(((h)&0x7)<<5)
-	#define PM3LBSourceReadMode_Layout			1<<8
-	#define PM3LBSourceReadMode_Origin			1<<9
-	#define PM3LBSourceReadMode_Packed16			1<<10
-	#define PM3LBSourceReadMode_Width(w)			(((w)&0xfff)<<11)
-#define PM3LBStencil						0x88a8
-#define PM3LBWriteBufferAddr					0xb540
-#define PM3LBWriteBufferOffset					0xb548
-#define PM3LBWriteFormat					0x88c8
-	#define PM3LBWriteFormat_DepthWidth(w)			(((w)&0x3)<<0)
-	#define PM3LBWriteFormat_StencilWidth(w)		(((w)&0xf)<<2)
-	#define PM3LBWriteFormat_StencilPosition(p)		(((p)&0x1f)<<6)
-	#define PM3LBWriteFormat_GIDWidth(w)			(((w)&0x7)<<20)
-	#define PM3LBWriteFormat_GIDPosition(p)			(((p)&0x1f)<<23)
-#define PM3LBWriteMode						0x88c0
-#define PM3LBWriteModeAnd					0xac80
-#define PM3LBWriteModeOr					0xac88
-	#define PM3LBWriteMode_WriteDisable			0<<0
-	#define PM3LBWriteMode_WriteEnable			1<<0
-	#define PM3LBWriteMode_StripePitch(p)			(((p)&0x7)<<3)
-	#define PM3LBWriteMode_StripeHeight(h)			(((h)&0x7)<<6)
-	#define PM3LBWriteMode_Layout				1<<9
-	#define PM3LBWriteMode_Origin				1<<10
-	#define PM3LBWriteMode_Packed16				1<<11
-	#define PM3LBWriteMode_Width(w)				(((w)&0xfff)<<12)
-/* ... */
-#define PM3LineStippleMode					0x81a8
-#define PM3LineStippleModeAnd					0xabc0
-#define PM3LineStippleModeOr					0xabc8
-#define PM3LoadLineStippleCounters				0x81b0
-/* ... */
-#define PM3LogicalOpMode					0x8828
-#define PM3LogicalOpModeAnd					0xace0
-#define PM3LogicalOpModeOr					0xace8
-	#define PM3LogicalOpMode_Disable			(0<<0)
-	#define PM3LogicalOpMode_Enable				(1<<0)
-	#define PM3LogicalOpMode_LogicOp(op)			(((op)&0xf)<<1)
-	#define PM3LogicalOpMode_UseConstantWriteData_Disable	(0<<5)
-	#define PM3LogicalOpMode_UseConstantWriteData_Enable	(1<<5)
-	#define PM3LogicalOpMode_Background_Disable		(0<<6)
-	#define PM3LogicalOpMode_Background_Enable		(1<<6)
-	#define PM3LogicalOpMode_Background_LogicOp(op)		(((op)&0xf)<<7)
-	#define PM3LogicalOpMode_UseConstantSource_Disable	(0<<11)
-	#define PM3LogicalOpMode_UseConstantSource_Enable	(1<<11)
-
-/* ... */
-#define PM3LUT							0x8e80
-/* ... */
-#define PM3LUT							0x8e80
-#define PM3LUTAddress						0x84d0
-#define PM3LUTData						0x84c8
-#define PM3LUTIndex						0x84c0
-#define PM3LUTMode						0xb378
-#define PM3LUTModeAnd						0xad70
-#define PM3LUTModeOr						0xad78
-#define PM3LUTTransfer						0x84d8
-/* ... */
-#define PM3PixelSize						0x80c0
-	#define PM3PixelSize_GLOBAL_32BIT			(0<<0)
-	#define PM3PixelSize_GLOBAL_16BIT			(1<<0)
-	#define PM3PixelSize_GLOBAL_8BIT			(2<<0)
-	#define PM3PixelSize_RASTERIZER_32BIT			(0<<2)
-	#define PM3PixelSize_RASTERIZER_16BIT			(1<<2)
-	#define PM3PixelSize_RASTERIZER_8BIT			(2<<2)
-	#define PM3PixelSize_SCISSOR_AND_STIPPLE_32BIT		(0<<4)
-	#define PM3PixelSize_SCISSOR_AND_STIPPLE_16BIT		(1<<4)
-	#define PM3PixelSize_SCISSOR_AND_STIPPLE_8BIT		(2<<4)
-	#define PM3PixelSize_TEXTURE_32BIT			(0<<6)
-	#define PM3PixelSize_TEXTURE_16BIT			(1<<6)
-	#define PM3PixelSize_TEXTURE_8BIT			(2<<6)
-	#define PM3PixelSize_LUT_32BIT				(0<<8)
-	#define PM3PixelSize_LUT_16BIT				(1<<8)
-	#define PM3PixelSize_LUT_8BIT				(2<<8)
-	#define PM3PixelSize_FRAMEBUFFER_32BIT			(0<<10)
-	#define PM3PixelSize_FRAMEBUFFER_16BIT			(1<<10)
-	#define PM3PixelSize_FRAMEBUFFER_8BIT			(2<<10)
-	#define PM3PixelSize_LOGICAL_OP_32BIT			(0<<12)
-	#define PM3PixelSize_LOGICAL_OP_16BIT			(1<<12)
-	#define PM3PixelSize_LOGICAL_OP_8BIT			(2<<12)
-	#define PM3PixelSize_LOCALBUFFER_32BIT			(0<<14)
-	#define PM3PixelSize_LOCALBUFFER_16BIT			(1<<14)
-	#define PM3PixelSize_LOCALBUFFER_8BIT			(2<<14)
-	#define PM3PixelSize_SETUP_32BIT			(0<<16)
-	#define PM3PixelSize_SETUP_16BIT			(1<<16)
-	#define PM3PixelSize_SETUP_8BIT				(2<<16)
-	#define PM3PixelSize_GLOBAL				(0<<31)
-	#define PM3PixelSize_INDIVIDUAL				(1<<31)
-/* ... */
-#define PM3Render						0x8038
-	#define PM3Render_AreaStipple_Disable			(0<<0)
-	#define PM3Render_AreaStipple_Enable			(1<<0)
-	#define PM3Render_LineStipple_Disable			(0<<1)
-	#define PM3Render_LineStipple_Enable			(1<<1)
-	#define PM3Render_ResetLine_Disable			(0<<2)
-	#define PM3Render_ResetLine_Enable			(1<<2)
-	#define PM3Render_FastFill_Disable			(0<<3)
-	#define PM3Render_FastFill_Enable			(1<<3)
-	#define PM3Render_Primitive_Line			(0<<6)
-	#define PM3Render_Primitive_Trapezoid			(1<<6)
-	#define PM3Render_Primitive_Point			(2<<6)
-	#define PM3Render_Antialias_Disable			(0<<8)
-	#define PM3Render_Antialias_Enable			(1<<8)
-	#define PM3Render_Antialias_SubPixelRes_4x4		(0<<9)
-	#define PM3Render_Antialias_SubPixelRes_8x8		(1<<9)
-	#define PM3Render_UsePointTable_Disable			(0<<10)
-	#define PM3Render_UsePointTable_Enable			(1<<10)
-	#define PM3Render_SyncOnbitMask_Disable			(0<<11)
-	#define PM3Render_SyncOnBitMask_Enable			(1<<11)
-	#define PM3Render_SyncOnHostData_Disable		(0<<12)
-	#define PM3Render_SyncOnHostData_Enable			(1<<12)
-	#define PM3Render_Texture_Disable			(0<<13)
-	#define PM3Render_Texture_Enable			(1<<13)
-	#define PM3Render_Fog_Disable				(0<<14)
-	#define PM3Render_Fog_Enable				(1<<14)
-	#define PM3Render_Coverage_Disable			(0<<15)
-	#define PM3Render_Coverage_Enable			(1<<15)
-	#define PM3Render_SubPixelCorrection_Disable		(0<<16)
-	#define PM3Render_SubPixelCorrection_Enable		(1<<16)
-	#define PM3Render_SpanOperation_Disable			(0<<18)
-	#define PM3Render_SpanOperation_Enable			(1<<18)
-	#define PM3Render_FBSourceRead_Disable			(0<<27)
-	#define PM3Render_FBSourceRead_Enable			(1<<27)
-#define PM3RasterizerMode					0x80a0
-#define PM3RasterizerModeAnd					0xaba0
-#define PM3RasterizerModeOr					0xabb8
-#define PM3RectangleHeight					0x94e0
-#define PM3Render						0x8038
-#define PM3RepeatLine						0x9328
-#define PM3ResetPickResult					0x8c20
-#define PM3RLEMask						0x8c48
-#define PM3RouterMode						0x8840
-#define PM3RStart						0x8780
-#define PM3S1Start						0x8400
-#define PM3aveLineStippleCounters				0x81c0
-#define PM3ScissorMaxXY						0x8190
-#define PM3ScissorMinXY						0x8188
-#define PM3ScissorMode						0x8180
-#define PM3ScissorModeAnd					0xabb0
-#define PM3ScissorModeOr					0xabb8
-#define PM3ScreenSize						0x8198
-#define PM3Security						0x8908
-#define PM3SetLogicalTexturePage				0xb360
-#define PM3SizeOfFramebuffer					0xb0a8
-#define PM3SStart						0x8388
-#define PM3StartXDom						0x8000
-#define PM3StartXSub						0x8010
-#define PM3StartY						0x8020
-/* ... */
-#define PM3SpanColorMask					0x8168
-/* ... */
-#define PM3TextureApplicationMode				0x8680
-#define PM3TextureApplicationModeAnd				0xac50
-#define PM3TextureApplicationModeOr				0xac58
-#define PM3TextureBaseAddr					0x8500
-#define PM3TextureCacheControl					0x8490
-#define PM3TextureChromaLower0					0x84f0
-#define PM3TextureChromaLower1					0x8608
-#define PM3TextureChromaUpper0					0x84e8
-#define PM3TextureChromaUpper1					0x8600
-#define PM3TextureCompositeAlphaMode0				0xb310
-#define PM3TextureCompositeAlphaMode0And			0xb390
-#define PM3TextureCompositeAlphaMode0Or				0xb398
-#define PM3TextureCompositeAlphaMode1				0xb320
-#define PM3TextureCompositeAlphaMode1And			0xb3b0
-#define PM3TextureCompositeAlphaMode1Or				0xb3b8
-#define PM3TextureCompositeColorMode0				0xb308
-#define PM3TextureCompositeColorMode0And			0xb380
-#define PM3TextureCompositeColorMode0Or				0xb388
-#define PM3TextureCompositeColorMode1				0xb318
-#define PM3TextureCompositeColorMode1And			0xb3a0
-#define PM3TextureCompositeColorMode1Or				0xb3a8
-#define PM3TextureCompositeFactor0				0xb328
-#define PM3TextureCompositeFactor1				0xb330
-#define PM3TextureCompositeMode					0xb300
-#define PM3TextureCoordMode					0x8380
-#define PM3TextureCoordModeAnd					0xac20
-#define PM3TextureCoordModeOr					0xac28
-#define PM3TextureData						0x88e8
-/*
-#define PM3TextureDownloadControl				0x0108
-*/
-#define PM3TextureDownloadOffset				0x88f0
-#define PM3TextureEnvColor					0x8688
-#define PM3TextureFilterMode					0x84e0
-#define PM3TextureFilterModeAnd					0xad50
-#define PM3TextureFilterModeOr					0xad58
-#define PM3TextureIndexMode0					0xb338
-#define PM3TextureIndexMode0And					0xb3c0
-#define PM3TextureIndexMode0Or					0xb3c8
-#define PM3TextureIndexMode1					0xb340
-#define PM3TextureIndexMode1And					0xb3d0
-#define PM3TextureIndexMode1Or					0xb3d8
-/* ... */
-#define PM3TextureMapSize                                       0xb428
-#define PM3TextureMapWidth0                                     0x8580
-#define PM3TextureMapWidth1                                     0x8588
-        #define PM3TextureMapWidth_Width(w)             ((w&0xfff)<<0)
-        #define PM3TextureMapWidth_BorderLayout                 (1<<12)
-        #define PM3TextureMapWidth_Layout_Linear                (0<<13)
-        #define PM3TextureMapWidth_Layout_Patch64               (1<<13)
-        #define PM3TextureMapWidth_Layout_Patch32_2             (2<<13)
-        #define PM3TextureMapWidth_Layout_Patch2                (3<<13)
-        #define PM3TextureMapWidth_HostTexture                  (1<<15)
-#define PM3TextureReadMode0                                     0xb400
-#define PM3TextureReadMode0And                                  0xac30
-#define PM3TextureReadMode0Or                                   0xac38
-#define PM3TextureReadMode1                                     0xb408
-#define PM3TextureReadMode1And                                  0xad40
-#define PM3TextureReadMode1Or                                   0xad48
-/* ... */
-#define PM3WaitForCompletion					0x80b8
-#define PM3Window						0x8980
-	#define PM3Window_ForceLBUpdate				1<<3
-	#define PM3Window_LBUpdateSource			1<<4
-	#define PM3Window_FrameCount(c)				(((c)&0xff)<<9
-	#define PM3Window_StencilFCP				1<<17
-	#define PM3Window_DepthFCP				1<<18
-	#define PM3Window_OverrideWriteFiltering		1<<19
-#define PM3WindowAnd						0xab80
-#define PM3WindowOr						0xab88
-#define PM3WindowOrigin						0x81c8
-#define PM3XBias						0x9480
-#define PM3YBias						0x9488
-#define PM3YLimits						0x80a8
-#define PM3UVMode						0x8f00
-#define PM3ZFogBias						0x86b8
-#define PM3ZStart						0xadd8
-#define PM3ZStartL						0x89b8
-#define PM3ZStartU						0x89b0
-
-
-/**********************************************
-*  GLINT Permedia3 2D setup Unit              *
-***********************************************/
-#define PM3Config2D						0xb618
-	#define PM3Config2D_OpaqueSpan				1<<0
-	#define PM3Config2D_MultiRXBlit				1<<1
-	#define PM3Config2D_UserScissorEnable			1<<2
-	#define PM3Config2D_FBDestReadEnable			1<<3
-	#define PM3Config2D_AlphaBlendEnable			1<<4
-	#define PM3Config2D_DitherEnable			1<<5
-	#define PM3Config2D_ForegroundROPEnable			1<<6
-	#define PM3Config2D_ForegroundROP(rop)		(((rop)&0xf)<<7)
-	#define PM3Config2D_BackgroundROPEnable			1<<11
-	#define PM3Config2D_BackgroundROP(rop)		(((rop)&0xf)<<12)
-	#define PM3Config2D_UseConstantSource			1<<16
-	#define PM3Config2D_FBWriteEnable			1<<17
-	#define PM3Config2D_Blocking				1<<18
-	#define PM3Config2D_ExternalSourceData			1<<19
-	#define PM3Config2D_LUTModeEnable			1<<20
-#define PM3DownloadGlyphwidth					0xb658
-	#define PM3DownloadGlyphwidth_GlyphWidth(gw)	((gw)&0xffff)
-#define PM3DownloadTarget					0xb650
-	#define PM3DownloadTarget_TagName(tag)		((tag)&0x1fff)
-#define PM3GlyphData						0xb660
-#define PM3GlyphPosition					0xb608
-	#define PM3GlyphPosition_XOffset(x)		((x)&0xffff)
-	#define PM3GlyphPosition_YOffset(y)		(((y)&0xffff)<<16)
-#define PM3Packed4Pixels					0xb668
-#define PM3Packed8Pixels					0xb630
-#define PM3Packed16Pixels					0xb638
-#define PM3RectanglePosition					0xb600
-	#define PM3RectanglePosition_XOffset(x)		((x)&0xffff)
-	#define PM3RectanglePosition_YOffset(y)		(((y)&0xffff)<<16)
-#define PM3Render2D						0xb640
-	#define PM3Render2D_Width(w)			((w)&0x0fff)
-	#define PM3Render2D_Operation_Normal			0<<12
-	#define PM3Render2D_Operation_SyncOnHostData		1<<12
-	#define PM3Render2D_Operation_SyncOnBitMask		2<<12
-	#define PM3Render2D_Operation_PatchOrderRendering	3<<12
-	#define PM3Render2D_FBSourceReadEnable			1<<14
-	#define PM3Render2D_SpanOperation			1<<15
-	#define PM3Render2D_Height(h)			(((h)&0x0fff)<<16)
-	#define PM3Render2D_XPositive				1<<28
-	#define PM3Render2D_YPositive				1<<29
-	#define PM3Render2D_AreaStippleEnable			1<<30
-	#define PM3Render2D_TextureEnable			1<<31
-#define PM3Render2DGlyph					0xb648
-	#define PM3Render2DGlyph_Width(w)		((w)&0x7f)
-	#define PM3Render2DGlyph_Height(h)		(((h)&0x7f)<<7)
-	#define PM3Render2DGlyph_XOffset(x)		(((x)&0x1ff)<<14)
-	#define PM3Render2DGlyph_YOffset(y)		(((y)&0x1ff)<<23)
-#define PM3RenderPatchOffset					0xb610
-	#define PM3RenderPatchOffset_XOffset(x)		((x)&0xffff)
-	#define PM3RenderPatchOffset_YOffset(y)		(((y)&0xffff)<<16)
-#define PM3RLCount						0xb678
-	#define PM3RLCount_Count(c)			((c)&0x0fff)
-#define PM3RLData						0xb670
-
-/**********************************************
-*  GLINT Permedia3 Alias Register             *
-***********************************************/
-#define PM3FillBackgroundColor                                  0x8330
-#define PM3FillConfig2D0                                        0x8338
-#define PM3FillConfig2D1                                        0x8360
-	#define PM3FillConfig2D_OpaqueSpan                      1<<0
-	#define PM3FillConfig2D_MultiRXBlit                     1<<1
-	#define PM3FillConfig2D_UserScissorEnable               1<<2
-	#define PM3FillConfig2D_FBDestReadEnable                1<<3
-	#define PM3FillConfig2D_AlphaBlendEnable                1<<4
-	#define PM3FillConfig2D_DitherEnable                    1<<5
-	#define PM3FillConfig2D_ForegroundROPEnable             1<<6
-	#define PM3FillConfig2D_ForegroundROP(rop)              (((rop)&0xf)<<7)
-	#define PM3FillConfig2D_BackgroundROPEnable             1<<11
-	#define PM3FillConfig2D_BackgroundROP(rop)              (((rop)&0xf)<<12)
-	#define PM3FillConfig2D_UseConstantSource               1<<16
-	#define PM3FillConfig2D_FBWriteEnable                   1<<17
-	#define PM3FillConfig2D_Blocking                        1<<18
-	#define PM3FillConfig2D_ExternalSourceData              1<<19
-	#define PM3FillConfig2D_LUTModeEnable                   1<<20
-#define PM3FillFBDestReadBufferAddr                             0x8310
-#define PM3FillFBSourceReadBufferAddr                           0x8308
-#define PM3FillFBSourceReadBufferOffset                         0x8340
-	#define PM3FillFBSourceReadBufferOffset_XOffset(x)     ((x)&0xffff)
-	#define PM3FillFBSourceReadBufferOffset_YOffset(y)      (((y)&0xffff)<<16)
-#define PM3FillFBWriteBufferAddr                                0x8300
-#define PM3FillForegroundColor0                                 0x8328
-#define PM3FillForegroundColor1                                 0x8358
-#define PM3FillGlyphPosition                                    0x8368
-        #define PM3FillGlyphPosition_XOffset(x)                        ((x)&0xffff)
-	#define PM3FillGlyphPosition_YOffset(y)                        (((y)&0xffff)<<16)
-#define PM3FillRectanglePosition                                0x8348
-	#define PM3FillRectanglePosition_XOffset(x)            ((x)&0xffff)
-	#define PM3FillRectanglePosition_YOffset(y)            (((y)&0xffff)<<16)
-
-#define PM3_REGS_SIZE           0x10000
-#define PM3_MAX_PIXCLOCK        300000
-/* a few more useful registers & regs value... */
-#define PM3Sync 0x8c40
-        #define PM3Sync_Tag 0x188
-#define PM3FilterMode 0x8c00
-        #define PM3FilterModeSync 0x400
-#define PM3OutputFifo 0x2000
-#define PM3StatisticMode 0x8c08
-#define PM3AreaStippleMode 0x81a0
-        #define AreaStipplePattern0					(0x8200)
-        #define AreaStipplePattern1					(0x8208)
-        #define AreaStipplePattern2					(0x8210)
-        #define AreaStipplePattern3					(0x8218)
-        #define AreaStipplePattern4					(0x8220)
-        #define AreaStipplePattern5					(0x8228)
-        #define AreaStipplePattern6					(0x8230)
-        #define AreaStipplePattern7					(0x8238)
-        #define AreaStipplePattern8					(0x8240)
-        #define AreaStipplePattern9					(0x8248)
-        #define AreaStipplePattern10					(0x8250)
-        #define AreaStipplePattern11					(0x8258)
-        #define AreaStipplePattern12					(0x8260)
-        #define AreaStipplePattern13					(0x8268)
-        #define AreaStipplePattern14					(0x8270)
-        #define AreaStipplePattern15					(0x8278)
-        #define AreaStipplePattern16					(0x8280)
-        #define AreaStipplePattern17					(0x8288)
-        #define AreaStipplePattern18					(0x8290)
-        #define AreaStipplePattern19					(0x8298)
-        #define AreaStipplePattern20					(0x82a0)
-        #define AreaStipplePattern21					(0x82a8)
-        #define AreaStipplePattern22					(0x82b0)
-        #define AreaStipplePattern23					(0x82b8)
-        #define AreaStipplePattern24					(0x82c0)
-        #define AreaStipplePattern25					(0x82c8)
-        #define AreaStipplePattern26					(0x82d0)
-        #define AreaStipplePattern27					(0x82d8)
-        #define AreaStipplePattern28					(0x82eo)
-        #define AreaStipplePattern29					(0x82e8)
-        #define AreaStipplePattern30					(0x82f0)
-        #define AreaStipplePattern31					(0x82f8)
-        #define AreaStipplePattern_indexed(i)             (0x8200 + ((i) * 0x8))
-
-#define PM3DepthMode 0x89a0
-#define PM3StencilMode 0x8988
-#define PM3StencilData 0x8990
-#define PM3TextureReadMode 0x8670
-#define PM3FogMode 0x8690
-#define PM3ChromaTestMode 0x8f18
-#define PM3YUVMode 0x8f00
-#define PM3BitMaskPattern 0x8068
-
-/* ***************************** */
-/* ***** pm3fb IOCTL const ***** */
-/* ***************************** */
-/* debug-only IOCTL */
-#define PM3FBIO_CLEARMEMORY 0x504D3300 /* 'PM3\000' */
-#define PM3FBIO_CLEARCMAP   0x504D3301 /* 'PM3\001' */
-/* common use IOCTL */
-#define PM3FBIO_RESETCHIP   0x504D33FF /* 'PM3\377' */
-
-/* ***************************************** */
-/* ***** pm3fb useful define and macro ***** */
-/* ***************************************** */
-
-/* kernel -specific definitions */
-/* what kernel is this ? */
-#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)))
-#define KERNEL_2_5
-#endif
-
-#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)))
-#define KERNEL_2_4
-#endif
-
-#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))) 
-#define KERNEL_2_2
-/* pci_resource_start, available in 2.2.18 */
-#include <linux/kcomp.h>
-#ifdef CONFIG_FB_OF
-#define SUPPORT_FB_OF
-#endif
-#endif
-
-#if (!defined(KERNEL_2_2)) && (!defined(KERNEL_2_4)) && (!defined(KERNEL_2_5))
-#error "Only kernel 2.2.x, kernel 2.4.y and kernel 2.5.z might work"
-#endif
-
-/* not sure if/why it's needed. doesn't work without on my PowerMac... */
-#ifdef __BIG_ENDIAN
-#define MUST_BYTESWAP
-#endif
-
-/* for compatibility between 2.5, 2.4 and 2.2 */
-#ifndef B_FREE
-#define B_FREE   -1
-#endif
-
-/* permedia3 -specific definitions */
-#define PM3_SCALE_TO_CLOCK(pr, fe, po) ((2 * PM3_REF_CLOCK * fe) / (pr * (1 << (po))))
-
-/* in case it's not in linux/pci.h */
-#ifndef PCI_DEVICE_ID_3DLABS_PERMEDIA3
-#define PCI_DEVICE_ID_3DLABS_PERMEDIA3 0x000a
-#endif
-
-/* max number of simultaneous board */
-/* warning : make sure module array def's are coherent with PM3_MAX_BOARD */
-#define PM3_MAX_BOARD 4
-#define PM3_MAX_BOARD_MODULE_ARRAY_SHORT "1-4h"
-#define PM3_MAX_BOARD_MODULE_ARRAY_STRING "1-4s"
-
-/* max size of options */
-#define PM3_OPTIONS_SIZE 256
-
-/* max size of font name */
-#define PM3_FONTNAME_SIZE 40
-
-/* do we want accelerated console  */
-#define PM3FB_USE_ACCEL 1
-
-/* useful ? */
-#define CHAR_IS_NUM(a)  ((((a) >= '0') && ((a) <= '9')) ? 1 : 0)
-
-/* for driver debugging ONLY */
-/* 0 = assert only, 1 = error, 2 = info, 3+ = verbose */
-/* define PM3FB_MASTER_DEBUG 1 */
-#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 3)
-#define PM3FB_TRACE
-#endif /* defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 3) */
-
-#ifdef PM3FB_MASTER_DEBUG
-#define DPRINTK(l,a,b...) do { if ((l) <= PM3FB_MASTER_DEBUG) printk("pm3fb: %s: " a, __FUNCTION__ , ## b); } while (0)
-#define DASSERT(t,a,b...) do { if (!(t)) printk("pm3fb: _assert failed: %s: " a, __FUNCTION__ , ## b); } while (0)
-#ifdef PM3FB_TRACE
-#define DTRACE printk("pm3fb: _enter %s\n", __FUNCTION__)
-#else /* PM3FB_TRACE */
-#define DTRACE
-#endif /* PM3FB_TRACE */
-#else /* PM3FB_MASTER_DEBUG */
-#define DPRINTK(l,a,b...)
-#define DASSERT(t,a,b...)
-#define DTRACE
-#endif /* PM3FB_MASTER_DEBUG */
-
-#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2)
-#define PM3_SHOW_CUR_MODE pm3fb_show_cur_mode(l_fb_info)
-#else
-#define PM3_SHOW_CUR_MODE /* pm3fb_show_cur_mode() */
-#endif
-
-/* ******************************************** */
-/* ***** A bunch of register-access macro ***** */
-/* ******************************************** */
-#ifdef KERNEL_2_2
-#ifdef MUST_BYTESWAP /* we are writing big_endian to big_endian through a little_endian macro */
-#define PM3_READ_REG(r) __swab32(readl((l_fb_info->vIOBase + r)))
-#define PM3_WRITE_REG(r, v) writel(__swab32(v), (l_fb_info->vIOBase + r))
-#else /* MUST_BYTESWAP */
-#define PM3_WRITE_REG(r, v) writel(v, (l_fb_info->vIOBase + r))
-#define PM3_READ_REG(r) readl((l_fb_info->vIOBase + r))
-#endif /* MUST_BYTESWAP */
-#endif /* KERNEL_2_2 */
-#if (defined KERNEL_2_4) || (defined KERNEL_2_5) /* native-endian access */
-#define PM3_WRITE_REG(r, v) fb_writel(v, (l_fb_info->vIOBase + r))
-#define PM3_READ_REG(r) fb_readl((l_fb_info->vIOBase + r))
-#endif /* KERNEL_2_4 or KERNEL_2_5 */
-
-
-#define depth2bpp(d) ((d + 7L) & ~7L)
-#define depth2ByPP(d) (depth2bpp(d) / 8)
-
-#define depth_supported(d) ((d == 8) || (d == 12) || (d == 15) || (d == 16) || (d==32))
-
-
-#define PM3_WAIT(n) \
-do{ \
-	while(PM3_READ_REG(PM3InFIFOSpace)<(n)); \
-} while(0)
-
-#define PM3_DELAY(x) do { \
-        int delay = x; \
-        unsigned char tmp; \
-        while(delay--){tmp = PM3_READ_REG(PM3InFIFOSpace);}; \
-} while(0)
-
-#define PM3_SLOW_WRITE_REG(r,v)	\
-do{                             \
-    DASSERT((l_fb_info->vIOBase != (unsigned char*)(-1)), "l_fb_info->vIOBase mapped in slow write\n"); \
-	mb();                   \
-	PM3_WAIT(1);            \
-	mb();                   \
-    PM3_WRITE_REG(r,v);     \
-} while(0)
-
-#define PM3_SET_INDEX(index) \
-do{ \
-	PM3_SLOW_WRITE_REG(PM3RD_IndexHigh,(((index)>>8)&0xff)); \
-	PM3_SLOW_WRITE_REG(PM3RD_IndexLow,((index)&0xff)); \
-} while(0)
-
-#define PM3_WRITE_DAC_REG(r, v) \
-do { \
-     DASSERT((l_fb_info->vIOBase != (unsigned char*)(-1)), "l_fb_info->vIOBase mapped in write dac reg\n"); \
-     PM3_SET_INDEX(r); \
-     mb(); \
-     PM3_WRITE_REG(PM3RD_IndexedData, v); \
-} while (0)
-
-/* next one is really a function, added as a macro to be consistent */
-#define PM3_READ_DAC_REG(r) pm3fb_read_dac_reg(l_fb_info, r)
-
-
-#define PM3_COLOR(c) \
-do { \
-  if (l_fb_info->current_par->depth == 8) \
-    { \
-      c = (c & 0xFF); \
-      c = c | (c << 8); \
-    } \
-  if ((l_fb_info->current_par->depth == 8) || (depth2bpp(l_fb_info->current_par->depth) == 16)) \
-    { \
-      c = (c & 0xFFFF); \
-      c = c | (c << 16); \
-    } \
-} while (0)
-
-#endif /* PM3FB_H */
diff -Nru a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
--- a/drivers/video/pmag-ba-fb.c	Tue Nov 26 16:03:46 2002
+++ b/drivers/video/pmag-ba-fb.c	Thu Feb 13 18:50:30 2003
@@ -34,7 +34,7 @@
 #include <asm/bootinfo.h>
 #include <asm/dec/machtype.h>
 #include <asm/dec/tc.h>
-#include "pmag-ba-fb.h"
+#include <video/pmag-ba-fb.h>
 
 struct pmag_ba_ramdac_regs {
 	unsigned char addr_low;
diff -Nru a/drivers/video/pmag-ba-fb.h b/drivers/video/pmag-ba-fb.h
--- a/drivers/video/pmag-ba-fb.h	Tue Feb  5 10:13:06 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,24 +0,0 @@
-/*
- *      linux/drivers/video/pmag-ba-fb.h
- *
- *      TurboChannel PMAG-BA framebuffer card support,
- *      Copyright (C) 1999,2000,2001 by
- *      Michael Engel <engel@unix-ag.org>,
- *      Karsten Merker <merker@linuxtag.org>
- *      This file is subject to the terms and conditions of the GNU General
- *      Public License.  See the file COPYING in the main directory of this
- *      archive for more details.
- */
-
-/*
- * Bt459 RAM DAC register base offset (rel. to TC slot base address)
- */
-
-#define PMAG_BA_BT459_OFFSET                    0x00200000
-
-/*
- * Begin of PMAG-BA framebuffer memory relative to TC slot address,
- * resolution is 1024x864x8
- */
-
-#define PMAG_BA_ONBOARD_FBMEM_OFFSET    0x00000000
diff -Nru a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
--- a/drivers/video/pmagb-b-fb.c	Tue Nov 26 16:03:46 2002
+++ b/drivers/video/pmagb-b-fb.c	Thu Feb 13 18:50:30 2003
@@ -37,7 +37,7 @@
 #include <asm/bootinfo.h>
 #include <asm/dec/machtype.h>
 #include <asm/dec/tc.h>
-#include "pmagb-b-fb.h"
+#include <video/pmagb-b-fb.h>
 
 struct pmagb_b_ramdac_regs {
 	unsigned char addr_low;
diff -Nru a/drivers/video/pmagb-b-fb.h b/drivers/video/pmagb-b-fb.h
--- a/drivers/video/pmagb-b-fb.h	Mon Dec 30 11:39:54 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- *      linux/drivers/video/pmagb-b-fb.h
- *
- *      TurboChannel PMAGB-B framebuffer card support,
- *      Copyright (C) 1999, 2000, 2001 by
- *      Michael Engel <engel@unix-ag.org> and 
- *      Karsten Merker <merker@linuxtag.org>
- *      This file is subject to the terms and conditions of the GNU General
- *      Public License.  See the file COPYING in the main directory of this
- *      archive for more details.
- */
-
-
-/*
- * Bt459 RAM DAC register base offset (rel. to TC slot base address)
- */
-#define PMAGB_B_BT459_OFFSET			0x001C0000
-
-/*
- * Begin of PMAGB-B framebuffer memory, resolution is configurable:
- * 1024x864x8 or 1280x1024x8, settable by jumper on the card
- */
-#define PMAGB_B_ONBOARD_FBMEM_OFFSET	0x00201000
-
-/*
- * Bt459 register offsets, byte-wide registers
- */
-
-#define BT459_ADR_LOW			BT459_OFFSET + 0x00	/* addr. low */
-#define BT459_ADR_HIGH			BT459_OFFSET + 0x04	/* addr. high */
-#define BT459_DATA			BT459_OFFSET + 0x08	/* r/w data */
-#define BT459_CMAP			BT459_OFFSET + 0x0C	/* color map */
diff -Nru a/drivers/video/q40fb.c b/drivers/video/q40fb.c
--- a/drivers/video/q40fb.c	Tue Feb 18 10:38:27 2003
+++ b/drivers/video/q40fb.c	Mon Feb 24 13:47:01 2003
@@ -111,7 +111,6 @@
 	fb_info.pseudo_palette = pseudo_palette;	
    	fb_info.screen_base = (char *) q40fb_fix.smem_start;
 
-	/* The below fields will go away !!!! */
 	fb_alloc_cmap(&fb_info.cmap, 16, 0);
 
 	master_outb(3, DISPLAY_CONTROL_REG);
diff -Nru a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
--- a/drivers/video/radeonfb.c	Sat Dec 28 14:39:38 2002
+++ b/drivers/video/radeonfb.c	Tue Jan 28 12:28:57 2003
@@ -2212,6 +2212,7 @@
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
 #endif
+	.fb_cursor	= soft_cursor,
 };
 
 
diff -Nru a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
--- a/drivers/video/riva/fbdev.c	Thu Feb  6 07:33:47 2003
+++ b/drivers/video/riva/fbdev.c	Fri Feb 28 10:40:11 2003
@@ -150,7 +150,7 @@
 static struct riva_chip_info {
 	const char *name;
 	unsigned arch_rev;
-} riva_chip_info[] __devinitdata = {
+} riva_chip_info[] __initdata = {
 	{ "RIVA-128", NV_ARCH_03 },
 	{ "RIVA-TNT", NV_ARCH_04 },
 	{ "RIVA-TNT2", NV_ARCH_04 },
@@ -193,7 +193,7 @@
 	{ "Quadro4-700-XGL", NV_ARCH_20 }
 };
 
-static struct pci_device_id rivafb_pci_tbl[] __devinitdata = {
+static struct pci_device_id rivafb_pci_tbl[] __initdata = {
 	{ PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_128 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT,
@@ -286,7 +286,6 @@
 
 /* command line data, set in rivafb_setup() */
 static u32 pseudo_palette[17];
-static int noblink = 0;
 static int flatpanel __initdata = -1; /* Autodetect later */
 static int forceCRTC __initdata = -1;
 #ifdef CONFIG_MTRR
@@ -310,9 +309,9 @@
 	xres_virtual:	640,
 	yres_virtual:	480,
 	bits_per_pixel:	8,
-	red:		{0, 6, 0},
-	green:		{0, 6, 0},
-	blue:		{0, 6, 0},
+	red:		{0, 8, 0},
+	green:		{0, 8, 0},
+	blue:		{0, 8, 0},
 	transp:		{0, 0, 0},
 	activate:	FB_ACTIVATE_NOW,
 	height:		-1,
@@ -458,7 +457,7 @@
 		m = *((u32 *)mask)++;
 		for (j = 0; j < w/2; j++) {
 			tmp = 0;
-#if defined (__BIG_ENDIAN__)
+#if defined (__BIG_ENDIAN)
 			if (m & (1 << 31))
 				tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
 			b <<= 1;
@@ -515,6 +514,31 @@
 }
 
 /**
+ * riva_rclut - read fromCLUT register
+ * @chip: pointer to RIVA_HW_INST object
+ * @regnum: register number
+ * @red: red component
+ * @green: green component
+ * @blue: blue component
+ *
+ * DESCRIPTION:
+ * Reads red, green, and blue from color register @regnum.
+ *
+ * CALLED FROM:
+ * rivafb_setcolreg()
+ */
+static void riva_rclut(RIVA_HW_INST *chip,
+		       unsigned char regnum, unsigned char *red,
+		       unsigned char *green, unsigned char *blue)
+{
+	
+	VGA_WR08(chip->PDIO, 0x3c8, regnum);
+	*red = VGA_RD08(chip->PDIO, 0x3c9);
+	*green = VGA_RD08(chip->PDIO, 0x3c9);
+	*blue = VGA_RD08(chip->PDIO, 0x3c9);
+}
+
+/**
  * riva_save_state - saves current chip state
  * @par: pointer to riva_par object containing info for current riva board
  * @regs: pointer to riva_regs object
@@ -623,7 +647,7 @@
 	width = info->var.xres_virtual;
 	hDisplaySize = info->var.xres;
 	hDisplay = (hDisplaySize / 8) - 1;
-	hStart = (hDisplaySize + info->var.right_margin) / 8 + 2;
+	hStart = (hDisplaySize + info->var.right_margin) / 8 - 1;
 	hEnd = (hDisplaySize + info->var.right_margin +
 		info->var.hsync_len) / 8 - 1;
 	hTotal = (hDisplaySize + info->var.right_margin +
@@ -644,6 +668,9 @@
 
 	memcpy(&newmode, &reg_template, sizeof(struct riva_regs));
 
+	if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
+		vTotal |= 1;
+
 	if (par->FlatPanel) {
 		vStart = vTotal - 3;
 		vEnd = vTotal - 2;
@@ -693,11 +720,25 @@
 		| SetBitField(vStart,11:11,4:4)
 		| SetBitField(vBlankStart,11:11,6:6); 
 
-	newmode.ext.interlace = 0xff; /* interlace off */
+	if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+		int tmp = (hTotal >> 1) & ~1;
+		newmode.ext.interlace = Set8Bits(tmp);
+		newmode.ext.horiz |= SetBitField(tmp, 8:8,4:4);
+	} else 
+		newmode.ext.interlace = 0xff; /* interlace off */
 
 	if (par->riva.Architecture >= NV_ARCH_10)
 		par->riva.CURSOR = (U032 *)(info->screen_base + par->riva.CursorStart);
 
+	if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
+		newmode.misc_output &= ~0x40;
+	else
+		newmode.misc_output |= 0x40;
+	if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
+		newmode.misc_output &= ~0x80;
+	else
+		newmode.misc_output |= 0x80;	
+
 	par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,
 				  hDisplaySize, height, dotClock);
 
@@ -870,21 +911,18 @@
  */
 static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
 {
-	int rc = 16;		/* reasonable default */
+	int rc = 256;		/* reasonable default */
 
-	switch (var->bits_per_pixel) {
+	switch (var->green.length) {
 	case 8:
-		rc = 256;	/* pseudocolor... 256 entries HW palette */
+		rc = 256;	/* 256 entries (2^8), 8 bpp and RGB8888 */
 		break;
-	case 15:
-		rc = 15;	/* fix for 15 bpp depths on Riva 128 based cards */
+	case 5:
+		rc = 32;	/* 32 entries (2^5), 16 bpp, RGB555 */
 		break;
-	case 16:
-		rc = 16;	/* directcolor... 16 entries SW palette */
-		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
-	case 32:
-		rc = 16;	/* directcolor... 16 entries SW palette */
-		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
+	case 6:
+		rc = 64;	/* 64 entries (2^6), 16 bpp, RGB565 */
+		break;		
 	default:
 		/* should not occur */
 		break;
@@ -932,7 +970,7 @@
 	if (cnt == 1) {
 		par->riva.LockUnlock(&par->riva, 0);
 		par->riva.LoadStateExt(&par->riva, &par->initial_state.ext);
-
+		riva_load_state(par, &par->initial_state);
 		restore_vga(&par->state);
 		par->riva.LockUnlock(&par->riva, 1);
 	}
@@ -1138,6 +1176,7 @@
 {
 	struct riva_par *par = (struct riva_par *)info->par;
 	RIVA_HW_INST *chip = &par->riva;
+	int i;
 
 	if (regno >= riva_get_cmap_len(&info->var))
 		return -EINVAL;
@@ -1155,23 +1194,46 @@
 		break;
 	case 16:
 		if (info->var.green.length == 5) {
-			/* 0rrrrrgg gggbbbbb */
-			((u16 *)(info->pseudo_palette))[regno] =
+			if (regno < 16) {
+				/* 0rrrrrgg gggbbbbb */
+				((u32 *)info->pseudo_palette)[regno] =
 					((red & 0xf800) >> 1) |
 					((green & 0xf800) >> 6) |
 					((blue & 0xf800) >> 11);
+			}
+			for (i = 0; i < 8; i++) 
+				riva_wclut(chip, regno*8+i, red >> 8,
+					   green >> 8, blue >> 8);
 		} else {
-			/* rrrrrggg gggbbbbb */
-			((u16 *)(info->pseudo_palette))[regno] =
+			u8 r, g, b;
+
+			if (regno < 16) {
+				/* rrrrrggg gggbbbbb */
+				((u32 *)info->pseudo_palette)[regno] =
 					((red & 0xf800) >> 0) |
 					((green & 0xf800) >> 5) |
 					((blue & 0xf800) >> 11);
+			}
+			if (regno < 32) {
+				for (i = 0; i < 8; i++) {
+					riva_wclut(chip, regno*8+i, red >> 8, 
+						   green >> 8, blue >> 8);
+				}
+			}
+			for (i = 0; i < 4; i++) {
+				riva_rclut(chip, regno*2+i, &r, &g, &b);
+				riva_wclut(chip, regno*4+i, r, green >> 8, b);
+			}
 		}
 		break;
 	case 32:
-		((u32 *) (info->pseudo_palette))[regno] =
-		    		((red & 0xff00) << 8) |
-		    		((green & 0xff00)) | ((blue & 0xff00) >> 8);
+		if (regno < 16) {
+			((u32 *)info->pseudo_palette)[regno] =
+				((red & 0xff00) << 8) |
+				((green & 0xff00)) | ((blue & 0xff00) >> 8);
+			
+		}
+		riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
 		break;
 	default:
 		/* do nothing */
@@ -1192,7 +1254,7 @@
  * CALLED FROM:
  * framebuffer hook
  */
-static void rivafb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
 	struct riva_par *par = (struct riva_par *) info->par;
 	u_int color, rop = 0;
@@ -1200,7 +1262,7 @@
 	if (info->var.bits_per_pixel == 8)
 		color = rect->color;
 	else
-		color = ((u32 *)(info->pseudo_palette))[rect->color];
+		color = ((u32 *)info->pseudo_palette)[rect->color];
 
 	switch (rect->rop) {
 	case ROP_XOR:
@@ -1238,7 +1300,7 @@
  * CALLED FROM:
  * framebuffer hook
  */
-static void rivafb_copyarea(struct fb_info *info, struct fb_copyarea *region)
+static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
 {
 	struct riva_par *par = (struct riva_par *) info->par;
 
@@ -1288,6 +1350,8 @@
 {
 	u8 *a = (u8 *)l;
 	*a = byte_rev[*a], a++;
+	*a = byte_rev[*a], a++;
+	*a = byte_rev[*a], a++;
 	*a = byte_rev[*a];
 }
 
@@ -1315,102 +1379,71 @@
  * CALLED FROM:
  * framebuffer hook
  */
-static void rivafb_imageblit(struct fb_info *info, struct fb_image *image)
+static void rivafb_imageblit(struct fb_info *info, 
+			     const struct fb_image *image)
 {
 	struct riva_par *par = (struct riva_par *) info->par;
-	u32 fgx = 0, bgx = 0, width, mod;
-	u8 *cdat = image->data, *dat;
+	u32 fgx = 0, bgx = 0, width, tmp;
+	u8 *cdat = (u8 *) image->data;
 	volatile u32 *d;
-	int i, j, size;
+	int i, size;
 
-	if (image->depth != 1) {
-		wait_for_idle(par);
+	if (image->depth != 0) {
 		cfb_imageblit(info, image);
 		return;
 	}
 
-	width = (image->width + 7)/8;
-
-	size = image->width * image->height;
-	dat = cdat;
-/*
-	for (i = 0; i < size; i++) {
-		*dat = byte_rev[*dat];
-		dat++;
-	}
-*/
 	switch (info->var.bits_per_pixel) {
 	case 8:
 		fgx = image->fg_color;
 		bgx = image->bg_color;
 		break;
 	case 16:
-		fgx |= ((u16 *) (info->pseudo_palette))[image->fg_color];
-		bgx |= ((u16 *) (info->pseudo_palette))[image->bg_color];
+		fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
+		bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
 		if (info->var.green.length == 6)
 			convert_bgcolor_16(&bgx);	
 		break;
 	case 32:
-		fgx |= ((u32 *) (info->pseudo_palette))[image->fg_color];
-		bgx |= ((u32 *) (info->pseudo_palette))[image->bg_color];
+		fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
+		bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
 		break;
 	}
 
 	RIVA_FIFO_FREE(par->riva, Bitmap, 7);
-	par->riva.Bitmap->ClipE.TopLeft     = (image->dy << 16) | (image->dx & 0xFFFF);
-	par->riva.Bitmap->ClipE.BottomRight = (((image->dy + image->height) << 16) |
-                                       		((image->dx + image->width) & 0xffff));
+	par->riva.Bitmap->ClipE.TopLeft     = 
+		(image->dy << 16) | (image->dx & 0xFFFF);
+	par->riva.Bitmap->ClipE.BottomRight = 
+		(((image->dy + image->height) << 16) |
+		 ((image->dx + image->width) & 0xffff));
 	par->riva.Bitmap->Color0E           = bgx;
 	par->riva.Bitmap->Color1E           = fgx;
-	par->riva.Bitmap->WidthHeightInE    = (image->height << 16) | ((image->width + 31) & ~31);
-	par->riva.Bitmap->WidthHeightOutE   = (image->height << 16) | ((image->width + 31) & ~31);
-	par->riva.Bitmap->PointE            = (image->dy << 16) | (image->dx & 0xFFFF);
+	par->riva.Bitmap->WidthHeightInE    = 
+		(image->height << 16) | ((image->width + 31) & ~31);
+	par->riva.Bitmap->WidthHeightOutE   = 
+		(image->height << 16) | ((image->width + 31) & ~31);
+	par->riva.Bitmap->PointE            = 
+		(image->dy << 16) | (image->dx & 0xFFFF);
 
 	d = &par->riva.Bitmap->MonochromeData01E;
 
-	mod = width % 4;
-
-	if (width >= 4) {
-		while (image->height--) {
-			size = width / 4;
-			while (size >= 16) {
-				RIVA_FIFO_FREE(par->riva, Bitmap, 16);
-				for (i = 0; i < 16; i++)
-					d[i] = *((u32 *)cdat)++;
-				size -= 16;
-			}
-
-			if (size) {
-				RIVA_FIFO_FREE(par->riva, Bitmap, size);
-				for (i = 0; i < size; i++)
-					d[i] = *((u32 *) cdat)++;
-			}
-
-			if (mod) {
-				u32 tmp;
-				RIVA_FIFO_FREE(par->riva, Bitmap, 1);
-				for (i = 0; i < mod; i++)
-					((u8 *)&tmp)[i] = *cdat++;
-				d[i] = tmp;
-			}
+	width = (image->width + 31)/32;
+	size = width * image->height;
+	while (size >= 16) {
+		RIVA_FIFO_FREE(par->riva, Bitmap, 16);
+		for (i = 0; i < 16; i++) {
+			tmp = *((u32 *)cdat)++;
+			reverse_order(&tmp);
+			d[i] = tmp;
 		}
-	} else {
-		u32 tmp;
-
-		for (i = image->height; i > 0; i-=16) {
-			if (i >= 16)
-				size = 16;
-			else
-				size = i;
-			RIVA_FIFO_FREE(par->riva, Bitmap, size);
-			for (j = 0; j < size; j++) {
-				if (image->width <= 8)
-					tmp = *cdat++;
-				else
-					tmp = *((u16 *)cdat)++;
-				reverse_order(&tmp);
-				d[j] = tmp;
-			}
+		size -= 16;
+	}
+	if (size) {
+		RIVA_FIFO_FREE(par->riva, Bitmap, size);
+		for (i = 0; i < size; i++) {
+			tmp = *((u32 *) cdat)++;
+			reverse_order(&tmp);
+			d[i] = tmp;
 		}
 	}
 }
@@ -1470,14 +1503,19 @@
 	if (flags & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETDEST)) {
 		int bg_idx = cursor->image.bg_color;
 		int fg_idx = cursor->image.fg_color;
+		int width = (cursor->image.width+7)/8;
+		u8 *dat = (u8 *) cursor->image.data;
+		u8 *dst = (u8 *) cursor->dest;
+		u8 *msk = (u8 *) cursor->mask;
 
 		switch (cursor->rop) {
 		case ROP_XOR:
 			for (i = 0; i < cursor->image.height; i++) {
-				for (j = 0; j < (cursor->image.width + 7)/8; j++) {
+				for (j = 0; j < width; j++) {
 					d_idx = i * MAX_CURS/8  + j;
-					data[d_idx] =  byte_rev[((u8 *)cursor->image.data)[s_idx] ^ ((u8 *)cursor->dest)[s_idx]]; 	
-					mask[d_idx] = byte_rev[((u8 *)cursor->mask)[s_idx]];
+					data[d_idx] =  byte_rev[dat[s_idx] ^ 
+								dst[s_idx]];
+					mask[d_idx] = byte_rev[msk[s_idx]];
 					s_idx++;
 				}
 			}
@@ -1485,24 +1523,24 @@
 		case ROP_COPY:
 		default:
 			for (i = 0; i < cursor->image.height; i++) {
-				for (j = 0; j < (cursor->image.width + 7)/8; j++) {
+				for (j = 0; j < width; j++) {
 					d_idx = i * MAX_CURS/8 + j;
-					data[d_idx] = byte_rev[((u8 *)cursor->image.data)[s_idx]];
-					mask[d_idx] = byte_rev[((u8 *)cursor->mask)[s_idx]];
+					data[d_idx] = byte_rev[dat[s_idx]];
+					mask[d_idx] = byte_rev[msk[s_idx]];
 					s_idx++;
 				}
 			}
 			break;
 		}
-/*
-		bg = ((par->cmap[bg_idx].red & 0xf8) << 7) |
-		     ((par->cmap[bg_idx].green & 0xf8) << 2) |
-		     ((par->cmap[bg_idx].blue & 0xf8) >> 3) | 1 << 15;
-
-		fg = ((par->cmap[fg_idx].red & 0xf8) << 7) |
-		     ((par->cmap[fg_idx].green & 0xf8) << 2) |
-		     ((par->cmap[fg_idx].blue & 0xf8) >> 3) | 1 << 15;
-*/
+
+		bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
+		     ((info->cmap.green[bg_idx] & 0xf8) << 2) |
+		     ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
+
+		fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
+		     ((info->cmap.green[fg_idx] & 0xf8) << 2) |
+		     ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
+
 		par->riva.LockUnlock(&par->riva, 0);
 		rivafb_load_cursor_image(data, mask, par, cursor->image.width,
 		cursor->image.height, bg, fg);
@@ -1538,12 +1576,12 @@
 	.fb_blank 	= rivafb_blank,
 	.fb_fillrect 	= rivafb_fillrect,
 	.fb_copyarea 	= rivafb_copyarea,
-	.fb_imageblit 	= cfb_imageblit,
-	.fb_cursor	= soft_cursor,	
+	.fb_imageblit 	= rivafb_imageblit,
+	.fb_cursor	= rivafb_cursor,	
 	.fb_sync 	= rivafb_sync,
 };
 
-static int __devinit riva_set_fbinfo(struct fb_info *info)
+static int __init riva_set_fbinfo(struct fb_info *info)
 {
 	struct riva_par *par = (struct riva_par *) info->par;
 	unsigned int cmap_len;
@@ -1554,7 +1592,7 @@
 	info->fix = rivafb_fix;
 	info->fbops = &riva_fb_ops;
 	info->pseudo_palette = pseudo_palette;
-	
+
 #ifndef MODULE
 	if (mode_option)
 		fb_find_mode(&info->var, info, mode_option,
@@ -1566,6 +1604,12 @@
 
 	cmap_len = riva_get_cmap_len(&info->var);
 	fb_alloc_cmap(&info->cmap, cmap_len, 0);	
+
+	info->pixmap.size = 64 * 1024;
+	info->pixmap.buf_align = 4;
+	info->pixmap.scan_align = 4;
+	info->pixmap.flags = FB_PIXMAP_SYSTEM;
+
 	return 0;
 }
 
@@ -1689,8 +1733,8 @@
  *
  * ------------------------------------------------------------------------- */
 
-static int __devinit rivafb_probe(struct pci_dev *pd,
-				     const struct pci_device_id *ent)
+static int __init rivafb_probe(struct pci_dev *pd,
+			     	const struct pci_device_id *ent)
 {
 	struct riva_chip_info *rci = &riva_chip_info[ent->driver_data];
 	struct riva_par *default_par;
@@ -1710,6 +1754,11 @@
 	memset(info, 0, sizeof(struct fb_info));
 	memset(default_par, 0, sizeof(struct riva_par));
 
+	info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
+	if (info->pixmap.addr == NULL)
+		goto err_out_kfree1;
+	memset(info->pixmap.addr, 0, 64 * 1024);
+
 	strcat(rivafb_fix.id, rci->name);
 	default_par->riva.Architecture = rci->arch_rev;
 
@@ -1739,7 +1788,7 @@
 	if (!request_mem_region(rivafb_fix.mmio_start,
 				rivafb_fix.mmio_len, "rivafb")) {
 		printk(KERN_ERR PFX "cannot reserve MMIO region\n");
-		goto err_out_kfree;
+		goto err_out_kfree2;
 	}
 
 	default_par->ctrl_base = ioremap(rivafb_fix.mmio_start,
@@ -1788,8 +1837,8 @@
 		default_par->riva.PCRTC = default_par->riva.PCRTC0 = default_par->riva.PGRAPH;
 	}
 
-	rivafb_fix.smem_len = default_par->riva.RamAmountKBytes * 1024;
-	default_par->dclk_max = default_par->riva.MaxVClockFreqKHz * 1000;
+	rivafb_fix.smem_len = riva_get_memlen(default_par) * 1024;
+	default_par->dclk_max = riva_get_maxdclk(default_par) * 1000;
 
 	if (!request_mem_region(rivafb_fix.smem_start,
 				rivafb_fix.smem_len, "rivafb")) {
@@ -1819,21 +1868,15 @@
 	}
 #endif /* CONFIG_MTRR */
 
-	/* unlock io */
-	CRTCout(default_par, 0x11, 0xFF);/* vgaHWunlock() + riva unlock (0x7F) */
-	default_par->riva.LockUnlock(&default_par->riva, 0);
-
-	riva_save_state(default_par, &default_par->initial_state);
-
 	if (riva_set_fbinfo(info) < 0) {
 		printk(KERN_ERR PFX "error setting initial video mode\n");
-		goto err_out_load_state;
+		goto err_out_iounmap_fb;
 	}
 
 	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR PFX
 			"error registering riva framebuffer\n");
-		goto err_out_load_state;
+		goto err_out_iounmap_fb;
 	}
 
 	pci_set_drvdata(pd, info);
@@ -1847,9 +1890,7 @@
 		info->fix.smem_start);
 	return 0;
 
-err_out_load_state:
-	riva_load_state(default_par, &default_par->initial_state);
-/* err_out_iounmap_fb: */
+err_out_iounmap_fb:
 	iounmap(info->screen_base);
 err_out_free_base1:
 	release_mem_region(rivafb_fix.smem_start, rivafb_fix.smem_len);
@@ -1863,13 +1904,17 @@
 	iounmap(default_par->ctrl_base);
 err_out_free_base0:
 	release_mem_region(rivafb_fix.mmio_start, rivafb_fix.mmio_len);
+err_out_kfree2:
+	kfree(info->pixmap.addr);
+err_out_kfree1:
+	kfree(default_par);
 err_out_kfree:
 	kfree(info);
 err_out:
 	return -ENODEV;
 }
 
-static void __devexit rivafb_remove(struct pci_dev *pd)
+static void __exit rivafb_remove(struct pci_dev *pd)
 {
 	struct fb_info *info = pci_get_drvdata(pd);
 	struct riva_par *par = (struct riva_par *) info->par;
@@ -1877,10 +1922,7 @@
 	if (!info)
 		return;
 
-	riva_load_state(par, &par->initial_state);
-
 	unregister_framebuffer(info);
-
 #ifdef CONFIG_MTRR
 	if (par->mtrr.vram_valid)
 		mtrr_del(par->mtrr.vram, info->fix.smem_start,
@@ -1899,6 +1941,7 @@
 		iounmap((caddr_t)par->riva.PRAMIN);
 		release_mem_region(info->fix.smem_start + 0x00C00000, 0x00008000);
 	}
+	kfree(info->pixmap.addr);
 	kfree(par);
 	kfree(info);
 	pci_set_drvdata(pd, NULL);
@@ -1919,15 +1962,7 @@
 		return 0;
 
 	while ((this_opt = strsep(&options, ",")) != NULL) {
-		if (!*this_opt)
-			continue;
-		if (!strncmp(this_opt, "noblink", 7)) {
-			noblink = 1;
-#ifdef CONFIG_MTRR
-		} else if (!strncmp(this_opt, "nomtrr", 6)) {
-			nomtrr = 1;
-#endif
-		} else if (!strncmp(this_opt, "forceCRTC", 9)) {
+		if (!strncmp(this_opt, "forceCRTC", 9)) {
 			char *p;
 			
 			p = this_opt + 9;
@@ -1937,6 +1972,10 @@
 				forceCRTC = -1;
 		} else if (!strncmp(this_opt, "flatpanel", 9)) {
 			flatpanel = 1;
+#ifdef CONFIG_MTRR
+		} else if (!strncmp(this_opt, "nomtrr", 6)) {
+			nomtrr = 1;
+#endif
 		} else
 			mode_option = this_opt;
 	}
@@ -1948,7 +1987,7 @@
 	name:		"rivafb",
 	id_table:	rivafb_pci_tbl,
 	probe:		rivafb_probe,
-	remove:		__devexit_p(rivafb_remove),
+	remove:		__exit_p(rivafb_remove),
 };
 
 
@@ -1961,12 +2000,10 @@
 
 int __init rivafb_init(void)
 {
-	int err;
-	err = pci_module_init(&rivafb_driver);
-	if (err)
-		return err;
-	pci_register_driver(&rivafb_driver);
-	return 0;
+	if (pci_register_driver(&rivafb_driver) > 0)
+		return 0;
+	pci_unregister_driver(&rivafb_driver);
+	return -ENODEV;
 }
 
 
@@ -1979,8 +2016,6 @@
 module_init(rivafb_init);
 module_exit(rivafb_exit);
 
-MODULE_PARM(noblink, "i");
-MODULE_PARM_DESC(noblink, "Disables hardware cursor blinking (0 or 1=disabled) (default=0)");
 MODULE_PARM(flatpanel, "i");
 MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. (0 or 1=enabled) (default=0)");
 MODULE_PARM(forceCRTC, "i");
diff -Nru a/drivers/video/riva/nv_driver.c b/drivers/video/riva/nv_driver.c
--- a/drivers/video/riva/nv_driver.c	Mon Jan  6 14:40:01 2003
+++ b/drivers/video/riva/nv_driver.c	Sun Feb 16 10:36:47 2003
@@ -35,6 +35,7 @@
 5 20:47:06 mvojkovi Exp $ */
 
 #include <linux/delay.h>
+#include <linux/pci.h>
 #include <linux/pci_ids.h>
 #include "nv_type.h"
 #include "rivafb.h"
@@ -133,6 +134,159 @@
 	riva_override_CRTC(par);
 }
 
+unsigned long riva_get_memlen(struct riva_par *par)
+{
+	RIVA_HW_INST *chip = &par->riva;
+	unsigned long memlen = 0;
+	unsigned int chipset = par->Chipset;
+	struct pci_dev* dev;
+	int amt;
+
+	switch (chip->Architecture) {
+	case NV_ARCH_03:
+		if (chip->PFB[0x00000000/4] & 0x00000020) {
+			if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20)
+			    && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02)) {
+				/*
+				 * SDRAM 128 ZX.
+				 */
+				switch (chip->PFB[0x00000000/4] & 0x03) {
+				case 2:
+					memlen = 1024 * 4;
+					break;
+				case 1:
+					memlen = 1024 * 2;
+					break;
+				default:
+					memlen = 1024 * 8;
+					break;
+				}
+			} else {
+				memlen = 1024 * 8;
+			}            
+		} else 	{
+			/*
+			 * SGRAM 128.
+			 */
+			switch (chip->PFB[0x00000000/4] & 0x00000003) {
+			case 0:
+				memlen = 1024 * 8;
+				break;
+			case 2:
+				memlen = 1024 * 4;
+				break;
+			default:
+				memlen = 1024 * 2;
+				break;
+			}
+		}        
+		break;
+	case NV_ARCH_04:
+		if (chip->PFB[0x00000000/4] & 0x00000100) {
+			memlen = ((chip->PFB[0x00000000/4] >> 12) & 0x0F) * 
+				1024 * 2 + 1024 * 2;
+		} else {
+			switch (chip->PFB[0x00000000/4] & 0x00000003) {
+			case 0:
+				memlen = 1024 * 32;
+				break;
+			case 1:
+				memlen = 1024 * 4;
+				break;
+			case 2:
+				memlen = 1024 * 8;
+				break;
+			case 3:
+			default:
+				memlen = 1024 * 16;
+				break;
+			}
+		}
+		break;
+	case NV_ARCH_10:
+	case NV_ARCH_20:
+		if(chipset == NV_CHIP_IGEFORCE2) {
+
+			dev = pci_find_slot(0, 1);
+			pci_read_config_dword(dev, 0x7C, &amt);
+			memlen = (((amt >> 6) & 31) + 1) * 1024;
+		} else if (chipset == NV_CHIP_0x01F0) {
+			dev = pci_find_slot(0, 1);
+			pci_read_config_dword(dev, 0x84, &amt);
+			memlen = (((amt >> 4) & 127) + 1) * 1024;
+		} else {
+			switch ((chip->PFB[0x0000020C/4] >> 20) & 0x000000FF){
+			case 0x02:
+				memlen = 1024 * 2;
+				break;
+			case 0x04:
+				memlen = 1024 * 4;
+				break;
+			case 0x08:
+				memlen = 1024 * 8;
+				break;
+			case 0x10:
+				memlen = 1024 * 16;
+				break;
+			case 0x20:
+				memlen = 1024 * 32;
+				break;
+			case 0x40:
+				memlen = 1024 * 64;
+				break;
+			case 0x80:
+				memlen = 1024 * 128;
+				break;
+			default:
+				memlen = 1024 * 16;
+				break;
+			}
+		}
+		break;
+	}
+	return memlen;
+}
+
+unsigned long riva_get_maxdclk(struct riva_par *par)
+{
+	RIVA_HW_INST *chip = &par->riva;
+	unsigned long dclk = 0;
+
+	switch (chip->Architecture) {
+	case NV_ARCH_03:
+		if (chip->PFB[0x00000000/4] & 0x00000020) {
+			if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20)
+			    && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02)) {   
+				/*
+				 * SDRAM 128 ZX.
+				 */
+				dclk = 800000;
+			} else {
+				dclk = 1000000;
+			}            
+		} else {
+			/*
+			 * SGRAM 128.
+			 */
+			dclk = 1000000;
+		} 
+		break;
+	case NV_ARCH_04:
+	case NV_ARCH_10:
+	case NV_ARCH_20:
+		switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003) {
+		case 3:
+			dclk = 800000;
+			break;
+		default:
+			dclk = 1000000;
+			break;
+		}
+		break;
+	}
+	return dclk;
+}
+
 void
 riva_common_setup(struct riva_par *par)
 {
@@ -200,8 +354,6 @@
 		par->riva.PRAMDAC = par->riva.PRAMDAC0;
 		par->riva.PDIO = par->riva.PDIO0;
 	}
-
-	RivaGetConfig(&par->riva, par->Chipset);
 
 	if (par->FlatPanel == -1) {
 		/* Fix me, need x86 DDC code */
diff -Nru a/drivers/video/riva/rivafb.h b/drivers/video/riva/rivafb.h
--- a/drivers/video/riva/rivafb.h	Mon Jan  6 14:40:01 2003
+++ b/drivers/video/riva/rivafb.h	Sun Feb 16 10:36:48 2003
@@ -55,5 +55,7 @@
 };
 
 void riva_common_setup(struct riva_par *);
+unsigned long riva_get_memlen(struct riva_par *);
+unsigned long riva_get_maxdclk(struct riva_par *);
 
 #endif /* __RIVAFB_H */
diff -Nru a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
--- a/drivers/video/sbuslib.c	Tue Mar  4 09:55:26 2003
+++ b/drivers/video/sbuslib.c	Sat Mar 22 23:56:59 2003
@@ -7,6 +7,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/fb.h>
+#include <linux/mm.h>
 
 #include <asm/oplib.h>
 #include <asm/fbio.h>
diff -Nru a/drivers/video/sis/300vtbl.h b/drivers/video/sis/300vtbl.h
--- a/drivers/video/sis/300vtbl.h	Thu Jul 11 10:30:29 2002
+++ b/drivers/video/sis/300vtbl.h	Fri Mar  7 11:19:00 2003
@@ -15,7 +15,7 @@
 	UCHAR VB_StTVYFilterIndex;
 } SiS300_StStruct;
 
-SiS300_StStruct  SiS300_SModeIDTable[]=
+static const SiS300_StStruct  SiS300_SModeIDTable[] =
 {
 	{0x01,0x9208,0x01,0x00,0x00,0x00,0x00,0x00},
 	{0x01,0x1210,0x14,0x01,0x01,0x00,0x00,0x00},
@@ -34,10 +34,9 @@
 	{0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x00},
 	{0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x00},
 	{0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x00},
-	/* {0x12,0x0210,0x18,0x00,0x00,0x00,0x00,0x00}, */  /* <--- Different in BIOS */
 	{0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x00},
 	{0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x00},
-	{0xff,0,0,0,0,0,0,0}
+	{0xff,     0,   0,   0,   0,   0,   0,   0}
 };
 
 typedef struct _SiS300_StandTableStruct
@@ -53,9 +52,9 @@
 	UCHAR GRC[9];
 } SiS300_StandTableStruct;
 
-SiS300_StandTableStruct  SiS300_StandTable[]=
-{ /* TW: @ 0x38d4 in BIOS */
- {0x28,0x18,0x08,0x0800,
+static const SiS300_StandTableStruct  SiS300_StandTable[] =
+{
+ {0x28,0x18,0x08,0x0800,			/* 0x00 */
   {0x09,0x03,0x00,0x02},
   0x63,
   {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
@@ -67,7 +66,7 @@
    0x08,0x00,0x0f,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff} },
- {0x28,0x18,0x08,0x0800,
+ {0x28,0x18,0x08,0x0800,			/* 0x01 */
   {0x09,0x03,0x00,0x02},
   0x63,
   {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
@@ -79,7 +78,7 @@
    0x08,0x00,0x0f,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff} },
- {0x50,0x18,0x08,0x1000,
+ {0x50,0x18,0x08,0x1000,			/* 0x02 */
   {0x01,0x03,0x00,0x02},
   0x63,
   {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
@@ -91,7 +90,7 @@
    0x08,0x00,0x0f,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff} },
- {0x50,0x18,0x08,0x1000,
+ {0x50,0x18,0x08,0x1000,			/* 0x03 */
   {0x01,0x03,0x00,0x02},
   0x63,
   {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
@@ -103,7 +102,7 @@
    0x08,0x00,0x0f,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff} },
- {0x28,0x18,0x08,0x4000,
+ {0x28,0x18,0x08,0x4000,			/* 0x04 */
   {0x09,0x03,0x00,0x02},
   0x63,
   {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
@@ -115,7 +114,7 @@
    0x01,0x00,0x03,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
    0xff} },
- {0x28,0x18,0x08,0x4000,
+ {0x28,0x18,0x08,0x4000,			/* 0x05 */
   {0x09,0x03,0x00,0x02},
   0x63,
   {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
@@ -127,7 +126,7 @@
    0x01,0x00,0x03,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
    0xff} },
- {0x50,0x18,0x08,0x4000,
+ {0x50,0x18,0x08,0x4000,			/* 0x06 */
   {0x01,0x01,0x00,0x06},
   0x63,
   {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
@@ -139,7 +138,7 @@
    0x01,0x00,0x01,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
    0xff} },
- {0x50,0x18,0x0e,0x1000,
+ {0x50,0x18,0x0e,0x1000,			/* 0x07 */
   {0x00,0x03,0x00,0x03},
   0xa6,
   {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
@@ -152,7 +151,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
    0xff} },
 /* MDA_DAC*/
- {0x00,0x00,0x00,0x0000,
+ {0x00,0x00,0x00,0x0000,			/* 0x08 */
   {0x00,0x00,0x00,0x15},
   0x15,
   {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
@@ -165,7 +164,7 @@
   {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
    0x3f} },
 /* CGA_DAC*/
- {0x00,0x10,0x04,0x0114,
+ {0x00,0x10,0x04,0x0114,			/* 0x09 */
   {0x11,0x09,0x15,0x00},
   0x10,
   {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
@@ -178,7 +177,7 @@
   {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
    0x3f} },
 /* EGA_DAC*/
- {0x00,0x10,0x04,0x0114,
+ {0x00,0x10,0x04,0x0114,			/* 0x0a */
   {0x11,0x05,0x15,0x20},
   0x30,
   {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
@@ -191,7 +190,7 @@
   {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
    0x3f} },
 /* VGA_DAC*/
- {0x00,0x10,0x04,0x0114,
+ {0x00,0x10,0x04,0x0114,			/* 0x0b */
   {0x11,0x09,0x15,0x2a},
   0x3a,
   {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
@@ -203,7 +202,7 @@
    0x1c,0x0e,0x11,0x15},
   {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
    0x04} },
- {0x08,0x0c,0x10,0x0a08,
+ {0x08,0x0c,0x10,0x0a08,			/* 0x0c */
   {0x0c,0x0e,0x10,0x0b},
   0x0c,
   {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
@@ -215,7 +214,7 @@
    0x00,0x00,0x00,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00} },
- {0x28,0x18,0x08,0x2000,
+ {0x28,0x18,0x08,0x2000,			/* 0x0d */
   {0x09,0x0f,0x00,0x06},
   0x63,
   {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
@@ -227,7 +226,7 @@
    0x01,0x00,0x0f,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
    0xff} },
- {0x50,0x18,0x08,0x4000,
+ {0x50,0x18,0x08,0x4000,			/* 0x0e */
   {0x01,0x0f,0x00,0x06},
   0x63,
   {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
@@ -239,8 +238,8 @@
    0x01,0x00,0x0f,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
    0xff} },
- {0x00,0x00,0x00,0x0000,	/* TW: Standtable for VGA modes */
-  {0x01,0x0f,0x00,0x0e},	/*    (identical to BIOS) */
+ {0x00,0x00,0x00,0x0000,			/* 0x0f */	/* TW: Standtable for VGA modes */
+  {0x01,0x0f,0x00,0x0e},
   0x23,
   {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
    0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
@@ -251,7 +250,7 @@
    0x01,0x00,0x00,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
    0xff} },
- {0x4a,0x36,0x00,0x00c0,
+ {0x4a,0x36,0x00,0x00c0,			/* 0x10 */
   {0x00,0x00,0x00,0x00},
   0x00,
   {0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x3a,
@@ -263,7 +262,7 @@
    0x00,0x00,0x00,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00} },
- {0x50,0x18,0x0e,0x8000,
+ {0x50,0x18,0x0e,0x8000,			/* 0x11 */
   {0x01,0x0f,0x00,0x06},
   0xa2,
   {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
@@ -275,7 +274,7 @@
    0x0b,0x00,0x05,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
    0xff} },
- {0x50,0x18,0x0e,0x8000,
+ {0x50,0x18,0x0e,0x8000,			/* 0x12 */
   {0x01,0x0f,0x00,0x06},
   0xa3,
   {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
@@ -287,7 +286,7 @@
    0x01,0x00,0x0f,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
    0xff} },
- {0x28,0x18,0x0e,0x0800,
+ {0x28,0x18,0x0e,0x0800,			/* 0x13 */
   {0x09,0x03,0x00,0x02},
   0xa3,
   {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
@@ -299,7 +298,7 @@
    0x08,0x00,0x0f,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff} },
- {0x28,0x18,0x0e,0x0800,
+ {0x28,0x18,0x0e,0x0800,			/* 0x14 */
   {0x09,0x03,0x00,0x02},
   0xa3,
   {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
@@ -311,7 +310,7 @@
    0x08,0x00,0x0f,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff} },
- {0x50,0x18,0x0e,0x1000,
+ {0x50,0x18,0x0e,0x1000,			/* 0x15 */
   {0x01,0x03,0x00,0x02},
   0xa3,
   {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
@@ -323,7 +322,7 @@
    0x08,0x00,0x0f,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff} },
- {0x50,0x18,0x0e,0x1000,
+ {0x50,0x18,0x0e,0x1000,			/* 0x16 */
   {0x01,0x03,0x00,0x02},
   0xa3,
   {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
@@ -335,7 +334,7 @@
    0x08,0x00,0x0f,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff} },
- {0x28,0x18,0x10,0x0800,
+ {0x28,0x18,0x10,0x0800,			/* 0x17 */
   {0x08,0x03,0x00,0x02},
   0x67,
   {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
@@ -347,7 +346,7 @@
    0x0c,0x00,0x0f,0x08},
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff} },
- {0x50,0x18,0x10,0x1000,
+ {0x50,0x18,0x10,0x1000,			/* 0x18 */
   {0x00,0x03,0x00,0x02},
   0x67,
   {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
@@ -359,7 +358,7 @@
    0x0c,0x00,0x0f,0x08},
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff} },
- {0x50,0x18,0x10,0x1000,
+ {0x50,0x18,0x10,0x1000,			/* 0x19 */
   {0x00,0x03,0x00,0x02},
   0x66,
   {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
@@ -371,7 +370,7 @@
    0x0e,0x00,0x0f,0x08},
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
    0xff} },
- {0x50,0x1d,0x10,0xa000,
+ {0x50,0x1d,0x10,0xa000,			/* 0x1a */
   {0x01,0x0f,0x00,0x06},
   0xe3,
   {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
@@ -383,7 +382,7 @@
    0x01,0x00,0x0f,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
    0xff} },
- {0x50,0x1d,0x10,0xa000,
+ {0x50,0x1d,0x10,0xa000,			/* 0x1b */
   {0x01,0x0f,0x00,0x06},
   0xe3,
   {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
@@ -395,7 +394,7 @@
    0x01,0x00,0x0f,0x00},
   {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
    0xff} },
- {0x28,0x18,0x08,0x2000,
+ {0x28,0x18,0x08,0x2000,			/* 0x1c */
   {0x01,0x0f,0x00,0x0e},
   0x63,
   {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
@@ -424,61 +423,85 @@
 	UCHAR REFindex;
 } SiS300_ExtStruct;
 
-SiS300_ExtStruct  SiS300_EModeIDTable[]=
+static const SiS300_ExtStruct  SiS300_EModeIDTable[] =
 {
-	{0x6a,0x2212,0x47,0x3563,0x0102,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */  /* 800x600x? */
-	{0x2e,0x0a1b,0x36,0x3539,0x0101,0x08,0x06,0x00,0x00,0x00,0x08},  /* 37c3 */
-	{0x2f,0x021b,0x35,0x3532,0x0100,0x08,0x05,0x00,0x00,0x00,0x10},  /* 37bc */
-	{0x30,0x2a1b,0x47,0x3563,0x0103,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */
-	{0x31,0x0a1b,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 38ba */ /* 720x480x8 */
-	{0x32,0x2a1b,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 38c1 */ /* 720x576x8 */
-	{0x33,0x0a1d,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 38ba */ /* 720x480x16 */
-	{0x34,0x2a1d,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 38c1 */ /* 720x576x16 */
-	{0x35,0x0a1f,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 38ba */ /* 720x480x32 */
-	{0x36,0x2a1f,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 38c1 */ /* 720x576x32 */
-	{0x37,0x0212,0x58,0x358d,0x0104,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */ /* 1024x768x? */
-	{0x38,0x0a1b,0x58,0x358d,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */ /* 1024x768x8 */
-	{0x3a,0x0e3b,0x69,0x35be,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 3848 */ /* 1280x1024x8 */
-	{0x3c,0x063b,0x7a,0x35d4,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},  /* 385e */
-	{0x3d,0x067d,0x7a,0x35d4,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},  /* 385e */
-	{0x40,0x921c,0x00,0x3516,0x010d,0x08,0x00,0x00,0x00,0x00,0x23},  /* 37a0 */
-	{0x41,0x921d,0x00,0x3516,0x010e,0x08,0x00,0x00,0x00,0x00,0x23},  /* 37a0 */
-	{0x43,0x0a1c,0x36,0x3539,0x0110,0x08,0x06,0x00,0x00,0x00,0x08},  /* 37c3 */
-	{0x44,0x0a1d,0x36,0x3539,0x0111,0x08,0x06,0x00,0x00,0x00,0x08},  /* 37c3 */
-	{0x46,0x2a1c,0x47,0x3563,0x0113,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */
-	{0x47,0x2a1d,0x47,0x3563,0x0114,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */
-	{0x49,0x0a3c,0x58,0x358d,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */
-	{0x4a,0x0a3d,0x58,0x358d,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */
-	{0x4c,0x0e7c,0x69,0x35be,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 3848 */
-	{0x4d,0x0e7d,0x69,0x35be,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 3848 */
-	{0x50,0x921b,0x01,0x351d,0x0132,0x08,0x01,0x00,0x00,0x00,0x24},  /* 37a7 */
-	{0x51,0xb21b,0x13,0x3524,0x0133,0x08,0x03,0x00,0x00,0x00,0x25},  /* 37ae */
-	{0x52,0x921b,0x24,0x352b,0x0134,0x08,0x04,0x00,0x00,0x00,0x26},  /* 37b5 */
-	{0x56,0x921d,0x01,0x351d,0x0135,0x08,0x01,0x00,0x00,0x00,0x24},  /* 37a7 */
-	{0x57,0xb21d,0x13,0x3524,0x0136,0x08,0x03,0x00,0x00,0x00,0x25},  /* 37ae */
-	{0x58,0x921d,0x24,0x352b,0x0137,0x08,0x04,0x00,0x00,0x00,0x26},  /* 37b5 */
-	{0x59,0x921b,0x00,0x3516,0x0138,0x08,0x00,0x00,0x00,0x00,0x23},  /* 37a0 */
+	{0x6a,0x2212,0x47,0x3563,0x0102,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600x? */
+	{0x2e,0x0a1b,0x36,0x3539,0x0101,0x08,0x06,0x00,0x00,0x00,0x08},
+	{0x2f,0x021b,0x35,0x3532,0x0100,0x08,0x05,0x00,0x00,0x00,0x10},  /* 640x400x8 */
+	{0x30,0x2a1b,0x47,0x3563,0x0103,0x08,0x07,0x00,0x00,0x00,0x00},
+	{0x31,0x0a1b,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x8 */
+	{0x32,0x2a1b,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x8 */
+	{0x33,0x0a1d,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x16 */
+	{0x34,0x2a1d,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x16 */
+	{0x35,0x0a1f,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x32 */
+	{0x36,0x2a1f,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x32 */
+	{0x37,0x0212,0x58,0x358d,0x0104,0x08,0x08,0x00,0x00,0x00,0x13},  /* 1024x768x? */
+	{0x38,0x0a1b,0x58,0x358d,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},  /* 1024x768x8 */
+	{0x3a,0x0e3b,0x69,0x35be,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 1280x1024x8 */
+	{0x3c,0x063b,0x7a,0x35d4,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},
+	{0x3d,0x067d,0x7a,0x35d4,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},
+	{0x40,0x921c,0x00,0x3516,0x010d,0x08,0x00,0x00,0x00,0x00,0x23},
+	{0x41,0x921d,0x00,0x3516,0x010e,0x08,0x00,0x00,0x00,0x00,0x23},
+	{0x43,0x0a1c,0x36,0x3539,0x0110,0x08,0x06,0x00,0x00,0x00,0x08},
+	{0x44,0x0a1d,0x36,0x3539,0x0111,0x08,0x06,0x00,0x00,0x00,0x08},
+	{0x46,0x2a1c,0x47,0x3563,0x0113,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600 */
+	{0x47,0x2a1d,0x47,0x3563,0x0114,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600 */
+	{0x49,0x0a3c,0x58,0x358d,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
+	{0x4a,0x0a3d,0x58,0x358d,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},
+	{0x4c,0x0e7c,0x69,0x35be,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
+	{0x4d,0x0e7d,0x69,0x35be,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},
+	{0x50,0x921b,0x01,0x351d,0x0132,0x08,0x01,0x00,0x00,0x00,0x24},
+	{0x51,0xb21b,0x13,0x3524,0x0133,0x08,0x03,0x00,0x00,0x00,0x25},  /* 400x300 */
+	{0x52,0x921b,0x24,0x352b,0x0134,0x08,0x04,0x00,0x00,0x00,0x26},
+	{0x56,0x921d,0x01,0x351d,0x0135,0x08,0x01,0x00,0x00,0x00,0x24},
+	{0x57,0xb21d,0x13,0x3524,0x0136,0x08,0x03,0x00,0x00,0x00,0x25},  /* 400x300 */
+	{0x58,0x921d,0x24,0x352b,0x0137,0x08,0x04,0x00,0x00,0x00,0x26},  
+	{0x59,0x921b,0x00,0x3516,0x0138,0x08,0x00,0x00,0x00,0x00,0x23}, 
 	{0x5c,0x921f,0x24,0x352b,0x0000,0x08,0x04,0x00,0x00,0x00,0x26},  /* TW: inserted 512x384x32 */
-	{0x5d,0x021d,0x35,0x3532,0x0139,0x08,0x05,0x00,0x00,0x00,0x10},  /* 37bc */
-	{0x62,0x0a3f,0x36,0x3539,0x013a,0x08,0x06,0x00,0x00,0x00,0x08},  /* 37c3 */
-	{0x63,0x2a3f,0x47,0x3563,0x013b,0x08,0x07,0x00,0x00,0x00,0x00},  /* 37ed */
-	{0x64,0x0a7f,0x58,0x358d,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},  /* 3817 */
-	{0x65,0x0eff,0x69,0x35be,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 3848 */
-	{0x66,0x06ff,0x7a,0x35d4,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},  /* 385e */
-	{0x68,0x067b,0x8b,0x35ef,0x013f,0x08,0x0b,0x00,0x00,0x00,0x27},  /* 3879 */
-	{0x69,0x06fd,0x8b,0x35ef,0x0140,0x08,0x0b,0x00,0x00,0x00,0x27},  /* 3879 */
-	{0x6b,0x07ff,0x8b,0x35ef,0x0000,0x10,0x0b,0x00,0x00,0x00,0x27},  /* 3879 */
-	{0x6c,0x067b,0x9c,0x35f6,0x0000,0x08,0x0c,0x00,0x00,0x00,0x28},  /* 3880 */
-	{0x6d,0x06fd,0x9c,0x35f6,0x0000,0x10,0x0c,0x00,0x00,0x00,0x28},  /* 3880 */
-	{0x6e,0x0e3b,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 383c */  /* 1280x960x8 */
-	{0x6f,0x0e7d,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 383c */  /* 1280x960x16 */
-	{0x7b,0x0eff,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 383c */  /* 1280x960x32 */
-	{0x20,0x0a1b,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},              /* 1024x600 */
+	{0x5d,0x021d,0x35,0x3532,0x0139,0x08,0x05,0x00,0x00,0x00,0x10},  /* 640x400x16 */
+ 	{0x5e,0x021f,0x35,0x3532,0x0000,0x08,0x05,0x00,0x00,0x00,0x10},  /* TW: inserted 640x400x32 */
+	{0x62,0x0a3f,0x36,0x3539,0x013a,0x08,0x06,0x00,0x00,0x00,0x08},
+	{0x63,0x2a3f,0x47,0x3563,0x013b,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600 */
+	{0x64,0x0a7f,0x58,0x358d,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},
+	{0x65,0x0eff,0x69,0x35be,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},
+	{0x66,0x06ff,0x7a,0x35d4,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},
+	{0x68,0x067b,0x8b,0x35ef,0x013f,0x08,0x0b,0x00,0x00,0x00,0x27},
+	{0x69,0x06fd,0x8b,0x35ef,0x0140,0x08,0x0b,0x00,0x00,0x00,0x27},
+	{0x6b,0x07ff,0x8b,0x35ef,0x0000,0x10,0x0b,0x00,0x00,0x00,0x27},
+	{0x6c,0x067b,0x9c,0x35f6,0x0000,0x08,0x11,0x00,0x00,0x00,0x28},  /* TW: 2048x1536x8 - not in BIOS! */
+	{0x6d,0x06fd,0x9c,0x35f6,0x0000,0x10,0x11,0x00,0x00,0x00,0x28},  /* TW: 2048x1536x16 - not in BIOS! */
+	{0x6e,0x0a3b,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 1280x960x8 */
+	{0x6f,0x0a7d,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 1280x960x16 */
+	/* TW: 16:9 modes copied from 310/325 series - not in ANY BIOS */
+	{0x70,0x2a1b,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x8 */
+	{0x71,0x0a1b,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},    /* 1024x576x8 */
+	{0x74,0x0a1d,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},    /* 1024x576x16 */
+	{0x75,0x0e3d,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x16 */
+	{0x76,0x2a1f,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x32 */
+	{0x77,0x0a3f,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},	   /* 1024x576x32 */
+	{0x78,0x0eff,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x32 */
+	{0x79,0x0e3b,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x8 */
+	{0x7a,0x2a1d,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x16 */
+	/* TW: End of new 16:9 modes */
+	{0x7b,0x0aff,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},    /* 1280x960x32 */
+	{0x20,0x0a1b,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},    /* 1024x600 */
 	{0x21,0x0a3d,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
 	{0x22,0x0a7f,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
-	{0x23,0x0a1b,0xc5,0x0000,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},              /* 1152x768 */
+	{0x23,0x0a1b,0xc5,0x0000,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},    /* 1152x768 */
 	{0x24,0x0a3d,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
 	{0x25,0x0a7f,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
+	{0x29,0x0e1b,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},    /* TW: NEW 1152x864 - not in BIOS */
+	{0x2a,0x0e3d,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
+	{0x2b,0x0e7f,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
+	{0x39,0x2a1b,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},    /* TW: NEW 848x480 - not in BIOS */
+	{0x3b,0x2a3d,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
+	{0x3e,0x2a7f,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
+	{0x3f,0x2a1b,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},    /* TW: NEW 856x480 - not in BIOS */
+	{0x42,0x2a3d,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
+	{0x45,0x2a7f,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
+	{0x48,0x223b,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},    /* TW: NEW 1360x768 - not in BIOS */
+	{0x4b,0x227d,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
+	{0x4e,0x22ff,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
 	{0xff,0x0000,0x00,0x0000,0xffff,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
@@ -486,7 +509,7 @@
 {
 	USHORT Ext_InfoFlag;
 	UCHAR Ext_CRT1CRTC;  /* TW: Index in SiS300_CRT1Table */
-	UCHAR Ext_CRTVCLK;
+	UCHAR Ext_CRTVCLK;   /* TW: Index in VCLK array */
 	UCHAR Ext_CRT2CRTC;  /* TW: Index in LCD Paneltype arrays (&3f) */
 	UCHAR  ModeID;
 	USHORT XRes;
@@ -494,15 +517,15 @@
 	USHORT ROM_OFFSET;
 } SiS300_Ext2Struct;
 
-SiS300_Ext2Struct  SiS300_RefIndex[]=
+static const SiS300_Ext2Struct  SiS300_RefIndex[] =
 { /* TW: Don't ever insert anything here, table is indexed */
 	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3563}, /* 00 */
 	{0x0467,0x0e,0x44,0x05,0x6a, 800, 600,0x3568}, /* 01 */
-	{0x0067,0x4f,0x07,0x48,0x6a, 800, 600,0x356d}, /* 02 */
+	{0x0067,0x0f,0x07,0x48,0x6a, 800, 600,0x356d}, /* 02 - CRT1CRTC was 0x4f */
 	{0x0067,0x10,0x06,0x8b,0x6a, 800, 600,0x3572}, /* 03 */
 	{0x0147,0x11,0x08,0x00,0x6a, 800, 600,0x3577}, /* 04 */
 	{0x0147,0x12,0x0c,0x00,0x6a, 800, 600,0x357c}, /* 05 */
-	{0x0047,0x51,0x4e,0x00,0x6a, 800, 600,0x3581}, /* 06 */
+	{0x0047,0x11,0x4e,0x00,0x6a, 800, 600,0x3581}, /* 06 - CRT1CRTC was 0x51 */
 	{0x0047,0x11,0x13,0x00,0x6a, 800, 600,0x3586}, /* 07 */
 	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3539}, /* 08 */
 	{0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x353e}, /* 09 */
@@ -517,30 +540,46 @@
 	{0x000f,0x32,0x03,0x06,0x32, 720, 576,0x3637}, /* 12 */
 	{0x0187,0x15,0x05,0x00,0x37,1024, 768,0x358d}, /* 13 */
         {0xc877,0x16,0x09,0x06,0x37,1024, 768,0x3592}, /* 14 */
-	{0xc067,0x97,0x0b,0x49,0x37,1024, 768,0x3597}, /* 15 */
+	{0xc067,0x17,0x0b,0x49,0x37,1024, 768,0x3597}, /* 15 - CRT1CRTC was 0x97 */
 	{0x0267,0x18,0x0d,0x00,0x37,1024, 768,0x359c}, /* 16 */
-	{0x0047,0x59,0x11,0x8c,0x37,1024, 768,0x35a1}, /* 17 */
+	{0x0047,0x19,0x11,0x8c,0x37,1024, 768,0x35a1}, /* 17 - CRT1CRTC was 0x59 */
 	{0x0047,0x1a,0x52,0x00,0x37,1024, 768,0x35a6}, /* 18 */
-	{0x0047,0x5b,0x16,0x00,0x37,1024, 768,0x35ab}, /* 19 */
-	{0x0387,0x5c,0x4d,0x00,0x3a,1280,1024,0x35be}, /* 1a */
+	{0x0007,0x1b,0x16,0x00,0x37,1024, 768,0x35ab}, /* 19 - CRT1CRTC was 0x5b */
+	{0x0387,0x1c,0x4d,0x00,0x3a,1280,1024,0x35be}, /* 1a - CRT1CRTC was 0x5c */
 	{0x0077,0x1d,0x14,0x07,0x3a,1280,1024,0x35c3}, /* 1b */
 	{0x0047,0x1e,0x17,0x00,0x3a,1280,1024,0x35c8}, /* 1c */
 	{0x0007,0x1f,0x98,0x00,0x3a,1280,1024,0x35cd}, /* 1d */
-	{0x0007,0x60,0x59,0x00,0x3c,1600,1200,0x35d4}, /* 1e */
+	{0x0007,0x20,0x59,0x00,0x3c,1600,1200,0x35d4}, /* 1e - CRT1CRTC was 0x60 */
 	{0x0007,0x21,0x5a,0x00,0x3c,1600,1200,0x35d9}, /* 1f */
 	{0x0007,0x22,0x1b,0x00,0x3c,1600,1200,0x35de}, /* 20 */
-	{0x0007,0x63,0x1d,0x00,0x3c,1600,1200,0x35e3}, /* 21 */
+	{0x0007,0x23,0x1d,0x00,0x3c,1600,1200,0x35e3}, /* 21 - CRT1CRTC was 0x63 */
 	{0x0007,0x24,0x1e,0x00,0x3c,1600,1200,0x35e8}, /* 22 */
 	{0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3516}, /* 23 */
 	{0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x351d}, /* 24 */
 	{0x0077,0x02,0x04,0x05,0x51, 400, 300,0x3524}, /* 25 */
-	{0xc077,0x03,0x09,0x06,0x52, 512, 384,0x352b}, /* 26 */   
+	{0xc877,0x03,0x09,0x06,0x52, 512, 384,0x352b}, /* 26 */  /* was c077 */
 	{0x8207,0x25,0x1f,0x00,0x68,1920,1440,0x35ef}, /* 27 */
-	{0x0007,0x26,0x20,0x00,0x6c, 720, 480,0x35f6}, /* 28 */
-	{0x0027,0x27,0x14,0x08,0x6e,1280, 960,0x35b2}, /* 29 */
-	{0x0027,0x27,0x14,0x08,0x6e,1280, 960,0x35b7}, /* 2a */
+	{0x0007,0x26,0x20,0x00,0x6c,2048,1536,0x35f6}, /* 28 */
+	{0x0067,0x27,0x14,0x08,0x6e,1280, 960,0x35b7}, /* 29 - TW: 1280x960-60 */
+	{0x0027,0x45,0x3c,0x08,0x6e,1280, 960,0x35b7}, /* 2a - TW: 1280x960-85 */
 	{0xc077,0x33,0x09,0x06,0x20,1024, 600,0x0000}, /* 2b */
-	{0xc077,0x34,0x09,0x06,0x23,1152, 768,0x0000}, /* 2c */
+	{0xc077,0x34,0x0b,0x06,0x23,1152, 768,0x0000}, /* 2c */	/* VCLK 0x09 */
+	{0x0057,0x35,0x27,0x08,0x70, 800, 480,0x3b52}, /* 2d - TW: 16:9 modes */
+	{0x0047,0x36,0x37,0x08,0x70, 800, 480,0x3b57}, /* 2e */
+	{0x0047,0x37,0x08,0x08,0x70, 800, 480,0x3b5c}, /* 2f */
+	{0x0057,0x38,0x09,0x09,0x71,1024, 576,0x3b63}, /* 30 */
+	{0x0047,0x39,0x38,0x09,0x71,1024, 576,0x3b68}, /* 31 */
+	{0x0047,0x3a,0x11,0x09,0x71,1024, 576,0x3b6d}, /* 32 */
+	{0x0057,0x3b,0x39,0x0a,0x75,1280, 720,0x3b74}, /* 33 */
+	{0x0047,0x3c,0x3a,0x0a,0x75,1280, 720,0x3b79}, /* 34 */
+	{0x0007,0x3d,0x3b,0x0a,0x75,1280, 720,0x3b7e}, /* 35 - TW: END of 16:9 modes */
+	{0x0047,0x3e,0x34,0x06,0x29,1152, 864,0x0000}, /* 36 TW: 1152x864-75Hz - Non-BIOS, new */
+	{0x0047,0x44,0x3a,0x06,0x29,1152, 864,0x0000}, /* 37 TW: 1152x864-85Hz - Non-BIOS, new */
+	{0x00c7,0x3f,0x28,0x00,0x39, 848, 480,0x0000}, /* 38 TW: 848x480-38Hzi - Non-BIOS, new */
+	{0xc047,0x40,0x3d,0x00,0x39, 848, 480,0x0000}, /* 39 TW: 848x480-60Hz  - Non-BIOS, new */
+	{0x00c7,0x41,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3a TW: 856x480-38Hzi - Non-BIOS, new */
+	{0xc047,0x42,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3b TW: 856x480-60Hz  - Non-BIOS, new */
+	{0x0047,0x43,0x3e,0x00,0x48,1360, 768,0x0000}, /* 3c TW: 1360x768-60Hz - Non-BIOS, new */
 	{0xffff,0,0,0,0,0,0,0}
 };
 
@@ -557,9 +596,9 @@
 	UCHAR  _VB_LCDVIndex;
 }SiS_VBModeIDTableStruct;
 
-SiS_VBModeIDTableStruct  SiS300_VBModeIDTable[]=
+static const SiS_VBModeIDTableStruct  SiS300_VBModeIDTable[] =
 {
-	{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* TW: Identical to 630/301B BIOS */
+	{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 	{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
 	{0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x02},
 	{0x03,0x00,0x00,0x00,0x02,0x00,0x02,0x00},
@@ -619,7 +658,7 @@
 	UCHAR CR[17];
 } SiS300_CRT1TableStruct;
 
-SiS300_CRT1TableStruct  SiS300_CRT1Table[]=
+static const SiS300_CRT1TableStruct  SiS300_CRT1Table[] =
 {
  {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,    /* 0x00 */
   0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
@@ -636,29 +675,49 @@
  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
   0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
   0x00}},
- {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
+#if 0  
+ {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,    /* 0x05 */
   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
   0x00}},
- {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,
+#endif
+ {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e,    /* 0x05 - corrected 640x480-60 */
+  0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
+  0x00}},
+ #if 0  
+ {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,    /* 0x06 */
   0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
   0x00}},
+#endif  
+ {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e,    /* 0x06 - corrected 640x480-72 */
+  0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
+  0x00}},
  {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
   0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
   0x00}},
  {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
   0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
   0x00}},
- {{0x66,0x4f,0x4f,0x86,0x56,0x9e,0x03,0x3e,
+#if 0  
+ {{0x66,0x4f,0x4f,0x86,0x56,0x9e,0x03,0x3e,    /* 0x09 */
   0xe4,0x87,0xdf,0xdf,0x04,0x00,0x00,0x01,
   0x00}},
+#endif
+ {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e,    /* 0x09 - corrected 640x480-100 */
+  0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05,
+  0x00}},
+#if 0  
  {{0x6c,0x4f,0x4f,0x83,0x59,0x9e,0x00,0x3e,    /* 0x0a */
   0xe5,0x8d,0xdf,0xdf,0x01,0x00,0x00,0x01,
   0x00}},
+#endif    
+ {{0x67,0x4f,0x4f,0x8b,0x57,0x83,0x10,0x3e,    /* 0x0a - corrected 640x480-120 */
+  0xe7,0x8d,0xdf,0xe6,0x11,0x00,0x00,0x05,
+  0x00}},
  {{0x63,0x4f,0x4f,0x87,0x56,0x9d,0xfb,0x1f,
   0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x01,
   0x00}},
  {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
-  0xe6,0x8a,0xe5,0xe5,0xfc,0x00,0x00,0x01,
+  0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01,    /* TW: Corrected VDE, VBE */
   0x00}},
  {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
   0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
@@ -699,7 +758,7 @@
  {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
   0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
   0x01}},
- {{0x9f,0x7f,0x7f,0x83,0x83,0x93,0x1e,0xf5,
+ {{0x9f,0x7f,0x7f,0x83,0x83,0x93,0x1e,0xf5,  /* 0x1a */
   0x00,0x84,0xff,0xff,0x1f,0x10,0x00,0x02,
   0x01}},
  {{0xa2,0x7f,0x7f,0x86,0x84,0x94,0x37,0xf5,
@@ -738,9 +797,14 @@
  {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
   0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
   0x00}},
- {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef,
+#if 0  
+ {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef,  /* 0x27: 1280x960-70 - invalid! */
   0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
   0x01}},
+#endif  
+ {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff,  /* 0x27: 1280x960-60 - correct */
+  0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
+  0x01}},
  {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,  /* 0x28 */
   0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
   0x01}},
@@ -777,9 +841,70 @@
  {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,  /* 0x33 - 1024x600 */
   0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
   0x01}},
+#if 0
  {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,  /* 0x34 - 1152x768 */
   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
-  0x01}}
+  0x01}},
+#endif
+ {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5,  /* 0x34 - 1152x768 - TW: corrected */
+  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+  0x01}},
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,  /* 0x35 - NEW 16:9 modes, not in BIOS ------ */
+   0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
+   0x01}}, /* 0x35 */
+ {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
+   0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
+   0x01}}, /* 0x36 */
+ {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
+   0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
+   0x01}}, /* 0x37 */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
+   0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
+   0x01}}, /* 0x38 */
+ {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
+   0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
+   0x01}}, /* 0x39 */
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,   	/* TW: 95 was 15 - illegal HBE! */
+   0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
+   0x01}}, /* 0x3a */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
+   0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+   0x01}}, /* 0x3b */
+ {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
+   0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
+   0x01}}, /* 0x3c */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
+   0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
+   0x01}}, /* 0x3d */			     /* TW: End of 16:9 modes --------------- */
+ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef,  /* TW: New, 1152x864-75 (not in any BIOS)   */
+   0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
+   0x01}},  /* 0x3e */
+ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15,  /* TW: New, 848x480-38i, not in BIOS */
+   0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+   0x00}}, /* 0x3f */
+#if 0
+ {{0x81,0x69,0x69,0x85,0x70,0x00,0x0F,0x3E,  /* TW: New, 848x480-60, not in BIOS - incorrect for Philips panel */
+   0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+   0x00}}, /* 0x40 */
+#endif
+ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E,  /* TW: New, 848x480-60, not in BIOS */
+   0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
+   0x00}}, /* 0x40 */
+ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15,  /* TW: New, 856x480-38i, not in BIOS */
+   0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+   0x00}}, /* 0x41 */
+ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E,  /* TW: New, 856x480-60, not in BIOS */
+   0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+   0x00}}, /* 0x42 */
+ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd,  /* TW: New, 1360x768-60, not in BIOS */
+   0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
+   0x01}}, /* 0x43 */
+ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff,  /* TW: New, 1152x864-84 (not in any BIOS)   */
+   0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
+   0x01}}, /* 0x44 */   
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff,  /* TW: New, 1280x960-85 (not in any BIOS)   */
+   0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
+   0x01}}  /* 0x45 */
 };
 
 typedef struct _SiS300_MCLKDataStruct
@@ -788,7 +913,7 @@
 	USHORT CLOCK;
 } SiS300_MCLKDataStruct;
 
-SiS300_MCLKDataStruct  SiS300_MCLKData[]=
+static const SiS300_MCLKDataStruct  SiS300_MCLKData_630[] =	/* 630 */
 { /* TW: at 0x54 in BIOS */
 	{ 0x5a,0x64,0x80, 66},
 	{ 0xb3,0x45,0x80, 83},
@@ -800,13 +925,25 @@
 	{ 0x37,0x61,0x80,100}
 };
 
+static const SiS300_MCLKDataStruct  SiS300_MCLKData_300[] =  /* 300 */
+{ /* TW: at 0x54 in BIOS */
+	{ 0x68,0x43,0x80,125},
+	{ 0x68,0x43,0x80,125},
+	{ 0x68,0x43,0x80,125},
+	{ 0x37,0x61,0x80,100},
+	{ 0x37,0x61,0x80,100},
+	{ 0x37,0x61,0x80,100},
+	{ 0x37,0x61,0x80,100},
+	{ 0x37,0x61,0x80,100}
+};
+
 typedef struct _SiS300_ECLKDataStruct
 {
 	UCHAR SR2E,SR2F,SR30;
 	USHORT CLOCK;
 } SiS300_ECLKDataStruct;
 
-SiS300_ECLKDataStruct  SiS300_ECLKData[]=
+static const SiS300_ECLKDataStruct  SiS300_ECLKData[] =
 {
 	{ 0x54,0x43,0x80,100},
 	{ 0x53,0x43,0x80,100},
@@ -824,68 +961,79 @@
 	USHORT CLOCK;
 } SiS300_VCLKDataStruct;
 
-SiS300_VCLKDataStruct  SiS300_VCLKData[]=
+static const SiS300_VCLKDataStruct  SiS300_VCLKData[] =
 {
-	{ 0x1b,0xe1, 25},
+	{ 0x1b,0xe1, 25}, /* 0x00 */
 	{ 0x4e,0xe4, 28},
-	{ 0x57,0xe4, 32},
+	{ 0x57,0xe4, 32}, /* 0x02 */
 	{ 0xc3,0xc8, 36},
-	{ 0x42,0xc3, 40},
+	{ 0x42,0xc3, 40}, /* 0x04 */
 	{ 0x5d,0xc4, 45},
-	{ 0x52,0x65, 50},
+	{ 0x52,0x65, 50}, /* 0x06 */
 	{ 0x53,0x65, 50},
-	{ 0x6d,0x66, 56},
+	{ 0x6d,0x66, 56}, /* 0x08 */
 	{ 0x5a,0x64, 65},
-	{ 0x46,0x44, 68},
+	{ 0x46,0x44, 68}, /* 0x0a */
 	{ 0x3e,0x43, 75},
-	{ 0x6d,0x46, 76}, /* 0x0c: 800x600 | LVDS_2(CH), MITAC(CH);  - LVDS2(CH), A901(301B): 0xb1,0x46, 76 */
+	{ 0x6d,0x46, 76}, /* 0x0c: 800x600 | LVDS_2(CH), MITAC(CH);  - 730, A901(301B): 0xb1,0x46, 76 */
 	{ 0x41,0x43, 79},
-	{ 0x31,0x42, 79},
+	{ 0x31,0x42, 79}, /* 0x0e */
 	{ 0x46,0x25, 85},
 	{ 0x78,0x29, 87}, /* 0x10 */
 	{ 0x62,0x44, 95},
-	{ 0x2b,0x22,105},
+	{ 0x2b,0x22,105}, /* 0x12 */
 	{ 0x49,0x24,106},
-	{ 0xc3,0x28,108},
+	{ 0xc3,0x28,108}, /* 0x14 */
 	{ 0x3c,0x23,109},
-	{ 0xf7,0x2c,132},
+	{ 0xf7,0x2c,132}, /* 0x16 */
 	{ 0xd4,0x28,136},
-	{ 0x41,0x05,158},
+	{ 0x41,0x05,158}, /* 0x18 */
 	{ 0x43,0x05,162},
-	{ 0xe1,0x0f,175},
-	{ 0xfc,0x12,189},
-	{ 0xde,0x26,194},
+	{ 0xe1,0x0f,175}, /* 0x1a */
+	{ 0xfc,0x12,189}, /* 0x1b */
+	{ 0xde,0x26,194}, /* 0x1c */
 	{ 0x54,0x05,203},
-	{ 0x3f,0x03,230},
+	{ 0x3f,0x03,230}, /* 0x1e */
 	{ 0x30,0x02,234},
-	{ 0x24,0x01,266},  /* 0x20 */
-	{ 0x52,0x2a, 54},  /* 301 TV */
-	{ 0x52,0x6a, 27},  /* 301 TV */
-	{ 0x62,0x24, 70},  /* 301 TV */
-	{ 0x62,0x64, 70},  /* 301 TV */
-	{ 0xa8,0x4c, 30},  /* 301 TV */
-	{ 0x20,0x26, 33},  /* 301 TV */
+	{ 0x24,0x01,266}, /* 0x20 */
+	{ 0x52,0x2a, 54}, /* 301 TV */
+	{ 0x52,0x6a, 27}, /* 301 TV */
+	{ 0x62,0x24, 70}, /* 301 TV */
+	{ 0x62,0x64, 70}, /* 301 TV */
+	{ 0xa8,0x4c, 30}, /* 301 TV */
+	{ 0x20,0x26, 33}, /* 301 TV */
 	{ 0x31,0xc2, 39},
-	{ 0xbf,0xc8, 35},  /* 0x28 */
-	{ 0x60,0x36, 30},  /* 0x29  CH/UNTSC TEXT | LVDS_2(CH) - LVDS2(CH), A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
+	{ 0xbf,0xc8, 35}, /* 0x28 - 856x480 */
+	{ 0x60,0x36, 30}, /* 0x29  CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
 	{ 0x40,0x4a, 28},
 	{ 0x9f,0x46, 44},
 	{ 0x97,0x2c, 26},
 	{ 0x44,0xe4, 25},
 	{ 0x7e,0x32, 47},
-	{ 0x8a,0x24, 31},  /* 0x2f  CH/PAL TEXT | LVDS_2(CH), Mitac(CH) -  LVDS2(CH), A901(301B): 0x57, 0xe4, 31 */
+	{ 0x8a,0x24, 31}, /* 0x2f  CH/PAL TEXT | LVDS_2(CH), Mitac(CH) -  730, A901(301B): 0x57, 0xe4, 31 */
 	{ 0x97,0x2c, 26},
 	{ 0xce,0x3c, 39},
-	{ 0x52,0x4a, 36},
+	{ 0x52,0x4a, 36}, /* 0x32  CH/PAL 800x600 5/6 */
 	{ 0x34,0x61, 95},
 	{ 0x78,0x27,108},
-	{ 0xce,0x25,189},
-	{ 0x45,0x6b, 21},  /* 0x36 */  /* TW: Added from Mitac */
-	{ 0xff,0x00,  0}
+	{ 0xce,0x25,189}, /* 0x35 */
+	{ 0x45,0x6b, 21}, /* 0x36 */  /* TW: Added from Mitac */
+	{ 0x52,0xe2, 49}, /* 0x37 - added for 16:9 modes (not in any BIOS) */
+	{ 0x2b,0x61, 78}, /* 0x38 - added for 16:9 modes (not in any BIOS) */
+	{ 0x70,0x44,108}, /* 0x39 - added for 16:9 modes (not in any BIOS) */
+	{ 0x54,0x42,135}, /* 0x3a - added for 16:9 modes (not in any BIOS) */
+	{ 0x41,0x22,157}, /* 0x3b - added for 16:9 modes (not in any BIOS) */
+	{ 0x52,0x07,149}, /* 0x3c - added for 1280x960-85 (not in any BIOS)*/
+	{ 0x62,0xc6, 34}, /* 0x3d - added for 848x480-60 (not in any BIOS) */
+	{ 0x30,0x23, 88}, /* 0x3e - added for 1360x768-60 (not in any BIOS)*/
+	{ 0x3f,0x64, 46}, /* 0x3f - added for 640x480-100 (not in any BIOS)*/
+	{ 0x72,0x2a, 76}, /* 0x40 - test for SiS730 */
+	{ 0x15,0x21, 79}, /* 0x41 - test for SiS730 */
+	{ 0xff,0x00,  0}   
 };
 
 #if 0 /* TW: This table is in all BIOSes, but not used */
-SiS300_VCLKDataStruct  SiS300_VBVCLKData[]=
+static const SiS300_VCLKDataStruct  SiS300_VBVCLKData[] =
 {
 	{ 0x1b,0xe1, 25},
 	{ 0x4e,0xe4, 28},
@@ -938,10 +1086,11 @@
 };
 #endif
 
-UCHAR SiS300_ScreenOffset[] =
+static const UCHAR  SiS300_ScreenOffset[] =
 {
 	0x14,0x19,0x20,0x28,0x32,0x40,0x50,
-        0x64,0x78,0x80,0x2d,0x35,0x48,0xff
+        0x64,0x78,0x80,0x2d,0x35,0x48,0x35,  /* 0x35 for 848 and 856 */
+	0x55,0xff			     /* 0x55 for 1360 */	
 };
 
 typedef struct _SiS300_StResInfoStruct
@@ -950,7 +1099,7 @@
 	USHORT VTotal;
 } SiS300_StResInfoStruct;
 
-SiS300_StResInfoStruct  SiS300_StResInfo[] =
+static const SiS300_StResInfoStruct  SiS300_StResInfo[] =
 {
 	{ 640,400},
 	{ 640,350},
@@ -967,7 +1116,7 @@
 	UCHAR  YChar;
 } SiS300_ModeResInfoStruct;
 
-SiS300_ModeResInfoStruct  SiS300_ModeResInfo[] =
+static const SiS300_ModeResInfoStruct  SiS300_ModeResInfo[] =
 {
 	{  320, 200, 8, 8},  /* 0x00 */
 	{  320, 240, 8, 8},  /* 0x01 */
@@ -985,62 +1134,81 @@
 	{  720, 576, 8,16},  /* 0x0d */
 	{ 1280, 960, 8,16},  /* 0x0e */
 	{ 1024, 600, 8,16},  /* 0x0f */
-	{ 1152, 768, 8,16}   /* 0x10 */
+	{ 1152, 768, 8,16},  /* 0x10 */
+	{ 2048,1536, 8,16},  /* 0x11 - TW: Not in BIOS! */
+	{  800, 480, 8,16},  /* 0x12 - TW: New, not in any BIOS */
+	{ 1024, 576, 8,16},  /* 0x13 - TW: New, not in any BIOS */
+	{ 1280, 720, 8,16},  /* 0x14 - TW: New, not in any BIOS */
+	{ 1152, 864, 8,16},  /* 0x15 - TW: New, not in any BIOS */
+	{  848, 480, 8,16},  /* 0x16 - TW: New, not in any BIOS */
+	{  856, 480, 8,16},  /* 0x17 - TW: New, not in any BIOS */
+	{ 1360, 768, 8,16}   /* 0x18 - TW: New, not in any BIOS */
 };
 
-UCHAR SiS300_OutputSelect =0x40;
-UCHAR SiS300_SoftSetting = 30;
-UCHAR SiS300_SR07=0x10;
-UCHAR SiS300_SR15[8][4] =
-{
-	{0x1,0x9,0xa3,0x0},
-	{0x43,0x43,0x43,0x0},
-	{0x1e,0x1e,0x1e,0x0},
-	{0x2a,0x2a,0x2a,0x0},
-	{0x6,0x6,0x6,0x0},
-	{0x0,0x0,0x0,0x0},
-	{0x0,0x0,0x0,0x0},
-	{0x0,0x0,0x0,0x0}
-};
-UCHAR SiS300_SR1F=0x0;
-UCHAR SiS300_SR21=0x16;
-UCHAR SiS300_SR22=0xb2;
-UCHAR SiS300_SR23=0xf6;
-UCHAR SiS300_SR24=0xd;
-UCHAR SiS300_SR25[]={0x0,0x0};
-UCHAR SiS300_SR31=0x0;
-UCHAR SiS300_SR32=0x11;
-UCHAR SiS300_SR33=0x0;
-UCHAR SiS300_CRT2Data_1_2 = 0x40;
-UCHAR SiS300_CRT2Data_4_D = 0x0;
-UCHAR SiS300_CRT2Data_4_E = 0x0;
-UCHAR SiS300_CRT2Data_4_10 = 0x80;
-USHORT SiS300_RGBSenseData = 0xd1;
-USHORT SiS300_VideoSenseData = 0xb3;
-USHORT SiS300_YCSenseData = 0xb9;
-USHORT SiS300_RGBSenseData2 = 0x0190;     /*301b*/
-USHORT SiS300_VideoSenseData2 = 0x0174;
-USHORT SiS300_YCSenseData2 = 0x016b;
-
-UCHAR SiS300_CR40[5][4];
-UCHAR SiS300_CR49[2];
-UCHAR SiS300_NTSCPhase[]  = {0x21,0xed,0x8a,0x08};
-UCHAR SiS300_PALPhase[]   = {0x2a,0x05,0xd3,0x00};
-UCHAR SiS300_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};  /* 301b */
-UCHAR SiS300_PALPhase2[]  = {0x2a,0x09,0x86,0xe9};  /* 301b */
-UCHAR SiS300_PALMPhase[]  = {0x21,0xE4,0x2E,0x9B};  /* palmn */
-UCHAR SiS300_PALNPhase[]  = {0x21,0xF4,0x3E,0xBA};
-UCHAR SiS300_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/
-UCHAR SiS300_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/
+static const UCHAR SiS300_OutputSelect = 0x40;
+
+static const UCHAR SiS300_SoftSetting  = 0x30;
+
+#ifndef LINUX_XF86
+static UCHAR SiS300_SR07 = 0x10;
+#endif
+
+static const UCHAR  SiS300_SR15[8][4] =
+{
+	{0x01,0x09,0xa3,0x00},
+	{0x43,0x43,0x43,0x00},
+	{0x1e,0x1e,0x1e,0x00},
+	{0x2a,0x2a,0x2a,0x00},
+	{0x06,0x06,0x06,0x00},
+	{0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00}
+};
+
+#ifndef LINUX_XF86
+static UCHAR SiS300_SR1F = 0x00;
+static UCHAR SiS300_SR21 = 0x16;
+static UCHAR SiS300_SR22 = 0xb2;
+static UCHAR SiS300_SR23 = 0xf6;
+static UCHAR SiS300_SR24 = 0x0d;
+static UCHAR SiS300_SR25[] = {0x0,0x0};
+static UCHAR SiS300_SR31 = 0x00;
+static UCHAR SiS300_SR32 = 0x11;
+static UCHAR SiS300_SR33 = 0x00;
+static UCHAR SiS300_CRT2Data_1_2 = 0x40;
+static UCHAR SiS300_CRT2Data_4_D = 0x00;
+static UCHAR SiS300_CRT2Data_4_E = 0x00;
+static UCHAR SiS300_CRT2Data_4_10 = 0x80;
+
+static const USHORT SiS300_RGBSenseData = 0xd1;
+static const USHORT SiS300_VideoSenseData = 0xb3;
+static const USHORT SiS300_YCSenseData = 0xb9;
+static const USHORT SiS300_RGBSenseData2 = 0x0190;     /*301b*/
+static const USHORT SiS300_VideoSenseData2 = 0x0174;
+static const USHORT SiS300_YCSenseData2 = 0x016b;
+
+static const UCHAR SiS300_CR40[5][4];
+
+static UCHAR SiS300_CR49[2];
+#endif
+
+static const UCHAR SiS300_NTSCPhase[]  = {0x21,0xed,0xba,0x08};  /* TW: Was {0x21,0xed,0x8a,0x08}; */
+static const UCHAR SiS300_PALPhase[]   = {0x2a,0x05,0xe3,0x00};  /* TW: Was {0x2a,0x05,0xd3,0x00};  */
+static const UCHAR SiS300_PALMPhase[]  = {0x21,0xE4,0x2E,0x9B};  /* palmn */
+static const UCHAR SiS300_PALNPhase[]  = {0x21,0xF4,0x3E,0xBA};
+static const UCHAR SiS300_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};  /* 301b */
+static const UCHAR SiS300_PALPhase2[]  = {0x2a,0x09,0x86,0xe9};  /* 301b */
+static const UCHAR SiS300_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/
+static const UCHAR SiS300_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/
 
 typedef struct _SiS300_PanelDelayTblStruct
 {
 	UCHAR timer[2];
 } SiS300_PanelDelayTblStruct;
 
-SiS300_PanelDelayTblStruct SiS300_PanelDelayTbl[] =
+static const SiS300_PanelDelayTblStruct  SiS300_PanelDelayTbl[] =
 {
-	{{0x05,0xaa}},
+	{{0x05,0xaa}}, /* TW: From 2.04.5a */
 	{{0x05,0x14}},
 	{{0x05,0x36}},
 	{{0x05,0x14}},
@@ -1052,13 +1220,13 @@
 	{{0x05,0x14}},
 	{{0x05,0x14}},
 	{{0x05,0x14}},
-	{{0x05,0x64}},
+	{{0x20,0x80}},
 	{{0x05,0x14}},
-	{{0x05,0x14}},
-	{{0x05,0x14}} 
+	{{0x05,0x40}},
+	{{0x05,0x60}}
 };
 
-SiS300_PanelDelayTblStruct SiS300_PanelDelayTblLVDS[] =
+static const SiS300_PanelDelayTblStruct  SiS300_PanelDelayTblLVDS[] =
 {
 	{{0x05,0xaa}},
 	{{0x05,0x14}},
@@ -1071,7 +1239,7 @@
 	{{0x05,0x14}},
 	{{0x05,0x14}},
 	{{0x05,0x14}},
-	{{0x05,0x14}},
+	{{0x05,0x14}},  /* 2.07a (JVC): 14,96 */
 	{{0x05,0x28}},  /* 2.04.5c: 20, 80 - Clevo (2.04.2c): 05, 28 */
 	{{0x05,0x14}},
 	{{0x05,0x14}},  /* Some BIOSes: 05, 40 */
@@ -1088,7 +1256,7 @@
 	USHORT LCDVT;
 } SiS300_LCDDataStruct;
 
-SiS300_LCDDataStruct  SiS300_StLCD1024x768Data[]=
+static const SiS300_LCDDataStruct  SiS300_StLCD1024x768Data[] =
 {
 	{   66,  31, 992, 510,1320, 816},
 	{   66,  31, 992, 510,1320, 816},
@@ -1099,7 +1267,7 @@
 	{    1,   1,1344, 806,1344, 806}
 };
 
-SiS300_LCDDataStruct  SiS300_ExtLCD1024x768Data[]=
+static const SiS300_LCDDataStruct  SiS300_ExtLCD1024x768Data[] =
 {
 	{   12,   5, 896, 512,1344, 806},
 	{   12,   5, 896, 510,1344, 806},
@@ -1116,7 +1284,7 @@
 	{    1,   1,1344, 806,1344, 806}
 };
 
-SiS300_LCDDataStruct  SiS300_St2LCD1024x768Data[]=
+static const SiS300_LCDDataStruct  SiS300_St2LCD1024x768Data[] =
 {
 	{   62,  25, 800, 546,1344, 806},
 	{   32,  15, 930, 546,1344, 806},
@@ -1127,7 +1295,7 @@
 	{    1,   1,1344, 806,1344, 806}
 };
 
-SiS300_LCDDataStruct  SiS300_StLCD1280x1024Data[]=
+static const SiS300_LCDDataStruct  SiS300_StLCD1280x1024Data[] =
 {
 	{    4,   1, 880, 510,1650,1088},
 	{    4,   1, 880, 510,1650,1088},
@@ -1139,7 +1307,7 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
-SiS300_LCDDataStruct  SiS300_ExtLCD1280x1024Data[]=
+static const SiS300_LCDDataStruct  SiS300_ExtLCD1280x1024Data[] =
 {
 	{  211,  60,1024, 501,1688,1066},
 	{  211,  60,1024, 508,1688,1066},
@@ -1151,7 +1319,7 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
-SiS300_LCDDataStruct  SiS300_St2LCD1280x1024Data[]=
+static const SiS300_LCDDataStruct  SiS300_St2LCD1280x1024Data[] =
 {
 	{   22,   5, 800, 510,1650,1088},
 	{   22,   5, 800, 510,1650,1088},
@@ -1163,7 +1331,7 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
-SiS300_LCDDataStruct  SiS300_NoScaleData1024x768[]=
+static const SiS300_LCDDataStruct  SiS300_NoScaleData1024x768[] =
 {
 	{    1,   1, 800, 449, 800, 449},
 	{    1,   1, 800, 449, 800, 449},
@@ -1175,7 +1343,7 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
-SiS300_LCDDataStruct  SiS300_NoScaleData1280x1024[]=  /* TW: Fake */
+static const SiS300_LCDDataStruct  SiS300_NoScaleData1280x1024[] =  /* TW: Fake */
 {
 	{    1,   1, 800, 449, 800, 449},
 	{    1,   1, 800, 449, 800, 449},
@@ -1187,7 +1355,7 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
-SiS300_LCDDataStruct  SiS300_LCD1280x960Data[]=
+static const SiS300_LCDDataStruct  SiS300_LCD1280x960Data[] =
 {
 	{    9,   2, 800, 500,1800,1000},
 	{    9,   2, 800, 500,1800,1000},
@@ -1200,6 +1368,91 @@
 	{    1,   1,1800,1000,1800,1000}
 };
 
+static const SiS300_LCDDataStruct  SiS300_ExtLCD1400x1050Data[] =  /* TW: New */
+{
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0}
+};
+
+static const SiS300_LCDDataStruct  SiS300_ExtLCD1600x1200Data[] =  /* TW: New */
+{
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0}
+};
+
+static const SiS300_LCDDataStruct  SiS300_StLCD1400x1050Data[] =  /* TW: New */
+{
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0}
+};
+
+static const SiS300_LCDDataStruct  SiS300_StLCD1600x1200Data[] =  /* TW: New */
+{
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0}
+};
+
+static const SiS300_LCDDataStruct  SiS300_NoScaleData1400x1050[] =  /* TW: New */
+{
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0}
+};
+
+static const SiS300_LCDDataStruct  SiS300_NoScaleData1600x1200[] =  /* TW: New */
+{
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0},
+	{    0,   0,   0,   0,   0,   0}
+};
+
+
 typedef struct _SiS300_TVDataStruct
 {
 	USHORT RVBHCMAX;
@@ -1217,7 +1470,7 @@
 	UCHAR RY4COE;
 } SiS300_TVDataStruct;
 
-SiS300_TVDataStruct  SiS300_StPALData[]=
+static const SiS300_TVDataStruct  SiS300_StPALData[] =
 {
 	{    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
 	{    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
@@ -1227,7 +1480,7 @@
 	{    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
 };
 
-SiS300_TVDataStruct  SiS300_ExtPALData[]=
+static const SiS300_TVDataStruct  SiS300_ExtPALData[] =
 {
 	{   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
 	{  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
@@ -1236,11 +1489,11 @@
 	{    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},
 	{   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},
 	{    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},
-	{    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}     /*301b*/
+	{    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}
 
 };
 
-SiS300_TVDataStruct  SiS300_StNTSCData[]=
+static const SiS300_TVDataStruct  SiS300_StNTSCData[] =
 {
 	{    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
 	{    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
@@ -1249,7 +1502,7 @@
 	{    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
 };
 
-SiS300_TVDataStruct  SiS300_ExtNTSCData[]=
+static const SiS300_TVDataStruct  SiS300_ExtNTSCData[] =
 {
 	{  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
 	{   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
@@ -1258,59 +1511,152 @@
 	{  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
 	{  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
 	{  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},
-	{   65,  64,1056, 791,1270, 480, 638,   0,   0,0xf1,0x04,0x1f,0x18} /*301b*/
+	{   65,  64,1056, 791,1270, 480, 638,   0,   0,0xf1,0x04,0x1f,0x18}
 };
 
-SiS_TVDataStruct  SiS300_St1HiTVData[]=
+#if 0
+static const SiS300_TVDataStruct  SiS300_St1HiTVData[]=
 {
- 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+  
 };
+#endif
 
-SiS_TVDataStruct  SiS300_St2HiTVData[]=
+static const SiS300_TVDataStruct  SiS300_St2HiTVData[]=
 {
- 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
+ {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
+};
+
+static const SiS300_TVDataStruct  SiS300_ExtHiTVData[]=
+{
+ {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},
+ {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
+ {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+ {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},
+ {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
+ {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+ {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}
 };
 
-SiS_TVDataStruct  SiS300_ExtHiTVData[]=
+static const UCHAR SiS300_NTSCTiming[] =
 {
- 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
-};
-
-UCHAR SiS300_NTSCTiming[] = {
 	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
 	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
 	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
-	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
-	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
+	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,  /* (in 2.06.50) */
+/*	0x0c,0x50,0x00,0x99,0x00,0xec,0x4a,0x17,     (in 2.04.5a) */
+	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,  /* (in 2.06.50) */
+/*	0x88,0x00,0x4b,0x00,0x00,0xe2,0x00,0x02,     (in 2.04.5a) */
 	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
 	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
 	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
 };
 
-UCHAR SiS300_PALTiming[] = {
+static const UCHAR SiS300_PALTiming[] =
+{
 	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
 	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
 	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
-	0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
-	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
+        0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,  /* (in 2.06.50) */
+/*	0x70,0x50,0x00,0x97,0x00,0xd7,0x5d,0x17,     (in 2.04.5a) */
+	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,  /* (in 2.06.50) */
+/*	0x88,0x00,0x45,0x00,0x00,0xe8,0x00,0x02,     (in 2.04.5a) */
 	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
 	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
 	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
 };
 
-UCHAR SiS300_HiTVExtTiming[] = {0x00};
-
-UCHAR SiS300_HiTVSt1Timing[] = {0x00};
-
-UCHAR SiS300_HiTVSt2Timing[] = {0x00};
-
-UCHAR SiS300_HiTVTextTiming[] = {0x00};
-
-UCHAR SiS300_HiTVGroup3Data[] = {0x00};
-
-UCHAR SiS300_HiTVGroup3Simu[] = {0x00};
-
-UCHAR SiS300_HiTVGroup3Text[] = {0x00};
+static const UCHAR SiS300_HiTVExtTiming[] =	 /* TW: New */
+{
+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+};
+
+static const UCHAR SiS300_HiTVSt1Timing[] =   	/* TW: New */
+{
+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+	0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
+	0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
+	0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
+	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
+};
+
+static const UCHAR SiS300_HiTVSt2Timing[] =	/* TW: New */
+{
+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+};
+
+static const UCHAR SiS300_HiTVTextTiming[] =   	/* TW: New */
+{
+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+	0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
+	0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
+	0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
+        0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
+	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
+};
+
+static const UCHAR SiS300_HiTVGroup3Data[] =   	/* TW: New */
+{
+        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
+	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
+	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+	0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
+	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+	0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
+	0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
+	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+
+static const UCHAR SiS300_HiTVGroup3Simu[] =   	/* TW: New */
+{
+        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
+	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
+	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+	0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
+	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+	0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
+	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+
+static const UCHAR SiS300_HiTVGroup3Text[] =   	/* TW: New */
+{
+        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
+	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
+	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+	0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
+	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+	0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
+	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
 
 typedef struct _SiS300_LVDSDataStruct
 {
@@ -1320,7 +1666,20 @@
 	USHORT LCDVT;
 } SiS300_LVDSDataStruct;
 
-SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_1[]=
+static const SiS300_LVDSDataStruct  SiS300_LVDS320x480Data_1[] =
+{
+	{848, 433,400, 525},
+	{848, 389,400, 525},
+	{848, 433,400, 525},
+	{848, 389,400, 525},
+	{848, 518,400, 525},
+	{1056,628,400, 525},
+	{400, 525,400, 525},
+	{800, 449,1000, 644},
+	{800, 525,1000, 635}
+};
+
+static const SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_1[] =
 {
 	{848, 433,1060, 629},
 	{848, 389,1060, 629},
@@ -1333,7 +1692,7 @@
 	{800, 525,1000, 635}
 };
 
-SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_2[]=
+static const SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_2[] =
 {
 	{1056, 628,1056, 628},
 	{1056, 628,1056, 628},
@@ -1346,7 +1705,7 @@
 	{800, 525,1000, 635}
 };
 
-SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_1[]=
+static const SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_1[] =
 {
 	{840, 438,1344, 806},
 	{840, 409,1344, 806},
@@ -1359,7 +1718,7 @@
 	{800, 525,1280, 813}
 };
 
-SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_2[]=
+static const SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_2[] =
 {
 	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
@@ -1372,7 +1731,137 @@
 	{800, 525,1280, 813}
 };
 
-SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_1[]=
+static const SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_1[]=  
+{	
+	{1048, 442,1688,1066},
+	{1048, 392,1688,1066},
+	{1048, 442,1688,1066},
+	{1048, 392,1688,1066},
+	{1048, 522,1688,1066},
+	{1208, 642,1688,1066},
+	{1432, 810,1688,1066},
+	{1688,1066,1688,1066}
+};
+
+static const SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_2[]=  
+{	
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066}
+};
+
+static const SiS300_LVDSDataStruct  SiS300_LVDS1400x1050Data_1[] =   
+{
+        {928, 416, 1688, 1066},
+	{928, 366, 1688, 1066},
+	{928, 416, 1688, 1066},
+	{928, 366, 1688, 1066},
+	{928, 496, 1688, 1066},
+	{1088, 616, 1688, 1066},
+	{1312, 784, 1688, 1066},
+	{1568, 1040, 1688, 1066},
+	{1688, 1066, 1688, 1066}
+};
+
+static const SiS300_LVDSDataStruct  SiS300_LVDS1400x1050Data_2[] =  
+{
+        {1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+};
+
+static const SiS300_LVDSDataStruct  SiS300_LVDS1600x1200Data_1[]=  
+{
+        {1088, 450, 2048,1250},
+	{1088, 400, 2048,1250},
+	{1088, 450, 2048,1250},
+	{1088, 400, 2048,1250},
+	{1088, 530, 2048,1250},
+	{1248, 650, 2048,1250},
+	{1472, 818, 2048,1250},
+	{1728,1066, 2048,1250},
+	{1848,1066, 2048,1250},
+	{2048,1250, 2048,1250}
+};
+
+static const SiS300_LVDSDataStruct  SiS300_LVDS1600x1200Data_2[]= 
+{
+        {2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250}
+};
+
+static const SiS300_LVDSDataStruct  SiS300_LVDS1280x768Data_1[]= 
+{	
+	{ 768, 438, 1408, 806},
+	{ 768, 388, 1408, 806},
+	{ 768, 438, 1408, 806},
+	{ 768, 388, 1408, 806},
+	{ 768, 518, 1408, 806},
+	{ 928, 638, 1408, 806},
+	{1152, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806}
+};
+
+static const SiS300_LVDSDataStruct  SiS300_LVDS1280x768Data_2[]=  
+{	
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806}
+};
+
+static const SiS300_LVDSDataStruct  SiS300_LVDS1024x600Data_1[] =
+{
+	{840, 604,1344, 800},
+	{840, 560,1344, 800},
+	{840, 604,1344, 800},
+	{840, 560,1344, 800},
+	{840, 689,1344, 800},
+	{1050, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{800, 449,1280, 789},
+	{800, 525,1280, 785}
+};
+
+static const SiS300_LVDSDataStruct  SiS300_LVDS1024x600Data_2[] =
+{
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{800, 449,1280, 801},
+	{800, 525,1280, 813}
+};
+
+static const SiS300_LVDSDataStruct  SiS300_LVDS1152x768Data_1[] =
 {
 	{840, 438,1344, 806},
 	{840, 409,1344, 806},
@@ -1385,7 +1874,7 @@
 	{800, 525,1280, 813}
 };
 
-SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_2[]=
+static const SiS300_LVDSDataStruct  SiS300_LVDS1152x768Data_2[] =
 {
 	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
@@ -1398,7 +1887,22 @@
 	{800, 525,1280, 813}
 };
 
-SiS300_LVDSDataStruct  SiS300_LVDS640x480Data_1[]=
+/* TW: pass 1:1 data */
+static const SiS300_LVDSDataStruct  SiS300_LVDSXXXxXXXData_1[]=  
+{
+        { 800, 449,  800, 449},
+	{ 800, 449,  800, 449},
+	{ 900, 449,  900, 449},
+	{ 900, 449,  900, 449},
+	{ 800, 525,  800, 525},  /*  640x480   */
+	{1056, 628, 1056, 628},  /*  800x600   */
+	{1344, 806, 1344, 806},  /* 1024x768   */
+	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
+ 	{1688, 806, 1688, 806},  /* 1280x768 ! */
+	/* No other panels ! */
+};
+
+static const SiS300_LVDSDataStruct  SiS300_LVDS640x480Data_1[] =
 {
 	{800, 449, 800, 449},
 	{800, 449, 800, 449},
@@ -1411,22 +1915,20 @@
 	{1056, 628,1056, 628}
 };
 
-/* TW: New: */
-SiS300_LVDSDataStruct  SiS300_LVDS1024x600Data_1[]=
+static const SiS300_LVDSDataStruct  SiS300_LVDS1280x960Data_1[] =   /* TW: New */
 {
-	{840, 604,1344, 800},
-	{840, 560,1344, 800},
-	{840, 604,1344, 800},
-	{840, 560,1344, 800},
-	{840, 689,1344, 800},
-	{1050, 800,1344, 800},
-	{1344, 800,1344, 800},
+	{840, 438,1344, 806},
+	{840, 409,1344, 806},
+	{840, 438,1344, 806},
+	{840, 409,1344, 806},
+	{840, 518,1344, 806},
+	{1050, 638,1344, 806},
+	{1344, 806,1344, 806},
 	{800, 449,1280, 801},
 	{800, 525,1280, 813}
 };
 
-/* TW: New: */
-SiS300_LVDSDataStruct  SiS300_LVDS1024x600Data_2[]=
+static const SiS300_LVDSDataStruct  SiS300_LVDS1280x960Data_2[] =   /* TW: New */
 {
 	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
@@ -1439,36 +1941,64 @@
 	{800, 525,1280, 813}
 };
 
-/* TW: New: */
-SiS300_LVDSDataStruct  SiS300_LVDS1152x768Data_1[]=
-{
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 518,1344, 806},
-	{1050, 638,1344, 806},
+static const SiS300_LVDSDataStruct  SiS300_LCDA1400x1050Data_1[] =   /* TW: New */
+{	/* TW: Might be temporary (invalid) data */
+        {928, 416, 1688, 1066},
+	{928, 366, 1688, 1066},
+	{1008, 416, 1688, 1066},
+	{1008, 366, 1688, 1066},
+	{1200, 530, 1688, 1066},
+	{1088, 616, 1688, 1066},
+	{1312, 784, 1688, 1066},
+	{1568, 1040, 1688, 1066},
+	{1688, 1066, 1688, 1066}
+};
+
+static const SiS300_LVDSDataStruct  SiS300_LCDA1400x1050Data_2[] =   /* TW: New */
+{	/* TW: Temporary data. Not valid */
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
 	{800, 449,1280, 801},
 	{800, 525,1280, 813}
 };
 
-/* TW: New: */
-SiS300_LVDSDataStruct  SiS300_LVDS1152x768Data_2[]=
-{
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 518,1344, 806},
-	{1050, 638,1344, 806},
+static const SiS300_LVDSDataStruct  SiS300_LCDA1600x1200Data_1[] =   /* TW: New */
+{	/* TW: Temporary data. Not valid */
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
 	{800, 449,1280, 801},
 	{800, 525,1280, 813}
 };
 
+static const SiS300_LVDSDataStruct  SiS300_LCDA1600x1200Data_2[] =   /* TW: New */
+{	/* TW: Temporary data. Not valid */
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0}
+};
+
+
 /* TW: New: */
-SiS300_LVDSDataStruct  SiS300_CHTVUNTSCData[]=
+static const SiS300_LVDSDataStruct  SiS300_CHTVUNTSCData[] =
 {
 	{840, 600, 840, 600},
 	{840, 600, 840, 600},
@@ -1478,7 +2008,7 @@
 	{1064, 750,1064, 750}
 };
 
-SiS300_LVDSDataStruct  SiS300_CHTVONTSCData[]=
+static const SiS300_LVDSDataStruct  SiS300_CHTVONTSCData[] =
 {
 	{840, 525, 840, 525},
 	{840, 525, 840, 525},
@@ -1488,7 +2018,7 @@
 	{1040, 700,1040, 700}
 };
 
-SiS300_LVDSDataStruct  SiS300_CHTVUPALData[]=
+static const SiS300_LVDSDataStruct  SiS300_CHTVUPALData[] =
 {
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
@@ -1498,7 +2028,7 @@
 	{936, 836, 936, 836}
 };
 
-SiS300_LVDSDataStruct  SiS300_CHTVOPALData[]=
+static const SiS300_LVDSDataStruct  SiS300_CHTVOPALData[] =
 {
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
@@ -1507,6 +2037,17 @@
 	{840, 625, 840, 625},
 	{960, 750, 960, 750}
 };
+
+static const SiS300_LVDSDataStruct  SiS300_CHTVSOPALData[] =
+{
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{840, 500, 840, 500},
+	{944, 625, 944, 625}
+};
+
 /* TW: new end */
 
 typedef struct _SiS300_LVDSDesStruct
@@ -1515,7 +2056,7 @@
 	USHORT LCDVDES;
 } SiS300_LVDSDesStruct;
 
-SiS300_LVDSDesStruct  SiS300_PanelType00_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType00_1[] =
 {
 	{0, 626},
 	{0, 624},
@@ -1528,7 +2069,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType01_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType01_1[] =
 {
 	{1343, 798},
 	{1343, 794},
@@ -1541,7 +2082,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType02_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType02_1[] =
 {
 	{0, 626},
 	{0, 624},
@@ -1554,7 +2095,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType03_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType03_1[] =
 {
 	{ 8, 436},
 	{ 8, 440},
@@ -1567,7 +2108,7 @@
 	{1343, 794}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType04_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType04_1[] =
 {
 	{1343, 798},
 	{1343, 794},
@@ -1580,7 +2121,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType05_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType05_1[] =
 {
 	{1343, 798},
 	{1343, 794},
@@ -1593,7 +2134,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType06_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType06_1[] =
 {
 	{1343, 798},
 	{1343, 794},
@@ -1606,7 +2147,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType07_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType07_1[] =
 {
 	{1343, 798},
 	{1343, 794},
@@ -1619,7 +2160,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType08_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType08_1[] =
 {
 	{1059, 626},
 	{1059, 624},
@@ -1632,7 +2173,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType09_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType09_1[] =
 {
 	{1343, 798},
 	{1343, 794},
@@ -1645,7 +2186,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType0a_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType0a_1[] =
 {
 	{1059, 626},
 	{1059, 624},
@@ -1658,20 +2199,20 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType0b_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType0b_1[] =
 {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343,   0},
-	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{1343, 0},
+	{1343, 0},
+	{1343, 0},
+	{1343, 0},
+	{1343, 0},   /* 640x480 - BIOS 1343, 0 */
+	{1343, 0},
+	{ 0, 799},
+	{ 0, 0},
+	{ 0, 0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType0c_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType0c_1[] =
 {
 	{1343, 798},
 	{1343, 794},
@@ -1684,7 +2225,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType0d_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType0d_1[] =
 {
 	{1343, 798},
 	{1343, 794},
@@ -1697,7 +2238,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType0e_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType0e_1[] =
 {
 	{1343, 798},
 	{1343, 794},
@@ -1710,7 +2251,7 @@
 	{ 0,   0}     /* 1280x960 - not applicable */
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType0f_1[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType0f_1[] =
 {
 	{1343, 798},
 	{1343, 794},
@@ -1723,7 +2264,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType00_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType00_2[] =
 {
 	{976, 527},
 	{976, 502},
@@ -1736,7 +2277,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType01_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType01_2[] =
 {
 	{1152, 622},
 	{1152, 597},
@@ -1749,7 +2290,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType02_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType02_2[] =
 {
 	{976, 527},
 	{976, 502},
@@ -1762,7 +2303,7 @@
 	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType03_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType03_2[] =
 {
 	{1152, 622},
 	{1152, 597},
@@ -1775,7 +2316,7 @@
 	{1152, 597}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType04_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType04_2[] =
 {
 	{1152, 622},
 	{1152, 597},
@@ -1788,7 +2329,7 @@
 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType05_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType05_2[] =
 {
 	{1152, 622},
 	{1152, 597},
@@ -1801,7 +2342,7 @@
 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType06_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType06_2[] =
 {
 	{1152, 622},
 	{1152, 597},
@@ -1814,7 +2355,7 @@
 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType07_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType07_2[] =
 {
  	{1152, 622},
  	{1152, 597},
@@ -1827,7 +2368,7 @@
 	{   0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType08_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType08_2[] =
 {
  	{976, 527},
  	{976, 502},
@@ -1840,7 +2381,7 @@
  	{  0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType09_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType09_2[] =
 {
  	{1152, 622},
  	{1152, 597},
@@ -1853,7 +2394,7 @@
  	{   0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType0a_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType0a_2[] =
 {
  	{976, 527},
  	{976, 502},
@@ -1866,20 +2407,20 @@
  	{  0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType0b_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType0b_2[] =
 {
- 	{1152, 622},
- 	{1152, 597},
- 	{1152, 622},
- 	{1152, 597},
- 	{1152, 662},
- 	{1232, 722},
- 	{   0, 805},
- 	{   0, 794},
- 	{   0,   0}
+ 	{ 1152, 700},
+ 	{ 1152, 675},
+ 	{ 1152, 700},
+ 	{ 1152, 675},
+ 	{ 1152, 740},
+ 	{ 1232, 799},
+ 	{    0, 799},
+ 	{    0,   0},
+ 	{    0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType0c_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType0c_2[] =
 {
  	{1152, 622},
  	{1152, 597},
@@ -1892,7 +2433,7 @@
  	{   0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType0d_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType0d_2[] =
 {
  	{1152, 622},
  	{1152, 597},
@@ -1905,7 +2446,7 @@
  	{   0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType0e_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType0e_2[] =
 {
  	{1152, 622},
  	{1152, 597},
@@ -1918,7 +2459,7 @@
  	{   0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_PanelType0f_2[]=
+static const SiS300_LVDSDesStruct  SiS300_PanelType0f_2[] =
 {
  	{1152, 622},
  	{1152, 597},
@@ -1931,7 +2472,35 @@
  	{   0,   0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType1076_1[]=   /* TW: New */
+static const SiS300_LVDSDesStruct  SiS300_PanelTypeNS_1[]= 
+{
+	{ 8,   0},
+	{ 8,   0},
+	{ 8,   0},
+	{ 8,   0},
+	{ 8,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0, 806},
+	{ 0, 0 }
+};
+
+static const SiS300_LVDSDesStruct  SiS300_PanelTypeNS_2[] = 
+{
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS300_LVDSDesStruct SiS300_PanelType1076_1[] =   /* TW: New */
 {
 	{ 0 , 0},
 	{ 0 , 0},
@@ -1944,7 +2513,7 @@
 	{ 0 , 0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType1076_2[]=   /* TW: New */
+static const SiS300_LVDSDesStruct SiS300_PanelType1076_2[] =   /* TW: New */
 {
 	{ 1152, 622 },
 	{ 1152, 597 },
@@ -1957,7 +2526,7 @@
 	{    0, 0   }
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType1210_1[]=   /* TW: New */
+static const SiS300_LVDSDesStruct SiS300_PanelType1210_1[] =   /* TW: New */
 {
 	{ 0 , 0},
 	{ 0 , 0},
@@ -1970,7 +2539,7 @@
 	{ 0 , 0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType1210_2[]=   /* TW: New */
+static const SiS300_LVDSDesStruct SiS300_PanelType1210_2[] =   /* TW: New */
 {
 	{ 0 , 0},
 	{ 0 , 0},
@@ -1983,7 +2552,7 @@
 	{ 0 , 0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType1296_1[]=   /* TW: New */
+static const SiS300_LVDSDesStruct SiS300_PanelType1296_1[] =   /* TW: New */
 {
 	{ 0 , 0},
 	{ 0 , 0},
@@ -1996,7 +2565,7 @@
 	{ 0 , 0}
 };
 
-SiS300_LVDSDesStruct SiS300_PanelType1296_2[]=   /* TW: New */
+static const SiS300_LVDSDesStruct SiS300_PanelType1296_2[] =   /* TW: New */
 {
 	{ 0 , 0},
 	{ 0 , 0},
@@ -2011,7 +2580,7 @@
 
 
 /* TW: New */
-SiS300_LVDSDesStruct  SiS300_CHTVUNTSCDesData[]=
+static const SiS300_LVDSDesStruct  SiS300_CHTVUNTSCDesData[] =
 {
  	{ 0,   0},
  	{ 0,   0},
@@ -2021,7 +2590,7 @@
  	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_CHTVONTSCDesData[]=
+static const SiS300_LVDSDesStruct  SiS300_CHTVONTSCDesData[] =
 {
  	{ 0,   0},
  	{ 0,   0},
@@ -2031,7 +2600,7 @@
  	{ 0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_CHTVUPALDesData[]=
+static const SiS300_LVDSDesStruct  SiS300_CHTVUPALDesData[] =
 {
  	{256,   0},
  	{256,   0},
@@ -2041,7 +2610,7 @@
  	{  0,   0}
 };
 
-SiS300_LVDSDesStruct  SiS300_CHTVOPALDesData[]=
+static const SiS300_LVDSDesStruct  SiS300_CHTVOPALDesData[] =
 {
  	{256,   0},
  	{256,   0},
@@ -2052,12 +2621,90 @@
 };
 /* TW: New end */
 
+/* TW: New for SiS300+301LV */
+typedef struct _SiS300_Part2PortTblStruct
+{
+ 	UCHAR CR[12];
+} SiS300_Part2PortTblStruct;
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_1[] =
+{ /* VESA Timing */
+ {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_1[] =
+{	/* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_1[] =
+{	/* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_1[] =
+{	/* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] =
+{  /* Non-VESA */
+ {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x28,0x13,0xe7,0x0b,0xe8,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x38,0x18,0x16,0x00,0x00,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
+ {{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_2[] =
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_2[] =
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_2[] =
+{	/* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_3[] =
+{	/* TW: Temporary data, invalid */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_3[] =
+{	/* TW: Temporary data, invalid */
+  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_3[] =
+{	/* TW: Temporary data, invalid */
+  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
+static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_3[] =
+{	/* TW: Temporary data, invalid */
+  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+};
+
 typedef struct _SiS300_LVDSCRT1DataStruct
 {
 UCHAR CR[15];
 } SiS300_LVDSCRT1DataStruct;
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1[] =
 {
 	{{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
 	  0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -2079,7 +2726,7 @@
 	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1[] =
 { 
 	{{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
 	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
@@ -2101,10 +2748,10 @@
 	  0x01}},
 	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
 	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01} }
+	  0x01}}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1[] =
 {
 	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
 	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
@@ -2129,7 +2776,7 @@
 	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1_H[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1_H[] =
 {
 	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
 	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
@@ -2151,7 +2798,7 @@
 	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[] =
 {
 	{{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
 	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
@@ -2176,7 +2823,7 @@
 	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1_H[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1_H[] =
 {
 	{{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
 	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
@@ -2201,7 +2848,7 @@
 	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2[] =
 {
 	{{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
 	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
@@ -2223,7 +2870,7 @@
 	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2[] =
 {
 	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
@@ -2248,7 +2895,7 @@
 	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2[] =
 {
 	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
@@ -2273,7 +2920,7 @@
 	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2_H[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2_H[] =
 {
 	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
 	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
@@ -2295,7 +2942,7 @@
 	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2_H[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2_H[] =
 {
 	{{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
@@ -2320,7 +2967,7 @@
 	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2_H[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2_H[] =
 {
 	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
@@ -2345,7 +2992,7 @@
 	  0x01}}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_1[] =
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_1[] =
 {
         {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
 	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
@@ -2370,7 +3017,7 @@
 	  0x01}}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_1_H[] =
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_1_H[] =
 {
         {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
 	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
@@ -2395,7 +3042,7 @@
 	  0x01}}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_2[] =
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_2[] =
 {
         {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
@@ -2420,7 +3067,7 @@
 	  0x01}}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_2_H[] =
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_2_H[] =
 {
         {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
@@ -2445,7 +3092,7 @@
 	  0x01}}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_1[] =
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_1[] =
 {
         {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
 	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
@@ -2470,7 +3117,7 @@
 	  0x01}}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_1_H[] =
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_1_H[] =
 {
         {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
 	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
@@ -2495,7 +3142,7 @@
 	  0x01}}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_2[] =
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_2[] =
 {
         {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
@@ -2520,7 +3167,7 @@
 	  0x01}}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_2_H[] =
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_2_H[] =
 {
         {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
@@ -2546,7 +3193,7 @@
 };
 
 /* TW: New */
-SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UNTSC[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UNTSC[] =
 {
 	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
 	  0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
@@ -2568,7 +3215,7 @@
 	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1ONTSC[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1ONTSC[] =
 {
 	{{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
 	  0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
@@ -2590,7 +3237,7 @@
 	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UPAL[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UPAL[] =
 {
 	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
 	  0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -2612,7 +3259,7 @@
 	  0x01 }}
 };
 
-SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1OPAL[]=
+static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1OPAL[] =
 {
 	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
 	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
@@ -2633,6 +3280,28 @@
 	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
 	  0x01 }}
 };
+
+static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1SOPAL[] =
+{
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,  /* TODO */
+	  0x20,0x83,0xdf,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,  /* TODO */
+	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+	  0x01 }}
+};
 /* TW: New end */
 
 /* TW: New */
@@ -2641,7 +3310,8 @@
 	UCHAR Reg[16];
 } SiS300_CHTVRegDataStruct;
 
-SiS300_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] = {
+static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] =
+{
 	{{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
@@ -2650,7 +3320,8 @@
 	{{0x8d,0xc4,0x00,0x3b,0xfb,0,0,0,0,0,0,0,0,0,0,0}}  /* Mode 24: 800x600 NTSC 7/10 */
 };
 
-SiS300_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] = {
+static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] =
+{
 	{{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
@@ -2659,37 +3330,51 @@
 	{{0x8c,0xb4,0x00,0x32,0xf9,0,0,0,0,0,0,0,0,0,0,0}}  /* Mode 23: 800x600 NTSC 3/4 */
 };
 
-SiS300_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] = {
+static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] =
+{
 	{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x63,0x94,0x01,0x50,0x30,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 15: 640x480 PAL 5/6 */
-	/* TW: For 800x600, 3/4 is VERY underscan */
 	{{0x84,0x64,0x01,0x4e,0x2f,0,0,0,0,0,0,0,0,0,0,0}}  /* Mode 21: 800x600 PAL 3/4 */
-	/* TW: Mode 20 is still underscan, use it instead? */
-	/* {{0x83,0x76,0x01,0x40,0x31}} */ /* Mode 20: 800x600 PAL 5/6 */
+
 };
 
-SiS300_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] = {
+static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] =
+{
 	{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
 	{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x61,0x94,0x01,0x36,0x30,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 14: 640x480 PAL 1/1 */
 	{{0x83,0x76,0x01,0x40,0x31,0,0,0,0,0,0,0,0,0,0,0}}  /* Mode 20: 800x600 PAL 5/6 */
-	/* {{0x81,0x12,0x01,0x50,0x34}}  */ /* TW: (test) Mode 19: 800x600 PAL 1/1 */
+
+};
+
+static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_SOPAL[] =
+{
+	{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 5/4 */
+	{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
+	{{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* TW: Mode 13: 640x480 PAL 5/4 */
+	{{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}}  /* TW: Mode 19: 800x600 PAL 1/1 */
 };
 /* TW: New end */
 
 /* TW: New */
-UCHAR SiS300_CHTVVCLKUNTSC[] = {0x29,0x29,0x29,0x29,0x2a,0x2e};
+static const UCHAR SiS300_CHTVVCLKUNTSC[]  = {0x29,0x29,0x29,0x29,0x2a,0x2e};
+
+static const UCHAR SiS300_CHTVVCLKONTSC[]  = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
+
+static const UCHAR SiS300_CHTVVCLKSONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
 
-UCHAR SiS300_CHTVVCLKONTSC[] = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
+static const UCHAR SiS300_CHTVVCLKUPAL[]   = {0x2f,0x2f,0x2f,0x2f,0x2f,0x31};
 
-UCHAR SiS300_CHTVVCLKUPAL[]  = {0x2f,0x2f,0x2f,0x2f,0x2f,0x31};
+static const UCHAR SiS300_CHTVVCLKOPAL[]   = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
 
-UCHAR SiS300_CHTVVCLKOPAL[]  = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
+static const UCHAR SiS300_CHTVVCLKSOPAL[]  = {0x2f,0x2f,0x2f,0x2f,0x36,0x29};
 /* TW: New end */
 
 
diff -Nru a/drivers/video/sis/310vtbl.h b/drivers/video/sis/310vtbl.h
--- a/drivers/video/sis/310vtbl.h	Thu Jul 11 10:30:29 2002
+++ b/drivers/video/sis/310vtbl.h	Fri Mar  7 11:19:00 2003
@@ -1,6 +1,6 @@
 
 
-/* Register settings for SiS 310/325 series */
+/* Register settings for SiS 310/325/330 series */
 
 
 typedef struct _SiS310_StStruct
@@ -15,7 +15,7 @@
 	UCHAR VB_StTVYFilterIndex;
 } SiS310_StStruct;
 
-SiS310_StStruct SiS310_SModeIDTable[]=
+static const SiS310_StStruct SiS310_SModeIDTable[]=
 {
 	{0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00},
 	{0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00},
@@ -52,9 +52,9 @@
 	UCHAR GRC[9];
 } SiS310_StandTableStruct;
 
-SiS310_StandTableStruct SiS310_StandTable[]=
+static const SiS310_StandTableStruct SiS310_StandTable[]=
 {
-/* MD_0_200 */
+/* 0x00: MD_0_200 */
  {
   0x28,0x18,0x08,0x0800,
   {0x09,0x03,0x00,0x02},
@@ -69,7 +69,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff}
  },
-/* MD_1_200 */
+/* 0x01: MD_1_200 */
  {
   0x28,0x18,0x08,0x0800,
   {0x09,0x03,0x00,0x02},
@@ -84,7 +84,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff}
  },
-/* MD_2_200 */
+/* 0x02: MD_2_200 */
  {
   0x50,0x18,0x08,0x1000,
   {0x01,0x03,0x00,0x02},
@@ -99,7 +99,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff}
  },
-/* MD_3_200 */
+/* 0x03: MD_3_200 - mode 0x03 - 0 */
  {
   0x50,0x18,0x08,0x1000,
   {0x01,0x03,0x00,0x02},
@@ -114,7 +114,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff}
  },
-/* MD_4 */
+/* 0x04: MD_4 */
  {
   0x28,0x18,0x08,0x4000,
   {0x09,0x03,0x00,0x02},
@@ -129,7 +129,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
    0xff}
  },
-/* MD_5 */
+/* 0x05: MD_5 */
  {
   0x28,0x18,0x08,0x4000,
   {0x09,0x03,0x00,0x02},
@@ -144,7 +144,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
    0xff}
  },
-/* MD_6 */
+/* 0x06: MD_6 */
  {
   0x50,0x18,0x08,0x4000,
   {0x01,0x01,0x00,0x06},
@@ -159,7 +159,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
    0xff}
  },
-/* MD_7 */
+/* 0x07: MD_7 */
  {
   0x50,0x18,0x0e,0x1000,
   {0x00,0x03,0x00,0x03},
@@ -174,7 +174,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
    0xff}
  },
-/* MDA_DAC */
+/* 0x08: MDA_DAC */
  {
   0x00,0x00,0x00,0x0000,
   {0x00,0x00,0x00,0x15},
@@ -189,7 +189,7 @@
   {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
    0x3f}
  },
-/* CGA_DAC */
+/* 0x09: CGA_DAC */
  {
   0x00,0x10,0x04,0x0114,
   {0x11,0x09,0x15,0x00},
@@ -204,7 +204,7 @@
   {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
    0x3f}
  },
-/* EGA_DAC */
+/* 0x0a: EGA_DAC */
  {
   0x00,0x10,0x04,0x0114,
   {0x11,0x05,0x15,0x20},
@@ -219,7 +219,7 @@
   {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
    0x3f}
  },
-/* VGA_DAC */
+/* 0x0b: VGA_DAC */
  {
   0x00,0x10,0x04,0x0114,
   {0x11,0x09,0x15,0x2a},
@@ -234,6 +234,7 @@
   {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
    0x04}
  },
+/* 0x0c */ 
  {
   0x08,0x0c,0x10,0x0a08,
   {0x0c,0x0e,0x10,0x0b},
@@ -248,7 +249,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}
  },
-/* MD_D */
+/* 0x0d: MD_D */
  {
   0x28,0x18,0x08,0x2000,
   {0x09,0x0f,0x00,0x06},
@@ -263,7 +264,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
    0xff}
  },
-/* MD_E */
+/* 0x0e: MD_E */
  {
   0x50,0x18,0x08,0x4000,
   {0x01,0x0f,0x00,0x06},
@@ -278,7 +279,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
    0xff}
  },
-/* ExtVGATable */
+/* 0x0f: ExtVGATable - modes > 0x13 */
  {
   0x00,0x00,0x00,0x0000,
   {0x01,0x0f,0x00,0x0e},
@@ -293,7 +294,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
    0xff}
  },
-/* ROM_SAVEPTR */
+/* 0x10: ROM_SAVEPTR */
  {
   0x9f,0x3b,0x00,0x00c0,
   {0x00,0x00,0x00,0x00},
@@ -308,7 +309,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}
  },
-/* MD_F */
+/* 0x11: MD_F */
  {
   0x50,0x18,0x0e,0x8000,
   {0x01,0x0f,0x00,0x06},
@@ -323,7 +324,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
    0xff}
  },
-/* MD_10 */
+/* 0x12: MD_10 */
  {
   0x50,0x18,0x0e,0x8000,
   {0x01,0x0f,0x00,0x06},
@@ -338,7 +339,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
    0xff}
  },
-/* MD_0_350 */
+/* 0x13: MD_0_350 */
  {
   0x28,0x18,0x0e,0x0800,
   {0x09,0x03,0x00,0x02},
@@ -353,7 +354,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff}
  },
-/* MD_1_350 */
+/* 0x14: MD_1_350 */
  {
   0x28,0x18,0x0e,0x0800,
   {0x09,0x03,0x00,0x02},
@@ -368,7 +369,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff}
  },
-/* MD_2_350 */
+/* 0x15: MD_2_350 */
  {
   0x50,0x18,0x0e,0x1000,
   {0x01,0x03,0x00,0x02},
@@ -383,7 +384,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff}
  },
-/* MD_3_350 */
+/* 0x16: MD_3_350 - mode 0x03 - 1 */
  {
   0x50,0x18,0x0e,0x1000,
   {0x01,0x03,0x00,0x02},
@@ -398,7 +399,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff}
  },
-/* MD_0_1_400 */
+/* 0x17: MD_0_1_400 */
  {
   0x28,0x18,0x10,0x0800,
   {0x08,0x03,0x00,0x02},
@@ -413,7 +414,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff}
  },
-/* MD_2_3_400 */
+/* 0x18: MD_2_3_400 - mode 0x03 - 2 */
  {
   0x50,0x18,0x10,0x1000,
   {0x00,0x03,0x00,0x02},
@@ -428,7 +429,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
    0xff}
  },
-/* MD_7_400 */
+/* 0x19: MD_7_400 */
  {
   0x50,0x18,0x10,0x1000,
   {0x00,0x03,0x00,0x02},
@@ -443,7 +444,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
    0xff}
  },
-/* MD_11 */
+/* 0x1a: MD_11 */
  {
   0x50,0x1d,0x10,0xa000,
   {0x01,0x0f,0x00,0x06},
@@ -458,7 +459,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
    0xff}
  },
-/* ExtEGATable */
+/* 0x1b: ExtEGATable - Modes <= 0x02 */
  {
   0x50,0x1d,0x10,0xa000,
   {0x01,0x0f,0x00,0x06},
@@ -473,7 +474,7 @@
   {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
    0xff}
  },
-/* MD_13 */
+/* 0x1c: MD_13 */
  {
   0x28,0x18,0x08,0x2000,
   {0x01,0x0f,0x00,0x0e},
@@ -505,7 +506,8 @@
 	UCHAR REFindex;
 } SiS310_ExtStruct;
 
-SiS310_ExtStruct  SiS310_EModeIDTable[]=
+/* TW: Checked with 650/LVDS and 650/301LVx 1.10.6s */
+static const SiS310_ExtStruct  SiS310_EModeIDTable[]=
 {
 	{0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x? */
 	{0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x8 */
@@ -521,14 +523,11 @@
 	{0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x16 */
 	{0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},          /* 720x480x32 */
 	{0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x32 */
-	{0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x00,0x13},          /* 1024x768x? */
-	{0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},          /* 1024x768x8 */
-/*	{0x38,0x021b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},    */    /* 1024x768x8 - 650/LVDS BIOS (no CRt2Mode)  */
+	{0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x? */
+	{0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x8 */
 	{0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x8 */
-/*	{0x3a,0x063b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},    */    /* 1280x1024x8 - 650/LVDS BIOS*/
-	{0x3c,0x063b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x8 */
-/*	{0x3c,0x063b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},    */    /* 1600x1200x8 - 650/LVDS BIOS */
-	{0x3d,0x067d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x16 */
+	{0x3c,0x0e3b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x8 */
+	{0x3d,0x0e7d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x16 - 650/301LVx - no CRT2Mode? */
 	{0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x25},
 	{0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x25},
 	{0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x08},
@@ -536,30 +535,26 @@
 	{0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x00},
 	{0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x16 */
 	{0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
-	{0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},          /* 1024x768x16 */
+	{0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x16 */
 	{0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
 	{0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x16 */
-	{0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26},
-/*	{0x50,0x921b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26},     */   /* 650/LVDS BIOS */
+	{0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26},	   /* 320x240 */
 	{0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27},
-/*	{0x52,0x9a1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},  */
   	{0x52,0xba1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},          /* 650/301 BIOS */
-/*	{0x52,0xb21b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},     */   /* 650/LVDS BIOS (no CRT2Mode) */
 	{0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26},
 	{0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27},
-/*	{0x58,0x9a1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28},  */
  	{0x58,0xba1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28},          /* BIOS (301+LVDS) */
-	{0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25},
-/*	{0x59,0x921b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25},     */   /* 650/LVDS BIOS (no CRT2Mode) */
+	{0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25},	   /* 320x200 */
 	{0x5A,0x021b,0x0014,0x3b83,0x0138,0x08,0x01,0x00,0x00,0x04,0x3f},          /* 320x480x8 fstn add new mode*/
 	{0x5B,0x0a1d,0x0014,0x3b83,0x0135,0x08,0x01,0x00,0x00,0x04,0x3f},          /* 320x480x16 fstn add new mode*/
 	{0x5c,0xba1f,0x0204,0x3a49,0x0000,0x08,0x04,0x00,0x00,0x00,0x28},          /* TW: inserted 512x384x32 */
 	{0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x10},
+	{0x5e,0x0a1f,0x0305,0x3a50,0x0000,0x08,0x05,0x00,0x00,0x07,0x10},          /* TW: Inserted 640x400x32 */
 	{0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x32 */
 	{0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x32 */
-	{0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},          /* 1024x768x32 */
+	{0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x32 */
 	{0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x32 */
-	{0x66,0x06ff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x32 */
+	{0x66,0x0eff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x32 */
 	{0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x8 */
 	{0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x16 */
 	{0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x32 */
@@ -579,14 +574,24 @@
 	{0x7d,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x16 - TW */
 	{0x7e,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x32 - TW */
         /* TW: 650/LVDS BIOS new modes */
-/*	{0x23,0x063b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},  */      /* 1280x768x8 - 650/LVDS BIOS */
 	{0x23,0x0e3b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x8 */
 	{0x24,0x0e7d,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x16 */
 	{0x25,0x0eff,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x32 */
 	{0x26,0x0e3b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x8 */
-/*	{0x26,0x063b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},    */    /* 1400x1050x8 - 650/LVDS BIOS */
 	{0x27,0x0e7d,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x16 */
 	{0x28,0x0eff,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x32*/
+	{0x29,0x0e1b,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},    /* TW: NEW 1152x864 - not in BIOS */
+	{0x2a,0x0e3d,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
+	{0x2b,0x0e7f,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
+	{0x39,0x2a1b,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},    /* TW: NEW 848x480 - not in BIOS */
+	{0x3b,0x2a3d,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
+	{0x3e,0x2a7f,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
+	{0x3f,0x2a1b,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},    /* TW: NEW 856x480 - not in BIOS */
+	{0x42,0x2a3d,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
+	{0x45,0x2a7f,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
+	{0x48,0x2a1b,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},    /* TW: NEW 1360x768 - not in BIOS */
+	{0x4b,0x2a3d,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
+	{0x4e,0x2a7f,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
 	{0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
@@ -602,7 +607,7 @@
 	USHORT ROM_OFFSET;
 } SiS310_Ext2Struct;
 
-SiS310_Ext2Struct SiS310_RefIndex[]=
+static const SiS310_Ext2Struct SiS310_RefIndex[]=
 {
 /*	{0x005f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81},    0x0 - TW: Patch for Chrontel 7019  */
 	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, /* 0x0 */
@@ -610,33 +615,33 @@
 	{0x0067,0x0f,0x08,0x48,0x6a, 800, 600,0x3a8b}, /* 0x2 */
 	{0x0067,0x10,0x07,0x8b,0x6a, 800, 600,0x3a90}, /* 0x3 */
 	{0x0147,0x11,0x0a,0x00,0x6a, 800, 600,0x3a95}, /* 0x4 */
-	{0x4147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 */
-	{0x4047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 */
-	{0x4047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 */
+	{0x0147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 - 4147 TW: Test sync change */
+	{0x0047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 - 4047 */
+	{0x0047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 - 4047 */
 /*	{0xc05f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57},    0x8 - TW: Patch for Chrontel 7019  */
 	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, /* 0x8 */
 	{0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x3a5c}, /* 0x9 */
 	{0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3a61}, /* 0xa */
 	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3a66}, /* 0xb */
-	{0x4047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc */
-	{0x4047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd */
-	{0x4047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe */
+	{0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc - 4047 */
+	{0xc047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd - 4047 */
+	{0xc047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe - 4047 */
 	{0xc047,0x0c,0x15,0x00,0x2e, 640, 480,0x3a7a}, /* 0xf */
 	{0x407f,0x04,0x00,0x00,0x2f, 640, 400,0x3a50}, /* 0x10 */
 	{0xc00f,0x3c,0x01,0x06,0x31, 720, 480,0x3b85}, /* 0x11 */
 	{0x000f,0x3d,0x03,0x06,0x32, 720, 576,0x3b8c}, /* 0x12 */
 	{0x0187,0x15,0x06,0x00,0x37,1024, 768,0x3aab}, /* 0x13 */
-	{0xc877,0x16,0x0b,0x06,0x37,1024, 768,0x3ab0}, /* 0x14 301b TV1024x768*/
+	{0xc877,0x16,0x0b,0x06,0x37,1024, 768,0x3ab0}, /* 0x14 */
 	{0xc067,0x17,0x0f,0x49,0x37,1024, 768,0x3ab5}, /* 0x15 */
 	{0x0267,0x18,0x11,0x00,0x37,1024, 768,0x3aba}, /* 0x16 */
 	{0x0047,0x19,0x16,0x8c,0x37,1024, 768,0x3abf}, /* 0x17 */
-	{0x4047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 */
-	{0x4047,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 */
+	{0x0047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 - 4047 */
+	{0x0007,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 - 4047 */
 	{0x0387,0x1c,0x11,0x00,0x3a,1280,1024,0x3adc}, /* 0x1a */
 	{0x0077,0x1d,0x19,0x07,0x3a,1280,1024,0x3ae1}, /* 0x1b */
 	{0x0047,0x1e,0x1e,0x00,0x3a,1280,1024,0x3ae6}, /* 0x1c */
 	{0x0007,0x1f,0x20,0x00,0x3a,1280,1024,0x3aeb}, /* 0x1d */
-	{0x0007,0x20,0x21,0x00,0x3c,1600,1200,0x3af2}, /* 0x1e */
+	{0x0027,0x20,0x21,0x09,0x3c,1600,1200,0x3af2}, /* 0x1e */
 	{0x0007,0x21,0x22,0x00,0x3c,1600,1200,0x3af7}, /* 0x1f */
 	{0x0007,0x22,0x23,0x00,0x3c,1600,1200,0x3afc}, /* 0x20 */
 	{0x0007,0x23,0x25,0x00,0x3c,1600,1200,0x3b01}, /* 0x21 */
@@ -666,20 +671,29 @@
 	{0x0047,0x37,0x16,0x09,0x71,1024, 576,0x3b6d}, /* 0x39 */
 	{0x0057,0x38,0x19,0x0a,0x75,1280, 720,0x3b74}, /* 0x3a */
 	{0x0047,0x39,0x1e,0x0a,0x75,1280, 720,0x3b79}, /* 0x3b */
-	{0x0047,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */
-	{0x0027,0x3b,0x19,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3d */
-	{0x0027,0x3b,0x19,0x08,0x7c,1280, 960,0x3ad5}, /* 0x3e */
+	{0x0007,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */
+	{0x0067,0x3b,0x19,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3d */
+	{0x0027,0x4c,0x59,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3e */
 	{0xc07f,0x01,0x00,0x06,0x5a, 320, 480,0x3b83}, /* 0x3f */    /* FSTN mode */
-        {0x0077,0x42,0x12,0x07,0x23,1280, 768,0x0000}, /* 0x40 */    /* TW: 650/LVDS new mode */
-	{0x0067,0x43,0x4d,0x08,0x26,1400,1050,0x0000}, /* 0x41 */    /* TW: 650/LVDS new mode */
-	{0xffff,0x00,0x00,0x00,0x00,0000,0000,0x0000}
-};
+        {0x0077,0x42,0x12,0x08,0x23,1280, 768,0x0000}, /* 0x40 */  
+	{0x0067,0x43,0x4d,0x08,0x26,1400,1050,0x0000}, /* 0x41 */  
+	{0x0007,0x4b,0x5a,0x08,0x26,1400,1050,0x0000}, /* 0x42 */    /* TW: new, not in any BIOS */
+	{0x0047,0x44,0x19,0x00,0x29,1152, 864,0x0000}, /* 0x43 TW: Non-BIOS, new */
+	{0x0047,0x4a,0x1e,0x00,0x29,1152, 864,0x0000}, /* 0x44 TW: Non-BIOS, new */
+	{0x00c7,0x45,0x57,0x00,0x39, 848, 480,0x0000}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */
+	{0xc047,0x46,0x55,0x00,0x39, 848, 480,0x0000}, /* 0x46 TW: 848x480-60Hz  - Non-BIOS, new */
+	{0x00c7,0x47,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */
+	{0xc047,0x48,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x48 TW: 856x480-60Hz  - Non-BIOS, new */
+	{0x0047,0x49,0x58,0x00,0x48,1360, 768,0x0000}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */
+	{0xffff,0x00,0x00,0x00,0x00,   0,   0,0x0000}
+}; 
 
 typedef struct _SiS310_CRT1TableStruct
 {
  	UCHAR CR[17];
 } SiS310_CRT1TableStruct;
-SiS310_CRT1TableStruct SiS310_CRT1Table[]=
+
+static const SiS310_CRT1TableStruct SiS310_CRT1Table[]=
 {
  {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
    0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
@@ -696,12 +710,22 @@
  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
    0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
    0x00}}, /* 0x4 */
+#if 0   
  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
    0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
    0x00}}, /* 0x5 */
+#endif   
+ {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e,    /* 0x05 - corrected 640x480-60 */
+   0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
+   0x00}},
+#if 0   
  {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,
    0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
    0x00}}, /* 0x6 */
+#endif
+ {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e,    /* 0x06 - corrected 640x480-72 */
+   0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01,
+   0x00}},
  {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
    0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
    0x00}}, /* 0x7 */
@@ -709,16 +733,16 @@
    0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
    0x00}}, /* 0x8 */
  {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
-   0xe0,0x83,0xdf,0xdf,0xfc,0x00,0x00,0x05,
+   0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,  /* TW: Corrected VBE */
    0x61}}, /* 0x9 */
  {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
    0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
    0x61}}, /* 0xa */
  {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
-   0xe0,0x83,0xdf,0xdf,0x0e,0x10,0x00,0x05,
+   0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05,  /* TW: Corrected VBE */
    0x61}}, /* 0xb */
  {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
-   0xe6,0x8a,0xe5,0xe5,0xfc,0x00,0x00,0x01,
+   0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01,  /* TW: Corrected VDE, VBE */
    0x00}}, /* 0xc */
  {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
    0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
@@ -826,11 +850,11 @@
    0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
    0x44}}, /* 0x2f */
  {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
-  0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
-  0x44}}, /* 0x30 */
+   0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
+   0x44}}, /* 0x30 */
  {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
-  0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
-  0x00}}, /* 0x31 */
+   0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
+   0x00}}, /* 0x31 */
  {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
    0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
    0x01}}, /* 0x32 */
@@ -846,7 +870,7 @@
  {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
    0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
    0x01}}, /* 0x36 */
- {{0xa7,0x7f,0x7f,0x88,0x89,0x15,0x26,0xf1,
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,   /* TW: 95 was 15 - illegal HBE! */
    0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
    0x01}}, /* 0x37 */
  {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
@@ -858,9 +882,14 @@
  {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
    0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
    0x01}}, /* 0x3a */
- {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef,
+#if 0   
+ {{0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef,	/* 1280x960 - invalid */
    0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
    0x01}}, /* 0x3b */
+#endif  
+ {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff,	/* 1280x960-60 - corrected */
+   0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07,
+   0x01}}, /* 0x3b */ 
  {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
    0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
    0x00}}, /* 0x3c */
@@ -873,8 +902,7 @@
  {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,
    0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
    0x00}}, /* 0x3f */
- /* TW: New from 650/LVDS BIOS */
- {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,   /* TW: The following from 650/LVDS BIOS */
    0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
    0x01}},  /* 0x40 */
  {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
@@ -885,16 +913,44 @@
    0x01}},  /* 0x42 */
  {{0xe6,0xae,0xae,0x8a,0xbd,0x90,0x3d,0x10,
    0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x00,0x03,
-   0x00}}   /* 0x43 */
+   0x00}},  /* 0x43 */
+ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* TW: New, 1152x864-75, not in any BIOS */
+   0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
+   0x01}},  /* 0x44 */
+ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 848x480-38i, not in BIOS */
+   0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+   0x00}},  /* 0x45 */
+ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* TW: New, 848x480-60, not in BIOS */
+   0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
+   0x00}},  /* 0x46 */
+ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* TW: New, 856x480-38i, not in BIOS */
+   0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
+   0x00}},  /* 0x47 */
+ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* TW: New, 856x480-60, not in BIOS */
+   0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
+   0x00}},  /* 0x48 */
+ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* TW: New, 1360x768-60, not in BIOS */
+   0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
+   0x01}},  /* 0x49 */
+ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* TW: New, 1152x864-84, not in any BIOS   */
+   0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
+   0x01}},  /* 0x4a */
+ {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, /* TW: New, 1400x1050-75, not in any BIOS  */
+   0x1b,0x87,0x19,0x1a,0x41,0x0f,0x00,0x03,
+   0x00}},  /* 0x4b */ 
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85, not in any BIOS */
+   0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
+   0x01}}   /* 0x4c */
 };
 
+
 typedef struct _SiS310_MCLKDataStruct
 {
 	UCHAR SR28,SR29,SR2A;
 	USHORT CLOCK;
 } SiS310_MCLKDataStruct;
 
-SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] =
+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] =
 {
 	{ 0x3b,0x22,0x01,143},   /* TW: Was { 0x5c,0x23,0x01,166}, */
 	{ 0x5c,0x23,0x01,166},
@@ -906,7 +962,7 @@
 	{ 0x5c,0x23,0x01,166}
 };
 
-SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =	/* @ 0x54 */
+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =	/* @ 0x54 */
 {
 	{ 0x5a,0x64,0x82, 66},
 	{ 0xb3,0x45,0x82, 83},
@@ -918,7 +974,19 @@
 	{ 0x37,0x22,0x82,133}
 };
 
-SiS310_MCLKDataStruct SiS310_MCLKData_1[] =	/* @ 0x155 */
+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =   /* @ 0x54 */
+{
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x79,0x06,0x01,250},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x79,0x06,0x01,250}
+};
+
+static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =	/* @ 0x155 */
 {
         { 0x29,0x21,0x82,150},
 	{ 0x5c,0x23,0x82,166},
@@ -935,7 +1003,8 @@
  	UCHAR SR2E,SR2F,SR30;
  	USHORT CLOCK;
 } SiS310_ECLKDataStruct;
-SiS310_ECLKDataStruct SiS310_ECLKData[]=
+
+static const SiS310_ECLKDataStruct SiS310_ECLKData[]=
 {
 	{ 0x5c,0x23,0x01,166},
 	{ 0x5c,0x23,0x01,166},
@@ -949,7 +1018,7 @@
 	USHORT CLOCK;
 } SiS310_VCLKDataStruct;
 
-SiS310_VCLKDataStruct SiS310_VCLKData[]=
+static const SiS310_VCLKDataStruct SiS310_VCLKData[]=
 {
 	{ 0x1b,0xe1, 25}, /* 0x0 */   /* 650/LVDS BIOS: @ 0x5647 */
 	{ 0x4e,0xe4, 28}, /* 0x1 */
@@ -1016,7 +1085,6 @@
 	{ 0xa8,0x4c, 30}, /* 0x3e */
 	{ 0x20,0x26, 33}, /* 0x3f */
 	{ 0x31,0xc2, 39}, /* 0x40 */
-	/* TW: 650/LVDS BIOS @ 0x574b new: */
 	{ 0x60,0x36, 30}, /* 0x41 */  /* Chrontel */
 	{ 0x40,0x4a, 28}, /* 0x42 */  /* Chrontel */
 	{ 0x9f,0x46, 44}, /* 0x43 */  /* Chrontel */
@@ -1036,7 +1104,13 @@
 	{ 0x54,0x46, 58}, /* 0x51 */  /* Chrontel */
 	{ 0x25,0x42, 61}, /* 0x52 */
 	{ 0x44,0x44, 66}, /* 0x53 */  /* Chrontel */
-	{ 0x3a,0x62, 70}  /* 0x54 */  /* Chrontel */
+	{ 0x3a,0x62, 70}, /* 0x54 */  /* Chrontel */
+	{ 0x62,0xc6, 34}, /* 0x55 - added for 848x480-60 (not in any BIOS) */
+	{ 0x6a,0xc6, 37}, /* 0x56 - added for 848x480-75 (not in any BIOS)    - TEMP */
+	{ 0xbf,0xc8, 35}, /* 0x57 - added for 856x480-38i,60 (not in any BIOS) */
+	{ 0x30,0x23, 88}, /* 0x58 - added for 1360x768-62 (is 60Hz!) (not in any BIOS) */
+	{ 0x52,0x07,149}, /* 0x59 - added for 1280x960-85 (Not in any BIOS) */
+	{ 0x56,0x07,156}  /* 0x5a - added for 1400x1050-75 */
 };
 
 typedef struct _SiS310_VBVCLKDataStruct
@@ -1045,7 +1119,7 @@
 	USHORT CLOCK;
 } SiS310_VBVCLKDataStruct;
 
-SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
+static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
 {
 	{ 0x1b,0xe1, 25}, /* 0x0 */   /* 650/LVDS BIOS: @ 0x579c */
 	{ 0x4e,0xe4, 28}, /* 0x1 */
@@ -1112,19 +1186,40 @@
 	{ 0xa8,0x4c, 30}, /* 0x3e */
 	{ 0x20,0x26, 33}, /* 0x3f */
 	{ 0x31,0xc2, 39}, /* 0x40 */
-	/* TW: 650/LVDS+301 BIOS (@ 0x58a0 in LVDS) new: */
 	{ 0x2e,0x48, 25}, /* 0x41 */
 	{ 0x24,0x46, 25}, /* 0x42 */
 	{ 0x26,0x64, 28}, /* 0x43 */
 	{ 0x37,0x64, 40}, /* 0x44 */
 	{ 0xa1,0x42,108}, /* 0x45 */
 	{ 0x37,0x61,100}, /* 0x46 */
-	{ 0x78,0x27,108}  /* 0x47 */
-	/* --- 0x58bc --- */
-};
-
-UCHAR SiS310_ScreenOffset[]= { 0x14,0x19,0x20,0x28,0x32,0x40,
-                               0x50,0x64,0x78,0x80,0x2d,0x35,0x57};  /* TW: Added 1400x1050 offset */
+	{ 0x78,0x27,108}, /* 0x47 */
+	{ 0x97,0x2c, 26}, /* 0x48 */  /* UNUSED - Entries from here new, not in any BIOS */
+	{ 0xce,0x3c, 39}, /* 0x49 */  /* UNUSED */
+	{ 0x52,0x4a, 36}, /* 0x4a */  /* UNUSED */
+	{ 0x34,0x61, 95}, /* 0x4b */  /* UNUSED */
+	{ 0x78,0x27,108}, /* 0x4c */  /* UNUSED */
+	{ 0x66,0x43,123}, /* 0x4d */  /* 1400x1050-60 */
+	{ 0x41,0x4e, 21}, /* 0x4e */  /* UNUSED */
+	{ 0xa1,0x4a, 29}, /* 0x4f */  /* UNUSED */
+	{ 0x19,0x42, 42}, /* 0x50 */  /* UNUSED */
+	{ 0x54,0x46, 58}, /* 0x51 */  /* UNUSED */
+	{ 0x25,0x42, 61}, /* 0x52 */  /* UNUSED */
+	{ 0x44,0x44, 66}, /* 0x53 */  /* UNUSED */
+	{ 0x3a,0x62, 70}, /* 0x54 */  /* UNUSED */
+	{ 0x62,0xc6, 34}, /* 0x55 */  /* 848x480-60 */
+	{ 0x6a,0xc6, 37}, /* 0x56 */  /* 848x480-75 - TEMP, UNUSED */
+	{ 0xbf,0xc8, 35}, /* 0x57 */  /* 856x480-38i,60  */
+	{ 0x30,0x23, 88}, /* 0x58 */  /* 1360x768-62 (is 60Hz!) TEMP, UNUSED */
+	{ 0x52,0x07,149}, /* 0x59 */  /* 1280x960-85  - UNUSED */
+	{ 0x56,0x07,156}  /* 0x5a */  /* 1400x1050-75 - UNUSED */
+};
+
+static const UCHAR SiS310_ScreenOffset[] = 
+{
+        0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,
+	0x78,0x80,0x2d,0x35,0x57,0x48,0x55,
+	0xff
+};      /* TW: Added 1400x1050, 1152x864, 848/856x480, 1360x768 */
 
 typedef struct _SiS310_StResInfoStruct
 {
@@ -1132,7 +1227,7 @@
 	USHORT VTotal;
 } SiS310_StResInfoStruct;
 
-SiS310_StResInfoStruct SiS310_StResInfo[]=
+static const SiS310_StResInfoStruct SiS310_StResInfo[]=
 {
 	{ 640,400},
 	{ 640,350},
@@ -1149,7 +1244,7 @@
 	UCHAR  YChar;
 } SiS310_ModeResInfoStruct;
 
-SiS310_ModeResInfoStruct SiS310_ModeResInfo[]=
+static const SiS310_ModeResInfoStruct SiS310_ModeResInfo[] =
 {
 	{  320, 200, 8, 8},   /* 0x00 */
 	{  320, 240, 8, 8},   /* 0x01 */
@@ -1170,18 +1265,19 @@
 	{  800, 480, 8,16},   /* 0x10 */
 	{ 1024, 576, 8,16},   /* 0x11 */
 	{ 1280, 720, 8,16},   /* 0x12 */
-	{  856, 480, 8,16},   /* 0x13 19; TW: New from 650/LVDS BIOS */
-	{ 1280, 768, 8,16},   /* 0x14 20; TW: New from 650/LVDS BIOS */
-	{ 1400,1050, 8,16}    /* 0x15 21; TW: New from 650/LVDS BIOS */
+	{  856, 480, 8,16},   /* 0x13 - TW: New, not in any BIOS */
+	{ 1280, 768, 8,16},   /* 0x14 20; TW: New */
+	{ 1400,1050, 8,16},   /* 0x15 21; TW: New */
+	{ 1152, 864, 8,16},   /* 0x16 - TW: New, not in any BIOS */
+	{  848, 480, 8,16},   /* 0x17 - TW: New, not in any BIOS */
+	{ 1360, 768, 8,16}    /* 0x18 - TW: New, not in any BIOS */
 };
 
-UCHAR SiS310_OutputSelect = 0x40;
-
-UCHAR SiS310_SoftSetting  = 0x30;   /* TW: RAM setting */
+static const UCHAR SiS310_OutputSelect = 0x40;
 
-UCHAR SiS310_SR07 = 0x18;
+static const UCHAR SiS310_SoftSetting  = 0x30;   /* TW: RAM setting */
 
-UCHAR SiS310_SR15[8][4]={
+static const UCHAR SiS310_SR15[8][4]={
 	{0x00,0x04,0x60,0x60},
 	{0x0f,0x0f,0x0f,0x0f},
 	{0xba,0xba,0xba,0xba},
@@ -1192,7 +1288,11 @@
 	{0x00,0xa5,0xfb,0xf6}
 };
 
-UCHAR SiS310_CR40[5][4]={
+#ifndef LINUX_XF86
+
+static UCHAR SiS310_SR07 = 0x18;
+
+static const UCHAR SiS310_CR40[5][4]={
 	{0x77,0x77,0x33,0x33},
 	{0x77,0x77,0x33,0x33},
 	{0x00,0x00,0x00,0x00},
@@ -1200,34 +1300,37 @@
 	{0x00,0x00,0xf0,0xf8}
 };
 
-UCHAR SiS310_CR49[] = {0xaa,0x88};
-UCHAR SiS310_SR1F = 0x0;
-UCHAR SiS310_SR21 = 0xa5;
-UCHAR SiS310_SR22 = 0xfb;
-UCHAR SiS310_SR23 = 0xf6;
-UCHAR SiS310_SR24 = 0xd;
-UCHAR SiS310_SR25[] = {0x33,0x3};
-UCHAR SiS310_SR31 = 0x00;
-UCHAR SiS310_SR32 = 0x11;
-UCHAR SiS310_SR33 = 0x00;
-UCHAR SiS310_CRT2Data_1_2 = 0x00;
-UCHAR SiS310_CRT2Data_4_D = 0x00;
-UCHAR SiS310_CRT2Data_4_E = 0x00;
-UCHAR SiS310_CRT2Data_4_10 = 0x80;
-USHORT SiS310_RGBSenseData    = 0xd1;
-USHORT SiS310_VideoSenseData  = 0xb9;
-USHORT SiS310_YCSenseData     = 0xb3;
-USHORT SiS310_RGBSenseData2   = 0x0190;     /*301b*/
-USHORT SiS310_VideoSenseData2 = 0x0174;
-USHORT SiS310_YCSenseData2 = 0x016b;
-UCHAR SiS310_NTSCPhase[]  = {0x21,0xed,0xba,0x08};  /* TW: Was {0x21,0xed,0x8a,0x08}; */
-UCHAR SiS310_PALPhase[]   = {0x2a,0x05,0xe3,0x00};  /* TW: Was {0x2a,0x05,0xd3,0x00}; */
-UCHAR SiS310_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};
-UCHAR SiS310_PALPhase2[]  = {0x2a,0x09,0x86,0xe9};
-UCHAR SiS310_PALMPhase[]  = {0x21,0xE4,0x2E,0x9B}; /* TW: palm*/
-UCHAR SiS310_PALNPhase[]  = {0x21,0xF4,0x3E,0xBA}; /* TW: paln*/
-UCHAR SiS310_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/
-UCHAR SiS310_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/
+static UCHAR SiS310_CR49[] = {0xaa,0x88};
+static UCHAR SiS310_SR1F = 0x00;
+static UCHAR SiS310_SR21 = 0xa5;
+static UCHAR SiS310_SR22 = 0xfb;
+static UCHAR SiS310_SR23 = 0xf6;
+static UCHAR SiS310_SR24 = 0x0d;
+static UCHAR SiS310_SR25[] = {0x33,0x3};
+static UCHAR SiS310_SR31 = 0x00;
+static UCHAR SiS310_SR32 = 0x11;
+static UCHAR SiS310_SR33 = 0x00;
+static UCHAR SiS310_CRT2Data_1_2  = 0x00;
+static UCHAR SiS310_CRT2Data_4_D  = 0x00;
+static UCHAR SiS310_CRT2Data_4_E  = 0x00;
+static UCHAR SiS310_CRT2Data_4_10 = 0x80;
+static const USHORT SiS310_RGBSenseData    = 0xd1;
+static const USHORT SiS310_VideoSenseData  = 0xb9;
+static const USHORT SiS310_YCSenseData     = 0xb3;
+static const USHORT SiS310_RGBSenseData2   = 0x0190; 
+static const USHORT SiS310_VideoSenseData2 = 0x0174;
+static const USHORT SiS310_YCSenseData2    = 0x016b;
+#endif
+
+static const UCHAR SiS310_NTSCPhase[]    = {0x21,0xed,0xba,0x08};  /* TW: Was {0x21,0xed,0x8a,0x08}; */
+static const UCHAR SiS310_PALPhase[]     = {0x2a,0x05,0xe3,0x00};  /* TW: Was {0x2a,0x05,0xd3,0x00}; */
+static const UCHAR SiS310_PALMPhase[]    = {0x21,0xE4,0x2E,0x9B};  /* TW: palm*/
+static const UCHAR SiS310_PALNPhase[]    = {0x21,0xF4,0x3E,0xBA};  /* TW: paln*/
+static const UCHAR SiS310_NTSCPhase2[]   = {0x21,0xF0,0x7B,0xD6};
+static const UCHAR SiS310_PALPhase2[]    = {0x2a,0x09,0x86,0xe9};
+static const UCHAR SiS310_PALMPhase2[]   = {0x21,0xE6,0xEF,0xA4};  /* TW: palm 301b*/
+static const UCHAR SiS310_PALNPhase2[]   = {0x21,0xF6,0x94,0x46};  /* TW: paln 301b*/
+static const UCHAR SiS310_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
 
 typedef struct _SiS310_LCDDataStruct
 {
@@ -1239,7 +1342,7 @@
 	USHORT LCDVT;
 } SiS310_LCDDataStruct;
 
-SiS310_LCDDataStruct  SiS310_StLCD1024x768Data[]=
+static const SiS310_LCDDataStruct  SiS310_StLCD1024x768Data[]=
 {
 	{   62,  25, 800, 546,1344, 806},
 	{   32,  15, 930, 546,1344, 806},
@@ -1250,7 +1353,8 @@
 	{    1,   1,1344, 806,1344, 806}
 };
 
-SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] =   /* TW: Checked */
+#if 0   /* Seems out-dated, all BIOSes since 03/27/2002 have the other version */
+static const SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] = 
 {
 	{   12,   5, 896, 512,1344, 806},
 	{   12,   5, 896, 510,1344, 806},
@@ -1266,20 +1370,38 @@
 	{   42,  25,1024, 625,1344, 806},
 	{    1,   1,1344, 806,1344, 806}
 };
+#endif
+
+static const SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] =   
+{
+	{   42,  25,1536, 419,1344, 806},
+	{   48,  25,1536, 369,1344, 806},
+	{   42,  25,1536, 419,1344, 806},
+	{   48,  25,1536, 369,1344, 806},
+	{   12,   5, 896, 500,1344, 806},
+	{   42,  25,1024, 625,1344, 806},
+	{    1,   1,1344, 806,1344, 806},
+	{   12,   5, 896, 500,1344, 806},
+	{   42,  25,1024, 625,1344, 806},
+	{    1,   1,1344, 806,1344, 806},
+	{   12,   5, 896, 500,1344, 806},
+	{   42,  25,1024, 625,1344, 806},
+	{    1,   1,1344, 806,1344, 806}
+	 
+};
 
-SiS310_LCDDataStruct  SiS310_St2LCD1024x768Data[] =  /* TW: Checked */
+static const SiS310_LCDDataStruct  SiS310_St2LCD1024x768Data[] =  
 {
 	{   62,  25, 800, 546,1344, 806},
 	{   32,  15, 930, 546,1344, 806},
-/*	{   32,  15, 930, 546,1344, 806},   */
-        {   62,  25, 800, 546,1344, 806},    /* TW: Different in 650/301LV BIOS */
+        {   62,  25, 800, 546,1344, 806},    
 	{  104,  45, 945, 496,1344, 806},
 	{   62,  25, 800, 546,1344, 806},
 	{   31,  18,1008, 624,1344, 806},
 	{    1,   1,1344, 806,1344, 806}
 };
 
-SiS310_LCDDataStruct  SiS310_StLCD1280x1024Data[] =
+static const SiS310_LCDDataStruct  SiS310_StLCD1280x1024Data[] =
 {
 	{   22,   5, 800, 510,1650,1088},
 	{   22,   5, 800, 510,1650,1088},
@@ -1291,7 +1413,7 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
-SiS310_LCDDataStruct  SiS310_ExtLCD1280x1024Data[] =  /* TW: Checked */
+static const SiS310_LCDDataStruct  SiS310_ExtLCD1280x1024Data[] = 
 {
 	{  211,  60,1024, 501,1688,1066},
 	{  211,  60,1024, 508,1688,1066},
@@ -1300,10 +1422,11 @@
 	{  211,  60,1024, 500,1688,1066},
 	{  211,  75,1024, 625,1688,1066},
 	{  211, 120,1280, 798,1688,1066},
-	{    1,   1,1688,1066,1688,1066}
+	{    1,   1,1688,1066,1688,1066},
+	{    1,   1,1800,1000,1688,1066}  /* 1280x960 - does not work, use panel scaler instead */
 };
 
-SiS310_LCDDataStruct  SiS310_St2LCD1280x1024Data[] =
+static const SiS310_LCDDataStruct  SiS310_St2LCD1280x1024Data[] =
 {
 	{   22,   5, 800, 510,1650,1088},
 	{   22,   5, 800, 510,1650,1088},
@@ -1315,29 +1438,19 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
-SiS310_LCDDataStruct  SiS310_NoScaleData1024x768[] =  /* TW: Checked */
+static const SiS310_LCDDataStruct  SiS310_NoScaleData1024x768[] =  
 {
         {    1,   1,1344, 806,1344, 806},
 	{    1,   1,1344, 806,1344, 806},
 	{    1,   1,1344, 806,1344, 806},
-	{    1,   1,1344, 806,1344, 806},
-	{    1,   1,1344, 806,1344, 806},
+	{    1,   1,1344, 806,1344, 806},  /* 640x400 - does not work */
+	{    1,   1,1344, 806,1344, 806},  /* 640x480 - does not work */
 	{    1,   1,1344, 806,1344, 806},
 	{    1,   1,1344, 806,1344, 806},
 	{    1,   1,1344, 806,1344, 806}
-#if 0
-	{    1,   1, 800, 449, 800, 449},
-	{    1,   1, 800, 449, 800, 449},
-	{    1,   1, 900, 449, 900, 449},
-	{    1,   1, 900, 449, 900, 449},
-	{    1,   1, 800, 525, 800, 525},
-	{    1,   1,1056, 628,1056, 628},
-	{    1,   1,1344, 806,1344, 806},
-	{    1,   1,1688,1066,1688,1066}
-#endif
 };
 
-SiS310_LCDDataStruct  SiS310_NoScaleData1280x1024[] =  /* TW: New; Checked */
+static const SiS310_LCDDataStruct  SiS310_NoScaleData1280x1024[] =  
 {
         {    1,   1,1688,1066,1688,1066},
 	{    1,   1,1688,1066,1688,1066},
@@ -1346,10 +1459,11 @@
 	{    1,   1,1688,1066,1688,1066},
 	{    1,   1,1688,1066,1688,1066},
 	{    1,   1,1688,1066,1688,1066},
+	{    1,   1,1688,1066,1688,1066},
 	{    1,   1,1688,1066,1688,1066}
 };
 
-SiS310_LCDDataStruct  SiS310_LCD1280x960Data[] =
+static const SiS310_LCDDataStruct  SiS310_LCD1280x960Data[] =
 {
 	{    9,   2, 800, 500,1800,1000},
 	{    9,   2, 800, 500,1800,1000},
@@ -1362,6 +1476,60 @@
 	{    1,   1,1800,1000,1800,1000}
 };
 
+static const SiS310_LCDDataStruct  SiS310_StLCD1400x1050Data[] = 
+{  /* TW: New from 1.11.6s */
+	{ 211,  100, 2100,  408, 1688, 1066 },
+	{ 211,   64, 1536,  358, 1688, 1066 },
+	{ 211,  100, 2100,  408, 1688, 1066 },
+	{ 211,   64, 1536,  358, 1688, 1066 },
+	{ 211,   48,  840,  488, 1688, 1066 },
+	{ 211,   72, 1008,  609, 1688, 1066 },
+	{ 211,  128, 1400,  776, 1688, 1066 },
+	{ 211,  205, 1680, 1041, 1688, 1066 },
+	{   1,    1, 1688, 1066, 1688, 1066 }
+};
+
+static const SiS310_LCDDataStruct  SiS310_ExtLCD1400x1050Data[] = 
+{  /* TW: New from 1.11.6s */
+	{ 211,  100, 2100,  408, 1688, 1066 },
+	{ 211,   64, 1536,  358, 1688, 1066 },
+	{ 211,  100, 2100,  408, 1688, 1066 },
+	{ 211,   64, 1536,  358, 1688, 1066 },
+	{ 211,   48,  840,  488, 1688, 1066 },
+	{ 211,   72, 1008,  609, 1688, 1066 },
+	{ 211,  128, 1400,  776, 1688, 1066 },
+	{ 211,  205, 1680, 1041, 1688, 1066 },
+	{   1,    1, 1688, 1066, 1688, 1066 }
+};
+
+static const SiS310_LCDDataStruct  SiS310_NoScaleData1400x1050[] = 
+{  /* TW: To be checked (BIOS uses 1280x1024 data, one line too short) */
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 }
+};
+
+static const SiS310_LCDDataStruct  SiS310_StLCD1600x1200Data[] = 
+{  /* TODO */
+	{    0,   0,   0,   0,   0,   0}
+};
+
+static const SiS310_LCDDataStruct  SiS310_ExtLCD1600x1200Data[] = 
+{  /* TODO */
+	{    0,   0,   0,   0,   0,   0}
+};
+
+static const SiS310_LCDDataStruct  SiS310_NoScaleData1600x1200[] = 
+{  /* TODO */
+	{    0,   0,   0,   0,   0,   0}
+};
+
 typedef struct _SiS310_TVDataStruct
 {
 	USHORT RVBHCMAX;
@@ -1379,7 +1547,7 @@
 	UCHAR RY4COE;
 } SiS310_TVDataStruct;
 
-SiS310_TVDataStruct  SiS310_StPALData[]=
+static const SiS310_TVDataStruct  SiS310_StPALData[]=
 {
  {    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
  {    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
@@ -1389,19 +1557,19 @@
  {    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
 };
 
-SiS310_TVDataStruct  SiS310_ExtPALData[]=
+static const SiS310_TVDataStruct  SiS310_ExtPALData[] =   
 {
  {   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
  {  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
  {   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
  {    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
- {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},
- {   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},
- {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},
- {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}     /*301b*/
+ {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},  /* 640x480 */
+ {   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},  /* 800x600 */
+ {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},  /* 720x480/576 */
+ {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}   /* 1024x768 */
 };
 
-SiS310_TVDataStruct  SiS310_StNTSCData[]=
+static const SiS310_TVDataStruct  SiS310_StNTSCData[]=
 {
  {    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
  {    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
@@ -1410,35 +1578,51 @@
  {    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
 };
 
-SiS310_TVDataStruct  SiS310_ExtNTSCData[]=
+static const SiS310_TVDataStruct  SiS310_ExtNTSCData[]=
 {
  {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
  {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
  {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
  {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
- {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
- {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
- {    2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},
- {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08} /*301b*/     
-};
-
-/* TW: These tables will need data ! */
-SiS310_TVDataStruct  SiS310_St1HiTVData[]=
-{
-   	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+ {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},  /* 640x480 */
+ {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},  /* 800x600  */
+ {    2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},  /* 720x480/576 */
+ {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08}   /* 1024x768 */
 };
 
-SiS310_TVDataStruct  SiS310_St2HiTVData[]=
+#if 0
+static const SiS310_TVDataStruct  SiS310_St1HiTVData[]=
 {
-	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+  
 };
+#endif
 
-SiS310_TVDataStruct  SiS310_ExtHiTVData[]=
+static const SiS310_TVDataStruct  SiS310_St2HiTVData[]=
 {
-	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
+ {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
+};
+
+static const SiS310_TVDataStruct  SiS310_ExtHiTVData[]=
+{
+ {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},
+ {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
+ {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+ {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},
+ {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
+ {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+ {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}
 };
 
-UCHAR SiS310_NTSCTiming[] = {   /* TW: New */
+static const UCHAR SiS310_NTSCTiming[] = { 
 	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
 	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
 	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
@@ -1449,7 +1633,7 @@
 	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
 };
 
-UCHAR SiS310_PALTiming[] = {   /* TW: New */
+static const UCHAR SiS310_PALTiming[] = {  
 	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
 	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
 	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
@@ -1460,7 +1644,7 @@
 	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
 };
 
-UCHAR SiS310_HiTVExtTiming[] = {   /* TW: New */
+static const UCHAR SiS310_HiTVExtTiming[] = {  
         0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
 	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
 	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
@@ -1471,7 +1655,7 @@
 	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
 };
 
-UCHAR SiS310_HiTVSt1Timing[] = {   /* TW: New */
+static const UCHAR SiS310_HiTVSt1Timing[] = {  
         0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
 	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
 	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
@@ -1482,7 +1666,7 @@
 	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
 };
 
-UCHAR SiS310_HiTVSt2Timing[] = {   /* TW: New */
+static const UCHAR SiS310_HiTVSt2Timing[] = {  
         0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
 	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
 	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
@@ -1493,7 +1677,7 @@
 	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
 };
 
-UCHAR SiS310_HiTVTextTiming[] = {   /* TW: New */
+static const UCHAR SiS310_HiTVTextTiming[] = {  
         0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
 	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
 	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
@@ -1504,7 +1688,7 @@
 	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
 };
 
-UCHAR SiS310_HiTVGroup3Data[] = {   /* TW: New */
+static const UCHAR SiS310_HiTVGroup3Data[] = {  
         0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
 	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
 	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
@@ -1515,7 +1699,7 @@
 	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
 };
 
-UCHAR SiS310_HiTVGroup3Simu[] = {   /* TW: New */
+static const UCHAR SiS310_HiTVGroup3Simu[] = {  
         0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
 	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
 	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
@@ -1526,7 +1710,7 @@
 	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
 };
 
-UCHAR SiS310_HiTVGroup3Text[] = {   /* TW: New */
+static const UCHAR SiS310_HiTVGroup3Text[] = {  
         0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
 	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
 	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
@@ -1542,9 +1726,26 @@
  	UCHAR timer[2];
 } SiS310_PanelDelayTblStruct;
 
-SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=  /* TW: New from 650/301LV BIOS */
+static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=  
 {
-	{{0x28,0xc8}},
+        {{0x10,0x40}},		/* TW: from 650/301LVx 1.10.6s BIOS */
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}},
+	{{0x10,0x40}}
+#if 0
+	{{0x28,0xc8}},		/* TW: from 650/301LV BIOS */
 	{{0x28,0xc8}},
 	{{0x28,0xc8}},
 	{{0x28,0xc8}},
@@ -1560,9 +1761,10 @@
 	{{0x28,0xc8}},
 	{{0x28,0xc8}},
 	{{0x28,0xc8}}
+#endif
 };
 
-SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=  
+static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
 {
 	{{0x28,0xc8}},
 	{{0x28,0xc8}},
@@ -1590,33 +1792,33 @@
 	USHORT LCDVT;
 } SiS310_LVDSDataStruct;
 
-SiS310_LVDSDataStruct  SiS310_LVDS320x480Data_1[]=
+static const SiS310_LVDSDataStruct  SiS310_LVDS320x480Data_1[]=
 {
-	{848, 433,400,525},
-	{848, 389,400,525},
-	{848, 433,400,525},
-	{848, 389,400,525},
-	{848, 518,400, 525},
-	{1056, 628,400,525},
-	{400, 525,400,525},
-	{800, 449,1000, 644},
-	{800, 525,1000, 635}
-};
-
-SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_1[]=   /* TW: New */
-{
-	{848, 433,1060, 629},
-	{848, 389,1060, 629},
-	{848, 433,1060, 629},
-	{848, 389,1060, 629},
-	{848, 518,1060, 629},
+	{ 848, 433, 400, 525},
+	{ 848, 389, 400, 525},
+	{ 848, 433, 400, 525},
+	{ 848, 389, 400, 525},
+	{ 848, 518, 400, 525},
+	{1056, 628, 400, 525},
+	{ 400, 525, 400, 525},
+	{ 800, 449,1000, 644},
+	{ 800, 525,1000, 635}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_1[]= 
+{
+	{ 848, 433,1060, 629},
+	{ 848, 389,1060, 629},
+	{ 848, 433,1060, 629},
+	{ 848, 389,1060, 629},
+	{ 848, 518,1060, 629},
 	{1056, 628,1056, 628},
 	{1056, 628,1056, 628},
-	{800, 449,1000, 644},
-	{800, 525,1000, 635}
+	{ 800, 449,1000, 644},
+	{ 800, 525,1000, 635}
 };
 
-SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_2[]=   /* TW: New */
+static const SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_2[]=  
 {
 	{1056, 628,1056, 628},
 	{1056, 628,1056, 628},
@@ -1625,24 +1827,24 @@
 	{1056, 628,1056, 628},
 	{1056, 628,1056, 628},
 	{1056, 628,1056, 628},
-	{800, 449,1000, 644},
-	{800, 525,1000, 635}
+	{ 800, 449,1000, 644},
+	{ 800, 525,1000, 635}
 };
 
-SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_1[]=   /* TW: New */
+static const SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_1[]=  
 {
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 518,1344, 806},    /* 640x480 */
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 518,1344, 806},   /* 640x480 */
 	{1050, 638,1344, 806},   /* 800x600 */
 	{1344, 806,1344, 806},   /* 1024x768 */
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
 };
 
-SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_2[]=   /* TW: New */
+static const SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_2[]= 
 {
 	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
@@ -1651,50 +1853,48 @@
 	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
 };
 
-SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_1[]=   /* TW: New */
-{
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 518,1344, 806},
-	{1050, 638,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_2[]=   /* TW: New */
-{
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_1[]=   /* TW: New */
-{
-        {928, 416, 1688, 1066},
-	{928, 366, 1688, 1066},
-	{928, 416, 1688, 1066},
-	{928, 366, 1688, 1066},
-	{928, 496, 1688, 1066},
-	{1088, 616, 1688, 1066},
-	{1312, 784, 1688, 1066},
-	{1568, 1040, 1688, 1066},
-	{1688, 1066, 1688, 1066}
+static const SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_1[]=  
+{	
+	{1048, 442,1688,1066},
+	{1048, 392,1688,1066},
+	{1048, 442,1688,1066},
+	{1048, 392,1688,1066},
+	{1048, 522,1688,1066},
+	{1208, 642,1688,1066},
+	{1432, 810,1688,1066},
+	{1688,1066,1688,1066}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_2[]=  
+{	
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_1[]=  
+{
+        { 928, 416, 1688,1066},
+	{ 928, 366, 1688,1066},
+	{ 928, 416, 1688,1066},
+	{ 928, 366, 1688,1066},
+	{ 928, 496, 1688,1066},
+	{1088, 616, 1688,1066},
+	{1312, 784, 1688,1066},
+	{1568,1040, 1688,1066},
+	{1688,1066, 1688,1066}
 };
 
-SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_2[]=   /* TW: New */
+static const SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_2[]= 
 {
         {1688,1066, 1688,1066},
 	{1688,1066, 1688,1066},
@@ -1707,22 +1907,154 @@
 	{1688,1066, 1688,1066},
 };
 
-/* TW: New: - from 300 series */
-SiS310_LVDSDataStruct  SiS310_LVDS1024x600Data_1[]=
+static const SiS310_LVDSDataStruct  SiS310_LVDS1600x1200Data_1[]=  
 {
-	{840, 604,1344, 800},
-	{840, 560,1344, 800},
-	{840, 604,1344, 800},
-	{840, 560,1344, 800},
-	{840, 689,1344, 800},
-	{1050, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
+        {1088, 450, 2048,1250},
+	{1088, 400, 2048,1250},
+	{1088, 450, 2048,1250},
+	{1088, 400, 2048,1250},
+	{1088, 530, 2048,1250},
+	{1248, 650, 2048,1250},
+	{1472, 818, 2048,1250},
+	{1728,1066, 2048,1250},
+	{1848,1066, 2048,1250},
+	{2048,1250, 2048,1250}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_LVDS1600x1200Data_2[]= 
+{
+        {2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_LVDS1280x768Data_1[]= 
+{	
+	{ 768, 438, 1408, 806},
+	{ 768, 388, 1408, 806},
+	{ 768, 438, 1408, 806},
+	{ 768, 388, 1408, 806},
+	{ 768, 518, 1408, 806},
+	{ 928, 638, 1408, 806},
+	{1152, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_LVDS1280x768Data_2[]=  
+{	
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_LVDS1024x600Data_1[]=
+{
+	{ 840, 604, 1344, 800},
+	{ 840, 560, 1344, 800},
+	{ 840, 604, 1344, 800},
+	{ 840, 560, 1344, 800},
+	{ 840, 689, 1344, 800},
+	{1050, 800, 1344, 800},
+	{1344, 800, 1344, 800},
+	{ 800, 449, 1280, 801},
+	{ 800, 525, 1280, 813}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_LVDS1024x600Data_2[]=
+{
+	{1344, 800, 1344, 800},
+	{1344, 800, 1344, 800},
+	{1344, 800, 1344, 800},
+	{1344, 800, 1344, 800},
+	{1344, 800, 1344, 800},
+	{1344, 800, 1344, 800},
+	{1344, 800, 1344, 800},
+	{ 800, 449, 1280, 801},
+	{ 800, 525, 1280, 813}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_LVDS1152x768Data_1[]=
+{
+	{ 840, 438, 1344, 806},
+	{ 840, 409, 1344, 806},
+	{ 840, 438, 1344, 806},
+	{ 840, 409, 1344, 806},
+	{ 840, 518, 1344, 806},
+	{1050, 638, 1344, 806},
+	{1344, 806, 1344, 806},
+	{ 800, 449, 1280, 801},
+	{ 800, 525, 1280, 813}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_LVDS1152x768Data_2[]=
+{
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{ 800, 449, 1280, 801},
+	{ 800, 525, 1280, 813}
+};
+
+/* TW: Pass 1:1 data */
+static const SiS310_LVDSDataStruct  SiS310_LVDSXXXxXXXData_1[]=  
+{
+        { 800, 449,  800, 449},
+	{ 800, 449,  800, 449},
+	{ 900, 449,  900, 449},
+	{ 900, 449,  900, 449},
+	{ 800, 525,  800, 525},  /*  640x480   */
+	{1056, 628, 1056, 628},  /*  800x600   */
+	{1344, 806, 1344, 806},  /* 1024x768   */
+	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
+ 	{1688, 806, 1688, 806},  /* 1280x768 ! */
+	/* No other panels ! */
 };
 
-/* TW: New: - from 300 series */
-SiS310_LVDSDataStruct  SiS310_LVDS1024x600Data_2[]=
+static const SiS310_LVDSDataStruct  SiS310_LVDS640x480Data_1[]=  
+{
+	{ 800, 449, 800, 449},
+	{ 800, 449, 800, 449},
+	{ 800, 449, 800, 449},
+	{ 800, 449, 800, 449},
+	{ 800, 525, 800, 525},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_LVDS1280x960Data_1[]=   
+{
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 518,1344, 806},
+	{1050, 638,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_LVDS1280x960Data_2[]=  
 {
 	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
@@ -1731,91 +2063,114 @@
 	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
 };
 
-/* TW: New: - from 300 series */
-SiS310_LVDSDataStruct  SiS310_LVDS1152x768Data_1[]=
-{
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 518,1344, 806},
-	{1050, 638,1344, 806},
+/* LCDA */
+
+static const SiS310_LVDSDataStruct  SiS310_LCDA1400x1050Data_1[]=   
+{	/* TW: Might be temporary (invalid) data */
+        { 928, 416, 1688,1066},
+	{ 928, 366, 1688,1066},
+	{1008, 416, 1688,1066},
+	{1008, 366, 1688,1066},
+	{1200, 530, 1688,1066},
+	{1088, 616, 1688,1066},
+	{1312, 784, 1688,1066},
+	{1568,1040, 1688,1066},
+	{1688,1066, 1688,1066}
+};
+
+static const SiS310_LVDSDataStruct  SiS310_LCDA1400x1050Data_2[]=   
+{	/* TW: Temporary data. Not valid */
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
 };
 
-/* TW: New: - from 300 series */
-SiS310_LVDSDataStruct  SiS310_LVDS1152x768Data_2[]=
-{
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 518,1344, 806},
-	{1050, 638,1344, 806},
+static const SiS310_LVDSDataStruct  SiS310_LCDA1600x1200Data_1[]=  
+{	/* TW: Temporary data. Not valid */
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
 	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
 };
 
-/* TW: New in 650/LVDS BIOS - resolution unknown */
-SiS310_LVDSDataStruct  SiS310_LVDSXXXxXXXData_1[]=   /* TW: New */
+static const SiS310_LVDSDataStruct  SiS310_LCDA1600x1200Data_2[]=  
+{	/* TW: Temporary data. Not valid */
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0},
+	{0, 0, 0, 0}
+};
+
+/* Chrontel TV */
+
+static const SiS310_LVDSDataStruct  SiS310_CHTVUNTSCData[]=   
 {
-        { 800, 449, 800, 449},
-	{ 800, 449, 800, 449},
-	{ 900, 449, 900, 449},
-	{ 900, 449, 900, 449},
-	{ 800, 525, 800, 525},
-	{1056, 628,1056, 628},
-	{1344, 806,1344, 806},
-	{1688, 806,1688, 806}
+	{ 840, 600, 840, 600},
+	{ 840, 600, 840, 600},
+	{ 840, 600, 840, 600},
+	{ 840, 600, 840, 600},
+	{ 784, 600, 784, 600},
+	{1064, 750,1064, 750},
+        {1160, 945,1160, 945}           /* TW: For Ch7019 1024 */
 };
 
-SiS310_LVDSDataStruct  SiS310_LVDS640x480Data_1[]=   /* TW: New */
+static const SiS310_LVDSDataStruct  SiS310_CHTVONTSCData[]=   
 {
-	{800, 449, 800, 449},
-	{800, 449, 800, 449},
-	{800, 449, 800, 449},
-	{800, 449, 800, 449},
-	{800, 525, 800, 525},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628}
+	{ 840, 525, 840, 525},
+	{ 840, 525, 840, 525},
+	{ 840, 525, 840, 525},
+	{ 840, 525, 840, 525},
+	{ 784, 525, 784, 525},
+	{1040, 700,1040, 700},
+        {1160, 840,1160, 840}          	/* TW: For Ch7019 1024 */
 };
 
-SiS310_LVDSDataStruct  SiS310_LVDS1280x960Data_1[]=   /* TW: New */
+static const SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=   
 {
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 518,1344, 806},
-	{1050, 638,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{ 840, 625, 840, 625},
+	{ 960, 750, 960, 750},
+	{1400,1000,1400,1000}   	/*  TW: For Ch7019 1024 */
 };
 
-SiS310_LVDSDataStruct  SiS310_LVDS1280x960Data_2[]=   /* TW: New */
+static const SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]= 
 {
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{ 840, 625, 840, 625},
+	{ 944, 625, 944, 625},
+        {1400, 875,1400, 875}       	/*  TW: For Ch7019 1024 */
 };
 
-SiS310_LVDSDataStruct  SiS310_CHTVUNTSCData[]=   /* TW: New */
+static const SiS310_LVDSDataStruct  SiS310_CHTVUPALMData[]=  
 {
 	{ 840, 600, 840, 600},
 	{ 840, 600, 840, 600},
@@ -1826,7 +2181,7 @@
         {1160, 945,1160, 945}           /* TW: For Ch7019 1024 */
 };
 
-SiS310_LVDSDataStruct  SiS310_CHTVONTSCData[]=   /* TW: New */
+static const SiS310_LVDSDataStruct  SiS310_CHTVOPALMData[]=  
 {
 	{ 840, 525, 840, 525},
 	{ 840, 525, 840, 525},
@@ -1837,7 +2192,7 @@
         {1160, 840,1160, 840}          	/* TW: For Ch7019 1024 */
 };
 
-SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=   /* TW: New */
+static const SiS310_LVDSDataStruct  SiS310_CHTVUPALNData[]=  
 {
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
@@ -1848,7 +2203,7 @@
 	{1400,1000,1400,1000}   	/*  TW: For Ch7019 1024 */
 };
 
-SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]=   /* TW: New */
+static const SiS310_LVDSDataStruct  SiS310_CHTVOPALNData[]= 
 {
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
@@ -1859,15 +2214,24 @@
         {1400, 875,1400, 875}       	/*  TW: For Ch7019 1024 */
 };
 
+static const SiS310_LVDSDataStruct  SiS310_CHTVSOPALData[]=   /* TW: (super overscan - no effect on 7019) */
+{
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{1008, 625,1008, 625},
+	{ 840, 625, 840, 625},
+	{ 944, 625, 944, 625},
+        {1400, 875,1400, 875}       	
+};
+
 typedef struct _SiS310_LVDSDesStruct
 {
 	USHORT LCDHDES;
 	USHORT LCDVDES;
 } SiS310_LVDSDesStruct;
 
-/* TW: PanelType arrays taken from 650/LVDS BIOS 1.10.0 */
-
-SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=  
 {
 	{ 0, 0},
 	{ 0, 0},
@@ -1880,7 +2244,7 @@
 	{ 0, 0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=   
 {
 	{ 0, 0},
 	{ 0, 0},
@@ -1893,7 +2257,7 @@
 	{ 0, 0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=  
 {
 	{ 0, 0},
 	{ 0, 0},
@@ -1908,7 +2272,7 @@
 };
 
 
-SiS310_LVDSDesStruct  SiS310_PanelType03_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType03_1[]= 
 {
 	{ 0, 0},
 	{ 0, 0},
@@ -1921,7 +2285,7 @@
 	{ 0, 0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType04_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType04_1[]=  
 {
 	{1343, 798},
 	{1343, 794},
@@ -1934,7 +2298,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType05_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType05_1[]= 
 {
 	{1343, 798},
 	{1343, 794},
@@ -1947,7 +2311,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType06_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType06_1[]=  
 {
 	{1343, 798},
 	{1343, 794},
@@ -1960,7 +2324,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType07_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType07_1[]= 
 {
 	{1343, 798},
 	{1343, 794},
@@ -1973,7 +2337,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType08_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType08_1[]=   /* 1400x1050 */
 {
 	{ 0, 0},
 	{ 0, 0},
@@ -1988,32 +2352,37 @@
 	{ 0, 0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType09_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType09_1[]=   /* 1280x768 */
 {
-	{ 0, 448},
-	{ 0, 448},
-	{ 0, 448},
-	{ 0, 448},
-	{ 0, 524},
-	{ 0, 627},
-	{ 0, 805},
-	{ 0, 805},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType0a_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType0a_1[]=  /* 1600x1200 */
 {
-	{1059, 626},
-	{1059, 624},
-	{1059, 626},
-	{1059, 624},
-	{1059, 624},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0},
+	{ 0, 0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]= 
 {
 	{1343, 798},
 	{1343, 794},
@@ -2026,7 +2395,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=  
 {
 	{1343, 798},
 	{1343, 794},
@@ -2039,7 +2408,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]= 
 {
 	{1343, 798},
 	{1343, 794},
@@ -2052,7 +2421,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType0e_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType0e_1[]=  
 {
 	{1343, 798},
 	{1343, 794},
@@ -2065,7 +2434,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType0f_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType0f_1[]=  
 {
 	{1343, 798},
 	{1343, 794},
@@ -2078,7 +2447,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType00_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType00_2[]=  
 {
 	{980, 528},
 	{980, 503},
@@ -2091,7 +2460,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType01_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType01_2[]= 
 {
 	{1152, 622},
 	{1152, 597},
@@ -2104,7 +2473,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType02_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType02_2[]= 
 {
 	{1368, 754},
 	{1368, 729},
@@ -2119,7 +2488,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType03_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType03_2[]=  
 {
 	{ 0,   0},
 	{ 0,   0},
@@ -2130,7 +2499,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType04_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType04_2[]=  
 {
 	{ 0,   0},
 	{ 0,   0},
@@ -2143,7 +2512,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType05_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType05_2[]=  
 {
 	{1152, 622},
 	{1152, 597},
@@ -2156,7 +2525,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType06_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType06_2[]=  
 {
 	{1152, 622},
 	{1152, 597},
@@ -2169,7 +2538,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType07_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType07_2[]=  
 {
 	{1152, 622},
 	{1152, 597},
@@ -2182,8 +2551,20 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType08_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType08_2[]=  /* 1400x1050 */
 {
+	{1308, 741},
+	{1308, 716},
+	{1308, 741},
+	{1308, 716},
+	{1308, 781},
+	{1388, 841},
+	{1500, 925},
+	{1628,1053},
+	{   0,1065},
+	{   0,   0},
+	{   0,   0}
+#if 0
 	{976, 527},
 	{976, 502},
 	{976, 527},
@@ -2193,34 +2574,37 @@
 	{ 0, 627},
 	{ 0,   0},
 	{ 0,   0}
+#endif	
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType09_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType09_2[]= /* 1280x768 */
 {
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0}
+	{1083, 622},
+	{1083, 597},
+	{1083, 622},
+	{1083, 597},
+	{1083, 662},
+	{1163, 722},
+	{1286, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType0a_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType0a_2[]=  /* 1600x1200 */
 {
-	{976, 527},
-	{976, 502},
-	{976, 527},
-	{976, 502},
-	{976, 567},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{1568, 850},
+	{1568, 825},
+	{1568, 850},
+	{1568, 825},
+	{1568, 890},
+	{1648, 950},
+	{1760,1034},
+	{1888,1162},
+	{1948,1175},
+	{   0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=  
 {
 	{1152, 622},
 	{1152, 597},
@@ -2233,7 +2617,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]= 
 {
 	{1152, 622},
 	{1152, 597},
@@ -2246,7 +2630,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType0d_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType0d_2[]=  
 {
 	{1152, 622},
 	{1152, 597},
@@ -2259,7 +2643,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType0e_2[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType0e_2[]= 
 {
 	{1152, 622},
 	{1152, 597},
@@ -2272,7 +2656,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_PanelType0f_2[] =   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelType0f_2[] = 
 {
 	{1152, 622},
 	{1152, 597},
@@ -2285,7 +2669,21 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType1076_1[]=   /* TW: New */
+static const SiS310_LVDSDesStruct  SiS310_PanelTypeNS_1[]= 
+{
+	{ 8,   0},
+	{ 8,   0},
+	{ 8,   0},
+	{ 8,   0},
+	{ 8,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0, 806},
+	{ 0, 0 }
+};
+
+static const SiS310_LVDSDesStruct  SiS310_PanelTypeNS_2[] = 
 {
 	{ 0 , 0},
 	{ 0 , 0},
@@ -2295,15 +2693,29 @@
 	{ 0 , 0},
 	{ 0 , 0},
 	{ 0 , 0},
+	{ 0 , 0},
 	{ 0 , 0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType1076_2[]=   /* TW: New */
-{
-	{ 1152, 622 },
-	{ 1152, 597 },
-	{ 1152, 622 },
-	{ 1152, 597 },
+static const SiS310_LVDSDesStruct SiS310_PanelType1076_1[]=  
+{  /* 1024x768 - Checked (1.10.6s) */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType1076_2[]=  
+{  /* 1024x768 - Checked (1.10.6s) */
+	{ 1184, 622 },
+	{ 1184, 597 },
+	{ 1184, 622 },
+	{ 1184, 597 },
 	{ 1152, 622 },
 	{ 1232, 722 },
 	{    0, 0   },
@@ -2311,8 +2723,8 @@
 	{    0, 0   }
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType1210_1[]=   /* TW: New */
-{
+static const SiS310_LVDSDesStruct SiS310_PanelType1210_1[]=  
+{  /* 1280x1024 - Checked (1.10.6s) */
 	{ 0 , 0},
 	{ 0 , 0},
 	{ 0 , 0},
@@ -2324,8 +2736,8 @@
 	{ 0 , 0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType1210_2[]=   /* TW: New */
-{
+static const SiS310_LVDSDesStruct SiS310_PanelType1210_2[]=  
+{  /* 1280x1024 - Checked (1.10.6s) */
 	{ 0 , 0},
 	{ 0 , 0},
 	{ 0 , 0},
@@ -2337,8 +2749,8 @@
 	{ 0 , 0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType1296_1[]=   /* TW: New */
-{
+static const SiS310_LVDSDesStruct SiS310_PanelType1296_1[]=  
+{  /* 1400x1050 - Checked (1.10.6s) */
 	{ 0 , 0},
 	{ 0 , 0},
 	{ 0 , 0},
@@ -2350,8 +2762,36 @@
 	{ 0 , 0}
 };
 
-SiS310_LVDSDesStruct SiS310_PanelType1296_2[]=   /* TW: New */
-{
+static const SiS310_LVDSDesStruct SiS310_PanelType1296_2[]=  
+{  /* 1400x1050 - Checked (1.10.6s) - looks heavily invalid */
+	{ 808 , 740},
+	{ 0   , 715},
+	{ 632 , 740},
+	{ 632 , 715},
+	{ 1307, 780},
+	{ 1387,1157},
+	{ 1499, 924},
+	{ 1627,1052},
+	{ 0 , 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType1600_1[]= 
+{  /* 1600x1200 - Checked (1.10.6s) */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS310_LVDSDesStruct SiS310_PanelType1600_2[]= 
+{  /* 1600x1200 - Checked (1.10.6s) - looks heavily invalid, not copied */
+	{ 0 , 0},
 	{ 0 , 0},
 	{ 0 , 0},
 	{ 0 , 0},
@@ -2363,7 +2803,7 @@
 	{ 0 , 0}
 };
 
-SiS310_LVDSDesStruct  SiS310_CHTVUNTSCDesData[]= 
+static const SiS310_LVDSDesStruct  SiS310_CHTVUNTSCDesData[]=
 {
 	{ 0,   0},
 	{ 0,   0},
@@ -2374,7 +2814,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_CHTVONTSCDesData[]=
+static const SiS310_LVDSDesStruct  SiS310_CHTVONTSCDesData[]=
 {
 	{ 0,   0},
 	{ 0,   0},
@@ -2385,7 +2825,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_CHTVUPALDesData[]=
+static const SiS310_LVDSDesStruct  SiS310_CHTVUPALDesData[]=
 {
 	{256,   0},
 	{256,   0},
@@ -2396,7 +2836,7 @@
 	{ 0,   0}
 };
 
-SiS310_LVDSDesStruct  SiS310_CHTVOPALDesData[]=
+static const SiS310_LVDSDesStruct  SiS310_CHTVOPALDesData[]=
 {
 	{256,   0},
 	{256,   0},
@@ -2412,7 +2852,7 @@
  	UCHAR CR[12];
 } SiS310_Part2PortTblStruct;
 
-SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] =
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] =
 {
  {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
  {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
@@ -2421,22 +2861,50 @@
  {{0x38,0x13,0x16,0x0c,0xe6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
  {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
  {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
 };
 
-SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] =
-{
- {{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,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,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] =
+{	/* TW: Temporary data, invalid */
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] =
+{	/* TW: Temporary data, invalid */
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_1[] =
+{	/* TW: Temporary data, invalid */
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
 };
 
-SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] =
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] =
 {
  {{0x25,0x12,0x51,0x6e,0x48,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
  {{0x2c,0x12,0x38,0x55,0x2f,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
@@ -2445,10 +2913,11 @@
  {{0x2d,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
  {{0x29,0x12,0xb5,0xd2,0xac,0xe9,0x35,0xd9,0x47,0x11,0x99,0x33}},
  {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
 };
 
-SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_2[] =
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_2[] =
 {
  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
@@ -2457,12 +2926,49 @@
  {{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,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
 };
 
-
-SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_2[] =
 {
+ {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x33,0x13,0x01,0x0d,0xfd,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x3f,0x1b,0x3d,0x49,0x39,0x54,0x23,0xc0,0x27,0x66,0x30,0x42}},
+ {{0x33,0x1b,0x91,0x9d,0x8d,0x8c,0x23,0xf8,0x27,0x9e,0x68,0x42}},
+ {{0x43,0x24,0x11,0x1d,0x0d,0xcc,0x23,0x38,0x37,0xde,0xa8,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_2[] =
+{	/* TW: Temporary data, invalid */
+ {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x33,0x13,0x01,0x0d,0xfd,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
+ {{0x3f,0x1b,0x3d,0x49,0x39,0x54,0x23,0xc0,0x27,0x66,0x30,0x42}},
+ {{0x33,0x1b,0x91,0x9d,0x8d,0x8c,0x23,0xf8,0x27,0x9e,0x68,0x42}},
+ {{0x43,0x24,0x11,0x1d,0x0d,0xcc,0x23,0x38,0x37,0xde,0xa8,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
+};
+
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
+{	/* TW: Data from 650/301LVx 1.10.6s */
+ {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x25,0x13,0xc9,0x24,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x25,0x13,0xc9,0x25,0xff,0xf9,0x45,0x09,0x07,0xf9,0x09,0x24}}
+#if 0	/* TW: Data from 650/301LV */
  {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
  {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
  {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
@@ -2471,50 +2977,84 @@
  {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
  {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+#endif
 };
 
-SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
-{
- {{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,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,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+/*   1     2    4    5    6   1c   1d   1f   20   21   23   25   */
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
+{	/* TW: Temporary data, invalid */
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_3[] =
+{	
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_3[] =
+{	/* TW: Temporary data, invalid */
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
 };
 
-/*add for LCDA*/
 typedef struct _SiS310_LCDACRT1DataStruct
 {
  	UCHAR CR[17];
 }SiS310_LCDACRT1DataStruct;
 
-SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_1[] =
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_1[] =
 {
- {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
-   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01}}
+ {{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,
+   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,
+   0x00}}
 };
 
-SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1[]=
-{
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1[]=
+{  /* TW: Checked (1.10.6s) */
  {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
    0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
    0x00}},
@@ -2538,253 +3078,534 @@
    0x01}}
 };
 
-SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1[]=
-{
- {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1[]=
+{  /* Checked (1.10.6s) */
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
    0x00}},
- {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
+   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
    0x00}},
- {{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
    0x00}},
- {{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
+   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
    0x00}},
- {{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
-   0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x08,0x3e,
+   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x06,
    0x00}},
- {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
-   0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+ {{0x92,0x63,0x63,0x96,0x6c,0x1a,0x80,0xf0,
+   0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x06,
    0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+ {{0xae,0x7f,0x7f,0x92,0x88,0x96,0x28,0xf5,
+   0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x02,
+   0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xa8,0x16,0x28,0x5a,
+   0x00,0x84,0xff,0xff,0x29,0x01,0x00,0x07,
    0x01}}
 };
 
-SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_1_H[]=
-{
- {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1[]=
+{    /* Checked (1.10.6s) */
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+   0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
    0x00}},
- {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
+   0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
    0x00}},
- {{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+   0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
    0x00}},
- {{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
+   0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
    0x00}},
- {{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
-   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0xee,0x1f,
+   0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
    0x00}},
- {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
-   0x01}}
+ {{0x83,0x63,0x63,0x87,0x68,0x16,0x66,0xf0,
+   0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x06,
+   0x01}},
+ {{0x9f,0x7f,0x7f,0x83,0x84,0x92,0x0e,0xf5,
+   0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x02,
+   0x01}},
+ {{0xbf,0x9f,0x9f,0x83,0xa4,0x12,0x0e,0x5a,
+   0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x07,
+   0x01}},
+ {{0xce,0xae,0xae,0x92,0xb3,0x01,0x28,0x10,
+   0x1a,0x80,0x19,0x19,0x29,0x0f,0x00,0x03,
+   0x00}}
 };
 
-SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1_H[]=
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_1[]=
+{   /* MISSING */
+ {{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,
+   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,
+   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,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,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,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,0x00,0x00,
+   0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_1_H[]=
 {
- {{0x37,0x27,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+ {{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,
+   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,
+   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,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,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,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1_H[]=
+{  /* TW: Checked (1.10.6s) */
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
    0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
    0x00}},
- {{0x37,0x27,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
    0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
    0x00}},
- {{0x37,0x27,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
    0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
    0x00}},
- {{0x37,0x27,0x27,0x9B,0x2b,0x94,0x97,0x1f,
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
    0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
    0x00}},
- {{0x37,0x27,0x27,0x9B,0x2b,0x94,0x04,0x3e,
-   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x44,
+ {{0x4b,0x27,0x27,0x8f,0x32,0x1b,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x45,
    0x00}},
- {{0x41,0x31,0x31,0x85,0x35,0x1d,0x7c,0xf0,
+ {{0x55,0x31,0x31,0x99,0x46,0x1d,0x7c,0xf0,
    0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55,
    0x01}},
- {{0x4f,0x3F,0x3F,0x93,0x45,0x0D,0x24,0xf5,
+ {{0x63,0x3F,0x3F,0x87,0x4a,0x93,0x24,0xf5,
    0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x01,
    0x01}}
 };
 
-SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1_H[]=
-{
- {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
-   0x00}},
-{{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1_H[]=
+{   /* Checked (1.10.6s) */
+ {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
    0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
-   0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
+ {{0x3c,0x4f,0x4f,0x82,0x58,0x06,0x86,0xd1,    /* <-- Invalid data - one byte missing in BIOS */
+   0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06,
+   0x01}},
+ {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
    0x00}},
- {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-   0xe2,0x89,0xdf,0x05,0x00,0x00,0x04,
+ {{0x3c,0x4f,0x4f,0x82,0x58,0x06,0x86,0xd1,
+   0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06,
+   0x01}},
+ {{0x56,0x27,0x27,0x9a,0x30,0x1e,0x08,0x3e,
+   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x05,
    0x00}},
- {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-   0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+ {{0x60,0x31,0x31,0x84,0x3a,0x88,0x80,0xf0,
+   0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x01,
    0x01}},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ {{0x6e,0x3f,0x3f,0x92,0x48,0x96,0x28,0xf5,
+   0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x01,
    0x01}}
 };
 
-SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_2[]=
-{ 
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1_H[]=
+{   /* Checked (1.10.6s) */
+  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
+    0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+    0x00}},
+  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+    0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
+    0x00}},
+  {{0x47,0x27,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
+    0x92,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+    0x00}},
+  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+    0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
+    0x00}},
+  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
+    0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
+    0x00}},
+  {{0x51,0x31,0x31,0x95,0x36,0x04,0x66,0xf0,
+    0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x01,
+    0x01}},
+  {{0x5f,0x3f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
+    0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x01,
+    0x01}},
+  {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+    0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x05,
+    0x01}},
+  {{0x76,0x56,0x56,0x9a,0x5b,0x89,0x28,0x10,
+    0x1c,0x80,0x19,0x19,0x29,0x0b,0x00,0x05,
+    0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_1_H[]=
+{   /* MISSING */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
-   0x1c,0x80,0xdf,0x73,0x00,0x00,0x06,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01}}
+ {{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,
+   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,
+   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,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}}
 };
 
-SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2[]=
-{ 
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_2[]=
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-   0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+ {{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,
+   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,
+   0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2[]=
+{   /* Checked (1.10.6s) */
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
+   0x00}},
+ {{0xa3,0x63,0x63,0x87,0x78,0x89,0x24,0xf1,
+   0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x02,
    0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
    0x01}}
 };
 
-SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2[]=
-{
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2[]=
+{   /* Checked (1.10.6s) */
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
    0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
    0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
    0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
    0x00}},
- {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
    0x00}},
- {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-   0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+ {{0xa3,0x63,0x63,0x87,0x78,0x89,0x24,0xf1,
+   0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x02,
    0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
    0x01}}
 };
 
-SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_2_H[]=
-{ 
- {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-   0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2[]=
+{    /* Checked (1.10.6s) */
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
+   0x00}},
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03,
+   0x01}},
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
+   0x00}},
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
+   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03,
+   0x00}},
+ {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9e,
+   0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x03,
+   0x00}},
+ {{0xce,0x63,0x63,0x92,0x96,0x04,0x28,0xd4,
+   0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x07,
+   0x01}},
+ {{0xce,0x7f,0x7f,0x92,0xa4,0x12,0x28,0xd4,
+   0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x07,
+   0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xb4,0x02,0x28,0x5a,
+   0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x03,
+   0x01}},
+ {{0xce,0xae,0xae,0x92,0xbc,0x0a,0x28,0x10,
+   0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x03,
+   0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_2[]=
+{    /* MISSING */
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-   0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
-   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
-   0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00}},
- {{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
-   0x01}}
+ {{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,
+   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,
+   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,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}}
 };
 
-SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2_H[]=
-{ 
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_2_H[]=
+{
+ {{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,
+   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,
+   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,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,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,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2_H[]=
+{   /* Checked (1.10.6s) */
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
    0x00 }},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x31,0x87,0x8d,0x5d,0x25,0x30,0x00,0x01,   /* <-- invalid data */
    0x00 }},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
    0x00 }},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
    0x00 }},
- {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01,
    0x00 }},
- {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-   0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+ {{0x4f,0x31,0x31,0x93,0x3e,0x06,0x24,0xf1,
+   0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x01,  /* <-- invalid data */
    0x01 }},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
    0x01 }}
 };
 
-SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2_H[]=
-{ 
- {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2_H[]=
+{   /* Checked (1.10.6s) */
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
    0x00 }},
- {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
    0x00 }},
- {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
    0x00 }},
- {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
    0x00 }},
- {{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01,
    0x00 }},
- {{0x4f,0x31,0x93,0x3e,0x86,0x24,0xf1,
-   0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+ {{0x4f,0x31,0x31,0x93,0x3e,0x86,0x24,0xf1,
+   0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x01,
    0x01 }},
- {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
    0x01 }}
 };
 
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2_H[]=
+{  /* Checked (1.10.6s) */
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
+   0x00}},
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06,
+   0x00}},
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+   0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
+   0x00}},
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
+   0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06,
+   0x00}},
+ {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9e,
+   0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x06,
+   0x00}},
+ {{0x9c,0x31,0x31,0x80,0x64,0x92,0x28,0xd4,
+   0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x06,
+   0x01}},
+ {{0x8e,0x3f,0x3f,0x92,0x64,0x12,0x28,0xd4,
+   0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x06,
+   0x01}},
+ {{0x7e,0x4f,0x4f,0x82,0x64,0x12,0x28,0x5a,
+   0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x06,
+   0x01}},
+ {{0x76,0x56,0x56,0x9a,0x64,0x92,0x28,0x10,
+   0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x05,
+   0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_2_H[]=
+{  /* MISSING */
+ {{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,
+   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,
+   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,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,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,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,0x00,0x00,
+   0x00}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}}
+};
+
 typedef struct _SiS310_LVDSCRT1DataStruct
 {
  	UCHAR CR[15];
 } SiS310_LVDSCRT1DataStruct;
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1320x480_1[] =
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1320x480_1[] =
 {
  {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
    0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -2804,12 +3625,12 @@
  {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
    0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
    0x01 }},
-{{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
    0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
    0x00 }}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =   /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =   
 {
  {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
    0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -2831,7 +3652,7 @@
    0x01 }}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1[] =    /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1[] =    
 {
  {{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
    0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
@@ -2856,35 +3677,35 @@
    0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1[] =    /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1[] =   
 {
- {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f,
+ {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f,
    0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
-   0x00 }},
- {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f,
+   0x00}},
+ {{0x7e,0x4f,0x82,0x58,0x04,0x86,0x1f,
    0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
-   0x00 }},
- {{0x7e,0x4f,0x82,0x56,0x04,0xb8,0x1f,
+   0x00}},
+ {{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f,
    0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
-   0x00 }},
- {{0x7e,0x4f,0x82,0x56,0x04,0x86,0x1f,
+   0x00}},
+ {{0x7e,0x4f,0x82,0x58,0x04,0x86,0x1f,
    0x5e,0x82,0x5d,0x87,0x10,0x00,0x06,
-   0x00 }},
- {{0x7e,0x4f,0x82,0x56,0x04,0x08,0x3e,
+   0x00}},
+ {{0x7e,0x4f,0x82,0x58,0x04,0x08,0x3e,
    0xe0,0x84,0xdf,0x09,0x00,0x00,0x06,
-   0x00 }},
- {{0x92,0x63,0x96,0x6a,0x18,0x80,0xf0,
+   0x00}},
+ {{0x92,0x63,0x96,0x6c,0x18,0x80,0xf0,
    0x58,0x8c,0x57,0x81,0x20,0x00,0x06,
-   0x01 }},
- {{0xae,0x7f,0x92,0x86,0x94,0x28,0xf5,
+   0x01}},
+ {{0xae,0x7f,0x92,0x88,0x94,0x28,0xf5,
    0x00,0x84,0xff,0x29,0x10,0x00,0x02,
-   0x01 }},
- {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a,
+   0x01}},
+ {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
    0x00,0x84,0xff,0x29,0x09,0x00,0x07,
    0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1_H[] =    /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1_H[] =   
 {
  {{0x43,0x27,0x87,0x2d,0x1d,0xaa,0x1f,
    0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -2906,7 +3727,7 @@
    0x01 }}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1_H[] =    /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1_H[] = 
 {
  {{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
    0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
@@ -2931,32 +3752,32 @@
    0x01 }}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1_H[] =   /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1_H[] =  
 {
- {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f,
+ {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
    0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
-   0x00 }},
- {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f,
+   0x00}},
+ {{0x56,0x27,0x9a,0x31,0x1c,0x86,0x1f,
    0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
-   0x00 }},
- {{0x56,0x27,0x9a,0x2e,0x1c,0xb8,0x1f,
+   0x00}},
+ {{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
    0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
-   0x00 }},
- {{0x56,0x27,0x9a,0x2e,0x1c,0x86,0x1f,
+   0x00}},
+ {{0x56,0x27,0x9a,0x31,0x1c,0x86,0x1f,
    0x5e,0x82,0x5d,0x87,0x10,0x00,0x05,
-   0x01 }},
- {{0x56,0x27,0x9a,0x2e,0x1c,0x08,0x3e,
+   0x01}},
+ {{0x56,0x27,0x9a,0x31,0x1c,0x08,0x3e,
    0xe0,0x84,0xdf,0x09,0x00,0x00,0x05,
-   0x00 }},
- {{0x60,0x31,0x84,0x38,0x86,0x80,0xf0,
+   0x00}},
+ {{0x60,0x31,0x84,0x3a,0x86,0x80,0xf0,
    0x58,0x8c,0x57,0x81,0x20,0x00,0x01,
-   0x01 }},
- {{0x6e,0x3f,0x92,0x46,0x94,0x28,0xf5,
+   0x01}},
+ {{0x6e,0x3f,0x92,0x48,0x94,0x28,0xf5,
    0x00,0x84,0xff,0x29,0x10,0x00,0x01,
-   0x01 }}
+   0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2[]=   /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2[]=  
 {
  {{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
    0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
@@ -2978,7 +3799,7 @@
    0x01 }}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2[] =   /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2[] = 
 { 
  {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
    0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
@@ -3003,36 +3824,36 @@
    0x01 }}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2[] =  /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2[] =  
 {
- {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
-   0x00 }},
- {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
-   0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
-   0x00 }},
- {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
-   0x00 }},
- {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9a,
-   0xc2,0x86,0x5d,0x29,0x01,0x00,0x03,
-   0x00 }},
- {{0xce,0x4f,0x92,0x81,0x0f,0x28,0x9e,
-   0x03,0x87,0xdf,0x29,0x01,0x00,0x03,
-   0x00 }},
+ {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
+   0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02,
+   0x01}},
+ {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
+   0xaf,0x83,0x44,0x43,0x21,0x00,0x02,
+   0x01}},
+ {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
+   0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02,
+   0x01}},
+ {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
+   0xaf,0x83,0x44,0x43,0x21,0x00,0x02,
+   0x01}},
+ {{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
+   0xf0,0x84,0x85,0x84,0x11,0x00,0x02,
+   0x01}},
  {{0xce,0x63,0x92,0x8b,0x19,0x28,0xd4,
    0x3f,0x83,0x57,0x29,0x01,0x00,0x03,
-   0x01 }},
+   0x01}},
  {{0xce,0x7f,0x92,0x99,0x07,0x28,0xd4,
    0x93,0x87,0xff,0x29,0x21,0x00,0x07,
-   0x01 }},
- {{0xce,0x9f,0x92,0xa6,0x14,0x28,0x5a,
+   0x01}},
+ {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
    0x00,0x84,0xff,0x29,0x09,0x00,0x07,
    0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2_H[] =   /* TW: New */
-{ 
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2_H[] =  
+{
  {{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
    0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
    0x00 }},
@@ -3053,7 +3874,7 @@
    0x01 }}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2_H[] =   /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2_H[] =  
 { 
  {{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
    0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
@@ -3078,32 +3899,32 @@
    0x01 }}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2_H[] =   /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2_H[] = 
 {
- {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
-   0x00 }},
- {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
-   0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
-   0x00 }},
- {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
-   0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
-   0x00 }},
- {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9a,
-   0xc2,0x86,0x5d,0x29,0x01,0x00,0x06,
-   0x00 }},
- {{0xa6,0x27,0x8a,0x59,0x87,0x28,0x9e,
-   0x03,0x87,0xdf,0x29,0x01,0x00,0x06,
-   0x00 }},
+ {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
+   0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06,
+   0x01}},
+ {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
+   0xaf,0x83,0x44,0x43,0x21,0x00,0x06,
+   0x01}},
+ {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
+   0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06,
+   0x01}},
+ {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
+   0xfa,0x83,0x44,0x43,0x31,0x00,0x06,
+   0x01}},
+ {{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
+   0xf0,0x84,0x85,0x84,0x11,0x00,0x06,
+   0x01}},
  {{0x9c,0x31,0x80,0x59,0x87,0x28,0xd4,
    0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
-   0x01 }},
- {{0x8e,0x3f,0x92,0x79,0x07,0x28,0xd4,
+   0x01}},
+ {{0x8e,0x3f,0x92,0x59,0x07,0x28,0xd4,
    0x93,0x87,0xff,0x29,0x21,0x00,0x06,
    0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1[] =   /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1[] =  
 {
  {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
    0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
@@ -3126,12 +3947,15 @@
  {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
    0x02,0x88,0xff,0x25,0x10,0x00,0x02,
    0x01}},
+ {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
+   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+   0x01}},
  {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
    0x02,0x88,0xff,0x25,0x10,0x00,0x07,
    0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1_H[] =   /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1_H[] = 
 {
  {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
    0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
@@ -3156,8 +3980,36 @@
    0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =   /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =  
 {
+  {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+    0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
+    0x00}},
+  {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
+    0x5e,0x81,0x5d,0x6d,0x10,0x00,0x05,
+    0x00}},
+  {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+    0x90,0x83,0x8f,0x9f,0x30,0x00,0x05,
+    0x00}},
+  {{0x6f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
+    0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+    0x00}},
+  {{0x6f,0x4f,0x93,0x54,0x82,0xee,0x1f,
+    0xdf,0x82,0xdf,0xef,0x10,0x00,0x05,
+    0x00}},
+  {{0x83,0x63,0x87,0x68,0x16,0x66,0xf0,
+    0x57,0x8e,0x57,0x67,0x20,0x00,0x06,
+    0x01}},
+  {{0x9f,0x7f,0x83,0x84,0x92,0x0e,0xf1,
+    0xff,0x86,0xff,0x0f,0x10,0x00,0x02,
+    0x01,}},
+  {{0xbf,0x9f,0x83,0xa4,0x12,0x0e,0xde,
+    0xff,0x86,0xff,0x0f,0x01,0x00,0x07,
+    0x01}},
+  {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10,
+    0x19,0x80,0x19,0x29,0x0f,0x00,0x03,
+    0x00}}
+#if 0
  {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
    0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
    0x00}},
@@ -3185,11 +4037,40 @@
  {{0xce,0xae,0x92,0xb3,0x01,0x28,0x10,
    0x1a,0x80,0x19,0x29,0x0f,0x00,0x03,
    0x00}}
+#endif   
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1_H[] =   /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1_H[] = 
 {
  {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
+   0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
+  0x00}},
+ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
+   0x90,0x83,0x8f,0x9f,0x30,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
+   0xdf,0x86,0xdf,0xef,0x10,0x00,0x05,
+   0x00}},
+ {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
+   0x57,0x8e,0x57,0x67,0x20,0x00,0x01,
+   0x01}},
+ {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf1,
+   0xff,0x86,0xff,0x0f,0x10,0x00,0x01,
+   0x01}},
+ {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
+   0x01}},
+ {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10,
+   0x1c,0x80,0x19,0x29,0x0b,0x00,0x05,
+   0x00}}
+#if 0
+ {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
    0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
    0x00}},
  {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
@@ -3216,10 +4097,39 @@
  {{0x76,0x56,0x9a,0x5b,0x89,0x28,0x10,
    0x1c,0x80,0x19,0x29,0x0b,0x00,0x05,
    0x00}}
+#endif   
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2[] =    /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2[] =  
 {
+ {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
+   0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02,
+   0x01}},
+ {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
+   0xbe,0x82,0x44,0x43,0x01,0x00,0x02,
+   0x01}},
+ {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
+   0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02,
+   0x01}},
+ {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
+   0xbe,0x82,0x44,0x43,0x01,0x00,0x02,
+   0x01}},
+ {{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
+   0xff,0x83,0x85,0x84,0x11,0x00,0x02,
+   0x01}},
+ {{0xce,0x63,0x92,0x8e,0x1c,0x28,0xd4,
+   0x3f,0x83,0x57,0x29,0x01,0x00,0x03,
+   0x01}},
+ {{0xce,0x7f,0x92,0x9c,0x0a,0x28,0xd4,
+   0x93,0x87,0xff,0x29,0x21,0x00,0x07,
+   0x01}},
+ {{0xce,0x9f,0x92,0xac,0x1a,0x28,0x5a,
+   0x13,0x87,0xff,0x29,0x29,0x00,0x07,
+   0x01}},
+ {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10,
+   0x20,0x84,0x19,0x29,0x0f,0x00,0x03,
+   0x00}}
+#if 0
  {{0xce,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
    0xdb,0x8f,0x8f,0x29,0x21,0x00,0x03,
    0x00}},
@@ -3247,10 +4157,39 @@
  {{0xce,0xae,0x92,0xbc,0x0a,0x28,0x10,
    0x20,0x84,0x19,0x29,0x0f,0x00,0x03,
    0x00}}
+#endif   
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2_H[] =    /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_2_H[] =  
 {
+ {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
+   0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06,
+   0x01}},
+ {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
+   0xbe,0x82,0x44,0x43,0x01,0x00,0x06,
+   0x01}},
+ {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
+   0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06,
+   0x01}},
+ {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
+   0xbe,0x82,0x44,0x43,0x01,0x00,0x06,
+   0x01}},
+ {{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
+   0xff,0x83,0x85,0x84,0x11,0x00,0x06,
+   0x01}},
+ {{0x9c,0x31,0x80,0x5c,0x8a,0x28,0xd4,
+   0x3f,0x83,0x57,0x29,0x01,0x00,0x06,
+   0x01}},
+ {{0x8e,0x3f,0x92,0x5c,0x0a,0x28,0xd4,
+   0x93,0x87,0xff,0x29,0x21,0x00,0x06,
+   0x01}},
+ {{0x7e,0x4f,0x82,0x5c,0x0a,0x28,0x5a,
+   0x13,0x87,0xff,0x29,0x29,0x00,0x06,
+   0x01}},
+ {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10,
+   0x20,0x84,0x19,0x29,0x0f,0x00,0x05,
+   0x00}}
+#if 0
  {{0xa6,0x27,0x8a,0x64,0x92,0x28,0x9a,
    0xdb,0x8f,0x8f,0x29,0x21,0x00,0x06,
    0x00}},
@@ -3278,9 +4217,134 @@
  {{0x76,0x56,0x9a,0x64,0x92,0x28,0x10,
    0x20,0x84,0x19,0x29,0x0f,0x00,0x05,
    0x00}}
+#endif   
+};
+
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_1[] =  
+{	
+ {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
+   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
+   0x00}},
+ {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
+   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
+   0x00}},
+ {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
+   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
+   0x00}},
+ {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
+   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
+   0x00}},
+ {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
+   0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
+   0x00}},
+ {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
+   0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
+   0x01}},
+ {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
+   0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
+   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
+   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
+   0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1[] =
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_1_H[] = 
+{
+ {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
+   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
+   0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
+   0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
+   0x00}},
+ {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
+   0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
+   0x01}},
+ {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
+   0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
+   0x01}},
+ {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
+   0x01}},
+ {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
+   0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_2[] = 
+{
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+   0x00}},
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+   0x00}},
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+   0x00}},
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+   0x00}},
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
+   0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
+   0x01}},
+ {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
+   0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
+   0x01}},
+ {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+   0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_2_H[] =
+{
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+   0x00}},
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+   0x00}},
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+   0x00}},
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+   0x00}},
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
+   0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
+   0x01}},
+ {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
+   0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
+   0x01}},
+ {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+   0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1[] =
 {
         {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
 	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
@@ -3305,7 +4369,7 @@
 	  0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1_H[] =
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1_H[] =
 {
         {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
 	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
@@ -3330,7 +4394,7 @@
 	  0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_2[] =
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_2[] =
 {
         {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
@@ -3355,7 +4419,7 @@
 	  0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_2_H[] =
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_2_H[] =
 {
         {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
@@ -3380,7 +4444,7 @@
 	  0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1[] =
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1[] =
 {
         {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
 	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
@@ -3405,7 +4469,7 @@
 	  0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1_H[] =
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1_H[] =
 {
         {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
 	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
@@ -3430,7 +4494,7 @@
 	  0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2[] =
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2[] =
 {
         {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
@@ -3455,7 +4519,7 @@
 	  0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2_H[] =
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2_H[] =
 {
         {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
@@ -3480,113 +4544,276 @@
 	  0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UNTSC[] =    /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =  
+{    
+ {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
+   0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
+   0x00}},
+ {{0x83,0x4f,0x87,0x51,0x09,0x8e,0x1f,
+   0x5e,0x82,0x5d,0x8f,0x10,0x00,0x06,
+   0x00}},
+ {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
+   0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
+   0x00}},
+ {{0x83,0x4f,0x87,0x51,0x09,0x8e,0x1f,
+   0x5e,0x82,0x5d,0x8f,0x10,0x00,0x06,
+   0x00}},
+ {{0x83,0x4f,0x87,0x51,0x09,0x10,0x3e,
+   0xe0,0x84,0xdf,0x11,0x00,0x00,0x06,
+   0x00}},
+ {{0x97,0x63,0x9b,0x65,0x1d,0x88,0xf0,
+   0x58,0x8c,0x57,0x89,0x20,0x00,0x06,
+   0x01}},
+ {{0xb3,0x7f,0x97,0x81,0x99,0x30,0xf5,
+   0x00,0x84,0xff,0x31,0x10,0x00,0x02,
+   0x01}},
+ {{0xd3,0x9f,0x97,0xa1,0x19,0x30,0x5a,
+   0x00,0x84,0xff,0x31,0x09,0x00,0x07,
+   0x01}},
+ {{0xe2,0xae,0x86,0xb0,0x88,0x4a,0x10,
+   0x1a,0x8e,0x19,0x4b,0x2f,0x00,0x03,
+   0x00}},
+ {{0xfb,0xc7,0x9f,0xc9,0x81,0xe0,0x10,
+   0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x07,
+   0x00}}
+};
+
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1_H[] =
 { 
- {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
-   0x00 }},
- {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
-   0x00 }},
- {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
-   0x00 }},
- {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
-   0x00 }},
- {{0x5d,0x4f,0x81,0x56,0x99,0x56,0xba,
-   0x0a,0x84,0xdf,0x57,0x00,0x00,0x01,
-   0x00 }},
- {{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0,
-   0x7a,0x8f,0x57,0xed,0x20,0x00,0x06,
-   0x01 }},
- {{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,  /* TW: 1024x768 */
-   0x36,0x88,0xff,0xb0,0x10,0x00,0x02,
-   0x01}}
+ {{0x5b,0x27,0x9f,0x29,0x01,0xc0,0x1f,
+   0x90,0x84,0x8f,0xc1,0x30,0x00,0x01,
+   0x00}},
+ {{0x5b,0x27,0x9f,0x29,0x01,0x8e,0x1f,
+   0x5e,0x82,0x5d,0x8f,0x10,0x00,0x01,
+   0x00}},
+ {{0x5b,0x27,0x9f,0x29,0x01,0xc0,0x1f,
+   0x90,0x84,0x8f,0xc1,0x30,0x00,0x01,
+   0x00}},
+ {{0x5b,0x27,0x9f,0x29,0x01,0x8e,0x1f,
+   0x5e,0x82,0x5d,0x8f,0x10,0x00,0x01,
+   0x00}},
+ {{0x5b,0x27,0x9f,0x29,0x01,0x10,0x3e,
+   0xe0,0x84,0xdf,0x11,0x00,0x00,0x01,
+   0x00}},
+ {{0x65,0x31,0x89,0x33,0x8b,0x88,0xf0,
+   0x58,0x8c,0x57,0x89,0x20,0x00,0x01,
+   0x01}},
+ {{0x73,0x3f,0x97,0x41,0x99,0x30,0xf5,
+   0x00,0x84,0xff,0x31,0x10,0x00,0x01,
+   0x01}},
+ {{0x83,0x4f,0x87,0x51,0x09,0x30,0x5a,
+   0x00,0x84,0xff,0x31,0x09,0x00,0x06,
+   0x01}},
+ {{0x8a,0x56,0x8e,0x58,0x10,0x4a,0x10,
+   0x1a,0x8e,0x19,0x4b,0x2f,0x00,0x06,
+   0x00}},
+ {{0x97,0x63,0x9b,0x65,0x1d,0xe0,0x10,
+   0xb0,0x84,0xaf,0xe1,0x2f,0x00,0x06,
+   0x00}}
+};
+
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_2[] =
+{    
+ {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
+   0x20,0x84,0xb9,0xb8,0x01,0x00,0x07,
+   0x01}},
+ {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
+   0x07,0x8b,0xa0,0x9f,0x01,0x00,0x07,
+   0x01}},
+ {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
+   0x20,0x84,0xb9,0xb8,0x01,0x00,0x07,
+   0x01}},
+ {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
+   0x07,0x8b,0xa0,0x9f,0x01,0x00,0x07,
+   0x01}},
+ {{0xfb,0x88,0x87,0x90,0x08,0xe0,0x96,
+   0x48,0x8c,0xe1,0xe0,0x11,0x00,0x07,
+   0x01}},
+ {{0xfb,0x63,0x9f,0x9a,0x92,0xe0,0xd4,
+   0x9b,0x8f,0x9d,0x9c,0x21,0x00,0x07,
+   0x01}},
+ {{0xfb,0x7f,0x9f,0xa8,0x80,0xe0,0xd4,
+   0xef,0x83,0xff,0xe1,0x21,0x00,0x03,
+   0x01}},
+ {{0xfb,0x9f,0x9f,0xb8,0x90,0xe0,0x5a,
+   0x6f,0x83,0xff,0xe1,0x29,0x00,0x03,
+   0x01}},
+ {{0xfb,0xae,0x9f,0xbf,0x97,0xe0,0x10,
+   0x7c,0x80,0x19,0xe1,0x0f,0x00,0x03,
+   0x00}},
+ {{0xfb,0xc7,0x9f,0xc9,0x84,0xe0,0x10,
+   0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x07,
+   0x00}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[] =    /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_2_H[] = 
+{    
+ {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
+   0x20,0x84,0xb9,0xb8,0x01,0x00,0x02,
+   0x01}},
+ {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
+   0x07,0x8b,0xa0,0x9f,0x01,0x00,0x02,
+   0x01}},
+ {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
+   0x20,0x84,0xb9,0xb8,0x01,0x00,0x02,
+   0x01}},
+ {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
+   0x07,0x8b,0xa0,0x9f,0x01,0x00,0x02,
+   0x01}},
+ {{0xd3,0x60,0x9f,0x68,0x00,0xe0,0x96,
+   0x48,0x8c,0xe1,0xe0,0x11,0x00,0x02,
+   0x01}},
+ {{0xc9,0x31,0x8d,0x68,0x00,0xe0,0xd4,
+   0x9b,0x8f,0x9d,0x9c,0x21,0x00,0x03,
+   0x01}},
+ {{0xbb,0x3f,0x9f,0x68,0x80,0xe0,0xd4,
+   0xef,0x83,0xff,0xe1,0x21,0x00,0x02,
+   0x01}},
+ {{0xab,0x4f,0x8f,0x68,0x80,0xe0,0x5a,
+   0x6f,0x83,0xff,0xe1,0x29,0x00,0x02,
+   0x01}},
+ {{0xa3,0x56,0x87,0x67,0x9f,0xe0,0x10,
+   0x7c,0x80,0x19,0xe1,0x0f,0x00,0x06,
+   0x00}},
+ {{0x97,0x63,0x9b,0x68,0x00,0xe0,0x10,
+   0xc7,0x8b,0xaf,0xe1,0x0f,0x00,0x02,
+   0x00}}
+};
+
+
+static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UNTSC[] =  
 { 
- {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
-   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
-   0x00 }},
- {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
-   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
-   0x00 }},
- {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
-   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
-   0x00 }},
- {{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
-   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
-   0x00 }},
- {{0x5d,0x4f,0x81,0x58,0x9d,0x0b,0x3e,
-   0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
-   0x00 }},
- {{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0,
-   0x78,0x8a,0x57,0xbb,0x20,0x00,0x06,
-   0x01 }},
- {{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,   /* TW: 1024x768 */
-   0x15,0x88,0xff,0x47,0x70,0x00,0x02,
-   0x01 }}
+	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+	  0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+	  0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+	  0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+	  0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x5d,0x4f,0x81,0x56,0x99,0x56,0xba,
+	  0x0a,0x84,0xdf,0x57,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0,
+	  0x7a,0x8f,0x57,0xed,0x20,0x00,0x06,
+	  0x01 }},
+	{{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,  /* TW: 1024x768 */
+	  0x36,0x88,0xff,0xb0,0x10,0x00,0x02,
+	  0x01}}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UPAL[] =    /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[] =   
 { 
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
-   0x00 }},
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-   0x00 }},
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
-   0x00 }},
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-   0x00 }},
- {{0x64,0x4f,0x88,0x5a,0x9f,0x6f,0xba,
-   0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
-   0x00 }},
- {{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0,
-   0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
-   0x01 }},
- {{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,   /* TW: 1024x768 */
-   0x50,0x88,0xff,0xe7,0x10,0x00,0x02,
-   0x01}}
+	{{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+	  0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+	  0x00 }},
+	{{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+	  0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+	  0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
+	  0x00 }},
+	{{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
+	  0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x5d,0x4f,0x81,0x58,0x9d,0x0b,0x3e,
+	  0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0,
+	  0x78,0x8a,0x57,0xbb,0x20,0x00,0x06,
+	  0x01 }},
+	{{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,   /* TW: 1024x768 */
+	  0x15,0x88,0xff,0x47,0x70,0x00,0x02,
+	  0x01 }}
 };
 
-SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[] =    /* TW: New */
+static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UPAL[] =    
 { 
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
-   0x00 }},
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-   0x00 }},
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
-   0x00 }},
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-   0x00 }},
- {{0x64,0x4f,0x88,0x58,0x9d,0x6f,0xba,
-   0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
-   0x00 }},
- {{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
-   0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
-   0x01 }},
- {{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,   /* TW:  1024x768 */
-   0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
-   0x01 }}
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x5a,0x9f,0x6f,0xba,
+	  0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0,
+	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
+	  0x01 }},
+	{{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,   /* TW: 1024x768 */
+	  0x50,0x88,0xff,0xe7,0x10,0x00,0x02,
+	  0x01}}
+};
+
+static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[] = 
+{
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x58,0x9d,0x6f,0xba,
+	  0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
+	  0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
+	  0x01 }},
+	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,   /* TW:  1024x768 */
+	  0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
+	  0x01 }}
+};
+
+static const SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1SOPAL[] =
+{
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
+	  0x00 }},
+	{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+	  0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
+	  0x00 }},
+	{{0x64,0x4f,0x88,0x58,0x9d,0x6f,0xba,
+	  0x15,0x83,0xdf,0x70,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
+	  0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
+	  0x01 }},
+	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,   /* TW:  1024x768 */
+	  0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
+	  0x01 }}
 };
 
-/* TW: New data for Chrontel 7019 (From 650/LVDS BIOS 1.10.0) */
+/* TW: Data for Chrontel 7019  */
 typedef struct _SiS310_CHTVRegDataStruct
 {
  	UCHAR Reg[16];
 } SiS310_CHTVRegDataStruct;
 
-SiS310_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] = {
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
+{
 	{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
 	{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
 	{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -3596,7 +4823,8 @@
 	{{0xee,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xd3,0xf2,0x36,0x00}}
 };
 
-SiS310_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] = {
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] =
+{
 	{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
 	{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
 	{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -3606,7 +4834,8 @@
 	{{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}}
 };
 
-SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] = {
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] =
+{
 	{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
 	{{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
 	{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -3616,7 +4845,8 @@
 	{{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}}
 };
 
-SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] = {
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] =
+{
 	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
 	{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
 	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
@@ -3626,11 +4856,76 @@
 	{{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
 };
 
-UCHAR SiS310_CHTVVCLKUNTSC[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_SOPAL[] =
+{
+	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x26,0x2a,0x55,0x5d,0x00}},
+	{{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00}},
+	{{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
+};
+
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] =
+{
+	{{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x72,0x77,0xbb,0x6e,0x84,0x2e,0x02,0x5a,0x04,0x00,0x80,0x20,0x76,0xdb,0x6e,0x00}},
+	{{0xd7,0x77,0xb7,0xc8,0x84,0x3b,0x02,0x5a,0x04,0x00,0x80,0x19,0x84,0x0a,0xc7,0x00}},
+	{{0xf6,0x77,0xbb,0x66,0x87,0x32,0x01,0x5a,0x04,0x00,0x80,0x1b,0xdc,0xb0,0x8d,0x00}}
+};
+
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] =
+{
+	{{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x71,0x77,0xbb,0x6e,0x84,0x1e,0x00,0x5a,0x04,0x00,0x80,0x25,0x1a,0x1f,0x59,0x00}},
+	{{0xd6,0x77,0xb7,0xb6,0x83,0x2c,0x02,0x5a,0x04,0x00,0x80,0x1b,0xf8,0x1f,0x82,0x00}},
+	{{0xf5,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x58,0x46,0x9f,0x00}}
+};
+
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] =
+{
+	{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x12,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}},
+	{{0xc3,0x7f,0xb7,0x7a,0x84,0x40,0x02,0x5a,0x05,0x00,0x80,0x19,0x78,0xef,0x35,0x00}},
+	{{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x1a,0x33,0x3f,0x2f,0x00}}
+};
+
+static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] =
+{
+	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
+	{{0x61,0x7f,0xb7,0x99,0x84,0x35,0x04,0x5a,0x05,0x00,0x80,0x1f,0x0d,0x54,0x5e,0x00}},
+	{{0xc1,0x7f,0xb7,0x4d,0x8c,0x1e,0x31,0x5a,0x05,0x00,0x80,0x1f,0x15,0xc0,0x1e,0x00}},
+	{{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x1d,0xf1,0x6c,0xcb,0x00}}
+};
+
+static const UCHAR SiS310_CHTVVCLKUNTSC[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
+
+static const UCHAR SiS310_CHTVVCLKONTSC[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
+
+static const UCHAR SiS310_CHTVVCLKUPAL[]  = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
+
+static const UCHAR SiS310_CHTVVCLKOPAL[]  = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
+
+static const UCHAR SiS310_CHTVVCLKSOPAL[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
+
+static const UCHAR SiS310_CHTVVCLKUPALM[] = {0x41,0x41,0x41,0x41,0x42,0x46,0x53};
+
+static const UCHAR SiS310_CHTVVCLKOPALM[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
 
-UCHAR SiS310_CHTVVCLKONTSC[] = {0x48,0x48,0x48,0x48,0x45,0x43,0x51};
+static const UCHAR SiS310_CHTVVCLKUPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
 
-UCHAR SiS310_CHTVVCLKUPAL[]  = {0x47,0x47,0x47,0x47,0x48,0x4a,0x54};
+static const UCHAR SiS310_CHTVVCLKOPALN[] = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
 
-UCHAR SiS310_CHTVVCLKOPAL[]  = {0x47,0x47,0x47,0x47,0x48,0x4f,0x52};
-/* TW: New end */
diff -Nru a/drivers/video/sis/325vtbl.h b/drivers/video/sis/325vtbl.h
--- a/drivers/video/sis/325vtbl.h	Thu Jul 11 10:30:29 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,2335 +0,0 @@
-typedef struct _SiS310_StStruct
-{
-	UCHAR St_ModeID;
-	USHORT St_ModeFlag;
-	UCHAR St_StTableIndex;
-	UCHAR St_CRT2CRTC;
-	UCHAR St_ResInfo;
-	UCHAR VB_StTVFlickerIndex;
-	UCHAR VB_StTVEdgeIndex;
-	UCHAR VB_StTVYFilterIndex;
-} SiS310_StStruct;
-SiS310_StStruct SiS310_SModeIDTable[]=
-{
-	{0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00},
-	{0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00},
-	{0x01,0x1010,0x17,0x02,0x02,0x00,0x01,0x01},
-	{0x03,0x8208,0x03,0x00,0x00,0x00,0x01,0x02},
-	{0x03,0x0210,0x16,0x01,0x01,0x00,0x01,0x02},
-	{0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03},
-	{0x05,0x9209,0x05,0x00,0x00,0x00,0x00,0x04},
-	{0x06,0x8209,0x06,0x00,0x00,0x00,0x00,0x05},
-	{0x07,0x0000,0x07,0x03,0x03,0x00,0x01,0x03},
-	{0x07,0x0000,0x19,0x02,0x02,0x00,0x01,0x03},
-	{0x0d,0x920a,0x0d,0x00,0x00,0x00,0x00,0x04},
-	{0x0e,0x820a,0x0e,0x00,0x00,0x00,0x00,0x05},
-	{0x0f,0x0202,0x11,0x01,0x01,0x00,0x00,0x05},
-	{0x10,0x0212,0x12,0x01,0x01,0x00,0x00,0x05},
-	{0x11,0x0212,0x1a,0x04,0x04,0x00,0x00,0x05},
-	{0x12,0x0212,0x1b,0x04,0x04,0x00,0x00,0x05},
-	{0x13,0x021b,0x1c,0x00,0x00,0x00,0x00,0x04},
-	{0x12,0x0010,0x18,0x02,0x02,0x00,0x00,0x05},
-	{0x12,0x0210,0x18,0x01,0x01,0x00,0x00,0x05},
-	{0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
-};
-
-typedef struct _SiS310_StandTableStruct
-{
-	UCHAR CRT_COLS;
-	UCHAR ROWS;
-	UCHAR CHAR_HEIGHT;
-	USHORT CRT_LEN;
-	UCHAR SR[4];
-	UCHAR MISC;
-	UCHAR CRTC[0x19];
-	UCHAR ATTR[0x14];
-	UCHAR GRC[9];
-} SiS310_StandTableStruct;
-
-SiS310_StandTableStruct SiS310_StandTable[]=
-{
-/* MD_0_200 */
- {
-  0x28,0x18,0x08,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* MD_1_200 */
- {
-  0x28,0x18,0x08,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* MD_2_200 */
- {
-  0x50,0x18,0x08,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* MD_3_200 */
- {
-  0x50,0x18,0x08,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* MD_4 */
- {
-  0x28,0x18,0x08,0x4000,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-   0xff},
-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x03,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-   0xff}
- },
-/* MD_5 */
- {
-  0x28,0x18,0x08,0x4000,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-   0xff},
-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x03,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-   0xff}
- },
-/* MD_6 */
- {
-  0x50,0x18,0x08,0x4000,
-  {0x01,0x01,0x00,0x06},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
-   0xff},
-  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-   0x01,0x00,0x01,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
-   0xff}
- },
-/* MD_7 */
- {
-  0x50,0x18,0x0e,0x1000,
-  {0x00,0x03,0x00,0x03},
-  0xa6,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-   0x0e,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-   0xff}
- },
-/* MDA_DAC */
- {
-  0x00,0x00,0x00,0x0000,
-  {0x00,0x00,0x00,0x15},
-  0x15,
-  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
-   0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15},
-  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x3f}
- },
-/* CGA_DAC */
- {
-  0x00,0x10,0x04,0x0114,
-  {0x11,0x09,0x15,0x00},
-  0x10,
-  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
-   0x04},
-  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
-   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
-   0x3e,0x2b,0x3b,0x2f},
-  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-   0x3f}
- },
-/* EGA_DAC */
- {
-  0x00,0x10,0x04,0x0114,
-  {0x11,0x05,0x15,0x20},
-  0x30,
-  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
-   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
-   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
-   0x06},
-  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
-   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
-   0x1e,0x0b,0x1b,0x0f},
-  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-   0x3f}
- },
-/* VGA_DAC */
- {
-  0x00,0x10,0x04,0x0114,
-  {0x11,0x09,0x15,0x2a},
-  0x3a,
-  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
-   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
-   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
-   0x1f},
-  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
-   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
-   0x1c,0x0e,0x11,0x15},
-  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
-   0x04}
- },
- {
-  0x08,0x0c,0x10,0x0a08,
-  {0x0c,0x0e,0x10,0x0b},
-  0x0c,
-  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
-   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
-   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
-   0x06},
-  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
-   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
-   0x00,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}
- },
-/* MD_D */
- {
-  0x28,0x18,0x08,0x2000,
-  {0x09,0x0f,0x00,0x06},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
-/* MD_E */
- {
-  0x50,0x18,0x08,0x4000,
-  {0x01,0x0f,0x00,0x06},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
-/* ExtVGATable */
- {
-  0x00,0x00,0x00,0x0000,
-  {0x01,0x0f,0x00,0x0e},
-  0x23,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-   0x01,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-   0xff}
- },
-/* ROM_SAVEPTR */
- {
-  0x9f,0x3b,0x00,0x00c0,
-  {0x00,0x00,0x00,0x00},
-  0x00,
-  {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
-   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,0x00,0x00,0x00,0x00,
-   0x00}
- },
-/* MD_F */
- {
-  0x50,0x18,0x0e,0x8000,
-  {0x01,0x0f,0x00,0x06},
-  0xa2,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
-   0xff},
-  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
-   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
-   0x0b,0x00,0x05,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
-   0xff}
- },
-/* MD_10 */
- {
-  0x50,0x18,0x0e,0x8000,
-  {0x01,0x0f,0x00,0x06},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
-/* MD_0_350 */
- {
-  0x28,0x18,0x0e,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0xa3,
-  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* MD_1_350 */
- {
-  0x28,0x18,0x0e,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0xa3,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* MD_2_350 */
- {
-  0x50,0x18,0x0e,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* MD_3_350 */
- {
-  0x50,0x18,0x0e,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* MD_0_1_400 */
- {
-  0x28,0x18,0x10,0x0800,
-  {0x08,0x03,0x00,0x02},
-  0x67,
-  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x0c,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* MD_2_3_400 */
- {
-  0x50,0x18,0x10,0x1000,
-  {0x00,0x03,0x00,0x02},
-  0x67,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x0c,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* MD_7_400 */
- {
-  0x50,0x18,0x10,0x1000,
-  {0x00,0x03,0x00,0x02},
-  0x66,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-   0x0e,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-   0xff}
- },
-/* MD_11 */
- {
-  0x50,0x1d,0x10,0xa000,
-  {0x01,0x0f,0x00,0x06},
-  0xe3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,
-   0xff},
-  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
-   0xff}
- },
-/* ExtEGATable */
- {
-  0x50,0x1d,0x10,0xa000,
-  {0x01,0x0f,0x00,0x06},
-  0xe3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
-/* MD_13 */
- {
-  0x28,0x18,0x08,0x2000,
-  {0x01,0x0f,0x00,0x0e},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-   0x41,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-   0xff}
- }
-};
-
-typedef struct _SiS310_ExtStruct
-{
-	UCHAR Ext_ModeID;
-	USHORT Ext_ModeFlag;
-	USHORT Ext_ModeInfo;
-	USHORT Ext_Point;
-	USHORT Ext_VESAID;
-	UCHAR Ext_VESAMEMSize;
-	UCHAR Ext_RESINFO;
-	UCHAR VB_ExtTVFlickerIndex;
-	UCHAR VB_ExtTVEdgeIndex;
-	UCHAR VB_ExtTVYFilterIndex;
-	UCHAR REFindex;
-} SiS310_ExtStruct;
-
-SiS310_ExtStruct  SiS310_EModeIDTable[]=
-{
- {0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x00},
- {0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08},
- {0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10},
- {0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00},
- {0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},
- {0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},
- {0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},
- {0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},
- {0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},
- {0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},
- {0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x00,0x13},
- {0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},
- {0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},
- {0x3c,0x063b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},
- {0x3d,0x067d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},
- {0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x25},
- {0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x25},
- {0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x08},
- {0x44,0x0a1d,0x0306,0x3a57,0x0111,0x08,0x06,0x00,0x00,0x05,0x08},
- {0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x00},
- {0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x00},
- {0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
- {0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},
- {0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
- {0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},
- {0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26},
- {0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27},
- {0x52,0x9a1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},
- {0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26},
- {0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27},
- {0x58,0x9a1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28},
- {0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25},
- {0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x10},
- {0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x08},
- {0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x00},
- {0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},
- {0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},
- {0x66,0x06ff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},
- {0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29},
- {0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29},
- {0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29},
- {0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f},
- {0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},
- {0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},
- {0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
- {0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
- {0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
- {0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
- {0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
- {0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
- {0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
- {0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
- {0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
- {0x7b,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},
- {0x7c,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},
- {0x7d,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},
- {0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
-};
-
-typedef struct _SiS310_Ext2Struct
-{
-	USHORT Ext_InfoFlag;
-	UCHAR Ext_CRT1CRTC;
-	UCHAR Ext_CRTVCLK;
-	UCHAR Ext_CRT2CRTC;
-	UCHAR  ModeID;
-	USHORT XRes;
-	USHORT YRes;
-	USHORT ROM_OFFSET;
-} SiS310_Ext2Struct;
-SiS310_Ext2Struct SiS310_RefIndex[]=
-{
- {0x005f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, /* 0x0 */
- {0x0467,0x0e,0x04,0x05,0x6a, 800, 600,0x3a86}, /* 0x1 */
- {0x0067,0x0f,0x08,0x48,0x6a, 800, 600,0x3a8b}, /* 0x2 */
- {0x0067,0x10,0x07,0x8b,0x6a, 800, 600,0x3a90}, /* 0x3 */
- {0x0147,0x11,0x0a,0x00,0x6a, 800, 600,0x3a95}, /* 0x4 */
- {0x4147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 */
- {0x4047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 */
- {0x4047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 */
- {0xc05f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, /* 0x8 */
- {0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x3a5c}, /* 0x9 */
- {0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3a61}, /* 0xa */
- {0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3a66}, /* 0xb */
- {0x4047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc */
- {0x4047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd */
- {0x4047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe */
- {0xc047,0x0c,0x15,0x00,0x2e, 640, 480,0x3a7a}, /* 0xf */
- {0x407f,0x04,0x00,0x00,0x2f, 640, 400,0x3a50}, /* 0x10 */
- {0xc00f,0x3c,0x01,0x06,0x31, 720, 480,0x3b85}, /* 0x11 */
- {0x000f,0x3d,0x03,0x06,0x32, 720, 576,0x3b8c}, /* 0x12 */
- {0x0187,0x15,0x06,0x00,0x37,1024, 768,0x3aab}, /* 0x13 */
- {0xc877,0x16,0x0b,0x06,0x37,1024, 768,0x3ab0}, /* 0x14 301b TV1024x768*/
- {0xc067,0x17,0x0f,0x49,0x37,1024, 768,0x3ab5}, /* 0x15 */
- {0x0267,0x18,0x11,0x00,0x37,1024, 768,0x3aba}, /* 0x16 */
- {0x0047,0x19,0x16,0x8c,0x37,1024, 768,0x3abf}, /* 0x17 */
- {0x4047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 */
- {0x4047,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 */
- {0x0387,0x1c,0x11,0x00,0x3a,1280,1024,0x3adc}, /* 0x1a */
- {0x0077,0x1d,0x19,0x07,0x3a,1280,1024,0x3ae1}, /* 0x1b */
- {0x0047,0x1e,0x1e,0x00,0x3a,1280,1024,0x3ae6}, /* 0x1c */
- {0x0007,0x1f,0x20,0x00,0x3a,1280,1024,0x3aeb}, /* 0x1d */
- {0x0007,0x20,0x21,0x00,0x3c,1600,1200,0x3af2}, /* 0x1e */
- {0x0007,0x21,0x22,0x00,0x3c,1600,1200,0x3af7}, /* 0x1f */
- {0x0007,0x22,0x23,0x00,0x3c,1600,1200,0x3afc}, /* 0x20 */
- {0x0007,0x23,0x25,0x00,0x3c,1600,1200,0x3b01}, /* 0x21 */
- {0x0007,0x24,0x26,0x00,0x3c,1600,1200,0x3b06}, /* 0x22 */
- {0x0007,0x25,0x2c,0x00,0x3c,1600,1200,0x3b0b}, /* 0x23 */
- {0x0007,0x26,0x34,0x00,0x3c,1600,1200,0x3b10}, /* 0x24 */
- {0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3a34}, /* 0x25 */
- {0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x3a3b}, /* 0x26 */
- {0x007f,0x02,0x04,0x05,0x51, 400, 300,0x3a42}, /* 0x27 */
- {0xc077,0x03,0x0b,0x06,0x52, 512, 384,0x3a49}, /* 0x28 */
- {0x8007,0x27,0x27,0x00,0x68,1920,1440,0x3b17}, /* 0x29 */
- {0x4007,0x28,0x29,0x00,0x68,1920,1440,0x3b1c}, /* 0x2a */
- {0x4007,0x29,0x2e,0x00,0x68,1920,1440,0x3b21}, /* 0x2b */
- {0x4007,0x2a,0x30,0x00,0x68,1920,1440,0x3b26}, /* 0x2c */
- {0x4007,0x2b,0x35,0x00,0x68,1920,1440,0x3b2b}, /* 0x2d */
- {0x4005,0x2c,0x39,0x00,0x68,1920,1440,0x3b30}, /* 0x2e */
- {0x4007,0x2d,0x2b,0x00,0x6c,2048,1536,0x3b37}, /* 0x2f */
- {0x4007,0x2e,0x31,0x00,0x6c,2048,1536,0x3b3c}, /* 0x30 */
- {0x4007,0x2f,0x33,0x00,0x6c,2048,1536,0x3b41}, /* 0x31 */
- {0x4007,0x30,0x37,0x00,0x6c,2048,1536,0x3b46}, /* 0x32 */
- {0x4005,0x31,0x38,0x00,0x6c,2048,1536,0x3b4b}, /* 0x33 */
- {0x0057,0x32,0x40,0x08,0x70, 800, 480,0x3b52}, /* 0x34 */
- {0x0047,0x33,0x07,0x08,0x70, 800, 480,0x3b57}, /* 0x35 */
- {0x0047,0x34,0x0a,0x08,0x70, 800, 480,0x3b5c}, /* 0x36 */
- {0x0057,0x35,0x0b,0x09,0x71,1024, 576,0x3b63}, /* 0x37 */
- {0x0047,0x36,0x11,0x09,0x71,1024, 576,0x3b68}, /* 0x38 */
- {0x0047,0x37,0x16,0x09,0x71,1024, 576,0x3b6d}, /* 0x39 */
- {0x0057,0x38,0x19,0x0a,0x75,1280, 720,0x3b74}, /* 0x3a */
- {0x0047,0x39,0x1e,0x0a,0x75,1280, 720,0x3b79}, /* 0x3b */
- {0x0047,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */
- {0x0027,0x3b,0x19,0x08,0x7b,1280, 960,0x3ad0}, /* 0x3d */
- {0x0027,0x3b,0x19,0x08,0x7b,1280, 960,0x3ad5}, /* 0x3e */
- {0xffff,0x00,0x00,0x00,0x00,0000,0000,0x0000}
-};
-
-typedef struct _SiS310_CRT1TableStruct
-{
-	UCHAR CR[17];
-} SiS310_CRT1TableStruct;
-SiS310_CRT1TableStruct SiS310_CRT1Table[]=
-{
- {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
-  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
-  0x00}, /* 0x0 */
- {0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
-  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
-  0x00}, /* 0x1 */
- {0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
-  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
-  0x01}, /* 0x2 */
- {0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
-  0x01}, /* 0x3 */
- {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
-  0x00}, /* 0x4 */
- {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
-  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
-  0x00}, /* 0x5 */
- {0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,
-  0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
-  0x00}, /* 0x6 */
- {0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f,
-  0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01,
-  0x00}, /* 0x7 */
- {0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f,
-  0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
-  0x00}, /* 0x8 */
- {0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
-  0xe0,0x83,0xdf,0xdf,0xfc,0x00,0x00,0x05,
-  0x61}, /* 0x9 */
- {0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
-  0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
-  0x61}, /* 0xa */
- {0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
-  0xe0,0x83,0xdf,0xdf,0x0e,0x10,0x00,0x05,
-  0x61}, /* 0xb */
- {0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
-  0xe6,0x8a,0xe5,0xe5,0xfc,0x00,0x00,0x01,
-  0x00}, /* 0xc */
- {0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
-  0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
-  0x01}, /* 0xd */
- {0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06,
-  0x01}, /* 0xe */
- {0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0,
-  0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06,
-  0x01}, /* 0xf */
- {0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0,
-  0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06,
-  0x01}, /* 0x10 */
- {0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0,
-  0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06,
-  0x01}, /* 0x11 */
- {0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0,
-  0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06,
-  0x61}, /* 0x12 */
- {0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0,
-  0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06,
-  0x61}, /* 0x13 */
- {0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0,
-  0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06,
-  0x61}, /* 0x14 */
- {0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f,
-  0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02,
-  0x00}, /* 0x15 */
- {0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
-  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
-  0x01}, /* 0x16 */
- {0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5,
-  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
-  0x01}, /* 0x17 */
- {0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5,
-  0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02,
-  0x01}, /* 0x18 */
- {0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5,
-  0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02,
-  0x01}, /* 0x19 */
- {0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5,
-  0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02,
-  0x62}, /* 0x1a */
- {0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5,
-  0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02,
-  0x62}, /* 0x1b */
- {0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba,
-  0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03,
-  0x00}, /* 0x1c */
- {0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a,
-  0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
-  0x01}, /* 0x1d */
- {0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a,
-  0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07,
-  0x01}, /* 0x1e */
- {0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a,
-  0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07,
-  0x01}, /* 0x1f */
- {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
-  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-  0x00}, /* 0x20 */
- {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
-  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-  0x00}, /* 0x21 */
- {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
-  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-  0x00}, /* 0x22 */
- {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
-  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-  0x00}, /* 0x23 */
- {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
-  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-  0x00}, /* 0x24 */
- {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
-  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-  0x00}, /* 0x25 */
- {0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10,
-  0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04,
-  0x00}, /* 0x26 */
- {0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
-  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
-  0x00}, /* 0x27 */
- {0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f,
-  0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05,
-  0x63}, /* 0x28 */
- {0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f,
-  0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05,
-  0x63}, /* 0x29 */
- {0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
-  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
-  0x00}, /* 0x2a */
- {0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
-  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
-  0x00}, /* 0x2b */
- {0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f,
-  0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01,
-  0x00}, /* 0x2c */
- {0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba,
-  0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05,
-  0x44}, /* 0x2d */
- {0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba,
-  0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05,
-  0x44}, /* 0x2e */
- {0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba,
-  0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05,
-  0x44}, /* 0x2f */
- {0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba,
-  0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05,
-  0x44}, /* 0x30 */
- {0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba,
-  0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05,
-  0x00}, /* 0x31 */
- {0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,
-  0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
-  0x01}, /* 0x32 */
- {0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
-  0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06,
-  0x01}, /* 0x33 */
- {0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba,
-  0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06,
-  0x01}, /* 0x34 */
- {0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1,
-  0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02,
-  0x01}, /* 0x35 */
- {0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
-  0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
-  0x01}, /* 0x36 */
- {0xa7,0x7f,0x7f,0x88,0x89,0x15,0x26,0xf1,
-  0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
-  0x01}, /* 0x37 */
- {0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
-  0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
-  0x01}, /* 0x38 */
- {0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4,
-  0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07,
-  0x01}, /* 0x39 */
- {0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
-  0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
-  0x01}, /* 0x3a */
- {0xdc,0x9f,0x9f,0x00,0xab,0x19,0xe6,0xef,
-  0xc0,0xc3,0xbf,0xbf,0xe7,0x10,0x00,0x07,
-  0x01}, /* 0x3b */
- {0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e,
-  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
-  0x00}, /* 0x3c */
- {0x7b,0x59,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
-  0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
-  0x01} /* 0x3d */
-};
-
-typedef struct _SiS310_MCLKDataStruct
-{
-	UCHAR SR28,SR29,SR2A;
-	USHORT CLOCK;
-} SiS310_MCLKDataStruct;
-
-SiS310_MCLKDataStruct SiS310_MCLKData[]=
-{
-	{ 0x5c,0x23,0x01,166},
-	{ 0x5c,0x23,0x01,166},
-	{ 0x5c,0x23,0x01,166},
-	{ 0x5c,0x23,0x01,166}
-};
-
-typedef struct _SiS310_ECLKDataStruct
-{
-	UCHAR SR2E,SR2F,SR30;
-	USHORT CLOCK;
-} SiS310_ECLKDataStruct;
-SiS310_ECLKDataStruct SiS310_ECLKData[]=
-{
-	{ 0x5c,0x23,0x01,166},
-	{ 0x5c,0x23,0x01,166},
-	{ 0x5c,0x23,0x01,166},
-	{ 0x5c,0x23,0x01,166}
-};
-
-typedef struct _SiS310_VCLKDataStruct
-{
-	UCHAR SR2B,SR2C;
-	USHORT CLOCK;
-} SiS310_VCLKDataStruct;
-SiS310_VCLKDataStruct SiS310_VCLKData[]=
-{
-	{ 0x1b,0xe1, 25}, /* 0x0 */
-	{ 0x4e,0xe4, 28}, /* 0x1 */
-	{ 0x57,0xe4, 31}, /* 0x2 */
-	{ 0xc3,0xc8, 36}, /* 0x3 */
-	{ 0x42,0xe2, 40}, /* 0x4 */
-	{ 0xfe,0xcd, 43}, /* 0x5 */
-	{ 0x5d,0xc4, 44}, /* 0x6 */
-	{ 0x52,0xe2, 49}, /* 0x7 */
-	{ 0x53,0xe2, 50}, /* 0x8 */
-	{ 0x74,0x67, 52}, /* 0x9 */
-	{ 0x6d,0x66, 56}, /* 0xa */
-	{ 0x6c,0xc3, 65}, /* 0xb */
-	{ 0x46,0x44, 67}, /* 0xc */
-	{ 0xb1,0x46, 68}, /* 0xd */
-	{ 0xd3,0x4a, 72}, /* 0xe */
-	{ 0x29,0x61, 75}, /* 0xf */
-	{ 0x6e,0x46, 76}, /* 0x10 */
-	{ 0x2b,0x61, 78}, /* 0x11 */
-	{ 0x31,0x42, 79}, /* 0x12 */
-	{ 0xab,0x44, 83}, /* 0x13 */
-	{ 0x46,0x25, 84}, /* 0x14 */
-	{ 0x78,0x29, 86}, /* 0x15 */
-	{ 0x62,0x44, 94}, /* 0x16 */
-	{ 0x2b,0x41,104}, /* 0x17 */
-	{ 0x3a,0x23,105}, /* 0x18 */
-	{ 0x70,0x44,108}, /* 0x19 */
-	{ 0x3c,0x23,109}, /* 0x1a */
-	{ 0x5e,0x43,113}, /* 0x1b */
-	{ 0xbc,0x44,116}, /* 0x1c */
-	{ 0xe0,0x46,132}, /* 0x1d */
-	{ 0x54,0x42,135}, /* 0x1e */
-	{ 0xea,0x2a,139}, /* 0x1f */
-	{ 0x41,0x22,157}, /* 0x20 */
-	{ 0x70,0x24,162}, /* 0x21 */
-	{ 0x30,0x21,175}, /* 0x22 */
-	{ 0x4e,0x22,189}, /* 0x23 */
-	{ 0xde,0x26,194}, /* 0x24 */
-	{ 0x62,0x06,202}, /* 0x25 */
-	{ 0x3f,0x03,229}, /* 0x26 */
-	{ 0xb8,0x06,234}, /* 0x27 */
-	{ 0x34,0x02,253}, /* 0x28 */
-	{ 0x58,0x04,255}, /* 0x29 */
-	{ 0x24,0x01,265}, /* 0x2a */
-	{ 0x9b,0x02,267}, /* 0x2b */
-	{ 0x70,0x05,270}, /* 0x2c */
-	{ 0x25,0x01,272}, /* 0x2d */
-	{ 0x9c,0x02,277}, /* 0x2e */
-	{ 0x27,0x01,286}, /* 0x2f */
-	{ 0x3c,0x02,291}, /* 0x30 */
-	{ 0xef,0x0a,292}, /* 0x31 */
-	{ 0xf6,0x0a,310}, /* 0x32 */
-	{ 0x95,0x01,315}, /* 0x33 */
-	{ 0xf0,0x09,324}, /* 0x34 */
-	{ 0xfe,0x0a,331}, /* 0x35 */
-	{ 0xf3,0x09,332}, /* 0x36 */
-	{ 0xea,0x08,340}, /* 0x37 */
-	{ 0xe8,0x07,376}, /* 0x38 */
-	{ 0xde,0x06,389}, /* 0x39 */
-	{ 0x52,0x2a, 54}, /* 0x3a */
-	{ 0x52,0x6a, 27}, /* 0x3b */
-	{ 0x62,0x24, 70}, /* 0x3c */
-	{ 0x62,0x64, 70}, /* 0x3d */
-	{ 0xa8,0x4c, 30}, /* 0x3e */
-	{ 0x20,0x26, 33}, /* 0x3f */
-	{ 0x31,0xc2, 39}  /* 0x40 */
-};
-
-typedef struct _SiS310_VBVCLKDataStruct
-{
-	UCHAR Part4_A,Part4_B;
-	USHORT CLOCK;
-} SiS310_VBVCLKDataStruct;
-
-SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
-{
-	{ 0x1b,0xe1, 25}, /* 0x0 */
-	{ 0x4e,0xe4, 28}, /* 0x1 */
-	{ 0x57,0xe4, 31}, /* 0x2 */
-	{ 0xc3,0xc8, 36}, /* 0x3 */
-	{ 0x42,0x47, 40}, /* 0x4 */
-	{ 0xfe,0xcd, 43}, /* 0x5 */
-	{ 0x5d,0xc4, 44}, /* 0x6 */
-	{ 0x52,0x47, 49}, /* 0x7 */
-	{ 0x53,0x47, 50}, /* 0x8 */
-	{ 0x74,0x67, 52}, /* 0x9 */
-	{ 0x6d,0x66, 56}, /* 0xa */
-	{ 0x5a,0x64, 65}, /* 0xb */
-	{ 0x46,0x44, 67}, /* 0xc */
-	{ 0xb1,0x46, 68}, /* 0xd */
-	{ 0xd3,0x4a, 72}, /* 0xe */
-	{ 0x29,0x61, 75}, /* 0xf */
-	{ 0x6d,0x46, 75}, /* 0x10 */
-	{ 0x41,0x43, 78}, /* 0x11 */
-	{ 0x31,0x42, 79}, /* 0x12 */
-	{ 0xab,0x44, 83}, /* 0x13 */
-	{ 0x46,0x25, 84}, /* 0x14 */
-	{ 0x78,0x29, 86}, /* 0x15 */
-	{ 0x62,0x44, 94}, /* 0x16 */
-	{ 0x2b,0x22,104}, /* 0x17 */
-	{ 0x49,0x24,105}, /* 0x18 */
-	{ 0xf8,0x2f,108}, /* 0x19 */
-	{ 0x3c,0x23,109}, /* 0x1a */
-	{ 0x5e,0x43,113}, /* 0x1b */
-	{ 0xbc,0x44,116}, /* 0x1c */
-	{ 0xe0,0x46,132}, /* 0x1d */
-	{ 0xd4,0x28,135}, /* 0x1e */
-	{ 0xea,0x2a,139}, /* 0x1f */
-	{ 0x41,0x22,157}, /* 0x20 */
-	{ 0x70,0x24,162}, /* 0x21 */
-	{ 0x30,0x21,175}, /* 0x22 */
-	{ 0x4e,0x22,189}, /* 0x23 */
-	{ 0xde,0x26,194}, /* 0x24 */
-	{ 0x70,0x07,202}, /* 0x25 */
-	{ 0x3f,0x03,229}, /* 0x26 */
-	{ 0xb8,0x06,234}, /* 0x27 */
-	{ 0x34,0x02,253}, /* 0x28 */
-	{ 0x58,0x04,255}, /* 0x29 */
-	{ 0x24,0x01,265}, /* 0x2a */
-	{ 0x9b,0x02,267}, /* 0x2b */
-	{ 0x70,0x05,270}, /* 0x2c */
-	{ 0x25,0x01,272}, /* 0x2d */
-	{ 0x9c,0x02,277}, /* 0x2e */
-	{ 0x27,0x01,286}, /* 0x2f */
-	{ 0x3c,0x02,291}, /* 0x30 */
-	{ 0xef,0x0a,292}, /* 0x31 */
-	{ 0xf6,0x0a,310}, /* 0x32 */
-	{ 0x95,0x01,315}, /* 0x33 */
-	{ 0xf0,0x09,324}, /* 0x34 */
-	{ 0xfe,0x0a,331}, /* 0x35 */
-	{ 0xf3,0x09,332}, /* 0x36 */
-	{ 0xea,0x08,340}, /* 0x37 */
-	{ 0xe8,0x07,376}, /* 0x38 */
-	{ 0xde,0x06,389}, /* 0x39 */
-	{ 0x52,0x2a, 54}, /* 0x3a */
-	{ 0x52,0x6a, 27}, /* 0x3b */
-	{ 0x62,0x24, 70}, /* 0x3c */
-	{ 0x62,0x64, 70}, /* 0x3d */
-	{ 0xa8,0x4c, 30}, /* 0x3e */
-	{ 0x20,0x26, 33}, /* 0x3f */
-	{ 0x31,0xc2, 39}  /* 0x40 */
-};
-
-UCHAR SiS310_ScreenOffset[]={ 0x14,0x19,0x20,0x28,0x32,0x40,
-                              0x50,0x64,0x78,0x80,0x2d,0x35 };
-
-typedef struct _SiS310_StResInfoStruct
-{
-	USHORT HTotal;
-	USHORT VTotal;
-} SiS310_StResInfoStruct;
-
-SiS310_StResInfoStruct SiS310_StResInfo[]=
-{
-	{ 640,400},
-	{ 640,350},
-	{ 720,400},
-	{ 720,350},
-	{ 640,480}
-};
-
-typedef struct _SiS310_ModeResInfoStruct
-{
-	USHORT HTotal;
-	USHORT VTotal;
-	UCHAR  XChar;
-	UCHAR  YChar;
-} SiS310_ModeResInfoStruct;
-
-SiS310_ModeResInfoStruct SiS310_ModeResInfo[]=
-{
-	{  320, 200, 8, 8},
-	{  320, 240, 8, 8},
-	{  320, 400, 8, 8},
-	{  400, 300, 8, 8},
-	{  512, 384, 8, 8},
-	{  640, 400, 8,16},
-	{  640, 480, 8,16},
-	{  800, 600, 8,16},
-	{ 1024, 768, 8,16},
-	{ 1280,1024, 8,16},
-	{ 1600,1200, 8,16},
-	{ 1920,1440, 8,16},
-	{ 2048,1536, 8,16},
-	{  720, 480, 8,16},
-	{  720, 576, 8,16},
-	{ 1280, 960, 8,16},
-	{  800, 480, 8,16},
-	{ 1024, 576, 8,16},
-	{ 1280, 720, 8,16}
-};
-
-UCHAR SiS310_OutputSelect = 0;
-
-UCHAR SiS310_SoftSetting = 30;
-
-UCHAR SiS310_SR07=0x18;
-
-UCHAR SiS310_SR15[8][4]={
-	{0x00,0x04,0x60,0x60},
-	{0x0f,0x0f,0x0f,0x0f},
-	{0xba,0xba,0xba,0xba},
-	{0xa9,0xa9,0xac,0xac},
-	{0xa0,0xa0,0xa0,0xa8},
-	{0x00,0x00,0x02,0x02},
-	{0x30,0x30,0x40,0x40},
-	{0x00,0xa5,0xfb,0xf6}
-};
-UCHAR SiS310_CR40[5][4]={
-	{0x77,0x77,0x33,0x33},
-	{0x77,0x77,0x33,0x33},
-	{0x00,0x00,0x00,0x00},
-	{0x5b,0x5b,0x03,0x03},
-	{0x00,0x00,0xf0,0xf8}
-};
-UCHAR SiS310_CR49[]={0xaa,0x88};
-UCHAR SiS310_SR1F=0x0;
-UCHAR SiS310_SR21=0xa5;
-UCHAR SiS310_SR22=0xfb;
-UCHAR SiS310_SR23=0xf6;
-UCHAR SiS310_SR24=0xd;
-UCHAR SiS310_SR25[]={0x33,0x3};
-UCHAR SiS310_SR31=0x0;
-UCHAR SiS310_SR32=0x11;
-UCHAR SiS310_SR33=0x0;
-UCHAR SiS310_CRT2Data_1_2 = 0x0;
-UCHAR SiS310_CRT2Data_4_D = 0x0;
-UCHAR SiS310_CRT2Data_4_E = 0x0;
-UCHAR SiS310_CRT2Data_4_10 = 0x80;
-USHORT SiS310_RGBSenseData = 0xd1;
-USHORT SiS310_VideoSenseData = 0xb9;
-USHORT SiS310_YCSenseData = 0xb3;
-USHORT SiS310_RGBSenseData2 = 0x0190;     /*301b*/
-USHORT SiS310_VideoSenseData2 = 0x0174;
-USHORT SiS310_YCSenseData2 = 0x016b;
-UCHAR SiS310_NTSCPhase[] = {0x21,0xed,0x8a,0x8};
-
-UCHAR SiS310_PALPhase[] = {0x2a,0x5,0xd3,0x0};
-
-typedef struct _SiS310_LCDDataStruct
-{
-	USHORT RVBHCMAX;
-	USHORT RVBHCFACT;
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT LCDHT;
-	USHORT LCDVT;
-} SiS310_LCDDataStruct;
-
-SiS310_LCDDataStruct  SiS310_StLCD1024x768Data[]=
-{
-	{   62,  25, 800, 546,1344, 806},
-	{   32,  15, 930, 546,1344, 806},
-	{   32,  15, 930, 546,1344, 806},
-	{  104,  45, 945, 496,1344, 806},
-	{   62,  25, 800, 546,1344, 806},
-	{   31,  18,1008, 624,1344, 806},
-	{    1,   1,1344, 806,1344, 806}
-};
-
-SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[]=
-{
-	{   12,   5, 896, 512,1344, 806},
-	{   12,   5, 896, 510,1344, 806},
-	{   32,  15,1008, 505,1344, 806},
-	{   32,  15,1008, 514,1344, 806},
-	{   12,   5, 896, 500,1344, 806},
-	{   42,  25,1024, 625,1344, 806},
-	{    1,   1,1344, 806,1344, 806},
-	{   12,   5, 896, 500,1344, 806},
-	{   42,  25,1024, 625,1344, 806},
-	{    1,   1,1344, 806,1344, 806},
-	{   12,   5, 896, 500,1344, 806},
-	{   42,  25,1024, 625,1344, 806},
-	{    1,   1,1344, 806,1344, 806}
-};
-
-SiS310_LCDDataStruct  SiS310_St2LCD1024x768Data[]=
-{
-	{   62,  25, 800, 546,1344, 806},
-	{   32,  15, 930, 546,1344, 806},
-	{   32,  15, 930, 546,1344, 806},
-	{  104,  45, 945, 496,1344, 806},
-	{   62,  25, 800, 546,1344, 806},
-	{   31,  18,1008, 624,1344, 806},
-	{    1,   1,1344, 806,1344, 806}
-};
-
-SiS310_LCDDataStruct  SiS310_StLCD1280x1024Data[]=
-{
-	{   22,   5, 800, 510,1650,1088},
-	{   22,   5, 800, 510,1650,1088},
-	{  176,  45, 900, 510,1650,1088},
-	{  176,  45, 900, 510,1650,1088},
-	{   22,   5, 800, 510,1650,1088},
-	{   13,   5,1024, 675,1560,1152},
-	{   16,   9,1266, 804,1688,1072},
-	{    1,   1,1688,1066,1688,1066}
-};
-
-SiS310_LCDDataStruct  SiS310_ExtLCD1280x1024Data[]=
-{
-	{  211,  60,1024, 501,1688,1066},
-	{  211,  60,1024, 508,1688,1066},
-	{  211,  60,1024, 501,1688,1066},
-	{  211,  60,1024, 508,1688,1066},
-	{  211,  60,1024, 500,1688,1066},
-	{  211,  75,1024, 625,1688,1066},
-	{  211, 120,1280, 798,1688,1066},
-	{    1,   1,1688,1066,1688,1066}
-};
-
-SiS310_LCDDataStruct  SiS310_St2LCD1280x1024Data[]=
-{
-	{   22,   5, 800, 510,1650,1088},
-	{   22,   5, 800, 510,1650,1088},
-	{  176,  45, 900, 510,1650,1088},
-	{  176,  45, 900, 510,1650,1088},
-	{   22,   5, 800, 510,1650,1088},
-	{   13,   5,1024, 675,1560,1152},
-	{   16,   9,1266, 804,1688,1072},
-	{    1,   1,1688,1066,1688,1066}
-};
-
-SiS310_LCDDataStruct  SiS310_NoScaleData[]=
-{
-	{    1,   1, 800, 449, 800, 449},
-	{    1,   1, 800, 449, 800, 449},
-	{    1,   1, 900, 449, 900, 449},
-	{    1,   1, 900, 449, 900, 449},
-	{    1,   1, 800, 525, 800, 525},
-	{    1,   1,1056, 628,1056, 628},
-	{    1,   1,1344, 806,1344, 806},
-	{    1,   1,1688,1066,1688,1066}
-};
-
-SiS310_LCDDataStruct  SiS310_LCD1280x960Data[]=
-{
-	{    9,   2, 800, 500,1800,1000},
-	{    9,   2, 800, 500,1800,1000},
-	{    4,   1, 900, 500,1800,1000},
-	{    4,   1, 900, 500,1800,1000},
-	{    9,   2, 800, 500,1800,1000},
-	{   30,  11,1056, 625,1800,1000},
-	{    5,   3,1350, 800,1800,1000},
-	{    1,   1,1576,1050,1576,1050},
-	{    1,   1,1800,1000,1800,1000}
-};
-
-typedef struct _SiS310_TVDataStruct
-{
-	USHORT RVBHCMAX;
-	USHORT RVBHCFACT;
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT TVHDE;
-	USHORT TVVDE;
-	USHORT RVBHRS;
-	UCHAR FlickerMode;
-	USHORT HALFRVBHRS;
-	UCHAR RY1COE;
-	UCHAR RY2COE;
-	UCHAR RY3COE;
-	UCHAR RY4COE;
-} SiS310_TVDataStruct;
-SiS310_TVDataStruct  SiS310_StPALData[]=
-{
- {    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
- {    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
- {    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
- {    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
- {    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
- {    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
-};
-
-SiS310_TVDataStruct  SiS310_ExtPALData[]=
-{
- {   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
- {  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
- {   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
- {    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
- {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},
- {   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},
- {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},
- {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}     /*301b*/
-};
-
-SiS310_TVDataStruct  SiS310_StNTSCData[]=
-{
- {    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
- {    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
- {    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
- {    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
- {    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
-};
-
-SiS310_TVDataStruct  SiS310_ExtNTSCData[]=
-{
- {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
- {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
- {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
- {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
- {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
- {  143, 120,1056, 643,1288, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
- {    2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},
- {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08} /*301b*/     
-};
-
-SiS310_TVDataStruct  SiS310_St1HiTVData[]=
-{
-0x00};
-
-SiS310_TVDataStruct  SiS310_St2HiTVData[]=
-{
-0x00};
-
-SiS310_TVDataStruct  SiS310_ExtHiTVData[]=
-{
-0x00};
-
-UCHAR SiS310_NTSCTiming[] = {
-  0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
-  0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
-  0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
-  0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
-  0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
-  0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
-  0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
-  0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00};
-
-UCHAR SiS310_PALTiming[] = {
-  0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
-  0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
-  0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
-  0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
-  0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
-  0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
-  0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
-  0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00};
-
-UCHAR SiS310_HiTVExtTiming[] = {0x00};
-
-UCHAR SiS310_HiTVSt1Timing[] = {0x00};
-
-UCHAR SiS310_HiTVSt2Timing[] = {0x00};
-
-UCHAR SiS310_HiTVTextTiming[] = {0x00};
-
-UCHAR SiS310_HiTVGroup3Data[] = {0x00};
-
-UCHAR SiS310_HiTVGroup3Simu[] = {0x00};
-
-UCHAR SiS310_HiTVGroup3Text[] = {0x00};
-
-typedef struct _SiS310_PanelDelayTblStruct
-{
- UCHAR timer[2];
-} SiS310_PanelDelayTblStruct;
-SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
-{{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,0x00},
-{0x00,0x00},
-{0x00,0x00},
-{0x00,0x00}};
-
-typedef struct _SiS310_LVDSDataStruct
-{
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT LCDHT;
- USHORT LCDVT;
-} SiS310_LVDSDataStruct;
-SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_1[]=
-{
- {848, 433,1060, 629},
- {848, 389,1060, 629},
- {848, 433,1060, 629},
- {848, 389,1060, 629},
- {848, 518,1060, 629},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {800, 449,1000, 644},
- {800, 525,1000, 635}
-};
-
-SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_2[]=
-{
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {800, 449,1000, 644},
- {800, 525,1000, 635}
-};
-
-SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_1[]=
-{
- {840, 438,1344, 806},
- {840, 409,1344, 806},
- {840, 438,1344, 806},
- {840, 409,1344, 806},
- {840, 518,1344, 806},
- {1050, 638,1344, 806},
- {1344, 806,1344, 806},
- {800, 449,1280, 801},
- {800, 525,1280, 813}
-};
-
-SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_2[]=
-{
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {800, 449,1280, 801},
- {800, 525,1280, 813}
-};
-
-SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_1[]=
-{
- {840, 438,1344, 806},
- {840, 409,1344, 806},
- {840, 438,1344, 806},
- {840, 409,1344, 806},
- {840, 518,1344, 806},
- {1050, 638,1344, 806},
- {1344, 806,1344, 806},
- {800, 449,1280, 801},
- {800, 525,1280, 813}
-};
-
-SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_2[]=
-{
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {800, 449,1280, 801},
- {800, 525,1280, 813}
-};
-
-SiS310_LVDSDataStruct  SiS310_LVDS640x480Data_1[]=
-{
- {800, 449, 800, 449},
- {800, 449, 800, 449},
- {800, 449, 800, 449},
- {800, 449, 800, 449},
- {800, 525, 800, 525},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628}
-};
-
-SiS310_LVDSDataStruct  SiS310_CHTVUNTSCData[]=
-{
- {840, 600, 840, 600},
- {840, 600, 840, 600},
- {840, 600, 840, 600},
- {840, 600, 840, 600},
- {784, 600, 784, 600},
- {1064, 750,1064, 750}
-};
-
-SiS310_LVDSDataStruct  SiS310_CHTVONTSCData[]=
-{
- {840, 525, 840, 525},
- {840, 525, 840, 525},
- {840, 525, 840, 525},
- {840, 525, 840, 525},
- {784, 525, 784, 525},
- {1040, 700,1040, 700}
-};
-
-SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=
-{
- {1008, 625,1008, 625},
- {1008, 625,1008, 625},
- {1008, 625,1008, 625},
- {1008, 625,1008, 625},
- {840, 750, 840, 750},
- {936, 836, 936, 836}
-};
-
-SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]=
-{
- {1008, 625,1008, 625},
- {1008, 625,1008, 625},
- {1008, 625,1008, 625},
- {1008, 625,1008, 625},
- {840, 625, 840, 625},
- {960, 750, 960, 750}
-};
-
-typedef struct _SiS310_LVDSDesStruct
-{
- USHORT LCDHDES;
- USHORT LCDVDES;
-} SiS310_LVDSDesStruct;
-SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=
-{
- {1059, 626},
- {1059, 624},
- {1059, 626},
- {1059, 624},
- {1059, 624},
- { 0, 627},
- { 0, 627},
- { 0,   0},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343,   0},
- {1343,   0},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=
-{
- {1059, 626},
- {1059, 624},
- {1059, 626},
- {1059, 624},
- {1059, 624},
- { 0, 627},
- { 0, 627},
- { 0,   0},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType03_1[]=
-{
- { 8, 436},
- { 8, 440},
- { 8, 436},
- { 8, 440},
- { 8, 512},
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType04_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343,   0},
- {1343,   0},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType05_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343,   0},
- {1343,   0},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType06_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343,   0},
- {1343,   0},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType07_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343,   0},
- {1343,   0},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType08_1[]=
-{
- {1059, 626},
- {1059, 624},
- {1059, 626},
- {1059, 624},
- {1059, 624},
- { 0, 627},
- { 0, 627},
- { 0,   0},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType09_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343,   0},
- {1343,   0},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType0a_1[]=
-{
- {1059, 626},
- {1059, 624},
- {1059, 626},
- {1059, 624},
- {1059, 624},
- { 0, 627},
- { 0, 627},
- { 0,   0},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343,   0},
- {1343,   0},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343,   0},
- {1343,   0},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343,   0},
- {1343,   0},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType0e_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343,   0},
- {1343,   0},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType0f_1[]=
-{
- {1343, 798},
- {1343, 794},
- {1343, 798},
- {1343, 794},
- {1343,   0},
- {1343,   0},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType00_2[]=
-{
- {976, 527},
- {976, 502},
- {976, 527},
- {976, 502},
- {976, 567},
- { 0, 627},
- { 0, 627},
- { 0,   0},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType01_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType02_2[]=
-{
- {976, 527},
- {976, 502},
- {976, 527},
- {976, 502},
- {976, 567},
- { 0, 627},
- { 0, 627},
- { 0,   0},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType03_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- {1152, 622},
- {1152, 597}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType04_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType05_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType06_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType07_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType08_2[]=
-{
- {976, 527},
- {976, 502},
- {976, 527},
- {976, 502},
- {976, 567},
- { 0, 627},
- { 0, 627},
- { 0,   0},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType09_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType0a_2[]=
-{
- {976, 527},
- {976, 502},
- {976, 527},
- {976, 502},
- {976, 567},
- { 0, 627},
- { 0, 627},
- { 0,   0},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType0d_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType0e_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_PanelType0f_2[]=
-{
- {1152, 622},
- {1152, 597},
- {1152, 622},
- {1152, 597},
- {1152, 662},
- {1232, 722},
- { 0, 805},
- { 0, 794},
- { 0,   0}
-};
-/*301b*/
-SiS310_LVDSDesStruct SiS310_PanelType1076_1[]=
-{
-0x00,0x00};
-SiS310_LVDSDesStruct SiS310_PanelType1210_1[]=
-{
-0x00,0x00};
-SiS310_LVDSDesStruct SiS310_PanelType1296_1[]=
-{
-0x00,0x00};
-SiS310_LVDSDesStruct SiS310_PanelType1076_2[]=
-{
-0x00,0x00};
-SiS310_LVDSDesStruct SiS310_PanelType1210_2[]=
-{
-0x00,0x00};
-SiS310_LVDSDesStruct SiS310_PanelType1296_2[]=
-{
-0x00,0x00};
-/*end 301b*/
-
-SiS310_LVDSDesStruct  SiS310_CHTVUNTSCDesData[]=
-{
- { 0,   0},
- { 0,   0},
- { 0,   0},
- { 0,   0},
- { 0,   0},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_CHTVONTSCDesData[]=
-{
- { 0,   0},
- { 0,   0},
- { 0,   0},
- { 0,   0},
- { 0,   0},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_CHTVUPALDesData[]=
-{
- {256,   0},
- {256,   0},
- {256,   0},
- {256,   0},
- { 0,   0},
- { 0,   0}
-};
-
-SiS310_LVDSDesStruct  SiS310_CHTVOPALDesData[]=
-{
- {256,   0},
- {256,   0},
- {256,   0},
- {256,   0},
- { 0,   0},
- { 0,   0}
-};
-
-typedef struct _SiS310_LVDSCRT1DataStruct
-{
- UCHAR CR[17];
-} SiS310_LVDSCRT1DataStruct;
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[]=
-{{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-   0x00 },
- {0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 },
- {0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-   0x00 },
- {0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 },
- {0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
-   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
-   0x00 },
- {0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1[]=
-{{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
-   0x00 },
- {0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
-   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
-   0x00 },
- {0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
-   0x00},
- {0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
-   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
-   0x00 },
- {0x73,0x4f,0x4f,0x97,0x55,0x86,0x04,0x3e,
-   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
-   0x00},
- {0x87,0x63,0x63,0x8B,0x69,0x1A,0x7c,0xf0,
-   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x26,
-   0x01},
- {0xA3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x02,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1[]=
-{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-   0x00 },
- {0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-   0x00 },
- {0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-   0x00 },
- {0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-   0x00 },
- {0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
-   0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
-   0x00 },
- {0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
-   0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
-   0x01 },
- {0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1_H[]=
-{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
-   0x00 },
- {0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
-   0x00 },
- {0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
-   0x00 },
- {0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
-   0x00 },
- {0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
-   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
-   0x00 },
- {0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_1_H[]=
-{{0x37,0x27,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
-   0x00 },
- {0x37,0x27,0x27,0x9B,0x2b,0x94,0x97,0x1f,
-   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
-   0x00},
- {0x37,0x27,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
-   0x00},
- {0x37,0x27,0x27,0x9B,0x2b,0x94,0x97,0x1f,
-   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
-   0x00},
- {0x37,0x27,0x27,0x9B,0x2b,0x94,0x04,0x3e,
-   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x44,
-   0x00},
- {0x41,0x31,0x31,0x85,0x35,0x1d,0x7c,0xf0,
-   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55,
-   0x01},
- {0x4f,0x3F,0x3F,0x93,0x45,0x0D,0x24,0xf5,
-   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x01,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_1_H[]=
-{{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
-   0x00 },
- {0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
-   0x00 },
- {0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
-   0x00 },
- {0x2f,0x27,0x93,0x2b,0x90,0x82,0x1f,
-   0x60,0x87,0x5d,0x83,0x10,0x00,0x04,
-   0x00 },
- {0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-   0xe2,0x89,0xdf,0x05,0x00,0x00,0x04,
-   0x00 },
- {0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-   0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-   0x01 },
- {0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2[]=
-{ {0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
-   0x00 },
- {0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
-   0x00 },
- {0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
-   0x00 },
- {0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
-   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x06,
-   0x00 },
- {0x7f,0x4f,0x83,0x62,0x12,0x72,0xba,
-   0x1c,0x80,0xdf,0x73,0x00,0x00,0x06,
-   0x00 },
- {0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2[]=
-{ {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-   0x00 },
- {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-   0x00 },
- {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-   0x00 },
- {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-   0x00 },
- {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-   0x00 },
- {0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-   0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-   0x01 },
- {0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2[]=
-{ {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-   0x00 },
- {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-   0x00 },
- {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-   0x00 },
- {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-   0x00 },
- {0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-   0x00 },
- {0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-   0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-   0x01 },
- {0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_2_H[]=
-{ {0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-   0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
-   0x00 },
- {0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
-   0x00 },
- {0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-   0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
-   0x00 },
- {0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
-   0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
-   0x00 },
- {0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
-   0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
-   0x00 },
- {0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x768_2_H[]=
-{ {0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-   0x00 },
- {0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-   0x00 },
- {0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-   0x00 },
- {0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-   0x00 },
- {0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-   0x00 },
- {0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-   0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-   0x01 },
- {0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x1024_2_H[]=
-{ {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-   0x00 },
- {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-   0x00 },
- {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-   0x00 },
- {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-   0x00 },
- {0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-   0x00 },
- {0x4f,0x31,0x93,0x3e,0x86,0x24,0xf1,
-   0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-   0x01 },
- {0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UNTSC[]=
-{ {0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
-   0x00 },
- {0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
-   0x00 },
- {0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-   0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
-   0x00 },
- {0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-   0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,
-   0x00 },
- {0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba,
-   0x18,0x84,0xdf,0x57,0x00,0x00,0x01,
-   0x00 },
- {0x80,0x63,0x84,0x6c,0x17,0xec,0xf0,
-   0x90,0x8c,0x57,0xed,0x20,0x00,0x06,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1ONTSC[]=
-{ {0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
-   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
-   0x00 },
- {0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
-   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
-   0x00 },
- {0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
-   0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
-   0x00 },
- {0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
-   0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,
-   0x00 },
- {0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e,
-   0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,
-   0x00 },
- {0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0,
-   0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1UPAL[]=
-{ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
-   0x00 },
- {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-   0x00 },
- {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
-   0x00 },
- {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-   0x00 },
- {0x64,0x4f,0x88,0x55,0x80,0xec,0xba,
-   0x50,0x84,0xdf,0xed,0x00,0x00,0x05,
-   0x00 },
- {0x70,0x63,0x94,0x68,0x8d,0x42,0xf1,
-   0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,
-   0x01 }};
-
-SiS310_LVDSCRT1DataStruct  SiS310_CHTVCRT1OPAL[]=
-{ {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
-   0x00 },
- {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-   0x00 },
- {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
-   0x00 },
- {0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-   0xde,0x81,0x5d,0x70,0x00,0x00,0x05,
-   0x00 },
- {0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,
-   0x20,0x83,0xdf,0x70,0x00,0x00,0x05,
-   0x00 },
- {0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
-   0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
-   0x01 }};
-
-typedef struct _SiS310_CHTVRegDataStruct
-{
- UCHAR Reg[5];
-} SiS310_CHTVRegDataStruct;
-SiS310_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] = {
-0x00 };
-
-SiS310_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] = {
-0x00 };
-
-SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] = {
-0x00 };
-
-SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] = {
-0x00 };
-
-UCHAR SiS310_CHTVVCLKUNTSC[]={0x00 };
-
-UCHAR SiS310_CHTVVCLKONTSC[]={0x00 };
-
-UCHAR SiS310_CHTVVCLKUPAL[]={0x00 };
-
-UCHAR SiS310_CHTVVCLKOPAL[]={0x00 };
-
diff -Nru a/drivers/video/sis/init.c b/drivers/video/sis/init.c
--- a/drivers/video/sis/init.c	Thu Jul 11 10:30:30 2002
+++ b/drivers/video/sis/init.c	Fri Mar  7 11:19:00 2003
@@ -1,17 +1,24 @@
 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.c,v 1.3 2002/24/04 01:16:16 dawes Exp $ */
 /*
- * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740
+ * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740/330
  * (Universal module for Linux kernel framebuffer and XFree86 4.x)
  *
  * Assembler-To-C translation
- * Parts Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net>
+ * Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net>
+ * Minor parts Copyright SiS, Inc.
  *
  * Based on BIOS
- *     1.10.07 (1.10a) for SiS650/LVDS+CH7019
- *     1.07.1b for SiS650/301(B/LV)
- *     2.04.50 (I) and 2.04.5c (II) for SiS630/301(B)
- *     2.02.3b, 2.03.02 and 2.04.5c for 630/LVDS/LVDS+CH7005
+ *     1.10.07, 1.10a for 650/CH7019
+ *     1.11.21a for 740/CH7019
+ *     1.11.05 for 650/LVDS (w/o Chrontel)
+ *     1.07.1b, 1.11.6s, 1.11.6w, 1.11.7w, 1.11.8r for 650/301(B/LV)
+ *     2.04.50 (I) and 2.04.5c (II) for 630/301(B)
+ *     2.06.50 for 630/301B (dual VGA)
+ *     2.02.3b, 2.03.02, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
+ *     2.04.5c, 2.04.6c for 730+LVDS+CH7005
  *     1.09b for 315/301(B)
+ *     1.16.51 for 300+301LV (ECS A907)
+ *     1.01.03 for 330 (Xabre 400)
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -31,8 +38,16 @@
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  *
+ * TW says: This code looks awful, I know. But please don't do anything about
+ * this otherwise debugging will be hell.
+ * The code is extremely fragile as regards the different chipsets, different
+ * video bridges and combinations thereof. If anything is changed, extreme
+ * care has to be taken that that change doesn't break it for other chipsets,
+ * bridges or combinations thereof.
+ * All comments in this file are by me, regardless if they are marked TW or not.
+ *
  */
-
+ 
 #include "init.h"
 
 #ifdef SIS300
@@ -44,25 +59,27 @@
 #endif
 
 #ifdef LINUX_XF86
-BOOLEAN SiSBIOSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                       ScrnInfoPtr pScrn, DisplayModePtr mode);
+BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                       ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
+DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn);
 #ifdef SISDUALHEAD /* TW: For dual head */
-BOOLEAN SiSBIOSSetModeCRT1(PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                       ScrnInfoPtr pScrn, DisplayModePtr mode);
-BOOLEAN SiSBIOSSetModeCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                       ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
+BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
                        ScrnInfoPtr pScrn, DisplayModePtr mode);
 #endif /* dual head */
 #endif /* linux_xf86 */
 
-#ifndef LINUX_XF86
-BOOLEAN SiSInit(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#ifdef LINUXBIOS
+BOOLEAN SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
 #endif
 
 #ifdef LINUX_XF86
-BOOLEAN SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                   ScrnInfoPtr pScrn,USHORT ModeNo);
+BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                   ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
 #else
-BOOLEAN SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo);
+BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                   USHORT ModeNo);
 #endif
 
 #if defined(ALLOC_PRAGMA)
@@ -70,34 +87,13 @@
 #pragma alloc_text(PAGE,SiSInit)
 #endif
 
-void DelaySeconds(int seconds);
-void DebugCode(UCHAR code);
+static ULONG GetDRAMSize(SiS_Private *SiS_Pr,
+                         PSIS_HW_DEVICE_INFO HwDeviceExtension);
 
-#ifdef LINUX_XF86
-/* TW: Mode table for X driver */
-UShort  ModeIndex_320x480[]      = {0x5A, 0x5B, 0x00, 0x00};  /* DSTN/FSTN */
-UShort  ModeIndex_512x384[]      = {0x52, 0x58, 0x00, 0x5c};
-UShort  ModeIndex_640x480[]      = {0x2E, 0x44, 0x00, 0x62};
-UShort  ModeIndex_720x480[]      = {0x31, 0x33, 0x00, 0x35};
-UShort  ModeIndex_720x576[]      = {0x32, 0x34, 0x00, 0x36};
-UShort  ModeIndex_800x480[]      = {0x70, 0x7a, 0x00, 0x76};  /* 310/325 series only */
-UShort  ModeIndex_800x600[]      = {0x30, 0x47, 0x00, 0x63};
-UShort  ModeIndex_1024x768[]     = {0x38, 0x4A, 0x00, 0x64};
-UShort  ModeIndex_1024x576[]     = {0x71, 0x74, 0x00, 0x77};  /* 310/325 series only */
-UShort  ModeIndex_1024x600[]     = {0x20, 0x21, 0x00, 0x22};  /* 300 series only */
-UShort  ModeIndex_1280x1024[]    = {0x3A, 0x4D, 0x00, 0x65};
-UShort  ModeIndex_300_1280x960[] = {0x6e, 0x6f, 0x00, 0x7b};
-UShort  ModeIndex_310_1280x960[] = {0x7C, 0x7D, 0x00, 0x7E};
-UShort  ModeIndex_1152x768[]     = {0x23, 0x24, 0x00, 0x25};  /* 300 series only */
-UShort  ModeIndex_1280x768[]     = {0x23, 0x24, 0x00, 0x25};  /* 310/325 series only */
-UShort  ModeIndex_1280x720[]     = {0x79, 0x75, 0x00, 0x78};  /* 310/325 series only */
-UShort  ModeIndex_1400x1050[]    = {0x26, 0x27, 0x00, 0x28};  /* 310/325 series only */
-UShort  ModeIndex_1600x1200[]    = {0x3C, 0x3D, 0x00, 0x66};
-UShort  ModeIndex_1920x1440[]    = {0x68, 0x69, 0x00, 0x6B};
-UShort  ModeIndex_2048x1536[]    = {0x6c, 0x6d, 0x00, 0x6e};  /* 310/325 series only */
-#endif
+static void DelaySeconds(int seconds);
+void SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code);
 
-void
+static void
 DelaySeconds(int seconds)
 {
   int i;
@@ -124,453 +120,584 @@
 }
 
 void
-DebugCode(UCHAR code)
+SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code)
 {
-  OutPortByte ( 0x80, code);
-  /*OutPortByte ( 0x300, code);*/
+  OutPortByte(0x80, code);
   DelaySeconds(0x3);
 }
 
 #ifdef SIS300
-void
-InitTo300Pointer(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static void
+InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-   SiS_SModeIDTable = (SiS_StStruct *) SiS300_SModeIDTable;
-   SiS_VBModeIDTable = (SiS_VBModeStruct *) SiS300_VBModeIDTable;
-   SiS_StandTable = (SiS_StandTableStruct *) SiS300_StandTable;
-   SiS_EModeIDTable = (SiS_ExtStruct *) SiS300_EModeIDTable;
-   SiS_RefIndex = (SiS_Ext2Struct *) SiS300_RefIndex;
-   SiS_CRT1Table = (SiS_CRT1TableStruct *) SiS300_CRT1Table;
-   SiS_MCLKData_0 = (SiS_MCLKDataStruct *) SiS300_MCLKData;
-   SiS_ECLKData = (SiS_ECLKDataStruct *) SiS300_ECLKData;
-   SiS_VCLKData = (SiS_VCLKDataStruct *) SiS300_VCLKData;
-   SiS_VBVCLKData = (SiS_VBVCLKDataStruct *) SiS300_VCLKData;
-   SiS_ScreenOffset = SiS300_ScreenOffset;
-   SiS_StResInfo = (SiS_StResInfoStruct *) SiS300_StResInfo;
-   SiS_ModeResInfo = (SiS_ModeResInfoStruct *) SiS300_ModeResInfo;
-
-   pSiS_OutputSelect = &SiS300_OutputSelect;
-   pSiS_SoftSetting = &SiS300_SoftSetting;
-   pSiS_SR07 = &SiS300_SR07;
-   SiS_SR15 = SiS300_SR15;
-   SiS_CR40 = SiS300_CR40;
-   SiS_CR49 = SiS300_CR49;
-   pSiS_SR1F = &SiS300_SR1F;
-   pSiS_SR21 = &SiS300_SR21;
-   pSiS_SR22 = &SiS300_SR22;
-   pSiS_SR23 = &SiS300_SR23;
-   pSiS_SR24 = &SiS300_SR24;
-   SiS_SR25 = SiS300_SR25;
-   pSiS_SR31 = &SiS300_SR31;
-   pSiS_SR32 = &SiS300_SR32;
-   pSiS_SR33 = &SiS300_SR33;
-   pSiS_CRT2Data_1_2 = &SiS300_CRT2Data_1_2;
-   pSiS_CRT2Data_4_D = &SiS300_CRT2Data_4_D;
-   pSiS_CRT2Data_4_E = &SiS300_CRT2Data_4_E;
-   pSiS_CRT2Data_4_10 = &SiS300_CRT2Data_4_10;
-   pSiS_RGBSenseData = &SiS300_RGBSenseData;
-   pSiS_VideoSenseData = &SiS300_VideoSenseData;
-   pSiS_YCSenseData = &SiS300_YCSenseData;
-   pSiS_RGBSenseData2 = &SiS300_RGBSenseData2;
-   pSiS_VideoSenseData2 = &SiS300_VideoSenseData2;
-   pSiS_YCSenseData2 = &SiS300_YCSenseData2;
-
-   SiS_NTSCPhase  = SiS300_NTSCPhase;
-   SiS_PALPhase   = SiS300_PALPhase;
-   SiS_NTSCPhase2 = SiS300_NTSCPhase2;
-   SiS_PALPhase2  = SiS300_PALPhase2;
-   SiS_PALMPhase  = SiS300_PALMPhase;
-   SiS_PALNPhase  = SiS300_PALNPhase;
-   SiS_PALMPhase2 = SiS300_PALMPhase2;
-   SiS_PALNPhase2 = SiS300_PALNPhase2;
-
-   SiS_StLCD1024x768Data = (SiS_LCDDataStruct *) SiS300_StLCD1024x768Data;
-   SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *) SiS300_ExtLCD1024x768Data;
-   SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *) SiS300_St2LCD1024x768Data;
-   SiS_StLCD1280x1024Data = (SiS_LCDDataStruct *) SiS300_StLCD1280x1024Data;
-   SiS_ExtLCD1280x1024Data = (SiS_LCDDataStruct *) SiS300_ExtLCD1280x1024Data;
-   SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *) SiS300_St2LCD1280x1024Data;
-   SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *) SiS300_NoScaleData1024x768;
-   SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *) SiS300_NoScaleData1280x1024;
-   SiS_LCD1280x960Data = (SiS_LCDDataStruct *) SiS300_LCD1280x960Data;
-   SiS_StPALData = (SiS_TVDataStruct *) SiS300_StPALData;
-   SiS_ExtPALData = (SiS_TVDataStruct *) SiS300_ExtPALData;
-   SiS_StNTSCData = (SiS_TVDataStruct *) SiS300_StNTSCData;
-   SiS_ExtNTSCData = (SiS_TVDataStruct *) SiS300_ExtNTSCData;
-   SiS_St1HiTVData = (SiS_TVDataStruct *) SiS300_St1HiTVData;
-   SiS_St2HiTVData = (SiS_TVDataStruct *) SiS300_St2HiTVData;
-   SiS_ExtHiTVData = (SiS_TVDataStruct *) SiS300_ExtHiTVData;
-   SiS_NTSCTiming = SiS300_NTSCTiming;
-   SiS_PALTiming = SiS300_PALTiming;
-   SiS_HiTVSt1Timing = SiS300_HiTVSt1Timing;
-   SiS_HiTVSt2Timing = SiS300_HiTVSt2Timing;
-   SiS_HiTVTextTiming = SiS300_HiTVTextTiming;
-   SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data;
-   SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu;
-   SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text;
-
-   SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *) SiS300_PanelDelayTbl;
-   SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *) SiS300_PanelDelayTblLVDS;
-
-   SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *) SiS300_LVDS800x600Data_1;
-   SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *) SiS300_LVDS800x600Data_2;
-   SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *) SiS300_LVDS1024x768Data_1;
-   SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *) SiS300_LVDS1024x768Data_2;
-   SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_1;
-   SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_2;
-   SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_1;
-   SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *) SiS300_LVDS1280x1024Data_2;
-   SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *) SiS300_LVDS640x480Data_1;
-   SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *) SiS300_LVDS1024x600Data_1;
-   SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *) SiS300_LVDS1024x600Data_2;
-   SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *) SiS300_LVDS1152x768Data_1;
-   SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *) SiS300_LVDS1152x768Data_2;
-   SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *) SiS300_CHTVUNTSCData;
-   SiS_CHTVONTSCData = (SiS_LVDSDataStruct *) SiS300_CHTVONTSCData;
-   SiS_CHTVUPALData  = (SiS_LVDSDataStruct *) SiS300_CHTVUPALData;
-   SiS_CHTVOPALData  = (SiS_LVDSDataStruct *) SiS300_CHTVOPALData;
-   SiS_PanelType00_1 = (SiS_LVDSDesStruct *) SiS300_PanelType00_1;
-   SiS_PanelType01_1 = (SiS_LVDSDesStruct *) SiS300_PanelType01_1;
-   SiS_PanelType02_1 = (SiS_LVDSDesStruct *) SiS300_PanelType02_1;
-   SiS_PanelType03_1 = (SiS_LVDSDesStruct *) SiS300_PanelType03_1;
-   SiS_PanelType04_1 = (SiS_LVDSDesStruct *) SiS300_PanelType04_1;
-   SiS_PanelType05_1 = (SiS_LVDSDesStruct *) SiS300_PanelType05_1;
-   SiS_PanelType06_1 = (SiS_LVDSDesStruct *) SiS300_PanelType06_1;
-   SiS_PanelType07_1 = (SiS_LVDSDesStruct *) SiS300_PanelType07_1;
-   SiS_PanelType08_1 = (SiS_LVDSDesStruct *) SiS300_PanelType08_1;
-   SiS_PanelType09_1 = (SiS_LVDSDesStruct *) SiS300_PanelType09_1;
-   SiS_PanelType0a_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0a_1;
-   SiS_PanelType0b_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0b_1;
-   SiS_PanelType0c_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0c_1;
-   SiS_PanelType0d_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0d_1;
-   SiS_PanelType0e_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0e_1;
-   SiS_PanelType0f_1 = (SiS_LVDSDesStruct *) SiS300_PanelType0f_1;
-   SiS_PanelType00_2 = (SiS_LVDSDesStruct *) SiS300_PanelType00_2;
-   SiS_PanelType01_2 = (SiS_LVDSDesStruct *) SiS300_PanelType01_2;
-   SiS_PanelType02_2 = (SiS_LVDSDesStruct *) SiS300_PanelType02_2;
-   SiS_PanelType03_2 = (SiS_LVDSDesStruct *) SiS300_PanelType03_2;
-   SiS_PanelType04_2 = (SiS_LVDSDesStruct *) SiS300_PanelType04_2;
-   SiS_PanelType05_2 = (SiS_LVDSDesStruct *) SiS300_PanelType05_2;
-   SiS_PanelType06_2 = (SiS_LVDSDesStruct *) SiS300_PanelType06_2;
-   SiS_PanelType07_2 = (SiS_LVDSDesStruct *) SiS300_PanelType07_2;
-   SiS_PanelType08_2 = (SiS_LVDSDesStruct *) SiS300_PanelType08_2;
-   SiS_PanelType09_2 = (SiS_LVDSDesStruct *) SiS300_PanelType09_2;
-   SiS_PanelType0a_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0a_2;
-   SiS_PanelType0b_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0b_2;
-   SiS_PanelType0c_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0c_2;
-   SiS_PanelType0d_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0d_2;
-   SiS_PanelType0e_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0e_2;
-   SiS_PanelType0f_2 = (SiS_LVDSDesStruct *) SiS300_PanelType0f_2;
-   SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *) SiS300_CHTVUNTSCDesData;
-   SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *) SiS300_CHTVONTSCDesData;
-   SiS_CHTVUPALDesData = (SiS_LVDSDesStruct *) SiS300_CHTVUPALDesData;
-   SiS_CHTVOPALDesData = (SiS_LVDSDesStruct *) SiS300_CHTVOPALDesData;
-   SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_1;
-   SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_1;
-   SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_1;
-   SiS_LVDSCRT11024x600_1 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x600_1;
-   SiS_LVDSCRT11152x768_1 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11152x768_1;
-   SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_1_H;
-   SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_1_H;
-   SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_1_H;
-   SiS_LVDSCRT11024x600_1_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x600_1_H;
-   SiS_LVDSCRT11152x768_1_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11152x768_1_H;
-   SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_2;
-   SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_2;
-   SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_2;
-   SiS_LVDSCRT11024x600_2 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x600_2;
-   SiS_LVDSCRT11152x768_2 = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11152x768_2;
-   SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT1800x600_2_H;
-   SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x768_2_H;
-   SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11280x1024_2_H;
-   SiS_LVDSCRT11024x600_2_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11024x600_2_H;
-   SiS_LVDSCRT11152x768_2_H = (SiS_LVDSCRT1DataStruct *) SiS300_LVDSCRT11152x768_2_H;
-   SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1UNTSC;
-   SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1ONTSC;
-   SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1UPAL;
-   SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *) SiS300_CHTVCRT1OPAL;
-   SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_UNTSC;
-   SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_ONTSC;
-   SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_UPAL;
-   SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *) SiS300_CHTVReg_OPAL;
-   SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
-   SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
-   SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL;
-   SiS_CHTVVCLKOPAL = SiS300_CHTVVCLKOPAL;
-
-   Panel320x480 = Panel300_320x480;
-   Panel640x480 = Panel300_640x480;
-   Panel800x600 = Panel300_800x600;
-   Panel1024x768 = Panel300_1024x768;
-   Panel1280x1024 = Panel300_1280x1024;
-   Panel1280x960 = Panel300_1280x960;
-   Panel1024x600 = Panel300_1024x600;
-   Panel1152x768 = Panel300_1152x768;
-   Panel1600x1200 = 16;  /*Panel300_1600x1200;  OLD */
-   Panel1400x1050 = 16;  /* TW: Something illegal */
-   Panel1152x864 = 16;   /* TW: Something illegal */
-   Panel1280x768 = 16;   /* TW: Something illegal */
-   Panel1024x600 = 16;   /* TW: Something illegal */
-   PanelMax = Panel300_320x480;        /* TW: highest value */
-   PanelMinLVDS = Panel300_800x600;    /* TW: Lowest value LVDS */
-   PanelMin301 = Panel310_1024x768;    /* TW: lowest value 301 */
+   SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS300_SModeIDTable;
+   SiS_Pr->SiS_VBModeIDTable = (SiS_VBModeStruct *)SiS300_VBModeIDTable;
+   SiS_Pr->SiS_StandTable    = (SiS_StandTableStruct *)SiS300_StandTable;
+   SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS300_EModeIDTable;
+   SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS300_RefIndex;
+   SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS300_CRT1Table;
+   if(HwDeviceExtension->jChipType == SIS_300) {
+      SiS_Pr->SiS_MCLKData_0    = (SiS_MCLKDataStruct *)SiS300_MCLKData_300; /* 300 */
+   } else {
+      SiS_Pr->SiS_MCLKData_0    = (SiS_MCLKDataStruct *)SiS300_MCLKData_630; /* 630, 730 */
+   }
+   SiS_Pr->SiS_ECLKData      = (SiS_ECLKDataStruct *)SiS300_ECLKData;
+   SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS300_VCLKData;
+   SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS300_VCLKData;
+   SiS_Pr->SiS_ScreenOffset  = SiS300_ScreenOffset;
+   SiS_Pr->SiS_StResInfo     = (SiS_StResInfoStruct *)SiS300_StResInfo;
+   SiS_Pr->SiS_ModeResInfo   = (SiS_ModeResInfoStruct *)SiS300_ModeResInfo;
 
+   SiS_Pr->pSiS_OutputSelect = &SiS300_OutputSelect;
+   SiS_Pr->pSiS_SoftSetting  = &SiS300_SoftSetting;
+
+   SiS_Pr->SiS_SR15  = SiS300_SR15;
+
+#ifndef LINUX_XF86
+   SiS_Pr->pSiS_SR07 = &SiS300_SR07;
+   SiS_Pr->SiS_CR40  = SiS300_CR40;
+   SiS_Pr->SiS_CR49  = SiS300_CR49;
+   SiS_Pr->pSiS_SR1F = &SiS300_SR1F;
+   SiS_Pr->pSiS_SR21 = &SiS300_SR21;
+   SiS_Pr->pSiS_SR22 = &SiS300_SR22;
+   SiS_Pr->pSiS_SR23 = &SiS300_SR23;
+   SiS_Pr->pSiS_SR24 = &SiS300_SR24;
+   SiS_Pr->SiS_SR25  = SiS300_SR25;
+   SiS_Pr->pSiS_SR31 = &SiS300_SR31;
+   SiS_Pr->pSiS_SR32 = &SiS300_SR32;
+   SiS_Pr->pSiS_SR33 = &SiS300_SR33;
+   SiS_Pr->pSiS_CRT2Data_1_2  = &SiS300_CRT2Data_1_2;
+   SiS_Pr->pSiS_CRT2Data_4_D  = &SiS300_CRT2Data_4_D;
+   SiS_Pr->pSiS_CRT2Data_4_E  = &SiS300_CRT2Data_4_E;
+   SiS_Pr->pSiS_CRT2Data_4_10 = &SiS300_CRT2Data_4_10;
+   SiS_Pr->pSiS_RGBSenseData    = &SiS300_RGBSenseData;
+   SiS_Pr->pSiS_VideoSenseData  = &SiS300_VideoSenseData;
+   SiS_Pr->pSiS_YCSenseData     = &SiS300_YCSenseData;
+   SiS_Pr->pSiS_RGBSenseData2   = &SiS300_RGBSenseData2;
+   SiS_Pr->pSiS_VideoSenseData2 = &SiS300_VideoSenseData2;
+   SiS_Pr->pSiS_YCSenseData2    = &SiS300_YCSenseData2;
+#endif
+
+   SiS_Pr->SiS_NTSCPhase  = SiS300_NTSCPhase;
+   SiS_Pr->SiS_PALPhase   = SiS300_PALPhase;
+   SiS_Pr->SiS_NTSCPhase2 = SiS300_NTSCPhase2;
+   SiS_Pr->SiS_PALPhase2  = SiS300_PALPhase2;
+   SiS_Pr->SiS_PALMPhase  = SiS300_PALMPhase;
+   SiS_Pr->SiS_PALNPhase  = SiS300_PALNPhase;
+   SiS_Pr->SiS_PALMPhase2 = SiS300_PALMPhase2;
+   SiS_Pr->SiS_PALNPhase2 = SiS300_PALNPhase2;
+
+   SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS300_StLCD1024x768Data;
+   SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_ExtLCD1024x768Data;
+   SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_St2LCD1024x768Data;
+   SiS_Pr->SiS_StLCD1280x1024Data   = (SiS_LCDDataStruct *)SiS300_StLCD1280x1024Data;
+   SiS_Pr->SiS_ExtLCD1280x1024Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1280x1024Data;
+   SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS300_St2LCD1280x1024Data;
+   SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS300_NoScaleData1024x768;
+   SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS300_NoScaleData1280x1024;
+   SiS_Pr->SiS_LCD1280x960Data      = (SiS_LCDDataStruct *)SiS300_LCD1280x960Data;
+   SiS_Pr->SiS_ExtLCD1400x1050Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1400x1050Data;
+   SiS_Pr->SiS_ExtLCD1600x1200Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1600x1200Data;
+   SiS_Pr->SiS_StLCD1400x1050Data   = (SiS_LCDDataStruct *)SiS300_StLCD1400x1050Data;
+   SiS_Pr->SiS_StLCD1600x1200Data   = (SiS_LCDDataStruct *)SiS300_StLCD1600x1200Data;
+   SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS300_NoScaleData1400x1050;
+   SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS300_NoScaleData1600x1200;
+
+   SiS_Pr->SiS_StPALData   = (SiS_TVDataStruct *)SiS300_StPALData;
+   SiS_Pr->SiS_ExtPALData  = (SiS_TVDataStruct *)SiS300_ExtPALData;
+   SiS_Pr->SiS_StNTSCData  = (SiS_TVDataStruct *)SiS300_StNTSCData;
+   SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS300_ExtNTSCData;
+/* SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS300_St1HiTVData;  */
+   SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS300_St2HiTVData;
+   SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS300_ExtHiTVData;
+
+   SiS_Pr->SiS_NTSCTiming     = SiS300_NTSCTiming;
+   SiS_Pr->SiS_PALTiming      = SiS300_PALTiming;
+   SiS_Pr->SiS_HiTVSt1Timing  = SiS300_HiTVSt1Timing;
+   SiS_Pr->SiS_HiTVSt2Timing  = SiS300_HiTVSt2Timing;
+   SiS_Pr->SiS_HiTVTextTiming = SiS300_HiTVTextTiming;
+   SiS_Pr->SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data;
+   SiS_Pr->SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu;
+   SiS_Pr->SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text;
+
+   SiS_Pr->SiS_PanelDelayTbl     = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
+   SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTblLVDS;
+
+   SiS_Pr->SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_1;
+   SiS_Pr->SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_2;
+   SiS_Pr->SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_1;
+   SiS_Pr->SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_2;
+   SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
+   SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
+   SiS_Pr->SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
+   SiS_Pr->SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
+   SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_1;
+   SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_2;
+   SiS_Pr->SiS_LVDS1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1600x1200Data_1;
+   SiS_Pr->SiS_LVDS1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1600x1200Data_2;
+   SiS_Pr->SiS_LVDS1280x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_1;
+   SiS_Pr->SiS_LVDS1280x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_2;
+   SiS_Pr->SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_1;
+   SiS_Pr->SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_2;
+   SiS_Pr->SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_1;
+   SiS_Pr->SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_2;
+   SiS_Pr->SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *)SiS300_LVDSXXXxXXXData_1;
+   SiS_Pr->SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS320x480Data_1;
+   SiS_Pr->SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS640x480Data_1;
+   SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_1;
+   SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_2;
+   SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_1;
+   SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_2;
+   SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData;
+   SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData;
+   SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;
+   SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;
+   SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData; /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData; /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;  /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;  /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVSOPALData;
+   SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS300_PanelType00_1;
+   SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS300_PanelType01_1;
+   SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS300_PanelType02_1;
+   SiS_Pr->SiS_PanelType03_1 = (SiS_LVDSDesStruct *)SiS300_PanelType03_1;
+   SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1;
+   SiS_Pr->SiS_PanelType05_1 = (SiS_LVDSDesStruct *)SiS300_PanelType05_1;
+   SiS_Pr->SiS_PanelType06_1 = (SiS_LVDSDesStruct *)SiS300_PanelType06_1;
+   SiS_Pr->SiS_PanelType07_1 = (SiS_LVDSDesStruct *)SiS300_PanelType07_1;
+   SiS_Pr->SiS_PanelType08_1 = (SiS_LVDSDesStruct *)SiS300_PanelType08_1;
+   SiS_Pr->SiS_PanelType09_1 = (SiS_LVDSDesStruct *)SiS300_PanelType09_1;
+   SiS_Pr->SiS_PanelType0a_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0a_1;
+   SiS_Pr->SiS_PanelType0b_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0b_1;
+   SiS_Pr->SiS_PanelType0c_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0c_1;
+   SiS_Pr->SiS_PanelType0d_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_1;
+   SiS_Pr->SiS_PanelType0e_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_1;
+   SiS_Pr->SiS_PanelType0f_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_1;
+   SiS_Pr->SiS_PanelType00_2 = (SiS_LVDSDesStruct *)SiS300_PanelType00_2;
+   SiS_Pr->SiS_PanelType01_2 = (SiS_LVDSDesStruct *)SiS300_PanelType01_2;
+   SiS_Pr->SiS_PanelType02_2 = (SiS_LVDSDesStruct *)SiS300_PanelType02_2;
+   SiS_Pr->SiS_PanelType03_2 = (SiS_LVDSDesStruct *)SiS300_PanelType03_2;
+   SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2;
+   SiS_Pr->SiS_PanelType05_2 = (SiS_LVDSDesStruct *)SiS300_PanelType05_2;
+   SiS_Pr->SiS_PanelType06_2 = (SiS_LVDSDesStruct *)SiS300_PanelType06_2;
+   SiS_Pr->SiS_PanelType07_2 = (SiS_LVDSDesStruct *)SiS300_PanelType07_2;
+   SiS_Pr->SiS_PanelType08_2 = (SiS_LVDSDesStruct *)SiS300_PanelType08_2;
+   SiS_Pr->SiS_PanelType09_2 = (SiS_LVDSDesStruct *)SiS300_PanelType09_2;
+   SiS_Pr->SiS_PanelType0a_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0a_2;
+   SiS_Pr->SiS_PanelType0b_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0b_2;
+   SiS_Pr->SiS_PanelType0c_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0c_2;
+   SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_2;
+   SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_2;
+   SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_2;
+   SiS_Pr->SiS_PanelTypeNS_1 = (SiS_LVDSDesStruct *)SiS300_PanelTypeNS_1;
+   SiS_Pr->SiS_PanelTypeNS_2 = (SiS_LVDSDesStruct *)SiS300_PanelTypeNS_2;
+   SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUNTSCDesData;
+   SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVONTSCDesData;
+   SiS_Pr->SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *)SiS300_CHTVUPALDesData;
+   SiS_Pr->SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *)SiS300_CHTVOPALDesData;
+   SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1;
+   SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1;
+   SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1;
+   SiS_Pr->SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1;
+   SiS_Pr->SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1;
+   SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1_H;
+   SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1_H;
+   SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1_H;
+   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1_H;
+   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1_H;
+   SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2;
+   SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2;
+   SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2;
+   SiS_Pr->SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2;
+   SiS_Pr->SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2;
+   SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2_H;
+   SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2_H;
+   SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2_H;
+   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2_H;
+   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2_H;
+   SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UNTSC;
+   SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1ONTSC;
+   SiS_Pr->SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UPAL;
+   SiS_Pr->SiS_CHTVCRT1OPAL  = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1OPAL;
+   SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1SOPAL;
+   SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UNTSC;
+   SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_ONTSC;
+   SiS_Pr->SiS_CHTVReg_UPAL  = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UPAL;
+   SiS_Pr->SiS_CHTVReg_OPAL  = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_OPAL;
+   SiS_Pr->SiS_CHTVReg_UPALM = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UNTSC;  /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVReg_OPALM = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_ONTSC;  /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UPAL;   /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_OPAL;   /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_SOPAL;
+   SiS_Pr->SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
+   SiS_Pr->SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
+   SiS_Pr->SiS_CHTVVCLKUPAL  = SiS300_CHTVVCLKUPAL;
+   SiS_Pr->SiS_CHTVVCLKOPAL  = SiS300_CHTVVCLKOPAL;
+   SiS_Pr->SiS_CHTVVCLKUPALM = SiS300_CHTVVCLKUNTSC;  /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVVCLKOPALM = SiS300_CHTVVCLKONTSC;  /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVVCLKUPALN = SiS300_CHTVVCLKUPAL;   /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL;   /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
+
+   /* TW: New from 300/301LV BIOS */
+   SiS_Pr->SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_1;
+   SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_1;
+   SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_1;
+   SiS_Pr->SiS_CRT2Part2_1600x1200_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_1;
+   SiS_Pr->SiS_CRT2Part2_1024x768_2  = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_2;
+   SiS_Pr->SiS_CRT2Part2_1280x1024_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_2;
+   SiS_Pr->SiS_CRT2Part2_1400x1050_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_2;
+   SiS_Pr->SiS_CRT2Part2_1600x1200_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_2;
+   SiS_Pr->SiS_CRT2Part2_1024x768_3  = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_3;
+   SiS_Pr->SiS_CRT2Part2_1280x1024_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_3;
+   SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_3;
+   SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_3;
+
+   /* TW: LCDResInfo will on 300 series be translated to 310/325 series definitions */
+   SiS_Pr->SiS_Panel320x480   = Panel_320x480;
+   SiS_Pr->SiS_Panel640x480   = Panel_640x480;
+   SiS_Pr->SiS_Panel800x600   = Panel_800x600;
+   SiS_Pr->SiS_Panel1024x768  = Panel_1024x768;
+   SiS_Pr->SiS_Panel1280x1024 = Panel_1280x1024;
+   SiS_Pr->SiS_Panel1280x960  = Panel_1280x960;
+   SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
+   SiS_Pr->SiS_Panel1152x768  = Panel_1152x768;
+   SiS_Pr->SiS_Panel1600x1200 = 16;  		/* TW: Something illegal */
+   SiS_Pr->SiS_Panel1400x1050 = 16;  		/* TW: Something illegal */
+   SiS_Pr->SiS_Panel1152x864  = 16;   		/* TW: Something illegal */
+   SiS_Pr->SiS_Panel1280x768  = 16;   		/* TW: Something illegal */
+   SiS_Pr->SiS_PanelMax       = Panel_320x480;     /* TW: highest value */
+   SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;     /* TW: Lowest value LVDS */
+   SiS_Pr->SiS_PanelMin301    = Panel_1024x768;    /* TW: lowest value 301 */
 }
 #endif
 
 #ifdef SIS315H
-void
-InitTo310Pointer(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static void
+InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-   SiS_SModeIDTable = (SiS_StStruct *) SiS310_SModeIDTable;
-   SiS_StandTable   = (SiS_StandTableStruct *) SiS310_StandTable;
-   SiS_EModeIDTable = (SiS_ExtStruct *) SiS310_EModeIDTable;
-   SiS_RefIndex     = (SiS_Ext2Struct *) SiS310_RefIndex;
-   SiS_CRT1Table    = (SiS_CRT1TableStruct *) SiS310_CRT1Table;
-
+   SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS310_SModeIDTable;
+   SiS_Pr->SiS_StandTable    = (SiS_StandTableStruct *)SiS310_StandTable;
+   SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS310_EModeIDTable;
+   SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS310_RefIndex;
+   SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS310_CRT1Table;
    /* TW: MCLK is different */
-   if(HwDeviceExtension->jChipType > SIS_315PRO) {
-      SiS_MCLKData_0 = (SiS_MCLKDataStruct *) SiS310_MCLKData_0_650;  /* 550, 650 */
+   if(HwDeviceExtension->jChipType == SIS_330) {
+      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_330;  /* 330 */
+   } else if(HwDeviceExtension->jChipType > SIS_315PRO) {
+      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_650;  /* 550, 650, 740 */
    } else {
-      SiS_MCLKData_0 = (SiS_MCLKDataStruct *) SiS310_MCLKData_0_315;  /* 315 */
+      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_315;  /* 315 */
    }
-   SiS_MCLKData_1    = (SiS_MCLKDataStruct *) SiS310_MCLKData_1;
-   SiS_ECLKData      = (SiS_ECLKDataStruct *) SiS310_ECLKData;
-   SiS_VCLKData      = (SiS_VCLKDataStruct *) SiS310_VCLKData;
-   SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *) SiS310_VBVCLKData;
-
-   SiS_ScreenOffset = SiS310_ScreenOffset;
-   SiS_StResInfo = (SiS_StResInfoStruct *) SiS310_StResInfo;
-   SiS_ModeResInfo = (SiS_ModeResInfoStruct *) SiS310_ModeResInfo;
-
-   pSiS_OutputSelect = &SiS310_OutputSelect;
-   pSiS_SoftSetting = &SiS310_SoftSetting;
-   pSiS_SR07 = &SiS310_SR07;
-   SiS_SR15 = SiS310_SR15;
-   SiS_CR40 = SiS310_CR40;
-   SiS_CR49 = SiS310_CR49;
-   pSiS_SR1F = &SiS310_SR1F;
-   pSiS_SR21 = &SiS310_SR21;
-   pSiS_SR22 = &SiS310_SR22;
-   pSiS_SR23 = &SiS310_SR23;
-   pSiS_SR24 = &SiS310_SR24;
-   SiS_SR25 = SiS310_SR25;
-   pSiS_SR31 = &SiS310_SR31;
-   pSiS_SR32 = &SiS310_SR32;
-   pSiS_SR33 = &SiS310_SR33;
-   pSiS_CRT2Data_1_2 = &SiS310_CRT2Data_1_2;
-   pSiS_CRT2Data_4_D = &SiS310_CRT2Data_4_D;
-   pSiS_CRT2Data_4_E = &SiS310_CRT2Data_4_E;
-   pSiS_CRT2Data_4_10 = &SiS310_CRT2Data_4_10;
-   pSiS_RGBSenseData = &SiS310_RGBSenseData;
-   pSiS_VideoSenseData = &SiS310_VideoSenseData;
-   pSiS_YCSenseData = &SiS310_YCSenseData;
-   pSiS_RGBSenseData2 = &SiS310_RGBSenseData2;
-   pSiS_VideoSenseData2 = &SiS310_VideoSenseData2;
-   pSiS_YCSenseData2 = &SiS310_YCSenseData2;
-   SiS_NTSCPhase = SiS310_NTSCPhase;
-   SiS_PALPhase = SiS310_PALPhase;
-   SiS_NTSCPhase2 = SiS310_NTSCPhase2;
-   SiS_PALPhase2 = SiS310_PALPhase2;
-   SiS_PALMPhase = SiS310_PALMPhase;
-   SiS_PALNPhase = SiS310_PALNPhase;
-   SiS_PALMPhase2 = SiS310_PALMPhase2;
-   SiS_PALNPhase2 = SiS310_PALNPhase2;
-
-   SiS_StLCD1024x768Data = (SiS_LCDDataStruct *) SiS310_StLCD1024x768Data;
-   SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *) SiS310_ExtLCD1024x768Data;
-   SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *) SiS310_St2LCD1024x768Data;
-   SiS_StLCD1280x1024Data = (SiS_LCDDataStruct *) SiS310_StLCD1280x1024Data;
-   SiS_ExtLCD1280x1024Data = (SiS_LCDDataStruct *) SiS310_ExtLCD1280x1024Data;
-   SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *) SiS310_St2LCD1280x1024Data;
-   SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *) SiS310_NoScaleData1024x768;
-   SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *) SiS310_NoScaleData1280x1024;
-   SiS_LCD1280x960Data = (SiS_LCDDataStruct *) SiS310_LCD1280x960Data;
-   SiS_StPALData = (SiS_TVDataStruct *) SiS310_StPALData;
-   SiS_ExtPALData = (SiS_TVDataStruct *) SiS310_ExtPALData;
-   SiS_StNTSCData = (SiS_TVDataStruct *) SiS310_StNTSCData;
-   SiS_ExtNTSCData = (SiS_TVDataStruct *) SiS310_ExtNTSCData;
-   SiS_St1HiTVData = (SiS_TVDataStruct *) SiS310_St1HiTVData;
-   SiS_St2HiTVData = (SiS_TVDataStruct *) SiS310_St2HiTVData;
-   SiS_ExtHiTVData = (SiS_TVDataStruct *) SiS310_ExtHiTVData;
-   SiS_NTSCTiming = SiS310_NTSCTiming;
-   SiS_PALTiming = SiS310_PALTiming;
-   SiS_HiTVSt1Timing = SiS310_HiTVSt1Timing;
-   SiS_HiTVSt2Timing = SiS310_HiTVSt2Timing;
-   SiS_HiTVTextTiming = SiS310_HiTVTextTiming;
-   SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data;
-   SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu;
-   SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text;
-
-   SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *) SiS310_PanelDelayTbl;
-   SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *) SiS310_PanelDelayTblLVDS;
-
-   SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *) SiS310_LVDS800x600Data_1;
-   SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *) SiS310_LVDS800x600Data_2;
-   SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *) SiS310_LVDS1024x768Data_1;
-   SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *) SiS310_LVDS1024x768Data_2;
-   SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *) SiS310_LVDS1280x1024Data_1;
-   SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *) SiS310_LVDS1280x1024Data_2;
-   SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *) SiS310_LVDS1280x960Data_1;
-   SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *) SiS310_LVDS1280x960Data_2;
-   SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *) SiS310_LVDS1400x1050Data_1;
-   SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *) SiS310_LVDS1400x1050Data_2;
-   SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *) SiS310_LVDS1024x600Data_1;
-   SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *) SiS310_LVDS1024x600Data_2;
-   SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *) SiS310_LVDS1152x768Data_1;
-   SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *) SiS310_LVDS1152x768Data_2;
-   SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *) SiS310_LVDSXXXxXXXData_1;
-   SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *) SiS310_LVDS320x480Data_1;
-   SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *) SiS310_LVDS640x480Data_1;
-   SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *) SiS310_CHTVUNTSCData;
-   SiS_CHTVONTSCData = (SiS_LVDSDataStruct *) SiS310_CHTVONTSCData;
-   SiS_CHTVUPALData  = (SiS_LVDSDataStruct *) SiS310_CHTVUPALData;
-   SiS_CHTVOPALData  = (SiS_LVDSDataStruct *) SiS310_CHTVOPALData;
-   SiS_PanelType00_1 = (SiS_LVDSDesStruct *) SiS310_PanelType00_1;
-   SiS_PanelType01_1 = (SiS_LVDSDesStruct *) SiS310_PanelType01_1;
-   SiS_PanelType02_1 = (SiS_LVDSDesStruct *) SiS310_PanelType02_1;
-   SiS_PanelType03_1 = (SiS_LVDSDesStruct *) SiS310_PanelType03_1;
-   SiS_PanelType04_1 = (SiS_LVDSDesStruct *) SiS310_PanelType04_1;
-   SiS_PanelType05_1 = (SiS_LVDSDesStruct *) SiS310_PanelType05_1;
-   SiS_PanelType06_1 = (SiS_LVDSDesStruct *) SiS310_PanelType06_1;
-   SiS_PanelType07_1 = (SiS_LVDSDesStruct *) SiS310_PanelType07_1;
-   SiS_PanelType08_1 = (SiS_LVDSDesStruct *) SiS310_PanelType08_1;
-   SiS_PanelType09_1 = (SiS_LVDSDesStruct *) SiS310_PanelType09_1;
-   SiS_PanelType0a_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0a_1;
-   SiS_PanelType0b_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0b_1;
-   SiS_PanelType0c_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0c_1;
-   SiS_PanelType0d_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0d_1;
-   SiS_PanelType0e_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0e_1;
-   SiS_PanelType0f_1 = (SiS_LVDSDesStruct *) SiS310_PanelType0f_1;
-   SiS_PanelType00_2 = (SiS_LVDSDesStruct *) SiS310_PanelType00_2;
-   SiS_PanelType01_2 = (SiS_LVDSDesStruct *) SiS310_PanelType01_2;
-   SiS_PanelType02_2 = (SiS_LVDSDesStruct *) SiS310_PanelType02_2;
-   SiS_PanelType03_2 = (SiS_LVDSDesStruct *) SiS310_PanelType03_2;
-   SiS_PanelType04_2 = (SiS_LVDSDesStruct *) SiS310_PanelType04_2;
-   SiS_PanelType05_2 = (SiS_LVDSDesStruct *) SiS310_PanelType05_2;
-   SiS_PanelType06_2 = (SiS_LVDSDesStruct *) SiS310_PanelType06_2;
-   SiS_PanelType07_2 = (SiS_LVDSDesStruct *) SiS310_PanelType07_2;
-   SiS_PanelType08_2 = (SiS_LVDSDesStruct *) SiS310_PanelType08_2;
-   SiS_PanelType09_2 = (SiS_LVDSDesStruct *) SiS310_PanelType09_2;
-   SiS_PanelType0a_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0a_2;
-   SiS_PanelType0b_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0b_2;
-   SiS_PanelType0c_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0c_2;
-   SiS_PanelType0d_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0d_2;
-   SiS_PanelType0e_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0e_2;
-   SiS_PanelType0f_2 = (SiS_LVDSDesStruct *) SiS310_PanelType0f_2;
-
-   LVDS1024x768Des_1 = (SiS_LVDSDesStruct *) SiS310_PanelType1076_1;
-   LVDS1280x1024Des_1= (SiS_LVDSDesStruct *) SiS310_PanelType1210_1;
-   LVDS1280x960Des_1 = (SiS_LVDSDesStruct *) SiS310_PanelType1296_1 ;
-   LVDS1024x768Des_2 = (SiS_LVDSDesStruct *) SiS310_PanelType1076_2;
-   LVDS1280x1024Des_2= (SiS_LVDSDesStruct *) SiS310_PanelType1210_2;
-   LVDS1280x960Des_2 = (SiS_LVDSDesStruct *) SiS310_PanelType1296_2;
+   SiS_Pr->SiS_MCLKData_1    = (SiS_MCLKDataStruct *)SiS310_MCLKData_1;
+   SiS_Pr->SiS_ECLKData      = (SiS_ECLKDataStruct *)SiS310_ECLKData;
+   SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS310_VCLKData;
+   SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS310_VBVCLKData;
+   SiS_Pr->SiS_ScreenOffset  = SiS310_ScreenOffset;
+   SiS_Pr->SiS_StResInfo     = (SiS_StResInfoStruct *)SiS310_StResInfo;
+   SiS_Pr->SiS_ModeResInfo   = (SiS_ModeResInfoStruct *)SiS310_ModeResInfo;
 
-   /* TW: New from 650/301LV BIOS */
-   SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *) SiS310_CRT2Part2_1024x768_1;
-   SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *) SiS310_CRT2Part2_1280x1024_1;
-   SiS_CRT2Part2_1024x768_2  = (SiS_Part2PortTblStruct *) SiS310_CRT2Part2_1024x768_2;
-   SiS_CRT2Part2_1280x1024_2 = (SiS_Part2PortTblStruct *) SiS310_CRT2Part2_1280x1024_2;
-   SiS_CRT2Part2_1024x768_3  = (SiS_Part2PortTblStruct *) SiS310_CRT2Part2_1024x768_3;
-   SiS_CRT2Part2_1280x1024_3 = (SiS_Part2PortTblStruct *) SiS310_CRT2Part2_1280x1024_3;
-
-   SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *) SiS310_CHTVUNTSCDesData;
-   SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *) SiS310_CHTVONTSCDesData;
-   SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *) SiS310_CHTVUPALDesData;
-   SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *) SiS310_CHTVOPALDesData;
-
-   SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_1;
-   SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_1;
-   SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_1;
-   SiS_LVDSCRT11400x1050_1   = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11400x1050_1;
-   SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x600_1;
-   SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11152x768_1;
-   SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_1_H;
-   SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_1_H;
-   SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_1_H;
-   SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11400x1050_1_H;
-   SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x600_1_H;
-   SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11152x768_1_H;
-   SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_2;
-   SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_2;
-   SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_2;
-   SiS_LVDSCRT11400x1050_2   = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11400x1050_2;
-   SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x600_2;
-   SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11152x768_2;
-   SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1800x600_2_H;
-   SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x768_2_H;
-   SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11280x1024_2_H;
-   SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11400x1050_2_H;
-   SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11024x600_2_H;
-   SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT11152x768_2_H;
-   SiS_LVDSCRT1XXXxXXX_1     = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1XXXxXXX_1;
-   SiS_LVDSCRT1320x480_1     = (SiS_LVDSCRT1DataStruct *) SiS310_LVDSCRT1320x480_1;
-   SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1UNTSC;
-   SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1ONTSC;
-   SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1UPAL;
-   SiS_CHTVCRT1OPAL  = (SiS_LVDSCRT1DataStruct *) SiS310_CHTVCRT1OPAL;
-   SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_UNTSC;
-   SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_ONTSC;
-   SiS_CHTVReg_UPAL  = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_UPAL;
-   SiS_CHTVReg_OPAL  = (SiS_CHTVRegDataStruct *) SiS310_CHTVReg_OPAL;
-   SiS_LCDACRT1800x600_1     = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_1;
-   SiS_LCDACRT11024x768_1    = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_1;
-   SiS_LCDACRT11280x1024_1   = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_1;
-   SiS_LCDACRT1800x600_1_H   = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_1_H;
-   SiS_LCDACRT11024x768_1_H  = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_1_H;
-   SiS_LCDACRT11280x1024_1_H = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_1_H;
-   SiS_LCDACRT1800x600_2     = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_2;
-   SiS_LCDACRT11024x768_2    = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_2;
-   SiS_LCDACRT11280x1024_2   = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_2;
-   SiS_LCDACRT1800x600_2_H   = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT1800x600_2_H;
-   SiS_LCDACRT11024x768_2_H  = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11024x768_2_H;
-   SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *) SiS310_LCDACRT11280x1024_2_H;
-   SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
-   SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
-   SiS_CHTVVCLKUPAL  = SiS310_CHTVVCLKUPAL;
-   SiS_CHTVVCLKOPAL  = SiS310_CHTVVCLKOPAL;
-
-   Panel320x480 = Panel310_320x480;
-   Panel640x480 = Panel310_640x480;
-   Panel800x600 = Panel310_800x600;
-   Panel1024x768 = Panel310_1024x768;
-   Panel1280x1024 = Panel310_1280x1024;
-   Panel1280x960 = Panel310_1280x960;
-   Panel1600x1200 = Panel310_1600x1200;
-   Panel1400x1050 = Panel310_1400x1050;
-   Panel1152x768 = Panel310_1152x768;
-   Panel1152x864 = Panel310_1152x864;
-   Panel1280x768 = Panel310_1280x768;
-   Panel1024x600 = Panel310_1024x600;
-   PanelMax = Panel310_320x480;       /* TW: highest value */
-   PanelMinLVDS = Panel310_800x600;   /* TW: lowest value LVDS */
-   PanelMin301 = Panel310_1024x768;   /* TW: lowest value 301 */
+   SiS_Pr->pSiS_OutputSelect = &SiS310_OutputSelect;
+   SiS_Pr->pSiS_SoftSetting  = &SiS310_SoftSetting;
+
+   SiS_Pr->SiS_SR15  = SiS310_SR15;
 
+#ifndef LINUX_XF86
+   SiS_Pr->pSiS_SR07 = &SiS310_SR07;
+   SiS_Pr->SiS_CR40  = SiS310_CR40;
+   SiS_Pr->SiS_CR49  = SiS310_CR49;
+   SiS_Pr->pSiS_SR1F = &SiS310_SR1F;
+   SiS_Pr->pSiS_SR21 = &SiS310_SR21;
+   SiS_Pr->pSiS_SR22 = &SiS310_SR22;
+   SiS_Pr->pSiS_SR23 = &SiS310_SR23;
+   SiS_Pr->pSiS_SR24 = &SiS310_SR24;
+   SiS_Pr->SiS_SR25  = SiS310_SR25;
+   SiS_Pr->pSiS_SR31 = &SiS310_SR31;
+   SiS_Pr->pSiS_SR32 = &SiS310_SR32;
+   SiS_Pr->pSiS_SR33 = &SiS310_SR33;
+   SiS_Pr->pSiS_CRT2Data_1_2  = &SiS310_CRT2Data_1_2;
+   SiS_Pr->pSiS_CRT2Data_4_D  = &SiS310_CRT2Data_4_D;
+   SiS_Pr->pSiS_CRT2Data_4_E  = &SiS310_CRT2Data_4_E;
+   SiS_Pr->pSiS_CRT2Data_4_10 = &SiS310_CRT2Data_4_10;
+   SiS_Pr->pSiS_RGBSenseData    = &SiS310_RGBSenseData;
+   SiS_Pr->pSiS_VideoSenseData  = &SiS310_VideoSenseData;
+   SiS_Pr->pSiS_YCSenseData     = &SiS310_YCSenseData;
+   SiS_Pr->pSiS_RGBSenseData2   = &SiS310_RGBSenseData2;
+   SiS_Pr->pSiS_VideoSenseData2 = &SiS310_VideoSenseData2;
+   SiS_Pr->pSiS_YCSenseData2    = &SiS310_YCSenseData2;
+#endif
+
+   SiS_Pr->SiS_NTSCPhase    = SiS310_NTSCPhase;
+   SiS_Pr->SiS_PALPhase     = SiS310_PALPhase;
+   SiS_Pr->SiS_NTSCPhase2   = SiS310_NTSCPhase2;
+   SiS_Pr->SiS_PALPhase2    = SiS310_PALPhase2;
+   SiS_Pr->SiS_PALMPhase    = SiS310_PALMPhase;
+   SiS_Pr->SiS_PALNPhase    = SiS310_PALNPhase;
+   SiS_Pr->SiS_PALMPhase2   = SiS310_PALMPhase2;
+   SiS_Pr->SiS_PALNPhase2   = SiS310_PALNPhase2;
+   SiS_Pr->SiS_SpecialPhase = SiS310_SpecialPhase;
+
+   SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS310_StLCD1024x768Data;
+   SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_ExtLCD1024x768Data;
+   SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_St2LCD1024x768Data;
+   SiS_Pr->SiS_StLCD1280x1024Data   = (SiS_LCDDataStruct *)SiS310_StLCD1280x1024Data;
+   SiS_Pr->SiS_ExtLCD1280x1024Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1280x1024Data;
+   SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS310_St2LCD1280x1024Data;
+   SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS310_NoScaleData1024x768;
+   SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS310_NoScaleData1280x1024;
+   SiS_Pr->SiS_LCD1280x960Data      = (SiS_LCDDataStruct *)SiS310_LCD1280x960Data;
+   SiS_Pr->SiS_ExtLCD1400x1050Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1400x1050Data;
+   SiS_Pr->SiS_ExtLCD1600x1200Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1600x1200Data;
+   SiS_Pr->SiS_StLCD1400x1050Data   = (SiS_LCDDataStruct *)SiS310_StLCD1400x1050Data;
+   SiS_Pr->SiS_StLCD1600x1200Data   = (SiS_LCDDataStruct *)SiS310_StLCD1600x1200Data;
+   SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS310_NoScaleData1400x1050;
+   SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS310_NoScaleData1600x1200;
+
+   SiS_Pr->SiS_StPALData   = (SiS_TVDataStruct *)SiS310_StPALData;
+   SiS_Pr->SiS_ExtPALData  = (SiS_TVDataStruct *)SiS310_ExtPALData;
+   SiS_Pr->SiS_StNTSCData  = (SiS_TVDataStruct *)SiS310_StNTSCData;
+   SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS310_ExtNTSCData;
+/* SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS310_St1HiTVData;  */
+   SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS310_St2HiTVData;
+   SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS310_ExtHiTVData;
+
+   SiS_Pr->SiS_NTSCTiming     = SiS310_NTSCTiming;
+   SiS_Pr->SiS_PALTiming      = SiS310_PALTiming;
+   SiS_Pr->SiS_HiTVSt1Timing  = SiS310_HiTVSt1Timing;
+   SiS_Pr->SiS_HiTVSt2Timing  = SiS310_HiTVSt2Timing;
+   SiS_Pr->SiS_HiTVTextTiming = SiS310_HiTVTextTiming;
+   SiS_Pr->SiS_HiTVExtTiming  = SiS310_HiTVExtTiming;
+   SiS_Pr->SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data;
+   SiS_Pr->SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu;
+   SiS_Pr->SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text;
+
+   SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
+   SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTblLVDS;
+
+   SiS_Pr->SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_1;
+   SiS_Pr->SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_2;
+   SiS_Pr->SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_1;
+   SiS_Pr->SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_2;
+   SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_1;
+   SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_2;
+   SiS_Pr->SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_1;
+   SiS_Pr->SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_2;
+   SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_1;
+   SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_2;
+   SiS_Pr->SiS_LVDS1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1600x1200Data_1;
+   SiS_Pr->SiS_LVDS1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1600x1200Data_2;
+   SiS_Pr->SiS_LVDS1280x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_1;
+   SiS_Pr->SiS_LVDS1280x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_2;
+   SiS_Pr->SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_1;
+   SiS_Pr->SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_2;
+   SiS_Pr->SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_1;
+   SiS_Pr->SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_2;
+   SiS_Pr->SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *)SiS310_LVDSXXXxXXXData_1;
+   SiS_Pr->SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS320x480Data_1;
+   SiS_Pr->SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS640x480Data_1;
+   SiS_Pr->SiS_LCDA1400x1050Data_1  = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_1;
+   SiS_Pr->SiS_LCDA1400x1050Data_2  = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_2;
+   SiS_Pr->SiS_LCDA1600x1200Data_1  = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_1;
+   SiS_Pr->SiS_LCDA1600x1200Data_2  = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_2;
+   SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVUNTSCData;
+   SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVONTSCData;
+   SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVUPALData;
+   SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVOPALData;
+   SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALMData;
+   SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALMData;
+   SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALNData;
+   SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALNData;
+   SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVSOPALData;
+   SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS310_PanelType00_1;
+   SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS310_PanelType01_1;
+   SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS310_PanelType02_1;
+   SiS_Pr->SiS_PanelType03_1 = (SiS_LVDSDesStruct *)SiS310_PanelType03_1;
+   SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS310_PanelType04_1;
+   SiS_Pr->SiS_PanelType05_1 = (SiS_LVDSDesStruct *)SiS310_PanelType05_1;
+   SiS_Pr->SiS_PanelType06_1 = (SiS_LVDSDesStruct *)SiS310_PanelType06_1;
+   SiS_Pr->SiS_PanelType07_1 = (SiS_LVDSDesStruct *)SiS310_PanelType07_1;
+   SiS_Pr->SiS_PanelType08_1 = (SiS_LVDSDesStruct *)SiS310_PanelType08_1;
+   SiS_Pr->SiS_PanelType09_1 = (SiS_LVDSDesStruct *)SiS310_PanelType09_1;
+   SiS_Pr->SiS_PanelType0a_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0a_1;
+   SiS_Pr->SiS_PanelType0b_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0b_1;
+   SiS_Pr->SiS_PanelType0c_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0c_1;
+   SiS_Pr->SiS_PanelType0d_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_1;
+   SiS_Pr->SiS_PanelType0e_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_1;
+   SiS_Pr->SiS_PanelType0f_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_1;
+   SiS_Pr->SiS_PanelType00_2 = (SiS_LVDSDesStruct *)SiS310_PanelType00_2;
+   SiS_Pr->SiS_PanelType01_2 = (SiS_LVDSDesStruct *)SiS310_PanelType01_2;
+   SiS_Pr->SiS_PanelType02_2 = (SiS_LVDSDesStruct *)SiS310_PanelType02_2;
+   SiS_Pr->SiS_PanelType03_2 = (SiS_LVDSDesStruct *)SiS310_PanelType03_2;
+   SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS310_PanelType04_2;
+   SiS_Pr->SiS_PanelType05_2 = (SiS_LVDSDesStruct *)SiS310_PanelType05_2;
+   SiS_Pr->SiS_PanelType06_2 = (SiS_LVDSDesStruct *)SiS310_PanelType06_2;
+   SiS_Pr->SiS_PanelType07_2 = (SiS_LVDSDesStruct *)SiS310_PanelType07_2;
+   SiS_Pr->SiS_PanelType08_2 = (SiS_LVDSDesStruct *)SiS310_PanelType08_2;
+   SiS_Pr->SiS_PanelType09_2 = (SiS_LVDSDesStruct *)SiS310_PanelType09_2;
+   SiS_Pr->SiS_PanelType0a_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0a_2;
+   SiS_Pr->SiS_PanelType0b_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0b_2;
+   SiS_Pr->SiS_PanelType0c_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0c_2;
+   SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_2;
+   SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_2;
+   SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_2;
+   SiS_Pr->SiS_PanelTypeNS_1 = (SiS_LVDSDesStruct *)SiS310_PanelTypeNS_1;
+   SiS_Pr->SiS_PanelTypeNS_2 = (SiS_LVDSDesStruct *)SiS310_PanelTypeNS_2;
+
+   SiS_Pr->LVDS1024x768Des_1  = (SiS_LVDSDesStruct *)SiS310_PanelType1076_1;
+   SiS_Pr->LVDS1280x1024Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_1;
+   SiS_Pr->LVDS1400x1050Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_1 ;
+   SiS_Pr->LVDS1600x1200Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_1 ;
+   SiS_Pr->LVDS1024x768Des_2  = (SiS_LVDSDesStruct *)SiS310_PanelType1076_2;
+   SiS_Pr->LVDS1280x1024Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_2;
+   SiS_Pr->LVDS1400x1050Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_2;
+   SiS_Pr->LVDS1600x1200Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_2 ;
+
+   /* TW: New from 650/301LV BIOS */
+   SiS_Pr->SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_1;
+   SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_1;
+   SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_1;
+   SiS_Pr->SiS_CRT2Part2_1600x1200_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_1;
+   SiS_Pr->SiS_CRT2Part2_1024x768_2  = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_2;
+   SiS_Pr->SiS_CRT2Part2_1280x1024_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_2;
+   SiS_Pr->SiS_CRT2Part2_1400x1050_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_2;
+   SiS_Pr->SiS_CRT2Part2_1600x1200_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_2;
+   SiS_Pr->SiS_CRT2Part2_1024x768_3  = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_3;
+   SiS_Pr->SiS_CRT2Part2_1280x1024_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_3;
+   SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_3;
+   SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_3;
+
+   SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUNTSCDesData;
+   SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVONTSCDesData;
+   SiS_Pr->SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *)SiS310_CHTVUPALDesData;
+   SiS_Pr->SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *)SiS310_CHTVOPALDesData;
+
+   SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1;
+   SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1;
+   SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1;
+   SiS_Pr->SiS_LVDSCRT11400x1050_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1;
+   SiS_Pr->SiS_LVDSCRT11280x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1;
+   SiS_Pr->SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1;
+   SiS_Pr->SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1;
+   SiS_Pr->SiS_LVDSCRT11600x1200_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1;
+   SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1_H;
+   SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1_H;
+   SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1_H;
+   SiS_Pr->SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1_H;
+   SiS_Pr->SiS_LVDSCRT11280x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1_H;
+   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1_H;
+   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1_H;
+   SiS_Pr->SiS_LVDSCRT11600x1200_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1_H;
+   SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2;
+   SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2;
+   SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2;
+   SiS_Pr->SiS_LVDSCRT11400x1050_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2;
+   SiS_Pr->SiS_LVDSCRT11280x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2;
+   SiS_Pr->SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2;
+   SiS_Pr->SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2;
+   SiS_Pr->SiS_LVDSCRT11600x1200_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2;
+   SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2_H;
+   SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2_H;
+   SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2_H;
+   SiS_Pr->SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2_H;
+   SiS_Pr->SiS_LVDSCRT11280x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2_H;
+   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2_H;
+   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2_H;
+   SiS_Pr->SiS_LVDSCRT11600x1200_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2_H;
+   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1;
+   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1_H;
+   SiS_Pr->SiS_LVDSCRT1320x480_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1320x480_1;
+   SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
+   SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
+   SiS_Pr->SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
+   SiS_Pr->SiS_CHTVCRT1OPAL  = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
+   SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL;
+   SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UNTSC;
+   SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_ONTSC;
+   SiS_Pr->SiS_CHTVReg_UPAL  = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPAL;
+   SiS_Pr->SiS_CHTVReg_OPAL  = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPAL;
+   SiS_Pr->SiS_CHTVReg_UPALM = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALM;
+   SiS_Pr->SiS_CHTVReg_OPALM = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALM;
+   SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALN;
+   SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALN;
+   SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_SOPAL;
+   SiS_Pr->SiS_LCDACRT1800x600_1     = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1;
+   SiS_Pr->SiS_LCDACRT11024x768_1    = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1;
+   SiS_Pr->SiS_LCDACRT11280x1024_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1;
+   SiS_Pr->SiS_LCDACRT11400x1050_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1;
+   SiS_Pr->SiS_LCDACRT11600x1200_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1;
+   SiS_Pr->SiS_LCDACRT1800x600_1_H   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1_H;
+   SiS_Pr->SiS_LCDACRT11024x768_1_H  = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1_H;
+   SiS_Pr->SiS_LCDACRT11280x1024_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1_H;
+   SiS_Pr->SiS_LCDACRT11400x1050_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1_H;
+   SiS_Pr->SiS_LCDACRT11600x1200_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1_H;
+   SiS_Pr->SiS_LCDACRT1800x600_2     = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_2;
+   SiS_Pr->SiS_LCDACRT11024x768_2    = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2;
+   SiS_Pr->SiS_LCDACRT11280x1024_2   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2;
+   SiS_Pr->SiS_LCDACRT11400x1050_2   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2;
+   SiS_Pr->SiS_LCDACRT11600x1200_2   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2;
+   SiS_Pr->SiS_LCDACRT1800x600_2_H   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_2_H;
+   SiS_Pr->SiS_LCDACRT11024x768_2_H  = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2_H;
+   SiS_Pr->SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2_H;
+   SiS_Pr->SiS_LCDACRT11400x1050_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2_H;
+   SiS_Pr->SiS_LCDACRT11600x1200_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2_H;
+   SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
+   SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
+   SiS_Pr->SiS_CHTVVCLKUPAL  = SiS310_CHTVVCLKUPAL;
+   SiS_Pr->SiS_CHTVVCLKOPAL  = SiS310_CHTVVCLKOPAL;
+   SiS_Pr->SiS_CHTVVCLKUPALM = SiS310_CHTVVCLKUPALM;
+   SiS_Pr->SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM;
+   SiS_Pr->SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN;
+   SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN;   
+   SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKSOPAL;
+
+   SiS_Pr->SiS_Panel320x480   = Panel_320x480;
+   SiS_Pr->SiS_Panel640x480   = Panel_640x480;
+   SiS_Pr->SiS_Panel800x600   = Panel_800x600;
+   SiS_Pr->SiS_Panel1024x768  = Panel_1024x768;
+   SiS_Pr->SiS_Panel1280x1024 = Panel_1280x1024;
+   SiS_Pr->SiS_Panel1280x960  = Panel_1280x960;
+   SiS_Pr->SiS_Panel1600x1200 = Panel_1600x1200;
+   SiS_Pr->SiS_Panel1400x1050 = Panel_1400x1050;
+   SiS_Pr->SiS_Panel1152x768  = Panel_1152x768;
+   SiS_Pr->SiS_Panel1152x864  = Panel_1152x864;
+   SiS_Pr->SiS_Panel1280x768  = Panel_1280x768;
+   SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
+   SiS_Pr->SiS_PanelMax       = Panel_320x480;    /* TW: highest value */
+   SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;    /* TW: lowest value LVDS/LCDA */
+   SiS_Pr->SiS_PanelMin301    = Panel_1024x768;   /* TW: lowest value 301 */
 }
 #endif
 
-#ifndef LINUX_XF86
+#ifdef LINUXBIOS
 /* -------------- SiSInit -----------------*/
+/* TW: I degraded this for LINUXBIOS only, because we
+ *     don't need this otherwise. Under normal
+ *     circumstances, the video BIOS has initialized
+ *     the adapter for us. BTW, this code is incomplete
+ *     and very possibly not working on newer chipsets.
+ */
 BOOLEAN
-SiSInit(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
    UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
    ULONG   FBAddr   = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
    USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
-   UCHAR   i,temp=0;
+   UCHAR   i, temp=0;
    UCHAR   SR11;
 #ifdef LINUX_KERNEL
    UCHAR   temp1;
    ULONG   base;
 #endif
-   UCHAR   SR13=0,SR14=0,SR16=0,SR17=0,SR19=0,SR1A=0;
+   UCHAR   SR13=0, SR14=0, SR16=0
+   UCHAR   SR17=0, SR19=0, SR1A=0;
 #ifdef SIS300
-   UCHAR   SR18=0,SR12=0;
+   UCHAR   SR18=0, SR12=0;
 #endif
 #ifdef SIS315H
-   UCHAR   CR37=0,CR38=0,CR79=0,CR7A=0,CR7B=0,CR7C=0;
-   UCHAR   SR1B=0,SR15=0;
-   PSIS_DSReg  pSR;
+   UCHAR   CR37=0, CR38=0, CR79=0,
+   UCHAR   CR7A=0, CR7B=0, CR7C=0;
+   UCHAR   SR1B=0, SR15=0;
+   PSIS_DSReg pSR;
    ULONG   Temp;
 #endif
    UCHAR   VBIOSVersion[5];
@@ -578,61 +705,64 @@
    if(FBAddr==0)    return (FALSE);
    if(BaseAddr==0)  return (FALSE);
 
-   SiS_SetReg3((USHORT)(BaseAddr+0x12),  0x67);  /* 3c2 <- 67 ,ynlai */
+   SiS_SetReg3((USHORT)(BaseAddr+0x12),  0x67);  /* Misc */
 
 #ifdef SIS315H
-   /*if(HwDeviceExtension->jChipType > SIS_315H)*/
    if(HwDeviceExtension->jChipType > SIS_315PRO) {
      if(!HwDeviceExtension->bIntegratedMMEnabled)
-     	return (FALSE);  /* alan  */
+     	return (FALSE);
    }
 #endif
 
    SiS_MemoryCopy(VBIOSVersion,HwDeviceExtension->szVBIOSVer,4);
-   VBIOSVersion[4]= 0x0;
-   /* 09/07/99 modify by domao */
+   VBIOSVersion[4]= 0x00;
+
+   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
 
+   /* TW: Init pointers */
 #ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_315H)||
-      (HwDeviceExtension->jChipType == SIS_315PRO)||
-      (HwDeviceExtension->jChipType == SIS_550)||
-      (HwDeviceExtension->jChipType == SIS_640)||
-      (HwDeviceExtension->jChipType == SIS_740)||
-      (HwDeviceExtension->jChipType == SIS_650))
-     InitTo310Pointer(HwDeviceExtension);
+   if((HwDeviceExtension->jChipType == SIS_315H) ||
+      (HwDeviceExtension->jChipType == SIS_315) ||
+      (HwDeviceExtension->jChipType == SIS_315PRO) ||
+      (HwDeviceExtension->jChipType == SIS_550) ||
+      (HwDeviceExtension->jChipType == SIS_650) ||
+      (HwDeviceExtension->jChipType == SIS_740) ||
+      (HwDeviceExtension->jChipType == SIS_330))
+     InitTo310Pointer(SiS_Pr, HwDeviceExtension);
 #endif
 
 #ifdef SIS300
-   if ((HwDeviceExtension->jChipType == SIS_540)||
-       (HwDeviceExtension->jChipType == SIS_630)||
-       (HwDeviceExtension->jChipType == SIS_730)||
-       (HwDeviceExtension->jChipType == SIS_300))
-     InitTo300Pointer(HwDeviceExtension);
+   if((HwDeviceExtension->jChipType == SIS_540) ||
+      (HwDeviceExtension->jChipType == SIS_630) ||
+      (HwDeviceExtension->jChipType == SIS_730) ||
+      (HwDeviceExtension->jChipType == SIS_300))
+     InitTo300Pointer(SiS_Pr, HwDeviceExtension);
 #endif
 
-   /* TW: Set SiS Register globals */
-   SiSRegInit(BaseAddr);
+   /* TW: Set SiS Register definitions */
+   SiSRegInit(SiS_Pr, BaseAddr);
 
    /* TW: Determine LVDS/CH70xx/TRUMPION */
-   SiS_Set_LVDS_TRUMPION(HwDeviceExtension);
+   SiS_Set_LVDS_TRUMPION(SiS_Pr, HwDeviceExtension);
 
-   SiS_SetReg1(SiS_P3c4,0x05,0x86);                     /* 1.Openkey - unlock registers */
+   /* TW: Unlock registers */
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
 
 #ifdef LINUX_KERNEL
 
-#ifdef SIS300                                         	/* Set SR14*/
-   if((HwDeviceExtension->jChipType==SIS_540)||
-      (HwDeviceExtension->jChipType==SIS_630)||
+#ifdef SIS300                                         	/* Set SR14 */
+   if((HwDeviceExtension->jChipType==SIS_540) ||
+      (HwDeviceExtension->jChipType==SIS_630) ||
       (HwDeviceExtension->jChipType==SIS_730)) {
      base=0x80000060;
      OutPortLong(base,0xcf8);
-     temp1=InPortLong(0xcfc);
+     temp1 = InPortLong(0xcfc);
      temp1 >>= (16+8+4);
      temp1 &= 0x07;
      temp1++;
      temp1 = 1 << temp1;
      SR14 = temp1 - 1;
-     base=0x80000064;
+     base = 0x80000064;
      OutPortLong(base,0xcf8);
      temp1 = InPortLong(0xcfc);
      temp1 &= 0x00000020;
@@ -641,9 +771,9 @@
    }
 #endif
 
-#ifdef SIS315H                                         /* Set SR14*/
-   if(HwDeviceExtension->jChipType==SIS_550) {
-     base=0x80000060;
+#ifdef SIS315H                                          /* Set SR14 */
+   if(HwDeviceExtension->jChipType == SIS_550) {
+     base = 0x80000060;
      OutPortLong(base,0xcf8);
      temp1 = InPortLong(0xcfc);
      temp1 >>= (16+8+4);
@@ -651,7 +781,7 @@
      temp1++;
      temp1 = 1 << temp1;
      SR14 = temp1 - 1;
-     base=0x80000064;
+     base = 0x80000064;
      OutPortLong(base,0xcf8);
      temp1 = InPortLong(0xcfc);
      temp1 &= 0x00000020;
@@ -659,10 +789,9 @@
      else       SR14 |= 0x40;
    }
 
-   if((HwDeviceExtension->jChipType == SIS_640)||
-      (HwDeviceExtension->jChipType == SIS_740)||
-      (HwDeviceExtension->jChipType == SIS_650)) {
-     base=0x80000064;
+   if((HwDeviceExtension->jChipType == SIS_740) ||     /* Set SR14 */
+      (HwDeviceExtension->jChipType == SIS_650))  {
+     base = 0x80000064;
      OutPortLong(base,0xcf8);
      temp1=InPortLong(0xcfc);
      temp1 >>= 4;
@@ -670,17 +799,17 @@
      if(temp1 > 2) {
        temp = temp1;
        switch(temp) {
-        case 3: temp1=0x07;  break;
-        case 4: temp1=0x0F;  break;
-        case 5: temp1=0x1F;  break;
-        case 6: temp1=0x05;  break;
-        case 7: temp1=0x17;  break;
+        case 3: temp1 = 0x07;  break;
+        case 4: temp1 = 0x0F;  break;
+        case 5: temp1 = 0x1F;  break;
+        case 6: temp1 = 0x05;  break;
+        case 7: temp1 = 0x17;  break;
         case 8: break;
         case 9: break;
        }
      }
      SR14 = temp1;
-     base=0x8000007C;
+     base = 0x8000007C;
      OutPortLong(base,0xcf8);
      temp1 = InPortLong(0xcfc);
      temp1 &= 0x00000020;
@@ -694,25 +823,24 @@
    if((HwDeviceExtension->jChipType == SIS_540)||
       (HwDeviceExtension->jChipType == SIS_630)||
       (HwDeviceExtension->jChipType == SIS_730)) {
-     SR12 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x12);
-     SR13 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x13);
-     SR14 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x14);
-     SR16 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x16);
-     SR17 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x17);
-     SR18 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x18);
-     SR19 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x19);
-     SR1A = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1A);
+     SR12 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x12);
+     SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
+     SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+     SR16 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+     SR17 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17);
+     SR18 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
+     SR19 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x19);
+     SR1A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
    } else if(HwDeviceExtension->jChipType == SIS_300){
-     SR13 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x13);
-     SR14 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x14);
+     SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
+     SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
    }
 #endif
 #ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_550)||
-      (HwDeviceExtension->jChipType == SIS_640)||
-      (HwDeviceExtension->jChipType == SIS_740)||
+   if((HwDeviceExtension->jChipType == SIS_550) ||
+      (HwDeviceExtension->jChipType == SIS_740) ||
       (HwDeviceExtension->jChipType == SIS_650)) {
-     SR19 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x19);
+     SR19 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x19);
      SR19 = (SR19)||0x01;  /* TW: ??? || ??? */
      if(SR19==0x00) {
      	SR13 = 0x22;
@@ -729,422 +857,419 @@
      	CR7B = 0x00;
      	CR7C = 0x00;
      } else {
-     	SR13 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x13);
-     	SR14 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x14);
-     	SR15 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x15);
-     	SR16 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x16);
-     	SR17 = (UCHAR)SiS_GetReg1(SiS_P3c4,0x17);
-     	SR1A = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1A);
-     	SR1B = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1B);
-     	CR37 = (UCHAR)SiS_GetReg1(SiS_P3d4,0x37);  /* TW: Was 0x02 - why? */
-     	CR38 = (UCHAR)SiS_GetReg1(SiS_P3d4,0x38);
-     	CR79 = (UCHAR)SiS_GetReg1(SiS_P3d4,0x79);
-     	CR7A = (UCHAR)SiS_GetReg1(SiS_P3d4,0x7A);
-     	CR7B = (UCHAR)SiS_GetReg1(SiS_P3d4,0x7B);
-     	CR7C = (UCHAR)SiS_GetReg1(SiS_P3d4,0x7C);
+     	SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
+     	SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+     	SR15 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15);
+     	SR16 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+     	SR17 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17);
+     	SR1A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
+     	SR1B = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1B);
+     	CR37 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);  /* TW: Was 0x02 - why? */
+     	CR38 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+     	CR79 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79);
+     	CR7A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7A);
+     	CR7B = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7B);
+     	CR7C = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7C);
      }
    }
 #endif
 
-/* ResetExtReg begin: Reset extended registers */
+   /* Reset extended registers */
 
-   for(i=0x06;i< 0x20;i++) SiS_SetReg1(SiS_P3c4,i,0);   /* 2.Reset Extended registers */
-   for(i=0x21;i<=0x27;i++) SiS_SetReg1(SiS_P3c4,i,0);
-   for(i=0x31;i<=0x3D;i++) SiS_SetReg1(SiS_P3c4,i,0);
+   for(i=0x06; i< 0x20; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
+   for(i=0x21; i<=0x27; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
+   for(i=0x31; i<=0x3D; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
 
 #ifdef SIS300
-   if((HwDeviceExtension->jChipType == SIS_540)||
-      (HwDeviceExtension->jChipType == SIS_630)||
-      (HwDeviceExtension->jChipType == SIS_730)||
+   if((HwDeviceExtension->jChipType == SIS_540) ||
+      (HwDeviceExtension->jChipType == SIS_630) ||
+      (HwDeviceExtension->jChipType == SIS_730) ||
       (HwDeviceExtension->jChipType == SIS_300)) {
-     	for(i=0x38;i<=0x3F;i++) SiS_SetReg1(SiS_P3d4,i,0);
+     	for(i=0x38; i<=0x3F; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0);
    }
 #endif
 
 #ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_315H)||
-      (HwDeviceExtension->jChipType == SIS_315PRO)||
-      (HwDeviceExtension->jChipType == SIS_550)||
-      (HwDeviceExtension->jChipType == SIS_640)||
-      (HwDeviceExtension->jChipType == SIS_740)||
-      (HwDeviceExtension->jChipType == SIS_650)) {
-   	for(i=0x12;i<=0x1B;i++) SiS_SetReg1(SiS_P3c4,i,0);
-   	for(i=0x79;i<=0x7C;i++) SiS_SetReg1(SiS_P3d4,i,0);
+   if((HwDeviceExtension->jChipType == SIS_315H) ||
+      (HwDeviceExtension->jChipType == SIS_315) ||
+      (HwDeviceExtension->jChipType == SIS_315PRO) ||
+      (HwDeviceExtension->jChipType == SIS_550) ||
+      (HwDeviceExtension->jChipType == SIS_650) ||
+      (HwDeviceExtension->jChipType == SIS_740) ||
+      (HwDeviceExtension->jChipType == SIS_330)) {
+   	for(i=0x12; i<=0x1B; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
+   	for(i=0x79; i<=0x7C; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0);
    }
 #endif
 
-/* ResetExtReg end */
+   /* Restore Extended Registers */
 
 #ifdef SIS300
-   if((HwDeviceExtension->jChipType == SIS_540)||
-      (HwDeviceExtension->jChipType == SIS_630)||
+   if((HwDeviceExtension->jChipType == SIS_540) ||
+      (HwDeviceExtension->jChipType == SIS_630) ||
       (HwDeviceExtension->jChipType == SIS_730)) {
-     SiS_SetReg1(SiS_P3c4,0x12,SR12);
-     SiS_SetReg1(SiS_P3c4,0x13,SR13);
-     SiS_SetReg1(SiS_P3c4,0x14,SR14);
-     SiS_SetReg1(SiS_P3c4,0x16,SR16);
-     SiS_SetReg1(SiS_P3c4,0x17,SR17);
-     SiS_SetReg1(SiS_P3c4,0x18,SR18);
-     SiS_SetReg1(SiS_P3c4,0x19,SR19);
-     SiS_SetReg1(SiS_P3c4,0x1A,SR1A);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);
    }
 #endif
 
 #ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_550)||
-      (HwDeviceExtension->jChipType == SIS_640)||
-      (HwDeviceExtension->jChipType == SIS_740)||
+   if((HwDeviceExtension->jChipType == SIS_550) ||
+      (HwDeviceExtension->jChipType == SIS_740) ||
       (HwDeviceExtension->jChipType == SIS_650)) {
-     SiS_SetReg1(SiS_P3c4,0x13,SR13);
-     SiS_SetReg1(SiS_P3c4,0x14,SR14);
-     SiS_SetReg1(SiS_P3c4,0x15,SR15);
-     SiS_SetReg1(SiS_P3c4,0x16,SR16);
-     SiS_SetReg1(SiS_P3c4,0x17,SR17);
-     SiS_SetReg1(SiS_P3c4,0x19,SR19);
-     SiS_SetReg1(SiS_P3c4,0x1A,SR1A);
-     SiS_SetReg1(SiS_P3c4,0x1B,SR1B);
-     SiS_SetReg1(SiS_P3d4,0x37,CR37);
-     SiS_SetReg1(SiS_P3d4,0x38,CR38);
-     SiS_SetReg1(SiS_P3d4,0x79,CR79);
-     SiS_SetReg1(SiS_P3d4,0x7A,CR7A);
-     SiS_SetReg1(SiS_P3d4,0x7B,CR7B);
-     SiS_SetReg1(SiS_P3d4,0x7C,CR7C);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,SR15);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1B,SR1B);
+     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,CR37);
+     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,CR38);
+     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x79,CR79);
+     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7A,CR7A);
+     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7B,CR7B);
+     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7C,CR7C);
    }
 #endif
 
 #ifdef SIS300
-   if((HwDeviceExtension->jChipType==SIS_540)||
-      (HwDeviceExtension->jChipType==SIS_630)||
+   if((HwDeviceExtension->jChipType==SIS_540) ||
+      (HwDeviceExtension->jChipType==SIS_630) ||
       (HwDeviceExtension->jChipType==SIS_730)) {
      	temp = (UCHAR)SR1A & 0x03;
-   } else if(HwDeviceExtension->jChipType==SIS_300) {
-        /* TW: Nothing? */
+   } else if(HwDeviceExtension->jChipType == SIS_300) {
+        /* TW: Nothing */
    }
 #endif
 #ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_315H )||
-      (HwDeviceExtension->jChipType == SIS_315PRO)) {
-      	if((*pSiS_SoftSetting & SoftDRAMType) == 0){
-          	temp = (UCHAR)SiS_GetReg1(SiS_P3c4,0x3A) & 0x03;
+   if((HwDeviceExtension->jChipType == SIS_315H)   ||
+      (HwDeviceExtension->jChipType == SIS_315)    ||
+      (HwDeviceExtension->jChipType == SIS_315PRO) ||
+      (HwDeviceExtension->jChipType == SIS_330) ) {
+      	if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
+          	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A) & 0x03;
         }
    }
-   if((HwDeviceExtension->jChipType == SIS_550)||
-      (HwDeviceExtension->jChipType == SIS_640)||
-      (HwDeviceExtension->jChipType == SIS_740)||
+   if((HwDeviceExtension->jChipType == SIS_550) ||
+      (HwDeviceExtension->jChipType == SIS_740) ||
       (HwDeviceExtension->jChipType == SIS_650)) {
-        if((*pSiS_SoftSetting & SoftDRAMType) == 0){
-          	temp = (UCHAR)SiS_GetReg1(SiS_P3c4,0x13) & 0x07;
+        if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
+          	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
         }
    }
 #endif
 
-   SiS_RAMType = temp;
-   SiS_SetMemoryClock(ROMAddr,HwDeviceExtension);
+   SiS_Pr->SiS_RAMType = temp;
+   SiS_SetMemoryClock(SiS_Pr, ROMAddr, HwDeviceExtension);
 
-/* SetDefExt1Regs begin: Set default register contents */
+   /* Set default register contents */
 
-   SiS_SetReg1(SiS_P3c4,0x07,*pSiS_SR07); 		/* DAC speed */
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x07,*SiS_Pr->pSiS_SR07); 		/* DAC speed */
 
    if((HwDeviceExtension->jChipType != SIS_540) &&
       (HwDeviceExtension->jChipType != SIS_630) &&
       (HwDeviceExtension->jChipType != SIS_730)){
      	for(i=0x15;i<0x1C;i++) {
-       		SiS_SetReg1(SiS_P3c4,i,SiS_SR15[i-0x15][SiS_RAMType]);
+       	    SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SiS_Pr->SiS_SR15[i-0x15][SiS_Pr->SiS_RAMType]);
      	}
    }
 
 #ifdef SIS315H
-   if ((HwDeviceExtension->jChipType == SIS_315H )||
-       (HwDeviceExtension->jChipType == SIS_315PRO)) {
+   if((HwDeviceExtension->jChipType == SIS_315H) ||
+      (HwDeviceExtension->jChipType == SIS_315)  ||
+      (HwDeviceExtension->jChipType == SIS_315PRO) ||
+      (HwDeviceExtension->jChipType == SIS_330)) {
      	for(i=0x40;i<=0x44;i++) {
-       		SiS_SetReg1(SiS_P3d4,i,SiS_CR40[i-0x40][SiS_RAMType]);
+       	    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,SiS_Pr->SiS_CR40[i-0x40][SiS_Pr->SiS_RAMType]);
      	}
-     	SiS_SetReg1(SiS_P3d4,0x48,0x23);
-     	SiS_SetReg1(SiS_P3d4,0x49,SiS_CR49[0]);
-    /*  SiS_SetReg1(SiS_P3c4,0x25,SiS_SR25[0]);  */
+     	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x48,0x23);
+     	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x49,SiS_Pr->SiS_CR49[0]);
+    /*  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[0]);  */
    }
 #endif
 
-   SiS_SetReg1(SiS_P3c4,0x1F,*pSiS_SR1F); 	/* DAC pedestal */
-   SiS_SetReg1(SiS_P3c4,0x20,0xA0);
-   SiS_SetReg1(SiS_P3c4,0x23,*pSiS_SR23);
-   SiS_SetReg1(SiS_P3c4,0x24,*pSiS_SR24);
-   SiS_SetReg1(SiS_P3c4,0x25,SiS_SR25[0]);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,*SiS_Pr->pSiS_SR1F); 	/* DAC pedestal */
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xA0);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x23,*SiS_Pr->pSiS_SR23);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x24,*SiS_Pr->pSiS_SR24);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[0]);
 
 #ifdef SIS300
-   if(HwDeviceExtension->jChipType==SIS_300) {
-     	SiS_SetReg1(SiS_P3c4,0x21,0x84);
-     	SiS_SetReg1(SiS_P3c4,0x22,0x00);
+   if(HwDeviceExtension->jChipType == SIS_300) {
+     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,0x84);
+     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,0x00);
    }
 #endif
 
-   SR11=0x0F;
-   SiS_SetReg1(SiS_P3c4,0x11,SR11);		/* Power Management & DDC port */
+   SR11 = 0x0F;
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x11,SR11);		/* Power Management & DDC port */
 
-   SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
-   SiS_SetReg1(SiS_Part1Port,0x00,0x00);
-   SiS_SetReg1(SiS_Part1Port,0x02,*pSiS_CRT2Data_1_2);
+   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,0x00);
+   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,*SiS_Pr->pSiS_CRT2Data_1_2);
 
 #ifdef SIS315H
    if((HwDeviceExtension->jChipType == SIS_315H) ||
+      (HwDeviceExtension->jChipType == SIS_315) ||
       (HwDeviceExtension->jChipType == SIS_315PRO) ||
-      (HwDeviceExtension->jChipType == SIS_550)||
-      (HwDeviceExtension->jChipType == SIS_640)||
-      (HwDeviceExtension->jChipType == SIS_740)||
-      (HwDeviceExtension->jChipType == SIS_650))
-     	SiS_SetReg1(SiS_Part1Port,0x2E,0x08);    /* use VB */
+      (HwDeviceExtension->jChipType == SIS_550) ||
+      (HwDeviceExtension->jChipType == SIS_650) ||
+      (HwDeviceExtension->jChipType == SIS_740) ||
+      (HwDeviceExtension->jChipType == SIS_330))
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2E,0x08);    /* use VB */
 #endif
 
-   temp=*pSiS_SR32;
-   if(SiS_BridgeIsOn(BaseAddr)) {
+   temp = *SiS_Pr->pSiS_SR32;
+   if(SiS_BridgeIsOn(SiS_Pr, BaseAddr)) {
      	temp &= 0xEF;
    }
-   SiS_SetReg1(SiS_P3c4,0x32,temp);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
 
 #ifdef SIS315H
-   if ((HwDeviceExtension->jChipType == SIS_315H) ||
-       (HwDeviceExtension->jChipType == SIS_315PRO)) {
-     HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension,0x50,0,&Temp);  /* Get */
+   if((HwDeviceExtension->jChipType == SIS_315H)   ||
+      (HwDeviceExtension->jChipType == SIS_315)    ||
+      (HwDeviceExtension->jChipType == SIS_315PRO) ||
+      (HwDeviceExtension->jChipType == SIS_330)) {
+     HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension,0x50,0,&Temp);
      Temp >>= 20;
      Temp &= 0xF;
-     if (Temp!=1) {
-     	SiS_SetReg1(SiS_P3c4,0x25,SiS_SR25[1]);
-     	SiS_SetReg1(SiS_P3d4,0x49,SiS_CR49[1]);
+     if (Temp != 1) {
+     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[1]);
+     	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x49,SiS_Pr->SiS_CR49[1]);
      }
 
-     SiS_SetReg1(SiS_P3c4,0x27,0x1F);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x27,0x1F);
 
-     SiS_SetReg1(SiS_P3c4,0x31,*pSiS_SR31);
-     SiS_SetReg1(SiS_P3c4,0x32,*pSiS_SR32);
-     SiS_SetReg1(SiS_P3c4,0x33,*pSiS_SR33);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,*SiS_Pr->pSiS_SR31);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,*SiS_Pr->pSiS_SR32);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x33,*SiS_Pr->pSiS_SR33);
    }
 #endif
 
-   if (SiS_BridgeIsOn(BaseAddr) == 0) {
-     	if(SiS_IF_DEF_LVDS==0) {
-       		SiS_SetReg1(SiS_Part2Port,0x00,0x1C);
-       		SiS_SetReg1(SiS_Part4Port,0x0D,*pSiS_CRT2Data_4_D);
-       		SiS_SetReg1(SiS_Part4Port,0x0E,*pSiS_CRT2Data_4_E);
-       		SiS_SetReg1(SiS_Part4Port,0x10,*pSiS_CRT2Data_4_10);
-       		SiS_SetReg1(SiS_Part4Port,0x0F,0x3F);
+   if (SiS_BridgeIsOn(SiS_Pr, BaseAddr) == 0) {
+     	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+       		SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,0x1C);
+       		SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0D,*SiS_Pr->pSiS_CRT2Data_4_D);
+       		SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0E,*SiS_Pr->pSiS_CRT2Data_4_E);
+       		SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x10,*SiS_Pr->pSiS_CRT2Data_4_10);
+       		SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0F,0x3F);
      	}
-     	SiS_LockCRT2(HwDeviceExtension, BaseAddr);
+     	SiS_LockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
    }
-   SiS_SetReg1(SiS_P3d4,0x83,0x00);
-
-/*   SetDefExt1Regs end */
+   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x83,0x00);
 
 #ifdef SIS315H
-   if ((HwDeviceExtension->jChipType==SIS_315H)||
-       (HwDeviceExtension->jChipType==SIS_315PRO)) {
-       	if (HwDeviceExtension->bSkipDramSizing==TRUE) {
-         	SiS_SetDRAMModeRegister(ROMAddr,HwDeviceExtension);
+   if((HwDeviceExtension->jChipType == SIS_315H)   ||
+      (HwDeviceExtension->jChipType == SIS_315)    ||
+      (HwDeviceExtension->jChipType == SIS_315PRO) ||
+      (HwDeviceExtension->jChipType == SIS_330)) {
+       	if(HwDeviceExtension->bSkipDramSizing==TRUE) {
+         	SiS_SetDRAMModeRegister(SiS_Pr, ROMAddr,HwDeviceExtension);
          	pSR = HwDeviceExtension->pSR;
-         	if (pSR!=NULL) {
-           		while (pSR->jIdx!=0xFF) {
-             			SiS_SetReg1(SiS_P3c4,pSR->jIdx,pSR->jVal);
+         	if(pSR != NULL) {
+           		while(pSR->jIdx != 0xFF) {
+             			SiS_SetReg1(SiS_Pr->SiS_P3c4,pSR->jIdx,pSR->jVal);
              			pSR++;
            		}
          	}
-       } else SiS_SetDRAMSize_310(HwDeviceExtension);
+       } else SiS_SetDRAMSize_310(SiS_Pr, HwDeviceExtension);
    }
 #endif
 
 #ifdef SIS315H
-   if((HwDeviceExtension->jChipType==SIS_550)){
+   if(HwDeviceExtension->jChipType == SIS_550) {
        /* SetDRAMConfig begin */
-/*     SiS_SetReg1(SiS_P3c4,0x12,SR12);
-       SiS_SetReg1(SiS_P3c4,0x13,SR13);
-       SiS_SetReg1(SiS_P3c4,0x14,SR14);
-       SiS_SetReg1(SiS_P3c4,0x16,SR16);
-       SiS_SetReg1(SiS_P3c4,0x17,SR17);
-       SiS_SetReg1(SiS_P3c4,0x18,SR18);
-       SiS_SetReg1(SiS_P3c4,0x19,SR19);
-       SiS_SetReg1(SiS_P3c4,0x1A,SR1A);   */
+/*     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12);
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18);
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);   */
        /* SetDRAMConfig end */
    }
 #endif
 
 #ifdef SIS300
-   if( HwDeviceExtension->jChipType==SIS_300) {
-       	if (HwDeviceExtension->bSkipDramSizing==TRUE) {
+   if(HwDeviceExtension->jChipType == SIS_300) {
+       	if (HwDeviceExtension->bSkipDramSizing == TRUE) {
 /*       	SiS_SetDRAMModeRegister(ROMAddr,HwDeviceExtension);
          	temp = (HwDeviceExtension->pSR)->jVal;
-         	SiS_SetReg1(SiS_P3c4,0x13,temp);
+         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,temp);
          	temp = (HwDeviceExtension->pSR)->jVal;
-         	SiS_SetReg1(SiS_P3c4,0x14,temp);   */
+         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,temp);   */
        } else {
 #ifdef TC
-         	SiS_SetReg1(SiS_P3c4,0x13,SR13);
-         	SiS_SetReg1(SiS_P3c4,0x14,SR14);
-         	SiS_SetRegANDOR(SiS_P3c4,0x15,0xFF,0x04);
+         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
+         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
+         	SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x15,0xFF,0x04);
 #else
-         	SiS_SetDRAMSize_300(HwDeviceExtension);
-         	SiS_SetDRAMSize_300(HwDeviceExtension);
+         	SiS_SetDRAMSize_300(SiS_Pr, HwDeviceExtension);
+         	SiS_SetDRAMSize_300(SiS_Pr, HwDeviceExtension);
 #endif
        }
    }
    if((HwDeviceExtension->jChipType==SIS_540)||
       (HwDeviceExtension->jChipType==SIS_630)||
-      (HwDeviceExtension->jChipType==SIS_730)){
-       	/* SetDRAMConfig begin */
+      (HwDeviceExtension->jChipType==SIS_730)) {
 #if 0
-     	SiS_SetReg1(SiS_P3c4,0x12,SR12);
-       	SiS_SetReg1(SiS_P3c4,0x13,SR13);
-       	SiS_SetReg1(SiS_P3c4,0x14,SR14);
-       	SiS_SetReg1(SiS_P3c4,0x16,SR16);
-       	SiS_SetReg1(SiS_P3c4,0x17,SR17);
-       	SiS_SetReg1(SiS_P3c4,0x18,SR18);
-       	SiS_SetReg1(SiS_P3c4,0x19,SR19);
-       	SiS_SetReg1(SiS_P3c4,0x1A,SR1A);
+     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12);
+       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
+       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
+       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
+       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
+       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18);
+       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
+       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);
 #endif
-       	/* SetDRAMConfig end */
    }
 /* SetDRAMSize end */
 #endif /* SIS300 */
 
-/*   SetDefExt2Regs begin  */
+   /* Set default Ext2Regs */
 #if 0
    AGP=1;
-   temp=(UCHAR)SiS_GetReg1(SiS_P3c4,0x3A);
-   temp=temp&0x30;
-   if(temp==0x30) AGP=0;
-   if(AGP==0) *pSiS_SR21=*pSiS_SR21&0xEF;
-   SiS_SetReg1(SiS_P3c4,0x21,*pSiS_SR21);
-   if(AGP==1) *pSiS_SR22=*pSiS_SR22&0x20;
-   SiS_SetReg1(SiS_P3c4,0x22,*pSiS_SR22);
-#endif
-   SiS_SetReg1(SiS_P3c4,0x21,*pSiS_SR21);
-   SiS_SetReg1(SiS_P3c4,0x22,*pSiS_SR22);
-/*   SetDefExt2Regs end  */
+   temp=(UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
+   temp &= 0x30;
+   if(temp == 0x30) AGP=0;
+   if(AGP == 0) *SiS_Pr->pSiS_SR21 &= 0xEF;
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,*SiS_Pr->pSiS_SR21);
+   if(AGP == 1) *SiS_Pr->pSiS_SR22 &= 0x20;
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,*SiS_Pr->pSiS_SR22);
+#endif
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,*SiS_Pr->pSiS_SR21);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,*SiS_Pr->pSiS_SR22);
 
 #if 0
-   SiS_SetReg3(SiS_P3c6,0xff);
-   SiS_ClearDAC(SiS_P3c8);        /* [ynlai] 05/22/01 */
+   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+   SiS_ClearDAC(SiS_Pr, SiS_Pr->SiS_P3c8);
 #endif
 
 #ifdef LINUXBIOS   /* TW: This is not needed for our purposes */
-   SiS_DetectMonitor(HwDeviceExtension,BaseAddr);
-   SiS_GetSenseStatus(HwDeviceExtension,ROMAddr);      /* sense CRT2 */
+   SiS_DetectMonitor(SiS_Pr, HwDeviceExtension,BaseAddr);    /* Sense CRT1 */
+   SiS_GetSenseStatus(SiS_Pr, HwDeviceExtension,ROMAddr);    /* Sense CRT2 */
 #endif
 
    return(TRUE);
 }
 
 void
-SiS_Set_LVDS_TRUMPION(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_Set_LVDS_TRUMPION(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-  USHORT temp=0;
+  USHORT temp = 0;
 
 #ifdef SiS300
-  if ((HwDeviceExtension->jChipType == SIS_540)||
-      (HwDeviceExtension->jChipType == SIS_630)||
-      (HwDeviceExtension->jChipType == SIS_730)) {
+  if((HwDeviceExtension->jChipType == SIS_540) ||
+     (HwDeviceExtension->jChipType == SIS_630) ||
+     (HwDeviceExtension->jChipType == SIS_730)) {
         /* TW: Read POWER_ON_TRAP and copy to CR37 */
-    	temp = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1A);
+    	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
     	temp = (temp & 0xE0) >> 4;
-   	SiS_SetRegANDOR(SiS_P3d4,0x37,0xF1,temp);
+   	SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0xF1,temp);
   }
 #endif
 #ifdef SIS315H
-  if ((HwDeviceExtension->jChipType == SIS_640)||
-      (HwDeviceExtension->jChipType == SIS_740)||
-      (HwDeviceExtension->jChipType == SIS_650)) {
+  if((HwDeviceExtension->jChipType == SIS_650) ||
+     (HwDeviceExtension->jChipType == SIS_740) ||
+     (HwDeviceExtension->jChipType == SIS_330)) {
 #if 0 /* TW: This is not required */
         /* TW: Read POWER_ON_TRAP and copy to CR37 */
-    	temp = (UCHAR)SiS_GetReg1(SiS_P3c4,0x1A);
+    	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
     	temp = (temp & 0xE0) >> 4;
-   	SiS_SetRegANDOR(SiS_P3d4,0x37,0xF1,temp);
+   	SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0xF1,temp);
 #endif
   }
 #endif
 
-   /* Set globals SiS_IF_DEF... */
-   SiSSetLVDSetc(HwDeviceExtension, 0);
+   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, 0);
 }
 
 /* ===============  SiS 300 dram sizing begin  =============== */
 #ifdef SIS300
 void
-SiS_SetDRAMSize_300(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
    ULONG   FBAddr = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
-   USHORT  SR13,SR14=0,buswidth,Done;
-   SHORT   i,j,k;
+   USHORT  SR13, SR14=0, buswidth, Done;
+   SHORT   i, j, k;
    USHORT  data, TotalCapacity, PhysicalAdrOtherPage=0;
    ULONG   Addr;
    UCHAR   temp;
-   int     PseudoRankCapacity,PseudoTotalCapacity,PseudoAdrPinCount;
-   int     RankCapacity,AdrPinCount,BankNumHigh,BankNumMid,MB2Bank;
-   int     PageCapacity,PhysicalAdrHigh,PhysicalAdrHalfPage;
-
-   SiSSetMode(HwDeviceExtension,0x2e);
-
-   data=SiS_GetReg1(SiS_P3c4,0x01);
-   data=data|0x20;
-   SiS_SetReg1(SiS_P3c4,0x01,data);                    /* Turn OFF Display  */
-
-   SiS_SetReg1(SiS_P3c4,0x13,0x00);
-   SiS_SetReg1(SiS_P3c4,0x14,0xBF);
-   buswidth=SiS_ChkBUSWidth_300(FBAddr);
-
-   MB2Bank=16;
-   Done=0;
-   for(i=6;i>=0;i--) {
-      if(Done==1) break;
-      PseudoRankCapacity=1<<i;
-      for(j=4;j>=1;j--) {
-         if(Done==1) break;
-         PseudoTotalCapacity=PseudoRankCapacity*j;
-         PseudoAdrPinCount=15-j;
+   int     PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount;
+   int     RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank;
+   int     PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage;
+
+   SiSSetMode(SiS_Pr, HwDeviceExtension, 0x2e);
+
+   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);        /* Turn OFF Display  */
+
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0xBF);
+
+   buswidth = SiS_ChkBUSWidth_300(SiS_Pr, FBAddr);
+
+   MB2Bank = 16;
+   Done = 0;
+   for(i=6; i>=0; i--) {
+      if(Done == 1) break;
+      PseudoRankCapacity = 1 << i;
+      for(j=4; j>=1; j--) {
+         if(Done == 1) break;
+         PseudoTotalCapacity = PseudoRankCapacity * j;
+         PseudoAdrPinCount = 15 - j;
          if(PseudoTotalCapacity <= 64) {
-            for(k=0;k<=16;k++) {
-               if(Done==1) break;
-               RankCapacity=buswidth*SiS_DRAMType[k][3];
-               AdrPinCount=SiS_DRAMType[k][2]+SiS_DRAMType[k][0];
-               if(RankCapacity==PseudoRankCapacity)
-                 if(AdrPinCount<=PseudoAdrPinCount) {
-                    if(j==3) {             /* Rank No */
-                       BankNumHigh=RankCapacity*MB2Bank*3-1;
-                       BankNumMid=RankCapacity*MB2Bank*1-1;
+            for(k=0; k<=16; k++) {
+               if(Done == 1) break;
+               RankCapacity = buswidth * SiS_DRAMType[k][3];
+               AdrPinCount = SiS_DRAMType[k][2] + SiS_DRAMType[k][0];
+               if(RankCapacity == PseudoRankCapacity)
+                 if(AdrPinCount <= PseudoAdrPinCount) {
+                    if(j == 3) {             /* Rank No */
+                       BankNumHigh = RankCapacity * MB2Bank * 3 - 1;
+                       BankNumMid = RankCapacity * MB2Bank * 1 - 1;
+                    } else {
+                       BankNumHigh = RankCapacity * MB2Bank * j - 1;
+                       BankNumMid = RankCapacity * MB2Bank * j / 2 - 1;
                     }
-                    else {
-                       BankNumHigh=RankCapacity*MB2Bank*j-1;
-                       BankNumMid=RankCapacity*MB2Bank*j/2-1;
-                    }
-                    PageCapacity=(1<<SiS_DRAMType[k][1])*buswidth*4;
-                    PhysicalAdrHigh =BankNumHigh;
-                    PhysicalAdrHalfPage=(PageCapacity/2+PhysicalAdrHigh)%PageCapacity;
-                    PhysicalAdrOtherPage=PageCapacity*SiS_DRAMType[k][2]+PhysicalAdrHigh;
+                    PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
+                    PhysicalAdrHigh = BankNumHigh;
+                    PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
+                    PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
                     /* Write data */
-                    /*Test */
-                    temp=(UCHAR)SiS_GetReg1(SiS_P3c4,0x15);
-                    SiS_SetReg1(SiS_P3c4,0x15,(USHORT)(temp&0xFB));
-
-                    temp=(UCHAR)SiS_GetReg1(SiS_P3c4,0x15);
-                    SiS_SetReg1(SiS_P3c4,0x15,(USHORT)(temp|0x04));
-                    /*Test */
-                    TotalCapacity=SiS_DRAMType[k][3]*buswidth;
-                    SR13=SiS_DRAMType[k][4];
-                    if(buswidth==4) SR14=(TotalCapacity-1)|0x80;
-                    if(buswidth==2) SR14=(TotalCapacity-1)|0x40;
-                    if(buswidth==1) SR14=(TotalCapacity-1)|0x00;
-                    SiS_SetReg1(SiS_P3c4,0x13,SR13);
-                    SiS_SetReg1(SiS_P3c4,0x14,SR14);
-
-                    Addr=FBAddr+(BankNumHigh)*64*1024+PhysicalAdrHigh;
-                    *((USHORT *)(Addr)) = (USHORT) PhysicalAdrHigh;
-                    Addr=FBAddr+(BankNumMid)*64*1024+PhysicalAdrHigh;
-                    *((USHORT *)(Addr)) = (USHORT) BankNumMid;
-                    Addr=FBAddr+(BankNumHigh)*64*1024+PhysicalAdrHalfPage;
-                    *((USHORT *)(Addr)) = (USHORT) PhysicalAdrHalfPage;
-                    Addr=FBAddr+(BankNumHigh)*64*1024+PhysicalAdrOtherPage;
-                    *((USHORT *)(Addr))=PhysicalAdrOtherPage;
+                    /*Test*/
+                    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x15,0xFB);
+                    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x15,0x04);
+                    /*/Test*/
+                    TotalCapacity = SiS_DRAMType[k][3] * buswidth;
+                    SR13 = SiS_DRAMType[k][4];
+                    if(buswidth == 4) SR14 = (TotalCapacity - 1) | 0x80;
+                    if(buswidth == 2) SR14 = (TotalCapacity - 1) | 0x40;
+                    if(buswidth == 1) SR14 = (TotalCapacity - 1) | 0x00;
+                    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
+                    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
+
+                    Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHigh;
+                    *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHigh;
+                    Addr = FBAddr + (BankNumMid) * 64 * 1024 + PhysicalAdrHigh;
+                    *((USHORT *)(Addr)) = (USHORT)BankNumMid;
+                    Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHalfPage;
+                    *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHalfPage;
+                    Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrOtherPage;
+                    *((USHORT *)(Addr)) = PhysicalAdrOtherPage;
 
                     /* Read data */
-                    Addr=FBAddr+(BankNumHigh)*64*1024+PhysicalAdrHigh;
-                    data=*((USHORT *)(Addr));
-                    if(data==PhysicalAdrHigh) Done=1;
+                    Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHigh;
+                    data = *((USHORT *)(Addr));
+                    if(data == PhysicalAdrHigh) Done = 1;
                  }  /* if struct */
             }  /* for loop (k) */
          }  /* if struct */
@@ -1153,21 +1278,20 @@
 }
 
 USHORT
-SiS_ChkBUSWidth_300(ULONG FBAddress)
+SiS_ChkBUSWidth_300(SiS_Private *SiS_Pr, ULONG FBAddress)
 {
-   /*USHORT  data;*/
    PULONG  pVideoMemory;
 
-   pVideoMemory = (PULONG) FBAddress;
+   pVideoMemory = (PULONG)FBAddress;
 
    pVideoMemory[0] = 0x01234567L;
    pVideoMemory[1] = 0x456789ABL;
    pVideoMemory[2] = 0x89ABCDEFL;
    pVideoMemory[3] = 0xCDEF0123L;
-   if (pVideoMemory[3]==0xCDEF0123L) { /*ChannelA128Bit */
+   if (pVideoMemory[3]==0xCDEF0123L) {  /* Channel A 128bit */
      return(4);
    }
-   if (pVideoMemory[1]==0x456789ABL) {  /*ChannelB64Bit */
+   if (pVideoMemory[1]==0x456789ABL) {  /* Channel B 64bit */
      return(2);
    }
    return(1);
@@ -1175,99 +1299,93 @@
 #endif
 /* ===============  SiS 300 dram sizing end    =============== */
 
-/* ==============  SiS 310 dram sizing begin ================= */
+/* ============  SiS 310/325 dram sizing begin  ============== */
 #ifdef SIS315H
 
 /* TW: Moved Get310DRAMType further down */
 
 void
-SiS_Delay15us(ULONG ulMicrsoSec)
+SiS_Delay15us(SiS_Private *SiS_Pr, ULONG ulMicrsoSec)
 {
 }
 
 void
-SiS_SDR_MRS(void)
+SiS_SDR_MRS(SiS_Private *SiS_Pr, )
 {
    USHORT  data;
 
-   data=SiS_GetReg1(SiS_P3c4,0x16);
-   data=data & 0x3F;          		/* SR16 D7=0,D6=0 */
-   SiS_SetReg1(SiS_P3c4,0x16,data);   	/* enable mode register set(MRS) low */
-   SiS_Delay15us(0x100);
-   data=data | 0x80;          		/* SR16 D7=1,D6=0 */
-   SiS_SetReg1(SiS_P3c4,0x16,data);   	/* enable mode register set(MRS) high */
-   SiS_Delay15us(0x100);
+   data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+   data &= 0x3F;          		        /* SR16 D7=0, D6=0 */
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);   	/* enable mode register set(MRS) low */
+   SiS_Delay15us(SiS_Pr, 0x100);
+   data |= 0x80;          		        /* SR16 D7=1, D6=0 */
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);   	/* enable mode register set(MRS) high */
+   SiS_Delay15us(SiS_Pr, 0x100);
 }
 
 void
-SiS_DDR_MRS(void)
+SiS_DDR_MRS(SiS_Private *SiS_Pr)
 {
    USHORT  data;
 
    /* SR16 <- 1F,DF,2F,AF */
 
    /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
-   data=SiS_GetReg1(SiS_P3c4,0x16);
+   data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
    data &= 0x0F;
    data |= 0x10;
-   SiS_SetReg1(SiS_P3c4,0x16,data);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
 
-   if (!(SiS_SR15[1][SiS_RAMType] & 0x10))
+   if (!(SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType] & 0x10))
      data &= 0x0F;
 
    /* SR16 D7=1,D6=1 */
    data |= 0xC0;
-   SiS_SetReg1(SiS_P3c4,0x16,data);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
    
    /* SR16 D7=1,D6=0,D5=1,D4=0 */
    data &= 0x0F;
    data |= 0x20;
-   SiS_SetReg1(SiS_P3c4,0x16,data);
-   if (!(SiS_SR15[1][SiS_RAMType] & 0x10))
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
+   if (!(SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType] & 0x10))
      data &= 0x0F;
 
    /* SR16 D7=1 */
    data |= 0x80;
-   SiS_SetReg1(SiS_P3c4,0x16,data);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
 }
 
 void
-SiS_SetDRAMModeRegister(UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
     if (SiS_Get310DRAMType(ROMAddr,HwDeviceExtension) < 2)
-        SiS_SDR_MRS();
+        SiS_SDR_MRS(SiS_Pr);
     else
         /* SR16 <- 0F,CF,0F,8F */
-        SiS_DDR_MRS();
+        SiS_DDR_MRS(SiS_Pr);
 }
 
 void
-SiS_DisableRefresh(void)
+SiS_DisableRefresh(SiS_Private *SiS_Pr)
 {
-   USHORT  data;
-
-   data=SiS_GetReg1(SiS_P3c4,0x17);
-   data &= 0xF8;
-   SiS_SetReg1(SiS_P3c4,0x17,data);
-
-   data=SiS_GetReg1(SiS_P3c4,0x19);
-   data |= 0x03;
-   SiS_SetReg1(SiS_P3c4,0x19,data);
+   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x17,0xF8);
+   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x19,0x03);
 }
 
 void
-SiS_EnableRefresh(UCHAR *ROMAddr)
+SiS_EnableRefresh(SiS_Private *SiS_Pr, UCHAR *ROMAddr)
 {
-   SiS_SetReg1(SiS_P3c4,0x17,SiS_SR15[2][SiS_RAMType]);  /* SR17 */
-   SiS_SetReg1(SiS_P3c4,0x19,SiS_SR15[4][SiS_RAMType]);  /* SR19 */
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SiS_Pr->SiS_SR15[2][SiS_Pr->SiS_RAMType]);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SiS_Pr->SiS_SR15[4][SiS_Pr->SiS_RAMType]);
 }
 
 void
-SiS_DisableChannelInterleaving(int index,USHORT SiS_DDRDRAM_TYPE[][5])
+SiS_DisableChannelInterleaving(SiS_Private *SiS_Pr, int index,
+                               USHORT SiS_DDRDRAM_TYPE[][5])
 {
    USHORT  data;
 
-   data=SiS_GetReg1(SiS_P3c4,0x15);
+   data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15);
    data &= 0x1F;
    switch (SiS_DDRDRAM_TYPE[index][3])
    {
@@ -1276,37 +1394,41 @@
      case 16: data |= 0x40;     break;
      case 4:  data |= 0x60;     break;
    }
-   SiS_SetReg1(SiS_P3c4,0x15,data);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,data);
 }
 
 void
-SiS_SetDRAMSizingType(int index,USHORT DRAMTYPE_TABLE[][5])
+SiS_SetDRAMSizingType(SiS_Private *SiS_Pr, int index, USHORT DRAMTYPE_TABLE[][5])
 {
-   USHORT  data;
-
-   data = DRAMTYPE_TABLE[index][4];
-   SiS_SetReg1(SiS_P3c4,0x13,data);
-
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,DRAMTYPE_TABLE[index][4]);
    /* should delay 50 ns */
 }
 
 void
-SiS_CheckBusWidth_310(UCHAR *ROMAddress,ULONG FBAddress,
+SiS_CheckBusWidth_310(SiS_Private *SiS_Pr, UCHAR *ROMAddress,ULONG FBAddress,
                       PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-   USHORT  data;
-   PULONG volatile pVideoMemory;
+   USHORT  data, temp;
+   PULONG  volatile pVideoMemory;
 
-   pVideoMemory = (PULONG) FBAddress;
-   if (SiS_Get310DRAMType(ROMAddress,HwDeviceExtension) < 2) {
+   pVideoMemory = (PULONG)FBAddress;
 
-     SiS_SetReg1(SiS_P3c4,0x13,0x00);
-     SiS_SetReg1(SiS_P3c4,0x14,0x12);
+   if(HwDeviceExtension->jChipType == SIS_330) temp = 1;
+   else temp = 2;
+
+   if(SiS_Get310DRAMType(ROMAddress,HwDeviceExtension) < temp) {
+
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00);
+     if(HwDeviceExtension->jChipType != SIS_330) {
+        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x12);
+     } else {
+        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x02);
+     }
      /* should delay */
-     SiS_SDR_MRS();
+     SiS_SDR_MRS(SiS_Pr);
 
-     SiS_ChannelAB = 0;
-     SiS_DataBusWidth = 128;
+     SiS_Pr->SiS_ChannelAB = 0;
+     SiS_Pr->SiS_DataBusWidth = 128;
      pVideoMemory[0] = 0x01234567L;
      pVideoMemory[1] = 0x456789ABL;
      pVideoMemory[2] = 0x89ABCDEFL;
@@ -1315,32 +1437,30 @@
      pVideoMemory[5] = 0x55555555L;
      pVideoMemory[6] = 0xFFFFFFFFL;
      pVideoMemory[7] = 0xFFFFFFFFL;
-     if ((pVideoMemory[3]!=0xCDEF0123L) || (pVideoMemory[2] != 0x89ABCDEFL)) {
-       /*ChannelA64Bit */
-       SiS_DataBusWidth = 64;
-       SiS_ChannelAB = 0;
-       data=SiS_GetReg1(SiS_P3c4,0x14);
-       SiS_SetReg1(SiS_P3c4,  0x14, (USHORT) (data & 0xFD));
+     if((pVideoMemory[3] != 0xCDEF0123L) || (pVideoMemory[2] != 0x89ABCDEFL)) {
+       /* Channel A 64Bit */
+       SiS_Pr->SiS_DataBusWidth = 64;
+       SiS_Pr->SiS_ChannelAB = 0;
+       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x14, 0xFD);
      }
-
-     if ((pVideoMemory[1]!=0x456789ABL) || (pVideoMemory[0] != 0x01234567L)) {
-       /*ChannelB64Bit */
-       SiS_DataBusWidth = 64;
-       SiS_ChannelAB = 1;
-       data=SiS_GetReg1(SiS_P3c4,0x14);
-       SiS_SetReg1(SiS_P3c4,0x14,(USHORT)((data&0xFD)|0x01));
+     if((pVideoMemory[1] != 0x456789ABL) || (pVideoMemory[0] != 0x01234567L)) {
+       /* Channel B 64Bit */
+       SiS_Pr->SiS_DataBusWidth = 64;
+       SiS_Pr->SiS_ChannelAB = 1;
+       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x14,0xfd,0x01);
      }
      return;
 
    } else {
+
      /* DDR Dual channel */
-     SiS_SetReg1(SiS_P3c4,0x13,0x00);
-     SiS_SetReg1(SiS_P3c4,0x14,0x02); /* Channel A, 64bit */
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x02); /* Channel A, 64bit */
      /* should delay */
-     SiS_DDR_MRS();
+     SiS_DDR_MRS(SiS_Pr);
 
-     SiS_ChannelAB = 0;
-     SiS_DataBusWidth = 64;
+     SiS_Pr->SiS_ChannelAB = 0;
+     SiS_Pr->SiS_DataBusWidth = 64;
      pVideoMemory[0] = 0x01234567L;
      pVideoMemory[1] = 0x456789ABL;
      pVideoMemory[2] = 0x89ABCDEFL;
@@ -1358,17 +1478,17 @@
      } else {
        if (pVideoMemory[0] == 0x01234567L) {
          /* Channel A 32bit */
-         SiS_DataBusWidth = 32;
-         SiS_SetReg1(SiS_P3c4,0x14,0x00);
+         SiS_Pr->SiS_DataBusWidth = 32;
+         SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x00);
          return;
        }
      }
 
-     SiS_SetReg1(SiS_P3c4,0x14,0x03); /* Channel B, 64bit */
-     SiS_DDR_MRS();
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x03); /* Channel B, 64bit */
+     SiS_DDR_MRS(SiS_Pr);
 
-     SiS_ChannelAB = 1;
-     SiS_DataBusWidth = 64;
+     SiS_Pr->SiS_ChannelAB = 1;
+     SiS_Pr->SiS_DataBusWidth = 64;
      pVideoMemory[0] = 0x01234567L;
      pVideoMemory[1] = 0x456789ABL;
      pVideoMemory[2] = 0x89ABCDEFL;
@@ -1377,19 +1497,19 @@
      pVideoMemory[5] = 0x55555555L;
      pVideoMemory[6] = 0xAAAAAAAAL;
      pVideoMemory[7] = 0xAAAAAAAAL;
-     if (pVideoMemory[1] == 0x456789ABL) {
+     if(pVideoMemory[1] == 0x456789ABL) {
        /* Channel B 64 */
-       if (pVideoMemory[0] == 0x01234567L) {
+       if(pVideoMemory[0] == 0x01234567L) {
          /* Channel B 64bit */
          return;
        } else {
          /* error */
        }
      } else {
-       if (pVideoMemory[0] == 0x01234567L) {
+       if(pVideoMemory[0] == 0x01234567L) {
          /* Channel B 32 */
-         SiS_DataBusWidth = 32;
-         SiS_SetReg1(SiS_P3c4,0x14,0x01);
+         SiS_Pr->SiS_DataBusWidth = 32;
+         SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x01);
        } else {
          /* error */
        }
@@ -1398,7 +1518,7 @@
 }
 
 int
-SiS_SetRank(int index,UCHAR RankNo,UCHAR SiS_ChannelAB,USHORT DRAMTYPE_TABLE[][5])
+SiS_SetRank(SiS_Private *SiS_Pr, int index,UCHAR RankNo,USHORT DRAMTYPE_TABLE[][5])
 {
   USHORT  data;
   int RankSize;
@@ -1406,68 +1526,66 @@
   if ((RankNo==2)&&(DRAMTYPE_TABLE[index][0]==2))
          return 0;
 
-  RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_DataBusWidth/32;
+  RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_Pr->SiS_DataBusWidth / 32;
 
-  if (RankNo*RankSize<=128) {
+  if (RankNo * RankSize <= 128) {
     data = 0;
-    while ((RankSize>>=1)>0) {
-      data+=0x10;
+    while((RankSize >>= 1) > 0) {
+      data += 0x10;
     }
-    data |= (RankNo-1)<<2;
-    data |= (SiS_DataBusWidth/64)&2;
-    data |= SiS_ChannelAB;
-    SiS_SetReg1(SiS_P3c4,0x14,data);
+    data |= (RankNo - 1) << 2;
+    data |= (SiS_Pr->SiS_DataBusWidth / 64) & 2;
+    data |= SiS_Pr->SiS_ChannelAB;
+    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data);
     /* should delay */
-    SiS_SDR_MRS();
+    SiS_SDR_MRS(SiS_Pr);
     return 1;
   } else
     return 0;
 }
 
 int
-SiS_SetDDRChannel(int index,UCHAR ChannelNo,UCHAR SiS_ChannelAB,
+SiS_SetDDRChannel(SiS_Private *SiS_Pr, int index,UCHAR ChannelNo,
                   USHORT DRAMTYPE_TABLE[][5])
 {
   USHORT  data;
   int RankSize;
 
-  RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_DataBusWidth/32;
+  RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_Pr->SiS_DataBusWidth / 32;
   /* RankSize = DRAMTYPE_TABLE[index][3]; */
-  if (ChannelNo*RankSize<=128) {
+  if (ChannelNo * RankSize <= 128) {
     data = 0;
-    while ((RankSize>>=1)>0) {
-      data+=0x10;
+    while((RankSize >>= 1) > 0) {
+      data += 0x10;
     }
-    if (ChannelNo==2)
-      data |= 0x0C;
-
-    data |= (SiS_DataBusWidth/32)&2;
-    data |= SiS_ChannelAB;
-    SiS_SetReg1(SiS_P3c4,0x14,data);
+    if(ChannelNo == 2) data |= 0x0C;
+    data |= (SiS_Pr->SiS_DataBusWidth / 32) & 2;
+    data |= SiS_Pr->SiS_ChannelAB;
+    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data);
     /* should delay */
-    SiS_DDR_MRS();
+    SiS_DDR_MRS(SiS_Pr);
     return 1;
   } else
     return 0;
 }
 
 int
-SiS_CheckColumn(int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+SiS_CheckColumn(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
   int i;
   ULONG Increment,Position;
 
-  /*Increment = 1<<(DRAMTYPE_TABLE[index][2] + SiS_DataBusWidth / 64 + 1); */
-  Increment = 1<<(10 + SiS_DataBusWidth / 64);
+  /*Increment = 1<<(DRAMTYPE_TABLE[index][2] + SiS_Pr->SiS_DataBusWidth / 64 + 1); */
+  Increment = 1 << (10 + SiS_Pr->SiS_DataBusWidth / 64);
 
   for (i=0,Position=0;i<2;i++) {
-         *((PULONG)(FBAddress+Position))=Position;
+         *((PULONG)(FBAddress + Position)) = Position;
          Position += Increment;
   }
 
   for (i=0,Position=0;i<2;i++) {
 /*    if (FBAddress[Position]!=Position) */
-         if ( (*(PULONG) (FBAddress + Position)) !=Position)
+         if((*(PULONG)(FBAddress + Position)) != Position)
                 return 0;
          Position += Increment;
   }
@@ -1475,21 +1593,21 @@
 }
 
 int
-SiS_CheckBanks(int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+SiS_CheckBanks(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
   int i;
   ULONG Increment,Position;
-  Increment = 1<<(DRAMTYPE_TABLE[index][2] + SiS_DataBusWidth / 64 + 2);
+  Increment = 1 << (DRAMTYPE_TABLE[index][2] + SiS_Pr->SiS_DataBusWidth / 64 + 2);
 
   for (i=0,Position=0;i<4;i++) {
 /*    FBAddress[Position]=Position; */
-    *((PULONG)(FBAddress+Position))=Position;
+    *((PULONG)(FBAddress + Position)) = Position;
     Position += Increment;
   }
 
   for (i=0,Position=0;i<4;i++) {
 /*    if (FBAddress[Position]!=Position) */
-    if ( (*(PULONG) (FBAddress + Position)) !=Position)
+    if((*(PULONG)(FBAddress + Position)) != Position)
       return 0;
     Position += Increment;
   }
@@ -1497,12 +1615,12 @@
 }
 
 int
-SiS_CheckRank(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+SiS_CheckRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
   int i;
   ULONG Increment,Position;
   Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
-                  DRAMTYPE_TABLE[index][0] + SiS_DataBusWidth / 64 + RankNo);
+                  DRAMTYPE_TABLE[index][0] + SiS_Pr->SiS_DataBusWidth / 64 + RankNo);
 
   for (i=0,Position=0;i<2;i++) {
 /*    FBAddress[Position]=Position; */
@@ -1522,90 +1640,91 @@
 }
 
 int
-SiS_CheckDDRRank(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+SiS_CheckDDRRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
   ULONG Increment,Position;
   USHORT  data;
-  
+
   Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
-                  DRAMTYPE_TABLE[index][0] + SiS_DataBusWidth / 64 + RankNo);
+                  DRAMTYPE_TABLE[index][0] + SiS_Pr->SiS_DataBusWidth / 64 + RankNo);
 
   Increment += Increment/2;
-  
+
   Position =0;
-  *((PULONG)(FBAddress+Position+0))=0x01234567;
-  *((PULONG)(FBAddress+Position+1))=0x456789AB;
-  *((PULONG)(FBAddress+Position+2))=0x55555555;
-  *((PULONG)(FBAddress+Position+3))=0x55555555;
-  *((PULONG)(FBAddress+Position+4))=0xAAAAAAAA;
-  *((PULONG)(FBAddress+Position+5))=0xAAAAAAAA;
+  *((PULONG)(FBAddress+Position + 0)) = 0x01234567;
+  *((PULONG)(FBAddress+Position + 1)) = 0x456789AB;
+  *((PULONG)(FBAddress+Position + 2)) = 0x55555555;
+  *((PULONG)(FBAddress+Position + 3)) = 0x55555555;
+  *((PULONG)(FBAddress+Position + 4)) = 0xAAAAAAAA;
+  *((PULONG)(FBAddress+Position + 5)) = 0xAAAAAAAA;
 
-  if ( (*(PULONG) (FBAddress + 1))==0x456789AB)
+  if ( (*(PULONG) (FBAddress + 1)) == 0x456789AB)
     return 1;
 
-  if ( (*(PULONG) (FBAddress + 0))==0x01234567)
+  if ( (*(PULONG) (FBAddress + 0)) == 0x01234567)
     return 0;
 
-  data=SiS_GetReg1(SiS_P3c4,0x14);
+  data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
   data &= 0xF3;
   data |= 0x08;
-  SiS_SetReg1(SiS_P3c4,0x14,data);
-  data=SiS_GetReg1(SiS_P3c4,0x15);
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data);
+  data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15);
   data += 0x20;
-  SiS_SetReg1(SiS_P3c4,0x15,data);
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,data);
 
   return 1;
 }
 
 int
-SiS_CheckRanks(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+SiS_CheckRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
 {
   int r;
 
   for (r=RankNo;r>=1;r--) {
-    if (!SiS_CheckRank(r,index,DRAMTYPE_TABLE,FBAddress))
+    if (!SiS_CheckRank(SiS_Pr, r, index, DRAMTYPE_TABLE, FBAddress))
       return 0;
   }
-  if (!SiS_CheckBanks(index,DRAMTYPE_TABLE,FBAddress))
+  if (!SiS_CheckBanks(SiS_Pr, index, DRAMTYPE_TABLE, FBAddress))
     return 0;
 
-  if (!SiS_CheckColumn(index,DRAMTYPE_TABLE,FBAddress))
+  if (!SiS_CheckColumn(SiS_Pr, index, DRAMTYPE_TABLE, FBAddress))
     return 0;
 
   return 1;
 }
 
 int
-SiS_CheckDDRRanks(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+SiS_CheckDDRRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],
+                  ULONG FBAddress)
 {
   int r;
 
   for (r=RankNo;r>=1;r--) {
-    if (!SiS_CheckDDRRank(r,index,DRAMTYPE_TABLE,FBAddress))
+    if (!SiS_CheckDDRRank(SiS_Pr, r,index,DRAMTYPE_TABLE,FBAddress))
       return 0;
   }
-  if (!SiS_CheckBanks(index,DRAMTYPE_TABLE,FBAddress))
+  if (!SiS_CheckBanks(SiS_Pr, index,DRAMTYPE_TABLE,FBAddress))
     return 0;
 
-  if (!SiS_CheckColumn(index,DRAMTYPE_TABLE,FBAddress))
+  if (!SiS_CheckColumn(SiS_Pr, index,DRAMTYPE_TABLE,FBAddress))
     return 0;
 
   return 1;
 }
 
 int
-SiS_SDRSizing(ULONG FBAddress)
+SiS_SDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress)
 {
   int    i;
   UCHAR  j;
 
   for (i=0;i<13;i++) {
-    SiS_SetDRAMSizingType(i, SiS_SDRDRAM_TYPE);
+    SiS_SetDRAMSizingType(SiS_Pr, i, SiS_SDRDRAM_TYPE);
     for (j=2;j>0;j--) {
-      if (!SiS_SetRank(i,(UCHAR) j, SiS_ChannelAB,SiS_SDRDRAM_TYPE))
+      if (!SiS_SetRank(SiS_Pr, i,(UCHAR) j, SiS_SDRDRAM_TYPE))
         continue;
       else {
-        if (SiS_CheckRanks(j,i,SiS_SDRDRAM_TYPE, FBAddress))
+        if (SiS_CheckRanks(SiS_Pr, j,i,SiS_SDRDRAM_TYPE, FBAddress))
           return 1;
       }
     }
@@ -1614,21 +1733,21 @@
 }
 
 int
-SiS_DDRSizing(ULONG FBAddress)
+SiS_DDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress)
 {
 
   int    i;
   UCHAR  j;
 
-  for (i=0;i<4;i++){
-    SiS_SetDRAMSizingType(i,SiS_DDRDRAM_TYPE);
-    SiS_DisableChannelInterleaving(i,SiS_DDRDRAM_TYPE);
-    for (j=2;j>0;j--) {
-      SiS_SetDDRChannel(i, j, SiS_ChannelAB, SiS_DDRDRAM_TYPE);
-      if (!SiS_SetRank(i,(UCHAR) j, SiS_ChannelAB,SiS_DDRDRAM_TYPE))
+  for (i=0; i<4; i++){
+    SiS_SetDRAMSizingType(SiS_Pr, i, SiS_DDRDRAM_TYPE);
+    SiS_DisableChannelInterleaving(SiS_Pr, i, SiS_DDRDRAM_TYPE);
+    for (j=2; j>0; j--) {
+      SiS_SetDDRChannel(SiS_Pr, i, j, SiS_DDRDRAM_TYPE);
+      if (!SiS_SetRank(SiS_Pr, i, (UCHAR) j, SiS_DDRDRAM_TYPE))
         continue;
       else {
-        if (SiS_CheckDDRRanks(j,i,SiS_DDRDRAM_TYPE, FBAddress))
+        if (SiS_CheckDDRRanks(SiS_Pr, j, i, SiS_DDRDRAM_TYPE, FBAddress))
           return 1;
       }
     }
@@ -1640,31 +1759,31 @@
  check if read cache pointer is correct
 */
 void
-SiS_VerifyMclk(ULONG FBAddr)
+SiS_VerifyMclk(SiS_Private *SiS_Pr, ULONG FBAddr)
 {
    PUCHAR  pVideoMemory = (PUCHAR) FBAddr;
-   UCHAR i,j;
-   USHORT Temp,SR21;
+   UCHAR   i, j;
+   USHORT  Temp,SR21;
 
-   pVideoMemory[0]=0xaa;  /* alan */
-   pVideoMemory[16]=0x55; /* note: PCI read cache is off */
+   pVideoMemory[0] = 0xaa;  /* alan */
+   pVideoMemory[16] = 0x55; /* note: PCI read cache is off */
 
-   if ((pVideoMemory[0]!=0xaa)||(pVideoMemory[16]!=0x55)) {
-     for (i=0,j=16;i<2;i++,j+=16)  {
-       SR21 = SiS_GetReg1(SiS_P3c4, 0x21);
-       Temp = SR21 & 0xFB;     /* disable PCI post write buffer empty gating */
-       SiS_SetReg1(SiS_P3c4, 0x21, Temp);
-
-       Temp = SiS_GetReg1(SiS_P3c4, 0x3C);
-       Temp = Temp | 0x01;                 /*MCLK reset */
-       SiS_SetReg1(SiS_P3c4, 0x3C, Temp);
-       Temp = SiS_GetReg1(SiS_P3c4, 0x3C);
-       Temp = Temp & 0xFE;                 /* MCLK normal operation */
-       SiS_SetReg1(SiS_P3c4, 0x3C, Temp);
-       SiS_SetReg1(SiS_P3c4, 0x21, SR21);
+   if((pVideoMemory[0] != 0xaa) || (pVideoMemory[16] != 0x55)) {
+     for (i=0,j=16; i<2; i++,j+=16)  {
+       SR21 = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x21);
+       Temp = SR21 & 0xFB;           /* disable PCI post write buffer empty gating */
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,Temp);
+
+       Temp = SiS_GetReg1(SiS_Pr->SiS_P3c4, 0x3C);
+       Temp |= 0x01;                 /* MCLK reset */
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3C,Temp);
+       Temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3C);
+       Temp &= 0xFE;                 /* MCLK normal operation */
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3C,Temp);
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,SR21);
 
        pVideoMemory[16+j] = j;
-       if (pVideoMemory[16+j]==j)  {
+       if(pVideoMemory[16+j] == j) {
          pVideoMemory[j] = j;
          break;
        }
@@ -1674,109 +1793,124 @@
 
 /* TW: Is this a 315E? */
 int
-Is315E(void)
+Is315E(SiS_Private *SiS_Pr)
 {
    USHORT  data;
 
-   data=SiS_GetReg1(SiS_P3d4,0x5F);
-   if (data&0x10) return 1;
+   data = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5F);
+   if(data & 0x10) return 1;
    else return 0;
 }
 
 /* TW: For 315 only */
 void
-SiS_SetDRAMSize_310(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetDRAMSize_310(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
    UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
    ULONG   FBAddr   = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
    USHORT  data;
 
 #ifdef SIS301	/* TW: SIS301 ??? */
-   /*SiS_SetReg1(SiS_P3d4,0x30,0x40);   */
+   /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x40);   */
 #endif
 #ifdef SIS302   /* TW: SIS302 ??? */
-   SiS_SetReg1(SiS_P3d4,0x30,0x4D);  /* alan,should change value */
-   SiS_SetReg1(SiS_P3d4,0x31,0xc0);  /* alan,should change value */
-   SiS_SetReg1(SiS_P3d4,0x34,0x3F);  /* alan,should change value */
+   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x4D);  /* alan,should change value */
+   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x31,0xc0);  /* alan,should change value */
+   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,0x3F);  /* alan,should change value */
 #endif
 
-   SiSSetMode(HwDeviceExtension,0x2e);
+   SiSSetMode(SiS_Pr, HwDeviceExtension, 0x2e);
+
+   data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x21);
+   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x21,0xDF);                 /* disable read cache */
 
-   data=SiS_GetReg1(SiS_P3c4,0x21);
-   SiS_SetReg1(SiS_P3c4,0x21,(USHORT) (data&0xDF));   /* disable read cache */
+   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);                  /* Turn OFF Display */
 
-   data=SiS_GetReg1(SiS_P3c4,0x1);
-   data=data|0x20;
-   SiS_SetReg1(SiS_P3c4,0x01,data);                   /* Turn OFF Display */
+   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x16,0x0F);                  /* assume lowest speed DRAM */
 
-   data=SiS_GetReg1(SiS_P3c4,0x16);
-   SiS_SetReg1(SiS_P3c4,0x16,(USHORT) (data|0x0F));   /* assume lowest speed DRAM */
+   SiS_SetDRAMModeRegister(SiS_Pr, ROMAddr, HwDeviceExtension);
+   SiS_DisableRefresh(SiS_Pr);
+   SiS_CheckBusWidth_310(SiS_Pr, ROMAddr, FBAddr, HwDeviceExtension);
 
-   SiS_SetDRAMModeRegister(ROMAddr,HwDeviceExtension);
-   SiS_DisableRefresh();
-   SiS_CheckBusWidth_310(ROMAddr,FBAddr,HwDeviceExtension);
+   SiS_VerifyMclk(SiS_Pr, FBAddr);
 
-   SiS_VerifyMclk(FBAddr); /* alan 2000/7/3 */
+   if(HwDeviceExtension->jChipType == SIS_330) temp = 1;
+   else temp = 2;
 
-   if (SiS_Get310DRAMType(ROMAddr, HwDeviceExtension)<2)
-     SiS_SDRSizing(FBAddr);
+   if(SiS_Get310DRAMType(SiS_Pr, ROMAddr, HwDeviceExtension) < temp)
+     SiS_SDRSizing(SiS_Pr, FBAddr);
    else
-     SiS_DDRSizing(FBAddr);
+     SiS_DDRSizing(SiS_Pr, FBAddr);
 
-   if (Is315E()) {
-     data=SiS_GetReg1(SiS_P3c4,0x14);
-     if ((data&0x0C)==0x0C) { 	/* dual channel */
-     	if ((data&0xF0)>0x40)
-     	  data = (data & 0x0F) | 0x40;
-     } else { 			/* single channel */
-     	if ((data&0xF0)>0x50)
-     	  data = (data & 0x0F) | 0x50;
+   if(HwDeviceExtension->jChipType != SIS_330) {
+     if(Is315E(SiS_Pr)) {
+       data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+       if((data & 0x0C) == 0x0C) { 	/* dual channel */
+     	 if((data & 0xF0) > 0x40)
+     	   data = (data & 0x0F) | 0x40;
+       } else { 				/* single channel */
+     	 if((data & 0xF0) > 0x50)
+     	   data = (data & 0x0F) | 0x50;
+       }
      }
    }
 
-   SiS_SetReg1(SiS_P3c4,0x16,SiS_SR15[1][SiS_RAMType]);  /* restore SR16 */
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType]);  /* restore SR16 */
 
-   SiS_EnableRefresh(ROMAddr);
-   data=SiS_GetReg1(SiS_P3c4,0x21);
-   SiS_SetReg1(SiS_P3c4,0x21,(USHORT) (data|0x20));      /* enable read cache */
+   SiS_EnableRefresh(SiS_Pr, ROMAddr);
+   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x21,0x20);      	/* enable read cache */
 }
 #endif
 
 void
-SiS_SetMemoryClock(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetMemoryClock(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-   SiS_SetReg1(SiS_P3c4,0x28,SiS_MCLKData_0[SiS_RAMType].SR28);
-   SiS_SetReg1(SiS_P3c4,0x29,SiS_MCLKData_0[SiS_RAMType].SR29);
-   SiS_SetReg1(SiS_P3c4,0x2A,SiS_MCLKData_0[SiS_RAMType].SR2A);
-   SiS_SetReg1(SiS_P3c4,0x2E,SiS_ECLKData[SiS_RAMType].SR2E);
-   SiS_SetReg1(SiS_P3c4,0x2F,SiS_ECLKData[SiS_RAMType].SR2F);
-   SiS_SetReg1(SiS_P3c4,0x30,SiS_ECLKData[SiS_RAMType].SR30);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x28,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR28);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x29,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR29);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2A,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR2A);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2E,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR2E);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2F,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR2F);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x30,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR30);
 
 #ifdef SIS315H
-   if (Is315E()) {
-     SiS_SetReg1(SiS_P3c4,0x28,0x3B); /* 143 */
-     SiS_SetReg1(SiS_P3c4,0x29,0x22);
-     SiS_SetReg1(SiS_P3c4,0x2E,0x3B); /* 143 */
-     SiS_SetReg1(SiS_P3c4,0x2F,0x22);
+   if (Is315E(SiS_Pr)) {
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x28,0x3B); /* 143 */
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x29,0x22);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2E,0x3B); /* 143 */
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2F,0x22);
    }
 #endif
 }
 
-#endif /* ifndef LINUX_XF86 */
+#endif /* ifdef LINUXBIOS */
 
 #ifdef SIS315H
 UCHAR
-SiS_Get310DRAMType(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-   UCHAR   data;
+   UCHAR data, temp;
 
-   if (*pSiS_SoftSetting & SoftDRAMType) {
-     data = *pSiS_SoftSetting & 0x03;
+   if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) {
+     data = *SiS_Pr->pSiS_SoftSetting & 0x03;
    } else {
-     if(HwDeviceExtension->jChipType > SIS_315PRO) {
-        data = SiS_GetReg1(SiS_P3c4,0x13) & 0x07;
-     } else {	/* TW: 315 */
-        data = SiS_GetReg1(SiS_P3c4,0x3a) & 0x03;
+     if((HwDeviceExtension->jChipType > SIS_315PRO) &&
+        (HwDeviceExtension->jChipType < SIS_330)) {
+        data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
+     } else {	/* TW: 315, 330 */
+        data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
+        if(HwDeviceExtension->jChipType == SIS_330) {
+	   if(data > 1) {
+	      temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0x30;
+	      switch(temp) {
+	      case 0x00: data = 1; break;
+	      case 0x10: data = 3; break;
+	      case 0x20: data = 3; break;
+	      case 0x30: data = 2; break;
+	      }
+	   } else {
+	      data = 0;
+	   }
+	}
      }
    }
 
@@ -1788,31 +1922,31 @@
 
 /* ----------------------------------------- */
 
-void SiSRegInit(USHORT BaseAddr)
+void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr)
 {
-   SiS_P3c4=BaseAddr+0x14;
-   SiS_P3d4=BaseAddr+0x24;
-   SiS_P3c0=BaseAddr+0x10;
-   SiS_P3ce=BaseAddr+0x1e;
-   SiS_P3c2=BaseAddr+0x12;
-   SiS_P3ca=BaseAddr+0x1a;
-   SiS_P3c6=BaseAddr+0x16;
-   SiS_P3c7=BaseAddr+0x17;
-   SiS_P3c8=BaseAddr+0x18;
-   SiS_P3c9=BaseAddr+0x19;
-   SiS_P3da=BaseAddr+0x2A;
-   SiS_Part1Port=BaseAddr+SIS_CRT2_PORT_04;   /* Digital video interface registers (LCD) */
-   SiS_Part2Port=BaseAddr+SIS_CRT2_PORT_10;   /* 301 TV Encoder registers */
-   SiS_Part3Port=BaseAddr+SIS_CRT2_PORT_12;   /* 301 Macrovision registers */
-   SiS_Part4Port=BaseAddr+SIS_CRT2_PORT_14;   /* 301 VGA2 registers */
-   SiS_Part5Port=BaseAddr+SIS_CRT2_PORT_14+2; /* 301 palette address port registers */
-   SiS_DDC_Port=BaseAddr+0x14;  /* 0x3c4; */  /* DDC Port ( = P3C4) */
+   SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
+   SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
+   SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
+   SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
+   SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
+   SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
+   SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
+   SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
+   SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
+   SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
+   SiS_Pr->SiS_P3da = BaseAddr + 0x2A;
+   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;   /* Digital video interface registers (LCD) */
+   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;   /* 301 TV Encoder registers */
+   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;   /* 301 Macrovision registers */
+   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;   /* 301 VGA2 (and LCD) registers */
+   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14+2; /* 301 palette address port registers */
+   SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;                /* DDC Port ( = P3C4, SR11/0A) */
 }
 
 void
-SiSInitPCIetc(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-#ifdef LINUX_XF86
+/* #ifdef LINUX_XF86 */
    if ((HwDeviceExtension->jChipType == SIS_540)||
        (HwDeviceExtension->jChipType == SIS_630)||
        (HwDeviceExtension->jChipType == SIS_730)||
@@ -1821,214 +1955,309 @@
 		  - PCI IO ENABLE  (0x20)
 		  - MMIO ENABLE (0x1)
   	*/
-       SiS_SetReg1(SiS_P3c4,0x20,0xa1);
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
        /* TW: Enable 2D (0x42) & 3D accelerator (0x18) */
-       SiS_SetRegANDOR(SiS_P3c4,0x1E,0xFF,0x5A);
+       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A);
    }
    if((HwDeviceExtension->jChipType == SIS_315H)||
+      (HwDeviceExtension->jChipType == SIS_315) ||
       (HwDeviceExtension->jChipType == SIS_315PRO)||
-      (HwDeviceExtension->jChipType == SIS_550)||
-      (HwDeviceExtension->jChipType == SIS_640)||
-      (HwDeviceExtension->jChipType == SIS_740)||
-      (HwDeviceExtension->jChipType == SIS_650)) {
+      (HwDeviceExtension->jChipType == SIS_550) ||
+      (HwDeviceExtension->jChipType == SIS_650) ||
+      (HwDeviceExtension->jChipType == SIS_740) ||
+      (HwDeviceExtension->jChipType == SIS_330)) {
       /* TW: This seems to be done the same way on these chipsets */
-      SiS_SetReg1(SiS_P3c4,0x20,0xa1);
-      SiS_SetRegANDOR(SiS_P3c4,0x1E,0xFF,0x5A);
+      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A);
    }
-#endif
+/* #endif */
 }
 
 void
-SiSSetLVDSetc(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
 {
    ULONG   temp;
 
-   SiS_IF_DEF_LVDS = 0;
-   SiS_IF_DEF_TRUMPION = 0;
-   SiS_IF_DEF_CH70xx = 0;
-   SiS_IF_DEF_HiVision = 0;
-   SiS_IF_DEF_DSTN = 0;
-   SiS_IF_DEF_FSTN = 0;
+   SiS_Pr->SiS_IF_DEF_LVDS = 0;
+   SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
+   SiS_Pr->SiS_IF_DEF_CH70xx = 0;
+   SiS_Pr->SiS_IF_DEF_HiVision = 0;
+   SiS_Pr->SiS_IF_DEF_DSTN = 0;
+   SiS_Pr->SiS_IF_DEF_FSTN = 0;
 
-   SiS_ChrontelInit = 0;
+   SiS_Pr->SiS_ChrontelInit = 0;
 
    if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
-   	SiS_IF_DEF_DSTN = 1;   /* for 550 dstn */
-   	SiS_IF_DEF_FSTN = 1;   /* for fstn */
+   	SiS_Pr->SiS_IF_DEF_DSTN = 1;   /* for 550 dstn */
+   	SiS_Pr->SiS_IF_DEF_FSTN = 1;   /* for fstn */
    }
 
 #ifdef SIS300
-   if((HwDeviceExtension->jChipType == SIS_540)||
-      (HwDeviceExtension->jChipType == SIS_630)||
+   if((HwDeviceExtension->jChipType == SIS_540) ||
+      (HwDeviceExtension->jChipType == SIS_630) ||
       (HwDeviceExtension->jChipType == SIS_730))
     {
-      	temp=SiS_GetReg1(SiS_P3d4,0x37);
+        /* TW: Check for SiS30x first */
+        temp = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
+	if((temp == 1) || (temp == 2)) return;
+      	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
       	temp = (temp & 0x0E) >> 1;
-      	if((temp >= 2) && (temp <= 5)) SiS_IF_DEF_LVDS = 1;
-      	if(temp == 3)   SiS_IF_DEF_TRUMPION = 1;
+      	if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
+      	if(temp == 3)   SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
       	if((temp == 4) || (temp == 5)) {
-		/* TW: Save power status (and error check) */
-		SiS_Backup70xx = SiS_GetCH700x(0x0e);
-		if (SiS_Backup70xx != 0xFFFF)
-			SiS_IF_DEF_CH70xx = 1;
+		/* TW: Save power status (and error check) - UNUSED */
+		SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
+		SiS_Pr->SiS_IF_DEF_CH70xx = 1;
         }
    }
 #endif
 #ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_550)||
-      (HwDeviceExtension->jChipType == SIS_640)||
-      (HwDeviceExtension->jChipType == SIS_740)||
-      (HwDeviceExtension->jChipType == SIS_650))
+   if((HwDeviceExtension->jChipType == SIS_550) ||
+      (HwDeviceExtension->jChipType == SIS_650) ||
+      (HwDeviceExtension->jChipType == SIS_740) ||
+      (HwDeviceExtension->jChipType == SIS_330))
     {
-        /* TW: CR37 is different on 310 series */
-        if (SiS_IF_DEF_FSTN)                       /* fstn: set CR37=0x04 */
-             SiS_SetReg1(SiS_P3d4,0x37,0x04);      /* (fake LVDS bridge) */
+        /* TW: CR37 is different on 310/325 series */
+        if(SiS_Pr->SiS_IF_DEF_FSTN)                       /* fstn: set CR37=0x04 */
+             SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x04);      /* (fake LVDS bridge) */
 
-	temp=SiS_GetReg1(SiS_P3d4,0x37);
+	temp=SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
       	temp = (temp & 0x0E) >> 1;
-      	if((temp >= 2) && (temp <= 3)) SiS_IF_DEF_LVDS = 1;
+      	if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
       	if(temp == 3)  {
-#if 0  /* Don't know how to do this on Chrontel 7019 */
-		/* TW: Save power status (and error check) */
-		SiS_Backup70xx = SiS_GetCH700x(0x0e);
-		if (SiS_Backup70xx != 0xFFFF)
-#endif
-			SiS_IF_DEF_CH70xx = 2;
+			SiS_Pr->SiS_IF_DEF_CH70xx = 2;
         }
-	SiS_IF_DEF_HiVision = 1;
+	
+	/* HiVision (HDTV) is done differently now. */
+	/* SiS_Pr->SiS_IF_DEF_HiVision = 1; */
     }
 #endif
 }
 
 void
-SiSInitPtr(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
 #ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_315H)||
-      (HwDeviceExtension->jChipType == SIS_315PRO)||
-      (HwDeviceExtension->jChipType == SIS_550)||
-      (HwDeviceExtension->jChipType == SIS_640)||
-      (HwDeviceExtension->jChipType == SIS_740)||
-      (HwDeviceExtension->jChipType == SIS_650))
-     InitTo310Pointer(HwDeviceExtension);
+   if((HwDeviceExtension->jChipType == SIS_315H) ||
+      (HwDeviceExtension->jChipType == SIS_315) ||
+      (HwDeviceExtension->jChipType == SIS_315PRO) ||
+      (HwDeviceExtension->jChipType == SIS_550) ||
+      (HwDeviceExtension->jChipType == SIS_650) ||
+      (HwDeviceExtension->jChipType == SIS_740) ||
+      (HwDeviceExtension->jChipType == SIS_330))
+     InitTo310Pointer(SiS_Pr, HwDeviceExtension);
 #endif
 
 #ifdef SIS300
-   if ((HwDeviceExtension->jChipType == SIS_540)||
-       (HwDeviceExtension->jChipType == SIS_630)||
-       (HwDeviceExtension->jChipType == SIS_730)||
+   if ((HwDeviceExtension->jChipType == SIS_540) ||
+       (HwDeviceExtension->jChipType == SIS_630) ||
+       (HwDeviceExtension->jChipType == SIS_730) ||
        (HwDeviceExtension->jChipType == SIS_300))
-     InitTo300Pointer(HwDeviceExtension);
+     InitTo300Pointer(SiS_Pr, HwDeviceExtension);
 #endif
 }
 
+void
+SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr)
+{
+   if((ROMAddr) && (HwDeviceExtension->UseROM)) {
+     if((ROMAddr[0x00] != 0x55) || (ROMAddr[0x01] != 0xAA)) {
+        SiS_Pr->SiS_UseROM = FALSE;
+     } else if(HwDeviceExtension->jChipType == SIS_300) {
+        /* TW: 300: We check if the code starts below 0x220 by
+	 *     checking the jmp instruction at the beginning
+	 *     of the BIOS image.
+	 */
+	 if((ROMAddr[3] == 0xe9) &&
+	    ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
+	      SiS_Pr->SiS_UseROM = TRUE;
+	 else SiS_Pr->SiS_UseROM = FALSE;
+     } else if(HwDeviceExtension->jChipType < SIS_315H) {
+        /* TW: Rest of 300 series: We don't use the ROM image if
+	 *     the BIOS version < 2.0.0 as such old BIOSes don't
+	 *     have the needed data at the expected locations.
+	 */
+        if(ROMAddr[0x06] < '2')  SiS_Pr->SiS_UseROM = FALSE;
+	else                     SiS_Pr->SiS_UseROM = TRUE;
+     } else {
+        /* TW: 310/325/330 series stick to the standard */
+	SiS_Pr->SiS_UseROM = TRUE;
+     }
+   } else SiS_Pr->SiS_UseROM = FALSE;
+
+}
+
 /*
  	=========================================
- 	======== SiS SetMode Function  ==========
+ 	======== SiS SetMode Functions ==========
  	=========================================
 */
 #ifdef LINUX_XF86
 /* TW: This is used for non-Dual-Head mode from X */
 BOOLEAN
-SiSBIOSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
-               DisplayModePtr mode)
+SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+               DisplayModePtr mode, BOOLEAN IsCustom)
 {
+   SISPtr  pSiS = SISPTR(pScrn);
    UShort  ModeNo=0;
+   
+   SiS_Pr->UseCustomMode = FALSE;
 
+   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
+   
+         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", 
+	 	SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
+		
+	 return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
+   
+   }
+   
    ModeNo = SiS_CalcModeIndex(pScrn, mode);
-   if (!ModeNo) return FALSE;
+   if(!ModeNo) return FALSE;
 
-   xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Setting mode 0x%x\n", ModeNo);
+   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting mode 0x%x\n", ModeNo);
 
-   return(SiSSetMode(HwDeviceExtension, pScrn, ModeNo));
+   return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));   
 }
 
 #ifdef SISDUALHEAD
 /* TW: Set CRT1 mode (used for dual head) */
 BOOLEAN
-SiSBIOSSetModeCRT1(PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
-               DisplayModePtr mode)
+SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+               DisplayModePtr mode, BOOLEAN IsCustom)
 {
    ULONG   temp;
    USHORT  ModeIdIndex;
-#ifndef LINUX_XF86
-   USHORT  KeepLockReg;
-#endif
    UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
    USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
    SISPtr  pSiS = SISPTR(pScrn);
    SISEntPtr pSiSEnt = pSiS->entityPrivate;
+   unsigned char backupreg=0;
+   BOOLEAN backupcustom;
 
    UShort  ModeNo=0;
+   
+   SiS_Pr->UseCustomMode = FALSE;
+   
+   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
+   
+         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+	 	"Setting custom mode %dx%d in CRT1\n", 
+	 	SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
+	 ModeNo = 0xfe;
+	 
+   } else {
 
-   ModeNo = SiS_CalcModeIndex(pScrn, mode);
-   if (!ModeNo) return FALSE;
+         ModeNo = SiS_CalcModeIndex(pScrn, mode);
+         if(!ModeNo) return FALSE;
+
+         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+	 	"Setting mode 0x%x on CRT1\n", ModeNo);
+   }
+
+   SiSInitPtr(SiS_Pr, HwDeviceExtension);
 
-   xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Setting mode 0x%x on CRT1\n", ModeNo);
+   SiSRegInit(SiS_Pr, BaseAddr);
 
-   SiSInitPtr(HwDeviceExtension);
+   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
 
-   SiSRegInit(BaseAddr);
+   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
 
-   SiSInitPCIetc(HwDeviceExtension);
+   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
 
-   SiSSetLVDSetc(HwDeviceExtension, ModeNo);
+   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
 
    /* TW: We don't clear the buffer under X */
-   flag_clearbuffer=0;
+   SiS_Pr->SiS_flag_clearbuffer = 0;
 
-   SiS_SetReg1(SiS_P3c4,0x05,0x86);                             		/* 1.Openkey */
+   /* 1.Openkey */
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
 
-   SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
 
-   temp = SiS_SearchModeID(ROMAddr,&ModeNo,&ModeIdIndex);        		/* 2.Get ModeID Table  */
-   if(temp==0)  return(0);
+   if(!SiS_Pr->UseCustomMode) {
+      /* 2.Get ModeID Table  */
+      temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
+      if(temp == 0)  return(0);
+   } else {
+      ModeIdIndex = 0;
+   }
 
    /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
-   SiS_GetVBType(BaseAddr,HwDeviceExtension);
+   SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension);
+
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwDeviceExtension->jChipType >= SIS_315H) {
+         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+      } else {
+         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+      }
+   }
 
    /* TW: Get VB information (connectors, connected devices) */
-   SiS_GetVBInfo301(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
-   SiS_SetHiVision(BaseAddr,HwDeviceExtension);
-   SiS_GetLCDResInfo301(ROMAddr,SiS_P3d4,ModeNo,ModeIdIndex,HwDeviceExtension);
-
-   /* TW: I am not sure the flag's name is correct */
-   if((SiS_IF_DEF_LVDS == 1) && (HwDeviceExtension->jChipType >= SIS_315H)) {
-      if(SiS_GetReg1(SiS_P3c4,0x17) & 0x08)  SiS_SetFlag |= CRT2IsVGA;
+   /* (We don't care if the current mode is a CRT2 mode) */
+   SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0);
+   SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension);
+   SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
+            if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
+         }
+      }
+
+      /* TW: New from 650/LV 1.10.6x */
+      if(IS_SIS650) {
+          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+	  }
+      }
    }
 
    /* TW: Set mode on CRT1 */
-   SiS_SetCRT1Group(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+   SiS_SetCRT1Group(SiS_Pr, ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
 
    pSiSEnt->CRT1ModeNo = ModeNo;
    pSiSEnt->CRT1DMode = mode;
 
    /* TW: SetPitch: Adapt to virtual size & position */
-   SiS_SetPitchCRT1(pScrn, BaseAddr);
+   SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
 
    /* We have to reset CRT2 if changing mode on CRT1 */
-   if (pSiSEnt->CRT2ModeNo != -1) {
-        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "(Re-)Setting mode 0x%x on CRT2\n",
+   if(pSiSEnt->CRT2ModeNo != -1) {
+        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+				"(Re-)Setting mode 0x%x on CRT2\n",
 				pSiSEnt->CRT2ModeNo);
-	SiSBIOSSetModeCRT2(HwDeviceExtension, pSiSEnt->pScrn_1,
+	backupcustom = SiS_Pr->UseCustomMode;
+	if(SiS_Pr->UseCustomMode) {
+	   SiS_Pr->CRT1UsesCustomMode = TRUE;
+	} else {
+	   SiS_Pr->CRT1UsesCustomMode = FALSE;
+	}
+	SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1,
 				pSiSEnt->CRT2DMode);
+	SiS_Pr->UseCustomMode = backupcustom;
+	SiS_Pr->CRT1UsesCustomMode = FALSE;
    }
+   
+   SiS_HandleCRT1(SiS_Pr);
 
-   if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_IF_DEF_LVDS == 0)) {
-      SiS_SetRegAND(SiS_P3d4,0x63,0xbf);
-      temp = SiS_GetReg1(SiS_P3c4,0x15);
-      if(!(temp & 0x01)) {
-          if(!(temp & 0xa0)) {
-	     if(SiS_GetReg1(SiS_P3c4,0x16) & 0x01) {
-	        SiS_SetRegOR(SiS_P3d4,0x64,0x40);
-	     }
-	  } else {
-	     SiS_SetRegOR(SiS_P3d4,0x64,0x40);
-	  }
+   SiS_DisplayOn(SiS_Pr);
+   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+
+   /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630/301B 2.06.50 */
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwDeviceExtension->jChipType >= SIS_315H) {
+	 SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
+      } else if((HwDeviceExtension->jChipType == SIS_630) ||
+                (HwDeviceExtension->jChipType == SIS_730)) {
+         SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,backupreg);
       }
    }
 
-   /* Backup/Set ModeNo in MMIO */
+   /* Backup/Set ModeNo in BIOS scratch area */
    SiS_GetSetModeID(pScrn,ModeNo);
 
    return TRUE;
@@ -2036,67 +2265,95 @@
 
 /* TW: Set CRT2 mode (used for dual head) */
 BOOLEAN
-SiSBIOSSetModeCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
+SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
                DisplayModePtr mode)
 {
    ULONG   temp;
    USHORT  ModeIdIndex;
-#ifndef LINUX_XF86
-   USHORT  KeepLockReg;
-#endif
    UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
    USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
-   UShort  ModeNo=0;
-   SISPtr  pSiS = SISPTR(pScrn);
+   UShort  ModeNo   = 0;
+   SISPtr  pSiS     = SISPTR(pScrn);
    SISEntPtr pSiSEnt = pSiS->entityPrivate;
-
+   unsigned char tempr1, tempr2, backupreg=0;
+   
+   SiS_Pr->UseCustomMode = FALSE;
+   
    ModeNo = SiS_CalcModeIndex(pScrn, mode);
-   if (!ModeNo) return FALSE;
+   if(!ModeNo) return FALSE;
+
+   SiSInitPtr(SiS_Pr, HwDeviceExtension);
 
-   SiSInitPtr(HwDeviceExtension);
+   SiSRegInit(SiS_Pr, BaseAddr);
 
-   SiSRegInit(BaseAddr);
+   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
 
-   SiSInitPCIetc(HwDeviceExtension);
+   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
 
-   SiSSetLVDSetc(HwDeviceExtension, ModeNo);
+   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
+
+   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
 
    /* TW: We don't clear the buffer under X */
-   flag_clearbuffer=0;
+   SiS_Pr->SiS_flag_clearbuffer=0;
 
    /* TW: Save ModeNo so we can set it from within SetMode for CRT1 */
    pSiSEnt->CRT2ModeNo = ModeNo;
    pSiSEnt->CRT2DMode = mode;
 
    /* TW: We can't set CRT2 mode before CRT1 mode is set */
-   if (pSiSEnt->CRT1ModeNo == -1) {
-   	xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+   if(pSiSEnt->CRT1ModeNo == -1) {
+   	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
 		"Setting CRT2 mode delayed until after setting CRT1 mode\n");
    	return TRUE;
    }
 
-   xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Setting mode 0x%x on CRT2\n", ModeNo);
+   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+   		"Setting mode 0x%x on CRT2\n", ModeNo);
 
    /* 1.Openkey */
-   SiS_SetReg1(SiS_P3c4,0x05,0x86);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
 
-   SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
 
    /* 2.Get ModeID */
-   temp = SiS_SearchModeID(ROMAddr,&ModeNo,&ModeIdIndex);
-   if(temp==0)  return(0);
+   temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
+   if(temp == 0)  return(0);
 
    /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
-   SiS_GetVBType(BaseAddr,HwDeviceExtension);
+   SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension);
+
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwDeviceExtension->jChipType >= SIS_315H) {
+         SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+	 if(HwDeviceExtension->jChipType < SIS_330) {
+           if(ROMAddr && SiS_Pr->SiS_UseROM) {
+             temp = ROMAddr[VB310Data_1_2_Offset];
+	     temp |= 0x40;
+             SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,temp);
+           }
+	 }
+	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
+
+	 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x02,0x0c);
+
+         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+      } else {
+         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+      }
+   }
 
    /* TW: Get VB information (connectors, connected devices) */
-   SiS_GetVBInfo301(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
-   SiS_SetHiVision(BaseAddr,HwDeviceExtension);
-   SiS_GetLCDResInfo301(ROMAddr,SiS_P3d4,ModeNo,ModeIdIndex,HwDeviceExtension);
-
-   /* TW: I am not sure the flag's name is correct */
-   if((SiS_IF_DEF_LVDS == 1) && (HwDeviceExtension->jChipType >= SIS_315H)) {
-      if(SiS_GetReg1(SiS_P3c4,0x17) & 0x08)  SiS_SetFlag |= CRT2IsVGA;
+   SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
+   SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension);
+   SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
+            if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
+         }
+      }
    }
 
    /* Set mode on CRT2 */
@@ -2107,35 +2364,56 @@
      case VB_CHIP_302:
      case VB_CHIP_302B:
      case VB_CHIP_302LV:
-        SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-        break;
-     case VB_CHIP_303:
+        SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
         break;
      case VB_CHIP_UNKNOWN:
-        if (SiS_IF_DEF_LVDS == 1 || SiS_IF_DEF_CH70xx == 1 || SiS_IF_DEF_TRUMPION != 0)
-             	SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+        if (SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
+	    SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
+	    SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
+             	SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+  	}
         break;
    }
 
-   if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_IF_DEF_LVDS == 0)) {
-      SiS_SetRegAND(SiS_P3d4,0x63,0xbf);
-      temp = SiS_GetReg1(SiS_P3c4,0x15);
-      if(!(temp & 0x01)) {
-          if(!(temp & 0xa0)) {
-	     if(SiS_GetReg1(SiS_P3c4,0x16) & 0x01) {
-	        SiS_SetRegOR(SiS_P3d4,0x64,0x40);
-	     }
-	  } else {
-	     SiS_SetRegOR(SiS_P3d4,0x64,0x40);
-	  }
+   SiS_DisplayOn(SiS_Pr);
+   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+         if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) {
+	     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+	 }
       }
    }
 
-   /* TW: SetPitch: Adapt to virtual size & position */
-   SiS_SetPitchCRT2(pScrn, BaseAddr);
+   /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630 2.06.50 */
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwDeviceExtension->jChipType >= SIS_315H) {
+	 if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
+	 } else {
+	     SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
+	 }
+
+	 SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
+
+	 tempr1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+	 tempr2 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00);
+	 if(tempr1 & SetCRT2ToAVIDEO) tempr2 &= 0xF7;
+	 if(tempr1 & SetCRT2ToSVIDEO) tempr2 &= 0xFB;
+	 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,tempr2);
+
+	 if(tempr1 & SetCRT2ToLCD) {
+	       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
+	 }
+      } else if((HwDeviceExtension->jChipType == SIS_630) ||
+                (HwDeviceExtension->jChipType == SIS_730)) {
+         SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,backupreg);
+      }
+   }
 
-   /* Backup/Set ModeNo in MMIO - don't do this for CRT2 */
-   /* SiS_GetSetModeID(pScrn,ModeNo); */
+   /* TW: SetPitch: Adapt to virtual size & position */
+   SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
 
    return TRUE;
 }
@@ -2145,75 +2423,144 @@
 #ifdef LINUX_XF86
 /* TW: We need pScrn for setting the pitch correctly */
 BOOLEAN
-SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,ScrnInfoPtr pScrn,USHORT ModeNo)
+SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch)
 #else
 BOOLEAN
-SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
 #endif
 {
    ULONG   temp;
    USHORT  ModeIdIndex,KeepLockReg;
    UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
    USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+   unsigned char backupreg=0, tempr1, tempr2;
+
+#ifndef LINUX_XF86
+   SiS_Pr->UseCustomMode = FALSE;
+   SiS_Pr->CRT1UsesCustomMode = FALSE;
+#endif
+   
+   if(SiS_Pr->UseCustomMode) {
+      ModeNo = 0xfe;
+   }      
+   
+   SiSInitPtr(SiS_Pr, HwDeviceExtension);
+
+   SiSRegInit(SiS_Pr, BaseAddr);
 
-   SiSInitPtr(HwDeviceExtension);
+#ifdef LINUX_XF86
+   if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+   else
+#endif
+         SiS_Pr->SiS_VGAINFO = 0x11;
+
+#ifdef LINUX_XF86
+#ifdef TWDEBUG
+   xf86DrvMsg(0, X_INFO, "VGAInfo 0x%02x\n", SiS_Pr->SiS_VGAINFO);
+#endif
+#endif	 	 
 
-   SiSRegInit(BaseAddr);
+   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
 
-   SiSInitPCIetc(HwDeviceExtension);
+   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
 
-   SiSSetLVDSetc(HwDeviceExtension, ModeNo);
+   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+
+   if(!SiS_Pr->UseCustomMode) {
+      /* TW: Shift the clear-buffer-bit away */
+      ModeNo = ((ModeNo & 0x80) << 8) | (ModeNo & 0x7f);
+   }      
 
 #ifdef LINUX_XF86
-   /* TW: We don't clear the buffer in X */
+   /* TW: We never clear the buffer in X */
    ModeNo |= 0x8000;
 #endif
 
    if(ModeNo & 0x8000) {
-     	ModeNo &= 0x007F;
-     	flag_clearbuffer=0;
+     	ModeNo &= 0x7fff;
+     	SiS_Pr->SiS_flag_clearbuffer = 0;
    } else {
-     	flag_clearbuffer=1;
+     	SiS_Pr->SiS_flag_clearbuffer = 1;
    }
 
    /* 1.Openkey */
-   KeepLockReg = SiS_GetReg1(SiS_P3c4,0x05);
-   SiS_SetReg1(SiS_P3c4,0x05,0x86);
-
-   SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+   KeepLockReg = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x05);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
 
-   /* 2.Get ModeID Table  */
-   temp = SiS_SearchModeID(ROMAddr,&ModeNo,&ModeIdIndex);
-   if(temp==0) return(0);
+   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
 
+   if(!SiS_Pr->UseCustomMode) {
+   
+      /* 2.Get ModeID Table  */
+      temp = SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
+      if(temp == 0) return(0);
+      
+   } else {
+   
+      ModeIdIndex = 0;
+      
+   }
+    
    /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
-   SiS_GetVBType(BaseAddr,HwDeviceExtension);
+   SiS_GetVBType(SiS_Pr,BaseAddr,HwDeviceExtension);
 
-   /* TW: Get VB information (connectors, connected devices) */
-   SiS_GetVBInfo301(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
-   SiS_SetHiVision(BaseAddr,HwDeviceExtension);
-   SiS_GetLCDResInfo301(ROMAddr,SiS_P3d4,ModeNo,ModeIdIndex,HwDeviceExtension);
+   /* TW: Init/restore some VB registers */
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+       if(HwDeviceExtension->jChipType >= SIS_315H) {
+         SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+	 if(HwDeviceExtension->jChipType < SIS_330) {
+           if(ROMAddr && SiS_Pr->SiS_UseROM) {
+             temp = ROMAddr[VB310Data_1_2_Offset];
+	     temp |= 0x40;
+             SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,temp);
+           }
+	 }
+	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
 
-   /* TW: I am not sure the flag's name is correct */
-   if((SiS_IF_DEF_LVDS == 1) && (HwDeviceExtension->jChipType >= SIS_315H)) {
-      if(SiS_GetReg1(SiS_P3c4,0x17) & 0x08)  SiS_SetFlag |= CRT2IsVGA;
+	 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x02,0x0c);
+
+         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+       } else {
+         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+       }
    }
+   
+   /* TW: Get VB information (connectors, connected devices) */
+   SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
+   SiS_SetHiVision(SiS_Pr,BaseAddr,HwDeviceExtension);
+   SiS_GetLCDResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
 
-   /* 3.Check memory size */
-   temp = SiS_CheckMemorySize(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex);
+   /* 3. Check memory size */
+   temp = SiS_CheckMemorySize(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex);
    if(!temp) return(0);
 
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
+            if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
+         }
+      }
+
+      /* TW: New from 650/LV 1.10.6x; not in any BIOS for other chipsets */
+      if(IS_SIS650) {
+          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+	  }
+      }
+   }
+
    /* TW: Set mode on CRT1 */
-   if(SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
-   	SiS_SetCRT1Group(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+   if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
+   	SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
    } else {
-     if(!(SiS_VBInfo & SwitchToCRT2)) {
-       	SiS_SetCRT1Group(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
+     if(!(SiS_Pr->SiS_VBInfo & SwitchToCRT2)) {
+       	SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
      }
    }
 
    /* TW: Set mode on CRT2 */
-   if(SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) {
+   if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) {
      switch (HwDeviceExtension->ujVBChipID) {
      case VB_CHIP_301:
      case VB_CHIP_301B:
@@ -2221,176 +2568,224 @@
      case VB_CHIP_302:
      case VB_CHIP_302B:
      case VB_CHIP_302LV:
-        SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-        break;
-     case VB_CHIP_303:
+        SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
         break;
      case VB_CHIP_UNKNOWN:
-	if (SiS_IF_DEF_LVDS == 1 || SiS_IF_DEF_CH70xx != 0 || SiS_IF_DEF_TRUMPION != 0)
-             	SiS_SetCRT2Group301(BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
+	if(SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
+	   SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
+	   SiS_Pr->SiS_IF_DEF_TRUMPION != 0)
+             	SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
         break;
      }
    }
+   
+   SiS_HandleCRT1(SiS_Pr);
+   
+   SiS_DisplayOn(SiS_Pr);
+   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
 
-   /* TW: Inserted from 650/301LV BIOS */
-   if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_IF_DEF_LVDS == 0)) {
-      SiS_SetRegAND(SiS_P3d4,0x63,0xbf);
-      temp = SiS_GetReg1(SiS_P3c4,0x15);
-      if(!(temp & 0x01)) {
-          if(!(temp & 0xa0)) {
-	     if(SiS_GetReg1(SiS_P3c4,0x16) & 0x01) {
-	        SiS_SetRegOR(SiS_P3d4,0x64,0x40);
-	     }
-	  } else {
-	     SiS_SetRegOR(SiS_P3d4,0x64,0x40);
-	  }
+   if(HwDeviceExtension->jChipType >= SIS_315H) {
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+         if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) {
+	     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+	 }
+      }
+   }
+
+   /* TW: New from 650/LV 1.10.6x and 1.10.7w */
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwDeviceExtension->jChipType >= SIS_315H) {
+	 if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
+	 } else {
+	     SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
+	 }
+
+	 SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
+
+	 tempr1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+	 tempr2 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00);
+	 if(tempr1 & SetCRT2ToAVIDEO) tempr2 &= 0xF7;
+	 if(tempr1 & SetCRT2ToSVIDEO) tempr2 &= 0xFB;
+	 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,tempr2);
+
+	 if((IS_SIS650) && (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & 0xfc)) {
+	    if((ModeNo == 0x03) || (ModeNo == 0x10)) {
+	        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80);
+	        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08);
+            }
+	 }
+
+	 if(tempr1 & SetCRT2ToLCD) {
+	       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
+	 }
+      } else if((HwDeviceExtension->jChipType == SIS_630) ||
+                (HwDeviceExtension->jChipType == SIS_730)) {
+         SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,backupreg);
       }
    }
 
 #ifdef LINUX_XF86
-   /* TW: SetPitch: Adapt to virtual size & position */
-   if(pScrn)
-      SiS_SetPitch(pScrn, BaseAddr);
+   if(pScrn) {
+      /* TW: SetPitch: Adapt to virtual size & position */
+      if((ModeNo > 0x13) && (dosetpitch)) {
+         SiS_SetPitch(SiS_Pr, pScrn, BaseAddr);
+      }
 
-   /* Backup/Set ModeNo in MMIO */
-   SiS_GetSetModeID(pScrn,ModeNo);
+      /* Backup/Set ModeNo in BIOS scratch area */
+      SiS_GetSetModeID(pScrn, ModeNo);
+   }
 #endif
 
 #ifndef LINUX_XF86  /* TW: We never lock registers in XF86 */
-   if(KeepLockReg==0xA1) SiS_SetReg1(SiS_P3c4,0x05,0x86);
-   else SiS_SetReg1(SiS_P3c4,0x05,0x00);
+   if(KeepLockReg == 0xA1) SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+   else SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x00);
 #endif
 
    return TRUE;
 }
 
 void
-SetEnableDstn()		/* TW: Called from sis_main.c */
+SiS_SetEnableDstn(SiS_Private *SiS_Pr)	/* TW: Called from sis_main.c */
+{
+   /* For 550 dstn */
+   SiS_Pr->SiS_IF_DEF_DSTN = 1;
+}
+
+void
+SiS_HandleCRT1(SiS_Private *SiS_Pr)
 {
-   SiS_IF_DEF_DSTN=1;   /* for 550 dstn */
+  /* TW: We don't do this at all. There is a new
+   * CRT1-is-connected-at-boot-time logic in the 650 BIOS, which
+   * confuses our own. So just clear the bit and skip the rest.
+   */
+
+  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
+
+#if 0
+  if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01))
+     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40);
+  }
+#endif
 }
 
 void
-SiS_SetCRT1Group(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
                  USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr)
 {
   USHORT  StandTableIndex,RefreshRateTableIndex;
 
-  SiS_CRT1Mode = ModeNo;
-  StandTableIndex = SiS_GetModePtr(ROMAddr,ModeNo,ModeIdIndex);
-  if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
-    if(SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
-      SiS_DisableBridge(HwDeviceExtension,BaseAddr);
+  SiS_Pr->SiS_CRT1Mode = ModeNo;
+  StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+  if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+    if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
+       SiS_DisableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
     }
   }
 
-  SiS_SetSeqRegs(ROMAddr,StandTableIndex);
-  SiS_SetMiscRegs(ROMAddr,StandTableIndex);
-  SiS_SetCRTCRegs(ROMAddr,HwDeviceExtension,StandTableIndex);
-  SiS_SetATTRegs(ROMAddr,StandTableIndex,ModeNo,HwDeviceExtension);
-  SiS_SetGRCRegs(ROMAddr,StandTableIndex);
-  SiS_ClearExt1Regs(HwDeviceExtension);
-  SiS_ResetCRT1VCLK(ROMAddr,HwDeviceExtension);
-  SiS_SelectCRT2Rate=0;
-  SiS_SetFlag &= (~ProgrammingCRT2);
+  SiS_SetSeqRegs(SiS_Pr,ROMAddr,StandTableIndex);
+  SiS_SetMiscRegs(SiS_Pr,ROMAddr,StandTableIndex);
+  SiS_SetCRTCRegs(SiS_Pr,ROMAddr,HwDeviceExtension,StandTableIndex);
+  SiS_SetATTRegs(SiS_Pr,ROMAddr,StandTableIndex,HwDeviceExtension);
+  SiS_SetGRCRegs(SiS_Pr,ROMAddr,StandTableIndex);
+  SiS_ClearExt1Regs(SiS_Pr,HwDeviceExtension);
+  SiS_ResetCRT1VCLK(SiS_Pr,ROMAddr,HwDeviceExtension);
+
+  SiS_Pr->SiS_SelectCRT2Rate = 0;
+  SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
 
 #ifdef LINUX_XF86
-  xf86DrvMsg(0, X_INFO, "(init: VBType = %x, LVDS=%d, VBInfo=%x)\n",
-                    SiS_VBType, SiS_IF_DEF_LVDS, SiS_VBInfo);
+  xf86DrvMsgVerb(0, X_PROBED, 3, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
+                    SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo);
 #endif
 
-  /* TW: Inserted this entire if-section from 650/LVDS and 650/301 BIOS */
-  if(SiS_VBInfo & SetSimuScanMode) {
-     if(SiS_VBInfo & SetInSlaveMode) {
-        SiS_SetFlag |= ProgrammingCRT2;
+  if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+        SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
      }
   }
-  /* TW: Removed 301B301LV302B302LV check here */
-  if(SiS_VBInfo & SetCRT2ToLCDA) {
-	 SiS_SetFlag |= ProgrammingCRT2;
+
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+	SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
   }
 
-  RefreshRateTableIndex = SiS_GetRatePtrCRT2(ROMAddr,ModeNo,ModeIdIndex);
+  RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
 
-  /* TW: Removed 301B301LV302B302LV check here */
-  if(!(SiS_VBInfo & SetCRT2ToLCDA)) {
-	 SiS_SetFlag &= (~ProgrammingCRT2);
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+	SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
   }
 
-  if (RefreshRateTableIndex != 0xFFFF) {
-    SiS_SetSync(ROMAddr,RefreshRateTableIndex);
-    SiS_SetCRT1CRTC(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
-    SiS_SetCRT1Offset(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
-    SiS_SetCRT1VCLK(ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,RefreshRateTableIndex);
+  if(RefreshRateTableIndex != 0xFFFF) {
+    	SiS_SetSync(SiS_Pr,ROMAddr,RefreshRateTableIndex);
+    	SiS_SetCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+    	SiS_SetCRT1Offset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+    	SiS_SetCRT1VCLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,RefreshRateTableIndex);
   }
 
 #ifdef SIS300
-  if((HwDeviceExtension->jChipType == SIS_630)||
-     (HwDeviceExtension->jChipType == SIS_730)||
+  if(HwDeviceExtension->jChipType == SIS_300) {
+     	SiS_SetCRT1FIFO_300(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex);
+  }
+  if((HwDeviceExtension->jChipType == SIS_630) ||
+     (HwDeviceExtension->jChipType == SIS_730) ||
      (HwDeviceExtension->jChipType == SIS_540)) {
-     	SiS_SetCRT1FIFO_300(ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex);
+     	SiS_SetCRT1FIFO_630(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex);
   }
 #endif
 #ifdef SIS315H
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-     	SiS_SetCRT1FIFO_310(ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+     	SiS_SetCRT1FIFO_310(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
   }
 #endif
 
-  SiS_SetCRT1ModeRegs(ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+  SiS_SetCRT1ModeRegs(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,RefreshRateTableIndex);
 
-#if 0  /* TW: Not done in any BIOS */
-#ifdef SIS315H
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-    if (RefreshRateTableIndex != 0xFFFF) {
-      	SiS_SetInterlace(ROMAddr,ModeNo,RefreshRateTableIndex);
-    }
-#endif
+  SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
+
+#ifndef LINUX_XF86
+  if(SiS_Pr->SiS_flag_clearbuffer) {
+        SiS_ClearBuffer(SiS_Pr,HwDeviceExtension,ModeNo);
   }
 #endif
 
-  SiS_LoadDAC(ROMAddr,ModeNo,ModeIdIndex);
-
-  if(flag_clearbuffer) SiS_ClearBuffer(HwDeviceExtension,ModeNo);
-
-  if(!(SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA))) {
-    SiS_LongWait();
-    SiS_DisplayOn();
+  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA))) {
+        SiS_LongWait(SiS_Pr);
+        SiS_DisplayOn(SiS_Pr);
   }
 }
 
 #ifdef LINUX_XF86
 void
-SiS_SetPitch(ScrnInfoPtr pScrn, UShort BaseAddr)
+SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
 {
    SISPtr pSiS = SISPTR(pScrn);
 
    /* TW: We need to set pitch for CRT1 if bridge is in SlaveMode, too */
    if( (pSiS->VBFlags & DISPTYPE_DISP1) ||
        ( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
-         ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
-           ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) ) {
-   	SiS_SetPitchCRT1(pScrn, BaseAddr);
+         ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
+           ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) ) {
+   	SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
    }
    if (pSiS->VBFlags & DISPTYPE_DISP2) {
-   	SiS_SetPitchCRT2(pScrn, BaseAddr);
+   	SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
    }
 }
 
 void
-SiS_SetPitchCRT1(ScrnInfoPtr pScrn, UShort BaseAddr)
+SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
 {
     SISPtr pSiS = SISPTR(pScrn);
     ULong  HDisplay,temp;
 
     HDisplay = pSiS->scrnPitch / 8;
-    SiS_SetReg1(SiS_P3d4, 0x13, (HDisplay & 0xFF));
-    temp = (SiS_GetReg1(SiS_P3c4, 0x0E) & 0xF0) | (HDisplay>>8);
-    SiS_SetReg1(SiS_P3c4, 0x0E, temp);
+    SiS_SetReg1(SiS_Pr->SiS_P3d4, 0x13, (HDisplay & 0xFF));
+    temp = (SiS_GetReg1(SiS_Pr->SiS_P3c4, 0x0E) & 0xF0) | (HDisplay>>8);
+    SiS_SetReg1(SiS_Pr->SiS_P3c4, 0x0E, temp);
 }
 
 void
-SiS_SetPitchCRT2(ScrnInfoPtr pScrn, UShort BaseAddr)
+SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
 {
     SISPtr pSiS = SISPTR(pScrn);
     ULong  HDisplay,temp;
@@ -2399,76 +2794,75 @@
 
     /* Unlock CRT2 */
     if (pSiS->VGAEngine == SIS_315_VGA)
-        SiS_SetRegANDOR(SiS_Part1Port,0x2F, 0xFF, 0x01);
+        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01);
     else
-        SiS_SetRegANDOR(SiS_Part1Port,0x24, 0xFF, 0x01);
+        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01);
 
-    SiS_SetReg1(SiS_Part1Port,0x07, (HDisplay & 0xFF));
-    temp = (SiS_GetReg1(SiS_Part1Port,0x09) & 0xF0) | ((HDisplay >> 8) & 0xFF);
-    SiS_SetReg1(SiS_Part1Port,0x09, temp);
+    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07, (HDisplay & 0xFF));
+    temp = (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x09) & 0xF0) | ((HDisplay >> 8) & 0xFF);
+    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09, temp);
 }
 #endif
 
-/* TW: Checked against 650/301 and 630/301B BIOS */
 void
-SiS_GetVBType(USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-  USHORT flag;
+  USHORT flag=0, rev=0, nolcd=0;
 
-  SiS_VBType = 0;
-  
-  if(SiS_IF_DEF_LVDS == 1) return;
+  SiS_Pr->SiS_VBType = 0;
 
-  flag = SiS_GetReg1(SiS_Part4Port,0x00);
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) return;
+
+  flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
 
   /* TW: Illegal values not welcome... */
-  if(flag > 10) return;
+  if(flag > 3) return;
+
+  rev = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);
 
   if (flag >= 2) {
-  	flag=SiS_GetReg1(SiS_Part4Port,0x01);
-        if(flag >= 0xB0){
-            	SiS_VBType = VB_SIS302B;
-            	if(flag >= 0xD0)
-               		SiS_VBType = VB_SIS302LV;
-        }
+        SiS_Pr->SiS_VBType = VB_SIS302B;
   } else if (flag == 1) {
-        flag=SiS_GetReg1(SiS_Part4Port,0x01);
-        if(flag >= 0xB0){
-            	SiS_VBType = VB_SIS301B;
-            	if(flag >= 0xD0)
-               		SiS_VBType = VB_SIS301LV;
-        } else
-            SiS_VBType = VB_SIS301;
+        SiS_Pr->SiS_VBType = VB_SIS301;
+        if(rev >= 0xB0) {
+            	SiS_Pr->SiS_VBType = VB_SIS301B;
+		/* Check if 30xB DH version (no LCD support, use Panel Link instead) */
+    		nolcd = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x23);
+                if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
+        }
   }
-  /* TW: This is checked in 630 BIOS, but not used */
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-    if(SiS_VBType & VB_SIS301BLV302BLV) {
-      flag = SiS_GetReg1(SiS_Part4Port,0x23);
-      if(!(flag & 0x02))
-       	SiS_VBType |= VB_NoLCD;
-    }
+  if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) {
+        if(rev >= 0xD0) {
+	        SiS_Pr->SiS_VBType &= ~(VB_SIS301B | VB_SIS302B);
+          	SiS_Pr->SiS_VBType |= VB_SIS301LV;
+		SiS_Pr->SiS_VBType &= ~(VB_NoLCD);
+		if(rev >= 0xE0) {
+		    SiS_Pr->SiS_VBType &= ~(VB_SIS301LV);
+		    SiS_Pr->SiS_VBType |= VB_SIS302LV;
+		}
+        }
   }
 }
 
 BOOLEAN
-SiS_SearchModeID(UCHAR *ROMAddr,USHORT *ModeNo,USHORT *ModeIdIndex)
+SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT *ModeNo,USHORT *ModeIdIndex)
 {
-   UCHAR VGAINFO = 0x11;  /* TW: Replaces ds:449 */
+   UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
 
    if(*ModeNo <= 0x13) {
 
-      if((*ModeNo) <= 5) (*ModeNo) |= 1;
+      if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01;
 
-      for (*ModeIdIndex=0;;(*ModeIdIndex)++) {
-         if (SiS_SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo)) break;
-         if (SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)   return FALSE;
+      for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
+         if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo)) break;
+         if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)   return FALSE;
       }
 
       if(*ModeNo == 0x07) {
           if(VGAINFO & 0x10) (*ModeIdIndex)++;   /* 400 lines */
           /* else 350 lines */
       }
-      if(*ModeNo <= 3) {
+      if(*ModeNo <= 0x03) {
          if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
          if(VGAINFO & 0x10)    (*ModeIdIndex)++; /* 400 lines  */
          /* else 350 lines  */
@@ -2477,9 +2871,9 @@
 
    } else {
 
-      for (*ModeIdIndex=0;;(*ModeIdIndex)++) {
-         if (SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break;
-         if (SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)   return FALSE;
+      for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
+         if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break;
+         if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)      return FALSE;
       }
 
    }
@@ -2488,16 +2882,16 @@
 
 /* For SiS 300 oem util: Search VBModeID */
 BOOLEAN
-SiS_SearchVBModeID(UCHAR *ROMAddr, USHORT *ModeNo)
+SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo)
 {
    USHORT ModeIdIndex;
-   UCHAR VGAINFO = 0x11;  /* TW: Replaces ds:449 */
+   UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
 
    if(*ModeNo <= 5) *ModeNo |= 1;
 
    for(ModeIdIndex=0; ; ModeIdIndex++) {
-       if (SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
-       if (SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)   return FALSE;
+        if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
+        if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return FALSE;
    }
 
    if(*ModeNo != 0x07) {
@@ -2510,89 +2904,80 @@
    return ((BOOLEAN)ModeIdIndex);
 }
 
-/* TW: Checked against 630/301B and 315 BIOS */
 BOOLEAN
-SiS_CheckMemorySize(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
                     USHORT ModeNo,USHORT ModeIdIndex)
 {
-  USHORT memorysize,modeflag,temp;
+  USHORT memorysize,modeflag;
+  ULONG  temp;
 
-  if((HwDeviceExtension->jChipType == SIS_550)||
-     (HwDeviceExtension->jChipType == SIS_640)||
-     (HwDeviceExtension->jChipType == SIS_740)||
-     (HwDeviceExtension->jChipType == SIS_650))
-    return(TRUE);
-
-  if (ModeNo<=0x13) {
-    modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
   } else {
-    modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     if(ModeNo <= 0x13) {
+        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     } else {
+        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     }
   }
 
   memorysize = modeflag & MemoryInfoFlag;
-  memorysize >>= MemorySizeShift;
-  memorysize++;                                        		/* Get memory size */
+  memorysize >>= MemorySizeShift;			/* Get required memory size */
+  memorysize++;
 
-  temp = SiS_GetReg1(SiS_P3c4,0x14);                            /* Get DRAM Size    */
-
-  if((HwDeviceExtension->jChipType == SIS_315H)||
-     (HwDeviceExtension->jChipType == SIS_315PRO)) {		/* 315 */
-    temp = 1 << ((temp & 0x0F0) >> 4);
-    if ((temp & 0x0c) == 0x08) {   /* DDR asymetric */
-      temp += (temp/2);
-    } else {
-      if ((temp & 0x0c) != 0) temp <<= 1;
-    }
-  } else { 							/* 300, 540, 630, 730 */
-    temp &= 0x3F;
-    temp++;
-  }
+  temp = GetDRAMSize(SiS_Pr, HwDeviceExtension);       	/* Get adapter memory size */
+  temp /= (1024*1024);   				/* (in MB) */
 
   if(temp < memorysize) return(FALSE);
   else return(TRUE);
 }
 
 UCHAR
-SiS_GetModePtr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
    UCHAR index;
 
-   if(ModeNo<=0x13) {
-     	index = SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
+   if(ModeNo <= 0x13) {
+     	index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
    } else {
-     	if(SiS_ModeType <= 0x02) index=0x1B;    /* 02 -> ModeEGA  */
-     	else index=0x0F;
+     	if(SiS_Pr->SiS_ModeType <= 0x02) index = 0x1B;    /* 02 -> ModeEGA  */
+     	else index = 0x0F;
    }
    return index;
 }
 
-/* TW: Checked against 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */
 void
-SiS_SetSeqRegs(UCHAR *ROMAddr,USHORT StandTableIndex)
+SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
 {
    UCHAR SRdata;
    USHORT i;
 
-   SiS_SetReg1(SiS_P3c4,0x00,0x03);           		/* Set SR0  */
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x00,0x03);           	/* Set SR0  */
 
-   SRdata=SiS_StandTable[StandTableIndex].SR[0];
+   SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0];
 
-   if(SiS_VBType & VB_SIS301BLV302BLV) {
-      	if(SiS_VBInfo & SetCRT2ToLCDA) {
-        	SRdata |= 0x01;
-        }
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+         SRdata |= 0x01;
+      }
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+         if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+	    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+               SRdata |= 0x01;          		/* 8 dot clock  */
+            }
+	 }
+      }
    }
-   if(SiS_IF_DEF_LVDS == 1) {
-     if(SiS_IF_DEF_CH70xx != 0) {
-       if(SiS_VBInfo & SetCRT2ToTV) {
-         if(SiS_VBInfo & SetInSlaveMode) {
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
            SRdata |= 0x01;        			/* 8 dot clock  */
          }
        }
      }
-     if(SiS_VBInfo & SetCRT2ToLCD) {
-       if(SiS_VBInfo & SetInSlaveMode) {
-         /* TW: wdr/300: if(SiS_LCDInfo & LCDNonExpanding) { */
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
          SRdata |= 0x01;          			/* 8 dot clock  */
        }
      }
@@ -2600,66 +2985,63 @@
 
    SRdata |= 0x20;                			/* screen off  */
 
-   SiS_SetReg1(SiS_P3c4,0x01,SRdata);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x01,SRdata);
 
-   for(i=02;i<=04;i++) {
-       	SRdata=SiS_StandTable[StandTableIndex].SR[i-1];
-     	SiS_SetReg1(SiS_P3c4,i,SRdata);
+   for(i = 2; i <= 4; i++) {
+       	SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1];
+     	SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SRdata);
    }
 }
 
-/* Checked against 650/301LV and 65/LVDS 1.10.07 BIOS */
 void
-SiS_SetMiscRegs(UCHAR *ROMAddr,USHORT StandTableIndex)
+SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
 {
    UCHAR Miscdata;
 
-   Miscdata = SiS_StandTable[StandTableIndex].MISC;
+   Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
 
-   if(SiS_VBType & VB_SIS301BLV302BLV) {
-      if(SiS_VBInfo & SetCRT2ToLCDA) {
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
         Miscdata |= 0x0C;
       }
-    }
+   }
 
-   SiS_SetReg3(SiS_P3c2,Miscdata);
+   SiS_SetReg3(SiS_Pr->SiS_P3c2,Miscdata);
 }
 
-/* Checked against 650/LVDS (1.10.07) and 650/301LV BIOS (630 code still there!) */
 void
-SiS_SetCRTCRegs(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
                 USHORT StandTableIndex)
 {
   UCHAR CRTCdata;
   USHORT i;
 
-  SiS_SetRegAND(SiS_P3d4,0x11,0x7f);                       /* Unlock CRTC */
+  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                       /* Unlock CRTC */
 
-  for(i=0;i<=0x18;i++) {
-     CRTCdata=SiS_StandTable[StandTableIndex].CRTC[i];
-     SiS_SetReg1(SiS_P3d4,i,CRTCdata);                     /* Set CRTC(3d4) */
+  for(i = 0; i <= 0x18; i++) {
+     CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
+     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,CRTCdata);                     /* Set CRTC(3d4) */
   }
   if( ( (HwDeviceExtension->jChipType == SIS_630) ||
         (HwDeviceExtension->jChipType == SIS_730) )  &&
-      (HwDeviceExtension->jChipRevision >= 0x30) ) {       /* for 630S0 */
-    if(SiS_VBInfo & SetInSlaveMode) {
-      if(SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
-        SiS_SetReg1(SiS_P3d4,0x18,0xFE);
+      (HwDeviceExtension->jChipRevision >= 0x30) ) {       	   /* for 630S0 */
+    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+        SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE);
       }
     }
   }
 }
 
-/* TW: Checked against 650/LVDS (1.10.07), 650/301LV and 630/301B BIOS */
 void
-SiS_SetATTRegs(UCHAR *ROMAddr,USHORT StandTableIndex,USHORT ModeNo,
+SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex,
                PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
    UCHAR ARdata;
    USHORT i;
 
-   for(i=0;i<=0x13;i++) {
-    ARdata = SiS_StandTable[StandTableIndex].ATTR[i];
+   for(i = 0; i <= 0x13; i++) {
+    ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
 #if 0
     if((i <= 0x0f) || (i == 0x11)) {
         if(ds:489 & 0x08) {
@@ -2668,217 +3050,304 @@
     }
 #endif
     if(i == 0x13) {
-      if(SiS_VBType & VB_SIS301BLV302BLV) {
-        if(SiS_VBInfo & SetCRT2ToLCDA)  ARdata=0;
+      /* Pixel shift. If screen on LCD or TV is shifted left or right, 
+       * this might be the cause. 
+       */
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  ARdata=0;
       }
-      if(SiS_IF_DEF_LVDS == 1) {
-        if(SiS_IF_DEF_CH70xx != 0) {
-          if(SiS_VBInfo & SetCRT2ToTV) {
-            if(SiS_VBInfo & SetInSlaveMode) ARdata=0;
-          }
-        }
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
+            }
+         }
       }
-      if(SiS_VBInfo & SetCRT2ToLCD) {
-        if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_IF_DEF_LVDS == 1)) {
-	  /* TW: From 650/LVDS 1.10.07, 1.10a */
-	  ARdata = 0;
-	} else {
-          if(SiS_VBInfo & SetInSlaveMode) {
-	     /* TW: wdr: if(SiS_LCDInfo & LCDNonExpanding) { */
-	     ARdata=0;
-          }
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+         if(HwDeviceExtension->jChipType >= SIS_315H) {
+	    if(IS_SIS650740 || IS_SIS550) {  
+	       /* 315, 330 don't do this */
+	       if(SiS_Pr->SiS_VBType & VB_SIS301B302B) { 
+	          if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
+	       } else {
+	          ARdata = 0;
+	       }
+	    }
+	 } else {
+           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  ARdata=0;
 	}
       }
     }
-    SiS_GetReg2(SiS_P3da);                              /* reset 3da  */
-    SiS_SetReg3(SiS_P3c0,i);                            /* set index  */
-    SiS_SetReg3(SiS_P3c0,ARdata);                       /* set data   */
+    SiS_GetReg2(SiS_Pr->SiS_P3da);                              /* reset 3da  */
+    SiS_SetReg3(SiS_Pr->SiS_P3c0,i);                            /* set index  */
+    SiS_SetReg3(SiS_Pr->SiS_P3c0,ARdata);                       /* set data   */
    }
-   SiS_GetReg2(SiS_P3da);                                /* reset 3da  */
-   SiS_SetReg3(SiS_P3c0,0x14);                           /* set index  */
-   SiS_SetReg3(SiS_P3c0,0x00);                           /* set data   */
+   SiS_GetReg2(SiS_Pr->SiS_P3da);                               /* reset 3da  */
+   SiS_SetReg3(SiS_Pr->SiS_P3c0,0x14);                          /* set index  */
+   SiS_SetReg3(SiS_Pr->SiS_P3c0,0x00);                          /* set data   */
 
-   SiS_GetReg2(SiS_P3da);                                /* Enable Attribute  */
-   SiS_SetReg3(SiS_P3c0,0x20);
+   SiS_GetReg2(SiS_Pr->SiS_P3da);
+   SiS_SetReg3(SiS_Pr->SiS_P3c0,0x20);				/* Enable Attribute  */
+   SiS_GetReg2(SiS_Pr->SiS_P3da);
 }
 
-/* TW: Checked against 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */
 void
-SiS_SetGRCRegs(UCHAR *ROMAddr,USHORT StandTableIndex)
+SiS_SetGRCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
 {
    UCHAR GRdata;
    USHORT i;
 
-   for(i=0;i<=0x08;i++) {
-     GRdata = SiS_StandTable[StandTableIndex].GRC[i]; 	  /* Get GR from file */
-     SiS_SetReg1(SiS_P3ce,i,GRdata);                      /* Set GR(3ce) */
+   for(i = 0; i <= 0x08; i++) {
+     GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
+     SiS_SetReg1(SiS_Pr->SiS_P3ce,i,GRdata);                    /* Set GR(3ce) */
    }
 
-   if(SiS_ModeType > ModeVGA) {
-     SiS_SetRegAND(SiS_P3ce,0x05,0xBF);			  /* 256 color disable */
+   if(SiS_Pr->SiS_ModeType > ModeVGA) {
+     SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF);			/* 256 color disable */
    }
 }
 
-/* TW: Checked against 650/LVDS (1.10.07, 1.10a), 650/301LV and 630/301B BIOS */
 void
-SiS_ClearExt1Regs(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT i;
 
-  for(i=0x0A;i<=0x0E;i++) SiS_SetReg1(SiS_P3c4,i,0x00);      /* Clear SR0A-SR0E */
+  for(i = 0x0A; i <= 0x0E; i++) {
+      SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0x00);      /* Clear SR0A-SR0E */
+  }
 
-  /* TW: New from 650/LVDS/301LV BIOSes: */
+  /* TW: 330, 650/LVDS/301LV, 740/LVDS */
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-     SiS_SetRegAND(SiS_P3c4,0x37,0xFE);
+     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
   }
 }
 
-/* TW: Checked against 650/LVDS (1.10.07) and 650/301LV BIOS */
 void
-SiS_SetSync(UCHAR *ROMAddr,USHORT RefreshRateTableIndex)
+SiS_SetSync(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT RefreshRateTableIndex)
 {
   USHORT sync;
   USHORT temp;
 
-  sync = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
+  if(SiS_Pr->UseCustomMode) {
+     sync = SiS_Pr->CInfoFlag >> 8;
+  } else {
+     sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
+  }     
 
   sync &= 0xC0;
   temp = 0x2F | sync;
-  SiS_SetReg3(SiS_P3c2,temp);                                 /* Set Misc(3c2) */
+  SiS_SetReg3(SiS_Pr->SiS_P3c2,temp);           /* Set Misc(3c2) */
 }
 
-/* TW: Checked against 650/LVDS (1.10.07) and 650/301LV BIOS */
 void
-SiS_SetCRT1CRTC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                 USHORT RefreshRateTableIndex,
 		PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   UCHAR  index;
-  USHORT temp,tempah,i,modeflag,j;
+  USHORT tempah,i,modeflag,j;
+#ifdef SIS315H
+  USHORT temp;
   USHORT ResInfo,DisplayType;
-  SiS_LCDACRT1DataStruct *LCDACRT1Ptr=NULL;
+  const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
+#endif
 
-  SiS_SetRegAND(SiS_P3d4,0x11,0x7f);		/*unlock cr0-7  */
+  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);		/*unlock cr0-7  */
 
-  if(ModeNo<=0x13) {
-        modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
   } else {
-        modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-  }
+     if(ModeNo <= 0x13) {
+        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     } else {
+        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     }
+  }     
 
-  if((SiS_VBType & (VB_SIS302B | VB_SIS302LV))
-                        && (SiS_VBInfo & SetCRT2ToLCDA)) {
+  if((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
-     /* 302B LCDA - TW: Not done in any BIOS version */
+#ifdef SIS315H
+
+     /* LCDA */
 
-     temp = SiS_GetLCDACRT1Ptr(ROMAddr,ModeNo,ModeIdIndex,
+     temp = SiS_GetLCDACRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
                        RefreshRateTableIndex,&ResInfo,&DisplayType);
-  
+
      switch(DisplayType) {
-      case 0 : LCDACRT1Ptr = SiS_LCDACRT1800x600_1;           break;
-      case 1 : LCDACRT1Ptr = SiS_LCDACRT11024x768_1;          break;
-      case 2 : LCDACRT1Ptr = SiS_LCDACRT11280x1024_1;         break;
-      case 3 : LCDACRT1Ptr = SiS_LCDACRT1800x600_1_H;         break;
-      case 4 : LCDACRT1Ptr = SiS_LCDACRT11024x768_1_H;        break;
-      case 5 : LCDACRT1Ptr = SiS_LCDACRT11280x1024_1_H;       break;
-      case 6 : LCDACRT1Ptr = SiS_LCDACRT1800x600_2;           break;
-      case 7 : LCDACRT1Ptr = SiS_LCDACRT11024x768_2;          break;
-      case 8 : LCDACRT1Ptr = SiS_LCDACRT11280x1024_2;         break;
-      case 9 : LCDACRT1Ptr = SiS_LCDACRT1800x600_2_H;         break;
-      case 10: LCDACRT1Ptr = SiS_LCDACRT11024x768_2_H;        break;
-      case 11: LCDACRT1Ptr = SiS_LCDACRT11280x1024_2_H;       break;
+      case Panel_800x600       : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1;      break;
+      case Panel_1024x768      : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;     break;
+      case Panel_1280x1024     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1;    break;
+      case Panel_1400x1050     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1;    break;
+      case Panel_1600x1200     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1;    break;
+      case Panel_800x600   + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1_H;    break;
+      case Panel_1024x768  + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1_H;   break;
+      case Panel_1280x1024 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1_H;  break;
+      case Panel_1400x1050 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1_H;  break;
+      case Panel_1600x1200 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1_H;  break;
+      case Panel_800x600   + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2;      break;
+      case Panel_1024x768  + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2;     break;
+      case Panel_1280x1024 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2;    break;
+      case Panel_1400x1050 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2;    break;
+      case Panel_1600x1200 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2;    break;
+      case Panel_800x600   + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2_H;    break;
+      case Panel_1024x768  + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2_H;   break;
+      case Panel_1280x1024 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H;  break;
+      case Panel_1400x1050 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2_H;  break;
+      case Panel_1600x1200 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2_H;  break;
+      default:                   LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;     break;
      }
 
      tempah = (LCDACRT1Ptr+ResInfo)->CR[0];
-     SiS_SetReg1(SiS_P3d4,0x00,tempah);
+     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
      for(i=0x01,j=1;i<=0x07;i++,j++){
        tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
-       SiS_SetReg1(SiS_P3d4,i,tempah);
+       SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
      }
      for(i=0x10,j=8;i<=0x12;i++,j++){
        tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
-       SiS_SetReg1(SiS_P3d4,i,tempah);
+       SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
      }
      for(i=0x15,j=11;i<=0x16;i++,j++){
        tempah =(LCDACRT1Ptr+ResInfo)->CR[j];
-       SiS_SetReg1(SiS_P3d4,i,tempah);
+       SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
      }
      for(i=0x0A,j=13;i<=0x0C;i++,j++){
        tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
-       SiS_SetReg1(SiS_P3c4,i,tempah);
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
      }
-  
+
      tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
      tempah &= 0x0E0;
-     SiS_SetReg1(SiS_P3c4,0x0E,tempah);
+     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
 
      tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
      tempah &= 0x01;
      tempah <<= 5;
      if(modeflag & DoubleScanMode)  tempah |= 0x080;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
 
-     SiS_SetRegANDOR(SiS_P3d4,0x09,~0x020,tempah);
-     if(SiS_ModeType > 0x03) SiS_SetReg1(SiS_P3d4,0x14,0x4F);
+#endif
 
   } else {
 
-     /* LVDS, 301, 301B, 301LV, 302LV, (302B non-LCDA) */
+     /* LVDS, 301, 301B, 301LV, 302LV, ... (non-LCDA) */
 
-     index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;  	/* Get index */
-     if(HwDeviceExtension->jChipType < SIS_315H) {
-        index &= 0x3F;
-     }
+     if(SiS_Pr->UseCustomMode) {
+     
+        for(i=0,j=0;i<=07;i++,j++) {
+          SiS_SetReg1(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+        }
+        for(j=0x10;i<=10;i++,j++) {
+          SiS_SetReg1(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+        }
+        for(j=0x15;i<=12;i++,j++) {
+          SiS_SetReg1(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+        }
+        for(j=0x0A;i<=15;i++,j++) {
+          SiS_SetReg1(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
+        }
+
+        tempah = SiS_Pr->CCRT1CRTC[16] & 0xE0;
+        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
+
+        tempah = SiS_Pr->CCRT1CRTC[16];
+        tempah &= 0x01;
+        tempah <<= 5;
+        if(modeflag & DoubleScanMode)  tempah |= 0x80;
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah);
+     
+     
+     } else {
+     
+        index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;  	/* Get index */
+#if 0   /* Not any longer... */     
+        if(HwDeviceExtension->jChipType < SIS_315H) {
+           index &= 0x3F;
+        }
+#endif
+
+        for(i=0,j=0;i<=07;i++,j++) {
+          tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
+          SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
+        }
+        for(j=0x10;i<=10;i++,j++) {
+          tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
+          SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
+        }
+        for(j=0x15;i<=12;i++,j++) {
+          tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
+          SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
+        }
+        for(j=0x0A;i<=15;i++,j++) {
+          tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
+          SiS_SetReg1(SiS_Pr->SiS_P3c4,j,tempah);
+        }
+
+        tempah = SiS_Pr->SiS_CRT1Table[index].CR[16];
+        tempah &= 0xE0;
+        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
+
+        tempah = SiS_Pr->SiS_CRT1Table[index].CR[16];
+        tempah &= 0x01;
+        tempah <<= 5;
+        if(modeflag & DoubleScanMode)  tempah |= 0x80;
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah);
 
-     for(i=0,j=0;i<=07;i++,j++) {
-       tempah=SiS_CRT1Table[index].CR[i];
-       SiS_SetReg1(SiS_P3d4,j,tempah);
-     }
-     for(j=0x10;i<=10;i++,j++) {
-       tempah=SiS_CRT1Table[index].CR[i];
-       SiS_SetReg1(SiS_P3d4,j,tempah);
-     }
-     for(j=0x15;i<=12;i++,j++) {
-       tempah=SiS_CRT1Table[index].CR[i];
-       SiS_SetReg1(SiS_P3d4,j,tempah);
-     }
-     for(j=0x0A;i<=15;i++,j++) {
-       tempah=SiS_CRT1Table[index].CR[i];
-       SiS_SetReg1(SiS_P3c4,j,tempah);
      }
+  }
 
-     tempah = SiS_CRT1Table[index].CR[16];
-     tempah &= 0xE0;
-     SiS_SetReg1(SiS_P3c4,0x0E,tempah);
+  if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg1(SiS_Pr->SiS_P3d4,0x14,0x4F);
+}
 
-     tempah = SiS_CRT1Table[index].CR[16];
-     tempah &= 0x01;
-     tempah <<= 5;
-     if(modeflag & DoubleScanMode)  tempah |= 0x80;
-     SiS_SetRegANDOR(SiS_P3d4,0x09,0xDF,tempah);
+BOOLEAN
+SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
+		   USHORT *DisplayType)
+ {
+  USHORT tempbx=0,modeflag=0;
+  USHORT CRT2CRTC=0;
 
-     if(SiS_ModeType > 0x03) SiS_SetReg1(SiS_P3d4,0x14,0x4F);
+  if(ModeNo <= 0x13) {
+  	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  	CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+  	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  	CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   }
+
+  tempbx = SiS_Pr->SiS_LCDResInfo;
+
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 32;
+  if(modeflag & HalfDCLK)                 tempbx += 16;
+
+  *ResInfo = CRT2CRTC & 0x3F;
+  *DisplayType = tempbx;
+
+  return 1;
 }
 
 /* TW: Set offset and pitch - partly overruled by SetPitch() in XF86 */
-/* TW: Checked against 650/LVDS (1.10.07), 650/301LV and 315 BIOS */
 void
-SiS_SetCRT1Offset(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_SetCRT1Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                   USHORT RefreshRateTableIndex,
 		  PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
    USHORT temp, DisplayUnit, infoflag;
 
-   infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-
-   DisplayUnit = SiS_GetOffset(ROMAddr,ModeNo,ModeIdIndex,
-                     RefreshRateTableIndex,HwDeviceExtension);
+   if(SiS_Pr->UseCustomMode) {
+      infoflag = SiS_Pr->CInfoFlag;
+   } else {
+      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+   }
+   
+   DisplayUnit = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+                     RefreshRateTableIndex,HwDeviceExtension);		     
 
    temp = (DisplayUnit >> 8) & 0x0f;
-   SiS_SetRegANDOR(SiS_P3c4,0x0E,0xF0,temp);
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
 
    temp = DisplayUnit & 0xFF;
-   SiS_SetReg1(SiS_P3d4,0x13,temp);
+   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x13,temp);
 
    if(infoflag & InterlaceMode) DisplayUnit >>= 1;
 
@@ -2886,210 +3355,223 @@
    temp = (DisplayUnit & 0xff00) >> 8;
    if (DisplayUnit & 0xff) temp++;
    temp++;
-   SiS_SetReg1(SiS_P3c4,0x10,temp);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x10,temp);
 }
 
 /* TW: New from 650/LVDS 1.10.07, 630/301B and 630/LVDS BIOS */
 void
-SiS_ResetCRT1VCLK(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
    USHORT index;
 
    /* TW: We only need to do this if Panel Link is to be
-    *     initialized, thus on 630/LVDS/301B, and 650/LVDS
+    *     initialized, thus on 630/LVDS/301BDH, and 650/LVDS
     */
    if(HwDeviceExtension->jChipType >= SIS_315H) {
-       if (SiS_IF_DEF_LVDS == 0)  return;
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 0)  return;
    } else {
-       if( (SiS_IF_DEF_LVDS == 0) &&
-           (!(SiS_VBType & VB_SIS301BLV302BLV)) ) {
-	   return;
+      if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
+          (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
+	 return;
       }
    }
 
    if(HwDeviceExtension->jChipType >= SIS_315H) {
-   	SiS_SetRegANDOR(SiS_P3c4,0x31,0xCF,0x20);
+   	SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xCF,0x20);
    } else {
-   	SiS_SetReg1(SiS_P3c4,0x31,0x20);
+   	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
    }
    index = 1;
-   SiS_SetReg1(SiS_P3c4,0x2B,SiS_VCLKData[index].SR2B);
-   SiS_SetReg1(SiS_P3c4,0x2C,SiS_VCLKData[index].SR2C);
-   SiS_SetReg1(SiS_P3c4,0x2D,0x80);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
    if(HwDeviceExtension->jChipType >= SIS_315H) {
-   	SiS_SetRegANDOR(SiS_P3c4,0x31,0xcf,0x10);
+   	SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
    } else {
-   	SiS_SetReg1(SiS_P3c4,0x31,0x10);
+   	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
    }
    index = 0;
-   SiS_SetReg1(SiS_P3c4,0x2B,SiS_VCLKData[index].SR2B);
-   SiS_SetReg1(SiS_P3c4,0x2C,SiS_VCLKData[index].SR2C);
-   SiS_SetReg1(SiS_P3c4,0x2D,0x80);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
+   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
 }
 
-/* TW: Checked against 650/LVDS, 650/301LV, 315, 630/301B, 630/LVDS BIOS */
 void
-SiS_SetCRT1VCLK(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                 PSIS_HW_DEVICE_INFO HwDeviceExtension,
 		USHORT RefreshRateTableIndex)
 {
-  USHORT  index;
-
-#if 0	/* TW: Wrong. 650/301LV uses same table for LCDA and CRT1 */
-  if( (SiS_VBType & VB_SIS301BLV302BLV)
-                       && (SiS_VBInfo & SetCRT2ToLCDA) ){
+  USHORT  index=0;
 
-        /* TW: For 302B/302LV LCDA */
+  if(!SiS_Pr->UseCustomMode) {
+     index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+	                  RefreshRateTableIndex,HwDeviceExtension);
+  }			  
 
-    	index = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,
-	                RefreshRateTableIndex,HwDeviceExtension);
+  if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ){
 
-    	SiS_SetRegAND(SiS_P3c4,0x31,0xCF);
+    	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
 
-    	SiS_SetReg1(SiS_P3c4,0x2B,SiS_VBVCLKData[index].Part4_A);
-    	SiS_SetReg1(SiS_P3c4,0x2C,SiS_VBVCLKData[index].Part4_B);
+    	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VBVCLKData[index].Part4_A);
+    	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VBVCLKData[index].Part4_B);
 
     	if(HwDeviceExtension->jChipType >= SIS_315H) {
-		SiS_SetReg1(SiS_P3c4,0x2D,0x01);
+		SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01);
    	} else {
-    		SiS_SetReg1(SiS_P3c4,0x2D,0x80);
+    		SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
     	}
 
   } else {
-#endif
-
-        index = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,
-	                  RefreshRateTableIndex,HwDeviceExtension);
-
-#if 0   /* TW: All BIOSes use GetVCLK2Ptr instead */
-    	index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-    	index &= 0x3F;
-#endif
 
 	if(HwDeviceExtension->jChipType >= SIS_315H) {
-	    SiS_SetRegAND(SiS_P3c4,0x31,0xCF);
+	    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
 	} else {
-	    SiS_SetReg1(SiS_P3c4,0x31,0x00);
+	    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
 	}
 
-    	SiS_SetReg1(SiS_P3c4,0x2B,SiS_VCLKData[index].SR2B);
-    	SiS_SetReg1(SiS_P3c4,0x2C,SiS_VCLKData[index].SR2C);
+	if(SiS_Pr->UseCustomMode) {
+	   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->CSR2B);
+	   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->CSR2C);
+	} else {
+    	   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
+    	   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
+  	}	   
 
     	if(HwDeviceExtension->jChipType >= SIS_315H) {
-	    SiS_SetReg1(SiS_P3c4,0x2D,0x01);
+	    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01);
 	} else {
-      	    SiS_SetReg1(SiS_P3c4,0x2D,0x80);
+      	    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
         }
-#if 0
   }
-#endif
 }
 
 #if 0  /* TW: Not used */
 void
-SiS_IsLowResolution(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
   USHORT ModeFlag;
 
-  SiS_SetRegAND(SiS_P3c4,0x0F,0x7F);
+  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0x7F);
 
   if(ModeNo > 0x13) {
-    ModeFlag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    ModeFlag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
     if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) {
-      SiS_SetRegOR(SiS_P3c4,0x0F,0x80);
-      SiS_SetRegAND(SiS_P3c4,0x01,0xF7);
+      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x80);
+      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xF7);
     }
   }
 }
 #endif
 
-/* TW: Checked against 630/LVDS, 650/LVDS and 315 BIOS */
 void
-SiS_SetCRT1ModeRegs(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
                     USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
 {
   USHORT data,data2,data3;
   USHORT infoflag=0,modeflag;
   USHORT resindex,xres;
 
-  if(ModeNo > 0x13) {
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+  if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
+     infoflag = SiS_Pr->CInfoFlag;
   } else {
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     if(ModeNo > 0x13) {
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+     } else {
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     }
   }
 
-  SiS_SetRegAND(SiS_P3c4,0x1F,0x3F); 		/* DAC pedestal */
+  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F); 		/* DAC pedestal */
 
   if(ModeNo > 0x13) data = infoflag;
   else data = 0;
 
-  data2 = SiS_GetReg1(SiS_P3c4,0x06) & 0xC0;  	/* TW: Preserve Xv display mode (DCLK/TCLK) ! */
+  data2 = 0;
   if(ModeNo > 0x13) {
-    if(SiS_ModeType > 0x02) {
+    if(SiS_Pr->SiS_ModeType > 0x02) {
        data2 |= 0x02;
-       data3 = (SiS_ModeType - ModeVGA) << 2;
+       data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
        data2 |= data3;
     }
   }
+#ifdef TWDEBUG
+  xf86DrvMsg(0, X_INFO, "Debug: Mode infoflag = %x, Chiptype %d\n", 
+  	data, HwDeviceExtension->jChipType);
+#endif  
   if(data & InterlaceMode) data2 |= 0x20;
-  SiS_SetReg1(SiS_P3c4,0x06,data2);
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data2);
 
-  resindex = SiS_GetResInfo(ROMAddr,ModeNo,ModeIdIndex);
-  if(ModeNo <= 0x13) {
-      	xres = SiS_StResInfo[resindex].HTotal;
+  if(SiS_Pr->UseCustomMode) {
+     xres = SiS_Pr->CHDisplay;
   } else {
-      	xres = SiS_ModeResInfo[resindex].HTotal;
+     resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+     if(ModeNo <= 0x13) {
+      	xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
+     } else {
+      	xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+     }
   }
 
-  data = 0x0000;
-  if(infoflag & InterlaceMode) {
-      if(xres == 1024) data = 0x0035;
-      else data = 0x0048;
-  }
-  data2 = data & 0x00FF;
-  SiS_SetReg1(SiS_P3d4,0x19,data2);
-  data2 = (data & 0xFF00) >> 8;
-  SiS_SetRegANDOR(SiS_P3d4,0x1a,0xFC,data2);
+  if(HwDeviceExtension->jChipType != SIS_300) {
+     data = 0x0000;
+     if(infoflag & InterlaceMode) {
+        if(xres == 1024) data = 0x0035;
+        else data = 0x0048;
+     }
+     data2 = data & 0x00FF;
+     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x19,data2);
+     data2 = (data & 0xFF00) >> 8;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,data2);
+  }
 
   if(modeflag & HalfDCLK) {
-     SiS_SetRegOR(SiS_P3c4,0x01,0x08);
+     SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
   }
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {
+  if(HwDeviceExtension->jChipType == SIS_300) {
      if(modeflag & LineCompareOff) {
-        SiS_SetRegANDOR(SiS_P3c4,0x0F,0xB7,0x08);
+        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x08);
      } else {
-        SiS_SetRegAND(SiS_P3c4,0x0F,0xB7);
+        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xF7);
+     }
+  } else if(HwDeviceExtension->jChipType < SIS_315H) {
+     if(modeflag & LineCompareOff) {
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08);
+     } else {
+        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
      }
      /* 630 BIOS does something for mode 0x12 here */
   } else {
      if(modeflag & LineCompareOff) {
-        SiS_SetRegANDOR(SiS_P3c4,0x0F,0xB7,0x08);
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08);
      } else {
-        SiS_SetRegAND(SiS_P3c4,0x0F,0xB7);
+        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
      }
   }
 
-  if(SiS_ModeType == ModeEGA) {
-     if(ModeNo > 0x13) {
-  	SiS_SetRegOR(SiS_P3c4,0x0F,0x40);
+  if(HwDeviceExtension->jChipType != SIS_300) {
+     if(SiS_Pr->SiS_ModeType == ModeEGA) {
+        if(ModeNo > 0x13) {
+  	   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40);
+        }
      }
   }
 
-  /* TW: 315 BIOS sets SR17 here (0x18bf) */
 #ifdef SIS315H
+  /* TW: 315 BIOS sets SR17 at this point */
   if(HwDeviceExtension->jChipType == SIS_315PRO) {
-      data = SiS_Get310DRAMType(ROMAddr,HwDeviceExtension);
-      data = SiS_SR15[2][data];
-      if(SiS_ModeType == ModeText) {
+      data = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension);
+      data = SiS_Pr->SiS_SR15[2][data];
+      if(SiS_Pr->SiS_ModeType == ModeText) {
           data &= 0xc7;
       } else {
-          data2 = SiS_GetOffset(ROMAddr,ModeNo,ModeIdIndex,
+          data2 = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
                                 RefreshRateTableIndex,HwDeviceExtension);
 	  data2 >>= 1;
 	  if(infoflag & InterlaceMode) data2 >>= 1;
-	  data3 = SiS_GetColorDepth(ROMAddr,ModeNo,ModeIdIndex);
+	  data3 = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
 	  data3 >>= 1;
 	  if(data3 == 0) data3++;
 	  data2 /= data3;
@@ -3098,36 +3580,78 @@
 	      data |= 0x50;
 	  }
       }
-      SiS_SetReg1(SiS_P3c4,0x17,data);
+      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,data);
+  }
+
+  /* TW: 330 BIOS sets SR17 at this point */
+  if(HwDeviceExtension->jChipType == SIS_330) {
+      data = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension);
+      data = SiS_Pr->SiS_SR15[2][data];
+      if(SiS_Pr->SiS_ModeType <= ModeEGA) {
+          data &= 0xc7;
+      } else {
+          if(SiS_Pr->UseCustomMode) {
+	     data2 = SiS_Pr->CSRClock;
+	  } else {
+             data2 = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+                               RefreshRateTableIndex,HwDeviceExtension);
+             data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
+	  }
+
+	  data3 = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+	  data3 >>= 1;
+
+	  data2 *= data3;
+
+	  data3 = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);
+	  data3 *= 1024;
+
+	  data2 = data3 / data2;
+
+	  if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
+            if(data2 >= 0x19c)      data = 0xba;
+	    else if(data2 >= 0x140) data = 0x7a;
+	    else if(data2 >= 0x101) data = 0x3a;
+	    else if(data2 >= 0xf5)  data = 0x32;
+	    else if(data2 >= 0xe2)  data = 0x2a;
+	    else if(data2 >= 0xc4)  data = 0x22;
+	    else if(data2 >= 0xac)  data = 0x1a;
+	    else if(data2 >= 0x9e)  data = 0x12;
+	    else if(data2 >= 0x8e)  data = 0x0a;
+	    else                    data = 0x02;
+	  } else {
+	    if(data2 >= 0x127)      data = 0xba;
+	    else                    data = 0x7a;
+	  }
+      }
+      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,data);
   }
 #endif
 
   data = 0x60;
-  if(SiS_ModeType != ModeText) {
-      data = data ^ 0x60;
-      if(SiS_ModeType != ModeEGA) {
-        data = data ^ 0xA0;
+  if(SiS_Pr->SiS_ModeType != ModeText) {
+      data ^= 0x60;
+      if(SiS_Pr->SiS_ModeType != ModeEGA) {
+          data ^= 0xA0;
       }
   }
-  SiS_SetRegANDOR(SiS_P3c4,0x21,0x1F,data);
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
 
-  SiS_SetVCLKState(ROMAddr,HwDeviceExtension,ModeNo,RefreshRateTableIndex,ModeIdIndex);
+  SiS_SetVCLKState(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,RefreshRateTableIndex,ModeIdIndex);
 
 #ifdef SIS315H
-  /* TW: New */
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-    if (SiS_GetReg1(SiS_P3d4,0x31) & 0x40) {
-        SiS_SetReg1(SiS_P3d4,0x52,0x2c);
+    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
+        SiS_SetReg1(SiS_Pr->SiS_P3d4,0x52,0x2c);
     } else {
-        SiS_SetReg1(SiS_P3d4,0x52,0x6c);
+        SiS_SetReg1(SiS_Pr->SiS_P3d4,0x52,0x6c);
     }
   }
 #endif
 }
 
-/* TW: Checked against 315, 650/LVDS, 650/301LV, 630/301B and 630/LVDS BIOS */
 void
-SiS_SetVCLKState(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
                  USHORT ModeNo,USHORT RefreshRateTableIndex,
                  USHORT ModeIdIndex)
 {
@@ -3136,36 +3660,39 @@
 
   if (ModeNo <= 0x13) VCLK = 0;
   else {
-     index = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,
+     if(SiS_Pr->UseCustomMode) {
+        VCLK = SiS_Pr->CSRClock;
+     } else {
+        index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
 	               RefreshRateTableIndex,HwDeviceExtension);
-     VCLK = SiS_VCLKData[index].CLOCK;
+        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
+     }	
   }
 
   if(HwDeviceExtension->jChipType < SIS_315H) {		/* 300 series */
 
     data2 = 0x00;
     if(VCLK > 150) data2 |= 0x80;
-    SiS_SetRegANDOR(SiS_P3c4,0x07,0x7B,data2); 	/* DAC speed */
+    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data2); 	/* DAC speed */
 
     data2 = 0x00;
     if(VCLK >= 150) data2 |= 0x08;       	/* VCLK > 150 */
-    SiS_SetRegANDOR(SiS_P3c4,0x32,0xF7,data2);
+    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
 
   } else { 						/* 310/325 series */
 
-    data = SiS_GetReg1(SiS_P3c4,0x32);
-    data &= 0xf3;
-    if(VCLK >= 166) data |= 0x0c;         	/* TW: Was 200; is 166 in 650 and 315 BIOSes */
-    SiS_SetReg1(SiS_P3c4,0x32,data);
+    data = 0;
+    if(VCLK >= 166) data |= 0x0c;         	/* TW: Was 200; is 166 in 650, 315 and 330 BIOSes */
+    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
 
-    if(VCLK >= 166) {				/* TW: Was 200, is 166 in 650 and 315 BIOSes */
-       SiS_SetRegAND(SiS_P3c4,0x1f,0xe7);
+    if(VCLK >= 166) {				/* TW: Was 200, is 166 in 650, 315 and 330 BIOSes */
+       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
     }
 #if 0 /* Not done in 315 and 650/301LV/LVDS BIOSes: */
-    data = SiS_GetReg1(SiS_P3c4,0x1F);	  	/* DAC pedestal */
+    data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);	  	/* DAC pedestal */
     data &= 0xE7;
     if(VCLK<200) data |= 0x10;
-    SiS_SetReg1(SiS_P3c4,0x1F,data);	  	/* DAC pedestal */
+    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,data);	  	/* DAC pedestal */
 #endif
   }
 
@@ -3173,36 +3700,46 @@
   if((VCLK >= 135) && (VCLK < 160)) data2 = 0x02;
   if((VCLK >= 160) && (VCLK < 260)) data2 = 0x01;
   if(VCLK >= 260) data2 = 0x00;
-  /* disable 24bit palette RAM gamma correction  */
+
   if(HwDeviceExtension->jChipType == SIS_540) {
     	if((VCLK == 203) || (VCLK < 234)) data2 = 0x02;
   }
+  
   if(HwDeviceExtension->jChipType < SIS_315H) {
-      SiS_SetRegANDOR(SiS_P3c4,0x07,0xFC,data2);  	/* DAC speed */
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data2);  	/* DAC speed */
   } else {
-      /* TW: This is done in 650/LVDS/301LV BIOSes; Not in 315 BIOS */
-      if(ModeNo > 13) data2 &= 0xfc;
-      SiS_SetRegANDOR(SiS_P3c4,0x07,0xF8,data2);  	/* DAC speed */
+      if(HwDeviceExtension->jChipType > SIS_315PRO) {
+         /* TW: This "if" is done in 330 and 650/LVDS/301LV BIOSes; Not in 315 BIOS */
+         if(ModeNo > 0x13) data2 &= 0xfc;
+      }
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data2);  	/* DAC speed */
   }
 }
 
 void
-SiS_LoadDAC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SiS_LoadDAC(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+            UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
    USHORT data,data2;
    USHORT time,i,j,k;
    USHORT m,n,o;
    USHORT si,di,bx,dl;
    USHORT al,ah,dh;
-   USHORT *table=NULL;
+   USHORT DACAddr, DACData, shiftflag;
+   const USHORT *table = NULL;
 #if 0
    USHORT tempah,tempch,tempcl,tempdh,tempal,tempbx;
 #endif
 
-   if (ModeNo<=0x13)
-        data = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-   else
-        data = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+   if(ModeNo <= 0x13) {
+        data = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+   } else {
+        if(SiS_Pr->UseCustomMode) {
+	   data = SiS_Pr->CModeFlag;
+	} else {
+           data = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ 	}	   
+   }
 
 #if 0
    if(!(ds:489 & 0x08)) {
@@ -3218,10 +3755,23 @@
 	   table = SiS_VGA_DAC;
 	}
 	if(time == 256) j = 16;
-	else j = time;
+	else            j = time;
 
-	SiS_SetReg3(SiS_P3c6,0xFF);
-	SiS_SetReg3(SiS_P3c8,0x00);
+	if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&        /* 301B-DH LCD */
+	      (SiS_Pr->SiS_VBType & VB_NoLCD) )        ||
+	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)       ||   /* LCDA */
+	    (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) {  /* Programming CRT1 */
+	   DACAddr = SiS_Pr->SiS_P3c8;
+	   DACData = SiS_Pr->SiS_P3c9;
+	   shiftflag = 0;
+	   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+	} else {
+	   shiftflag = 1;
+	   DACAddr = SiS_Pr->SiS_Part5Port;
+	   DACData = SiS_Pr->SiS_Part5Port + 1;
+	}
+
+	SiS_SetReg3(DACAddr,0x00);
 
 	for(i=0; i<j; i++) {
 	   data = table[i];
@@ -3229,41 +3779,43 @@
 		data2 = 0;
 		if(data & 0x01) data2 = 0x2A;
 		if(data & 0x02) data2 += 0x15;
-		SiS_SetReg3(SiS_P3c9,data2);
+		if(shiftflag) data2 <<= 2;
+		SiS_SetReg3(DACData,data2);
 		data >>= 2;
 	   }
 	}
 
 	if(time == 256) {
-	   for(i=16; i<32; i++) {
+	   for(i = 16; i < 32; i++) {
 		data = table[i];
-		for(k=0; k<3; k++) SiS_SetReg3(SiS_P3c9,data);
+		if(shiftflag) data <<= 2;
+		for(k=0; k<3; k++) SiS_SetReg3(DACData,data);
 	   }
 	   si = 32;
-	   for(m=0; m<9; m++) {
+	   for(m = 0; m < 9; m++) {
 	      di = si;
-	      bx = si+0x04;
+	      bx = si + 4;
 	      dl = 0;
-	      for(n=0; n<3; n++) {
-		 for(o=0; o<5; o++) {
+	      for(n = 0; n < 3; n++) {
+		 for(o = 0; o < 5; o++) {
 		    dh = table[si];
 		    ah = table[di];
 		    al = table[bx];
 		    si++;
-		    SiS_WriteDAC(dl,ah,al,dh);
-		 }         /* for 5 */
-		 si = si - 2;
-		 for(o=0; o<3; o++) {
+		    SiS_WriteDAC(SiS_Pr,DACData,shiftflag,dl,ah,al,dh);
+		 }
+		 si -= 2;
+		 for(o = 0; o < 3; o++) {
 		    dh = table[bx];
 		    ah = table[di];
 		    al = table[si];
 		    si--;
-		    SiS_WriteDAC(dl,ah,al,dh);
-		 }         /* for 3 */
+		    SiS_WriteDAC(SiS_Pr,DACData,shiftflag,dl,ah,al,dh);
+		 }
 		 dl++;
-	      }            /* for 3 */
-	      si = si + 5;
-	   }               /* for 9 */
+	      }            /* for n < 3 */
+	      si += 5;
+	   }               /* for m < 9 */
 	}
 #if 0
     }  /* ds:489 & 0x08 */
@@ -3273,10 +3825,10 @@
     if((!(ds:489 & 0x08)) && (ds:489 & 0x06)) {
            tempbx = 0;
 	   for(i=0; i< 256; i++) {
-               SiS_SetReg3(SiS_P3c8-1,tempbx);    	/* 7f87 */
-               tempah = SiS_GetReg3(SiS_P3c8+1);  	/* 7f83 */
-	       tempch = SiS_GetReg3(SiS_P3c8+1);
-	       tempcl = SiS_GetReg3(SiS_P3c8+1);
+               SiS_SetReg3(SiS_Pr->SiS_P3c8-1,tempbx);    	/* 7f87 */
+               tempah = SiS_GetReg3(SiS_Pr->SiS_P3c8+1);  	/* 7f83 */
+	       tempch = SiS_GetReg3(SiS_Pr->SiS_P3c8+1);
+	       tempcl = SiS_GetReg3(SiS_Pr->SiS_P3c8+1);
 	       tempdh = tempah;
 	       tempal = 0x4d * tempdh;          	/* 7fb8 */
 	       tempbx += tempal;
@@ -3288,65 +3840,90 @@
 	       tempdh = (tempbx & 0x00ff) >> 8;
 	       tempch = tempdh;
 	       tempcl = tempdh;
-	       SiS_SetReg3(SiS_P3c8,(tempbx & 0xff));  	/* 7f7c */
-	       SiS_SetReg3(SiS_P3c8+1,tempdh);          /* 7f92 */
-	       SiS_SetReg3(SiS_P3c8+1,tempch);
-	       SiS_SetReg3(SiS_P3c8+1,tempcl);
+	       SiS_SetReg3(SiS_Pr->SiS_P3c8,(tempbx & 0xff));  	/* 7f7c */
+	       SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempdh);          /* 7f92 */
+	       SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempch);
+	       SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempcl);
            }
     }
 #endif
 }
 
 void
-SiS_WriteDAC(USHORT dl, USHORT ah, USHORT al, USHORT dh)
+SiS_WriteDAC(SiS_Private *SiS_Pr, USHORT DACData, USHORT shiftflag,
+             USHORT dl, USHORT ah, USHORT al, USHORT dh)
 {
   USHORT temp;
   USHORT bh,bl;
 
-  bh=ah;
-  bl=al;
-  if(dl!=0) {
-    temp=bh;
-    bh=dh;
-    dh=temp;
-    if(dl==1) {
-       temp=bl;
-       bl=dh;
-       dh=temp;
+  bh = ah;
+  bl = al;
+  if(dl != 0) {
+    temp = bh;
+    bh = dh;
+    dh = temp;
+    if(dl == 1) {
+       temp = bl;
+       bl = dh;
+       dh = temp;
     } else {
-       temp=bl;
-       bl=bh;
-       bh=temp;
+       temp = bl;
+       bl = bh;
+       bh = temp;
     }
   }
-  SiS_SetReg3(SiS_P3c9,(USHORT)dh);
-  SiS_SetReg3(SiS_P3c9,(USHORT)bh);
-  SiS_SetReg3(SiS_P3c9,(USHORT)bl);
+  if(shiftflag) {
+     dh <<= 2;
+     bh <<= 2;
+     bl <<= 2;
+  }
+  SiS_SetReg3(DACData,(USHORT)dh);
+  SiS_SetReg3(DACData,(USHORT)bh);
+  SiS_SetReg3(DACData,(USHORT)bl);
 }
 
-ULONG
-GetDRAMSize(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static ULONG
+GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-  ULONG   AdapterMemorySize=0;
+  ULONG   AdapterMemorySize = 0;
 #ifdef SIS315H
   USHORT  counter;
 #endif
-  
+
 #ifdef SIS315H
   if ((HwDeviceExtension->jChipType == SIS_315H) ||
+      (HwDeviceExtension->jChipType == SIS_315)  ||
       (HwDeviceExtension->jChipType == SIS_315PRO)) {
-    	counter = SiS_GetReg1(SiS_P3c4,0x14) & 0xF0;
-    	counter >>= 4;
-    	AdapterMemorySize= 1 << counter;
-    	AdapterMemorySize *= 1024*1024;
+
+    	counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+	AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
+	counter >>= 2;
+	counter &= 0x03;
+	if(counter == 0x02) {
+		AdapterMemorySize += (AdapterMemorySize / 2);      /* DDR asymetric */
+	} else if(counter != 0) {
+		AdapterMemorySize <<= 1;                           /* SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK */
+	}
+	AdapterMemorySize *= (1024*1024);
+
+  } else if(HwDeviceExtension->jChipType == SIS_330) {
+
+    	counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+	AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
+	counter &= 0x0c;
+	if(counter != 0) {
+		AdapterMemorySize <<= 1;
+	}
+	AdapterMemorySize *= (1024*1024);
+
   } else if((HwDeviceExtension->jChipType == SIS_550) ||
-            (HwDeviceExtension->jChipType == SIS_640) ||
             (HwDeviceExtension->jChipType == SIS_740) ||
             (HwDeviceExtension->jChipType == SIS_650)) {
-      		counter = SiS_GetReg1(SiS_P3c4,0x14) & 0x3F;
-      		counter++;
-      		AdapterMemorySize = counter * 4;
-      		AdapterMemorySize *= 1024*1024;
+
+  	counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
+      	counter++;
+      	AdapterMemorySize = counter * 4;
+      	AdapterMemorySize *= (1024*1024);
   }
 #endif
 
@@ -3355,27 +3932,29 @@
       (HwDeviceExtension->jChipType==SIS_540) ||
       (HwDeviceExtension->jChipType==SIS_630) ||
       (HwDeviceExtension->jChipType==SIS_730)) {
-      	AdapterMemorySize = SiS_GetReg1(SiS_P3c4,0x14);
-      	AdapterMemorySize = AdapterMemorySize&0x3F;
+
+      	AdapterMemorySize = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
       	AdapterMemorySize++;
-      	AdapterMemorySize *= 1024*1024;
+      	AdapterMemorySize *= (1024*1024);
+
   }
 #endif
 
   return AdapterMemorySize;
 }
 
+#ifndef LINUX_XF86
 void
-SiS_ClearBuffer(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
 {
   PVOID   VideoMemoryAddress = (PVOID)HwDeviceExtension->pjVideoMemoryAddress;
   ULONG   AdapterMemorySize  = (ULONG)HwDeviceExtension->ulVideoMemorySize;
   PUSHORT pBuffer;
   int i;
 
-  if (SiS_ModeType>=ModeEGA) {
-    if (ModeNo>0x13) {
-      AdapterMemorySize = GetDRAMSize(HwDeviceExtension);
+  if (SiS_Pr->SiS_ModeType>=ModeEGA) {
+    if(ModeNo > 0x13) {
+      AdapterMemorySize = GetDRAMSize(SiS_Pr, HwDeviceExtension);
       SiS_SetMemory(VideoMemoryAddress,AdapterMemorySize,0);
     } else {
       pBuffer = VideoMemoryAddress;
@@ -3384,7 +3963,7 @@
     }
   } else {
     pBuffer = VideoMemoryAddress;
-    if (SiS_ModeType < ModeCGA) {
+    if (SiS_Pr->SiS_ModeType < ModeCGA) {
       for(i=0; i<0x4000; i++)
          pBuffer[i] = 0x0720;
     } else {
@@ -3392,17 +3971,18 @@
     }
   }
 }
+#endif
 
 void
-SiS_DisplayOn(void)
+SiS_DisplayOn(SiS_Private *SiS_Pr)
 {
-   SiS_SetRegANDOR(SiS_P3c4,0x01,0xDF,0x00);
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x00);
 }
 
 void
-SiS_DisplayOff(void)
+SiS_DisplayOff(SiS_Private *SiS_Pr)
 {
-   SiS_SetRegANDOR(SiS_P3c4,0x01,0xDF,0x20);
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x20);
 }
 
 
@@ -3418,12 +3998,12 @@
 /* ========================================== */
 /*  AR(3C0) */
 void
-SiS_SetReg2(USHORT port, USHORT index, USHORT data)
+SiS_SetReg2(SiS_Private *SiS_Pr, USHORT port, USHORT index, USHORT data)
 {
    InPortByte(port+0x3da-0x3c0);
-   OutPortByte(SiS_P3c0,index);
-   OutPortByte(SiS_P3c0,data);
-   OutPortByte(SiS_P3c0,0x20);
+   OutPortByte(SiS_Pr->SiS_P3c0,index);
+   OutPortByte(SiS_Pr->SiS_P3c0,data);
+   OutPortByte(SiS_Pr->SiS_P3c0,0x20);
 }
 
 void
@@ -3438,6 +4018,12 @@
    OutPortLong(port,data);
 }
 
+void
+SiS_SetReg5(USHORT port, USHORT data)
+{
+   OutPortWord(port,data);
+}
+
 UCHAR SiS_GetReg1(USHORT port, USHORT index)
 {
    UCHAR   data;
@@ -3468,29 +4054,39 @@
    return(data);
 }
 
+USHORT
+SiS_GetReg4(USHORT port)
+{
+   ULONG   data;
+
+   data = InPortWord(port);
+
+   return(data);
+}
+
 void
-SiS_ClearDAC(ULONG port)
+SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG port)
 {
    int i;
 
    OutPortByte(port, 0);
    port++;
-   for (i=0; i<256*3; i++) {
+   for (i=0; i < (256 * 3); i++) {
       OutPortByte(port, 0);
    }
 
 }
-/* ========================================== */
-#if 0  /* TW: Not done in any BIOS */
+
+#if 0  /* TW: Unused */
 void
-SiS_SetInterlace(UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex)
+SiS_SetInterlace(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex)
 {
   ULONG Temp;
   USHORT data,Temp2;
 
   if (ModeNo<=0x13) return;
 
-  Temp = (ULONG)SiS_GetReg1(SiS_P3d4,0x01);
+  Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x01);
   Temp++;
   Temp <<= 3;
 
@@ -3498,66 +4094,200 @@
   else if(Temp == 1280) data = 0x0048;
   else data = 0x0000;
 
-  Temp2 = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+  Temp2 = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
   Temp2 &= InterlaceMode;
   if(Temp2 == 0) data=0x0000;
 
-  SiS_SetReg1(SiS_P3d4,0x19,data);
+  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x19,data);
 
-  Temp = (ULONG)SiS_GetReg1(SiS_P3d4,0x1A);
+  Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x1A);
   Temp = (USHORT)(Temp & 0xFC);
-  SiS_SetReg1(SiS_P3d4,0x1A,(USHORT)Temp);
+  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x1A,(USHORT)Temp);
 
-  Temp = (ULONG)SiS_GetReg1(SiS_P3c4,0x0f);
+  Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x0f);
   Temp2 = (USHORT)Temp & 0xBF;
   if(ModeNo==0x37) Temp2 |= 0x40;
-  SiS_SetReg1(SiS_P3d4,0x1A,(USHORT)Temp2);
+  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x1A,(USHORT)Temp2);
 }
 #endif
 
-/* TW: Checked against 650/LVDS (1.10.07), 650/301LV and 315 BIOS */
 #ifdef SIS315H
 void
-SiS_SetCRT1FIFO_310(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                 PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT modeflag;
 
-  SiS_SetRegAND(SiS_P3c4,0x3D,0xFE);  /* disable auto-threshold */
+  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);  /* disable auto-threshold */
 
   if(ModeNo > 0x13) {
-    modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    if(SiS_Pr->UseCustomMode) {
+       modeflag = SiS_Pr->CModeFlag;
+    } else {
+       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    }       
     if( (!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
-       SiS_SetReg1(SiS_P3c4,0x08,0x34);
-       SiS_SetRegAND(SiS_P3c4,0x09,0xF0);
-       SiS_SetRegOR(SiS_P3c4,0x3D,0x01);
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0x34);
+       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
     } else {
-       SiS_SetReg1(SiS_P3c4,0x08,0xAE);
-       SiS_SetRegAND(SiS_P3c4,0x09,0xF0);
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0xAE);
+       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
     }
   } else {
-    SiS_SetReg1(SiS_P3c4,0x08,0xAE);
-    SiS_SetRegAND(SiS_P3c4,0x09,0xF0);
+    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0xAE);
+    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
   }
 }
 #endif
 
-#if 0  /* TW: Unused */
+#ifdef SIS300
+void
+SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                    USHORT RefreshRateTableIndex)
+{
+  USHORT  ThresholdLow = 0;
+  USHORT  index, VCLK, MCLK, colorth=0;
+  USHORT  tempah, temp;
+
+  if(ModeNo > 0x13) {
+
+     if(SiS_Pr->UseCustomMode) {
+        VCLK = SiS_Pr->CSRClock;
+     } else {
+        index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+        index &= 0x3F;
+        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;             /* Get VCLK  */
+     }
+
+     switch (SiS_Pr->SiS_ModeType - ModeEGA) {     /* Get half colordepth */
+        case 0 : colorth = 1; break;
+        case 1 : colorth = 1; break;
+        case 2 : colorth = 2; break;
+        case 3 : colorth = 2; break;
+        case 4 : colorth = 3; break;
+        case 5 : colorth = 4; break;
+     }
+
+     index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
+     index &= 0x07;
+     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
+
+     tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+     tempah &= 0xc3;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,tempah);
+
+     do {
+        ThresholdLow = SiS_CalcDelay(SiS_Pr, ROMAddr, VCLK, colorth, MCLK);
+        ThresholdLow++;
+        if(ThresholdLow < 0x13) break;
+        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
+        ThresholdLow = 0x13;
+        tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+        tempah >>= 6;
+        if(!(tempah)) break;
+        tempah--;
+        tempah <<= 6;
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,tempah);
+     } while(0);
+
+  } else ThresholdLow = 2;
+
+  /* Write CRT/CPU threshold low, CRT/Engine threshold high */
+  temp = (ThresholdLow << 4) | 0x0f;
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,temp);
+
+  temp = (ThresholdLow & 0x10) << 1;
+  if(ModeNo > 0x13) temp |= 0x40;
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
+
+  /* What is this? */
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3B,0x09);
+
+  /* Write CRT/CPU threshold high */
+  temp = ThresholdLow + 3;
+  if(temp > 0x0f) temp = 0x0f;
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x09,temp);
+}
+
+USHORT
+SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT VCLK, USHORT colordepth, USHORT MCLK)
+{
+  USHORT tempax, tempbx;
+
+  tempbx = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
+  tempax = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
+  if(tempax < 4) tempax = 4;
+  tempax -= 4;
+  if(tempbx < tempax) tempbx = tempax;
+  return(tempbx);
+}
+
+USHORT
+SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key)
+{
+  const UCHAR ThLowA[]   = { 61, 3,52, 5,68, 7,100,11,
+                             43, 3,42, 5,54, 7, 78,11,
+                             34, 3,37, 5,47, 7, 67,11 };
+
+  const UCHAR ThLowB[]   = { 81, 4,72, 6,88, 8,120,12,
+                             55, 4,54, 6,66, 8, 90,12,
+                             42, 4,45, 6,55, 8, 75,12 };
+
+  const UCHAR ThTiming[] = {  1, 2, 2, 3, 0, 1,  1, 2 };
+
+  USHORT tempah, tempal, tempcl, tempbx, temp;
+  ULONG  longtemp;
+
+  tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
+  tempah &= 0x62;
+  tempah >>= 1;
+  tempal = tempah;
+  tempah >>= 3;
+  tempal |= tempah;
+  tempal &= 0x07;
+  tempcl = ThTiming[tempal];
+  tempbx = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+  tempbx >>= 6;
+  tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+  tempah >>= 4;
+  tempah &= 0x0c;
+  tempbx |= tempah;
+  tempbx <<= 1;
+  if(key == 0) {
+     tempal = ThLowA[tempbx + 1];
+     tempal *= tempcl;
+     tempal += ThLowA[tempbx];
+  } else {
+     tempal = ThLowB[tempbx + 1];
+     tempal *= tempcl;
+     tempal += ThLowB[tempbx];
+  }
+  longtemp = tempal * VCLK * colordepth;
+  temp = longtemp % (MCLK * 16);
+  longtemp /= (MCLK * 16);
+  if(temp) longtemp++;
+  return((USHORT)longtemp);
+}
+
+#if 0  /* TW: Old fragment, unused */
 USHORT
-SiS_CalcDelay(UCHAR *ROMAddr,USHORT key)
+SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT key)
 {
   USHORT data,data2,temp0,temp1;
   UCHAR   ThLowA[]=   {61,3,52,5,68,7,100,11,
                        43,3,42,5,54,7, 78,11,
                        34,3,37,5,47,7, 67,11};
+
   UCHAR   ThLowB[]=   {81,4,72,6,88,8,120,12,
                        55,4,54,6,66,8, 90,12,
                        42,4,45,6,55,8, 75,12};
+
   UCHAR   ThTiming[]= {1,2,2,3,0,1,1,2};
 
-  data=SiS_GetReg1(SiS_P3c4,0x16);
+  data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
   data=data>>6;
-  data2=SiS_GetReg1(SiS_P3c4,0x14);
+  data2=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
   data2=(data2>>4)&0x0C;
   data=data|data2;
   data=data<1;
@@ -3570,7 +4300,7 @@
   }
 
   data2=0;
-  data=SiS_GetReg1(SiS_P3c4,0x18);
+  data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
   if(data&0x02) data2=data2|0x01;
   if(data&0x20) data2=data2|0x02;
   if(data&0x40) data2=data2|0x04;
@@ -3580,30 +4310,45 @@
 }
 #endif
 
-#ifdef SIS300
 void
-SiS_SetCRT1FIFO_300(UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+ 		    PSIS_HW_DEVICE_INFO HwDeviceExtension,
                     USHORT RefreshRateTableIndex)
 {
   USHORT  i,index,data,VCLK,MCLK,colorth=0;
   ULONG   B,eax,bl,data2;
   USHORT  ThresholdLow=0;
-  UCHAR   FQBQData[]= { 0x01,0x21,0x41,0x61,0x81,
-                        0x31,0x51,0x71,0x91,0xb1,
-                        0x00,0x20,0x40,0x60,0x80,
-                        0x30,0x50,0x70,0x90,0xb0,0xFF};
+  UCHAR   FQBQData[]= { 
+  	0x01,0x21,0x41,0x61,0x81,
+        0x31,0x51,0x71,0x91,0xb1,
+        0x00,0x20,0x40,0x60,0x80,
+        0x30,0x50,0x70,0x90,0xb0,
+	0xFF
+  };
+  UCHAR   FQBQData730[]= {
+        0x34,0x74,0xb4,
+	0x23,0x63,0xa3,
+	0x12,0x52,0x92,
+	0x01,0x41,0x81,
+	0x00,0x40,0x80,
+	0xff
+  };
 
   i=0;
-  if(ModeNo >= 0x13) {
-    index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-    index &= 0x3F;
-    VCLK = SiS_VCLKData[index].CLOCK;             /* Get VCLK  */
+  if(ModeNo > 0x13) {
+    if(SiS_Pr->UseCustomMode) {
+       VCLK = SiS_Pr->CSRClock;
+    } else {
+       index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+       index &= 0x3F;
+       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;          /* Get VCLK  */
+    }       
 
-    index = SiS_GetReg1(SiS_P3c4,0x1A);
+    index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
     index &= 0x07;
-    MCLK = SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
+    MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
 
-    data2 = SiS_ModeType - ModeEGA;
+    data2 = SiS_Pr->SiS_ModeType - ModeEGA;	  /* Get half colordepth */
     switch (data2) {
         case 0 : colorth = 1; break;
         case 1 : colorth = 1; break;
@@ -3613,295 +4358,501 @@
         case 5 : colorth = 4; break;
     }
 
-    do{
-       B = SiS_CalcDelay2(ROMAddr,FQBQData[i]) * VCLK * colorth;
-       bl = B / (MCLK * 16);
+    if(HwDeviceExtension->jChipType == SIS_730) {
+    
+       do {
+          B = SiS_CalcDelay2(SiS_Pr, ROMAddr, FQBQData730[i], HwDeviceExtension) * VCLK * colorth;
+	  bl = B / (MCLK * 16);
+
+          if(B == bl * 16 * MCLK) {
+             bl = bl + 1;
+          } else {
+             bl = bl + 2;
+          }
 
-       if (B==bl*16*MCLK) {
-         bl = bl + 1;
-       } else {
-         bl = bl + 2;
-       }
+          if(bl > 0x13) {
+             if(FQBQData730[i+1] == 0xFF) {
+                ThresholdLow = 0x13;
+                break;
+             }
+             i++;
+          } else {
+             ThresholdLow = bl;
+             break;
+          }
+       } while(FQBQData730[i] != 0xFF);
+       
+    } else {
+    
+       do {
+          B = SiS_CalcDelay2(SiS_Pr, ROMAddr, FQBQData[i], HwDeviceExtension) * VCLK * colorth;
+          bl = B / (MCLK * 16);
+
+          if(B == bl * 16 * MCLK) {
+             bl = bl + 1;
+          } else {
+             bl = bl + 2;
+          }
 
-       if(bl > 0x13) {
-          if(FQBQData[i+1] == 0xFF) {
-             ThresholdLow = 0x13;
+          if(bl > 0x13) {
+             if(FQBQData[i+1] == 0xFF) {
+                ThresholdLow = 0x13;
+                break;
+             }
+             i++;
+          } else {
+             ThresholdLow = bl;
              break;
           }
-          i++;
-       } else {
-          ThresholdLow = bl;
-          break;
-       }
-    } while(FQBQData[i] != 0xFF);
+       } while(FQBQData[i] != 0xFF);
+    }
   }
   else {
+    if(HwDeviceExtension->jChipType == SIS_730) { 
+    } else {
+      i = 9;
+    }
     ThresholdLow = 0x02;
   }
 
   /* Write foreground and background queue */
-  data2 = FQBQData[i];
-  data2 = (data2 & 0xf0)>>4;
-  data2 <<= 24;
+  if(HwDeviceExtension->jChipType == SIS_730) {  
+   
+     data2 = FQBQData730[i];
+     data2 = (data2 & 0xC0) >> 5;
+     data2 <<= 8;
 
 #ifndef LINUX_XF86
-  SiS_SetReg4(0xcf8,0x80000050);
-  eax = SiS_GetReg3(0xcfc);
-  eax &= 0xf0ffffff;
-  eax |= data2;
-  SiS_SetReg4(0xcfc,eax);
+     SiS_SetReg4(0xcf8,0x80000050);
+     eax = SiS_GetReg3(0xcfc);
+     eax &= 0xfffff9ff;
+     eax |= data2;
+     SiS_SetReg4(0xcfc,eax);
 #else
-  /* We use pci functions X offers. We use pcitag 0, because
-   * we want to read/write to the host bridge (which is always
-   * 00:00.0 on 630, 730 and 540), not the VGA device.
-   */
-  eax = pciReadLong(0x00000000, 0x50);
-  eax &= 0xf0ffffff;
-  eax |= data2;
-  pciWriteLong(0x00000000, 0x50, eax);
+     /* We use pci functions X offers. We use pcitag 0, because
+      * we want to read/write to the host bridge (which is always
+      * 00:00.0 on 630, 730 and 540), not the VGA device.
+      */
+     eax = pciReadLong(0x00000000, 0x50);
+     eax &= 0xfffff9ff;
+     eax |= data2;
+     pciWriteLong(0x00000000, 0x50, eax);
 #endif
 
-  /* TODO: write GUI grant timer (PCI config 0xA3) */
+     /* Write GUI grant timer (PCI config 0xA3) */
+     data2 = FQBQData730[i] << 8;
+     data2 = (data2 & 0x0f00) | ((data2 & 0x3000) >> 8);
+     data2 <<= 20;
+     
+#ifndef LINUX_XF86
+     SiS_SetReg4(0xcf8,0x800000A0);
+     eax = SiS_GetReg3(0xcfc);
+     eax &= 0x00ffffff;
+     eax |= data2;
+     SiS_SetReg4(0xcfc,eax);
+#else
+     eax = pciReadLong(0x00000000, 0xA0);
+     eax &= 0x00ffffff;
+     eax |= data2;
+     pciWriteLong(0x00000000, 0xA0, eax);
+#endif          
+
+  } else {
+  
+     data2 = FQBQData[i];
+     data2 = (data2 & 0xf0) >> 4;
+     data2 <<= 24;
+
+#ifndef LINUX_XF86
+     SiS_SetReg4(0xcf8,0x80000050);
+     eax = SiS_GetReg3(0xcfc);
+     eax &= 0xf0ffffff;
+     eax |= data2;
+     SiS_SetReg4(0xcfc,eax);
+#else
+     eax = pciReadLong(0x00000000, 0x50);
+     eax &= 0xf0ffffff;
+     eax |= data2;
+     pciWriteLong(0x00000000, 0x50, eax);
+#endif
+
+     /* Write GUI grant timer (PCI config 0xA3) */
+     data2 = FQBQData[i];
+     data2 &= 0x0f;
+     data2 <<= 24;
+
+#ifndef LINUX_XF86
+     SiS_SetReg4(0xcf8,0x800000A0);
+     eax = SiS_GetReg3(0xcfc);
+     eax &= 0xf0ffffff;
+     eax |= data2;
+     SiS_SetReg4(0xcfc,eax);
+#else
+     eax = pciReadLong(0x00000000, 0xA0);
+     eax &= 0xf0ffffff;
+     eax |= data2;
+     pciWriteLong(0x00000000, 0xA0, eax);
+#endif
+     
+  }
 
   /* Write CRT/CPU threshold low, CRT/Engine threshold high */
   data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
-  SiS_SetReg1(SiS_P3c4,0x08,data);
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,data);
 
   data = (ThresholdLow & 0x10) << 1;
-  SiS_SetRegANDOR(SiS_P3c4,0x0F,0xDF,data);
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
 
   /* What is this? */
-  SiS_SetReg1(SiS_P3c4,0x3B,0x09);
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3B,0x09);
 
-  /* Write CRT/CPU threshold high */
+  /* Write CRT/CPU threshold high (gap = 3) */
   data = ThresholdLow + 3;
   if(data > 0x0f) data = 0x0f;
-  SiS_SetRegANDOR(SiS_P3c4,0x09,0x80,data);
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
 }
 
 USHORT
-SiS_CalcDelay2(UCHAR *ROMAddr,UCHAR key)
+SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR *ROMAddr,UCHAR key, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT data,index;
-  UCHAR  LatencyFactor[] ={ 97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
-                            00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
-                            97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
-                            00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
-                            80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
-                            00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
-                            86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
-                            00, 68, 66, 59, 57, 37};      /*; 128 bit    BQ=1   */
-
-  index = (key & 0xE0) >> 5;
-  if(key & 0x10) index +=6;
-  if(!(key & 0x01)) index += 24;
-  data = SiS_GetReg1(SiS_P3c4,0x14);
-  if(data & 0x0080) index += 12;
-
-  data = LatencyFactor[index];
+  const UCHAR  LatencyFactor[] = { 
+   	97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
+        00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
+        97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
+        00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
+        80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
+        00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
+        86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
+        00, 68, 66, 59, 57, 37        /*; 128 bit    BQ=1   */
+  };
+  const UCHAR  LatencyFactor730[] = {
+         69, 63, 61, 
+	 86, 79, 77,
+	103, 96, 94,
+	120,113,111,
+	137,130,128,    /* --- Table ends with this entry, data below */
+	137,130,128,	/* to avoid using illegal values              */
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+  };
+
+  if(HwDeviceExtension->jChipType == SIS_730) {
+     index = ((key & 0x0f) * 3) + ((key & 0xC0) >> 6);
+     data = LatencyFactor730[index];
+  } else {			    
+     index = (key & 0xE0) >> 5;
+     if(key & 0x10) index +=6;
+     if(!(key & 0x01)) index += 24;
+     data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+     if(data & 0x0080) index += 12;
+     data = LatencyFactor[index];
+  }
   return(data);
 }
 #endif
 
 /* =============== Autodetection ================ */
+/*             I N C O M P L E T E                */
 
-#ifndef LINUX_XF86
+BOOLEAN
+SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  const USHORT PanelTypeTable300[16] = {
+      0xc101, 0xc117, 0x0121, 0xc135, 0xc142, 0xc152, 0xc162, 0xc072,
+      0xc181, 0xc192, 0xc1a1, 0xc1b6, 0xc1c2, 0xc0d2, 0xc1e2, 0xc1f2
+  };
+  const USHORT PanelTypeTable31030x[16] = {
+      0xc102, 0xc112, 0x0122, 0xc132, 0xc142, 0xc152, 0xc169, 0xc179,
+      0x0189, 0xc192, 0xc1a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+  };
+  const USHORT PanelTypeTable310LVDS[16] = {
+      0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188,
+      0xc199, 0xc0aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+  };
+  USHORT tempax,tempbx,tempah,temp;
+
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+
+    tempax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
+    tempbx = tempax & 0x0F;
+    if(!(tempax & 0x10)){
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
+        tempbx = 0;
+        temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x38);
+        if(temp & 0x40) tempbx |= 0x08;
+        if(temp & 0x20) tempbx |= 0x02;
+        if(temp & 0x01) tempbx |= 0x01;
+        temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x39);
+        if(temp & 0x80) tempbx |= 0x04;
+      } else {
+        return 0;
+      }
+    }
+    tempbx = PanelTypeTable300[tempbx];
+    tempbx |= LCDSync;
+    temp = tempbx & 0x00FF;
+    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
+    temp = (tempbx & 0xFF00) >> 8;
+    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
+
+  } else {
+
+    tempax = tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1a);
+    tempax &= 0x1e;
+    tempax >>= 1;
+    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+       if(tempax == 0) {
+           /* TODO: Include HUGE detection routine
+	            (Probably not worth bothering)
+	    */
+           return 0;
+       }
+       temp = tempax & 0xff;
+       tempax--;
+       tempbx = PanelTypeTable310LVDS[tempax];
+    } else {
+       tempbx = PanelTypeTable31030x[tempax];
+       temp = tempbx & 0xff;
+    }
+    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
+    tempbx = (tempbx & 0xff00) >> 8;
+    temp = tempbx & 0xc1;
+    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
+    if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+       temp = tempbx & 0x04;
+       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x39,0xfb,temp);
+    }
+
+  }
+  return 1;
+}
+
+
+#ifdef LINUXBIOS
 
-/* (ynlai) */
 void
-SiS_DetectMonitor(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+SiS_DetectMonitor(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
 {
-  UCHAR  DAC_TEST_PARMS[]={0x0F,0x0F,0x0F};
-  UCHAR  DAC_CLR_PARMS[]={0x00,0x00,0x00};
+  UCHAR  DAC_TEST_PARMS[] = {0x0F,0x0F,0x0F};
+  UCHAR  DAC_CLR_PARMS[]  = {0x00,0x00,0x00};
   USHORT SR1F;
 
-  SR1F=SiS_GetReg1(SiS_P3c4,0x1F);		/* DAC pedestal */
-  SiS_SetRegANDOR(SiS_P3c4,0x1F,0xFF,0x04);
-  if(SiS_IF_DEF_LVDS==0) {
-    if(SiS_BridgeIsOn(BaseAddr)==0) {    /* TW: Inserted "==0" */
-      SiS_SetReg1(SiS_P3d4,0x30,0x41);
+  SR1F = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);		/* backup DAC pedestal */
+  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1F,0x04);
+
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+    if(!(SiS_BridgeIsOn(SiS_Pr, BaseAddr))) {
+      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x41);
     }
   }
-  /*SiSSetMode(HwDeviceExtension,0x03);  */ /* ynlai InitMode */
 
-  SiSSetMode(HwDeviceExtension,0x2E);   /* alan */
-  SiS_SetReg3(SiS_P3c6,0xff);
-  SiS_ClearDAC(SiS_P3c8);
-  SiS_LongWait();
-  SiS_LongWait();
-  SiS_SetRegANDOR(SiS_P3d4,0x32,0xDF,0x00);
-  if(SiS_TestMonitorType(DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
-    SiS_SetRegANDOR(SiS_P3d4,0x32,0xDF,0x20);
-  }
-  if(SiS_TestMonitorType(DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
-    SiS_SetRegANDOR(SiS_P3d4,0x32,0xDF,0x20);
+  SiSSetMode(SiS_Pr,HwDeviceExtension,0x2E);
+  if(HwDeviceExtension->jChipType >= SIS_650) {
+     /* TW: On 650 only - enable CRT1 */
+     SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
+  }
+  SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+  SiS_ClearDAC(SiS_Pr, SiS_Pr->SiS_P3c8);
+  SiS_LongWait(SiS_Pr);
+  SiS_LongWait(SiS_Pr);
+  SiS_LongWait(SiS_Pr);
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x00);
+  if(SiS_TestMonitorType(SiS_Pr, DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
+    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x20);
+  } else if(SiS_TestMonitorType(SiS_Pr, DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
+    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x20);
   }
-  SiS_TestMonitorType(DAC_CLR_PARMS[0],DAC_CLR_PARMS[1],DAC_CLR_PARMS[2]);
-  SiS_SetReg1(SiS_P3c4,0x1F,SR1F);
+  SiS_TestMonitorType(SiS_Pr, DAC_CLR_PARMS[0],DAC_CLR_PARMS[1],DAC_CLR_PARMS[2]);
+
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,SR1F);
 }
 
 USHORT
-SiS_TestMonitorType(UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC)
+SiS_TestMonitorType(SiS_Private *SiS_Pr, UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC)
 {
    USHORT temp,tempbx;
 
-   tempbx=R_DAC*0x4d+G_DAC*0x97+B_DAC*0x1c;
-   if(tempbx>0x80) tempbx=tempbx+0x100;
-   tempbx = (tempbx&0xFF00)>>8;
+   tempbx = R_DAC * 0x4d + G_DAC * 0x97 + B_DAC * 0x1c;
+   if((tempbx & 0x00ff) > 0x80) tempbx += 0x100;
+   tempbx = (tempbx & 0xFF00) >> 8;
    R_DAC = (UCHAR) tempbx;
    G_DAC = (UCHAR) tempbx;
    B_DAC = (UCHAR) tempbx;
 
-   SiS_SetReg3(SiS_P3c8,0x00);
-   SiS_SetReg3(SiS_P3c9,R_DAC);
-   SiS_SetReg3(SiS_P3c9,G_DAC);
-   SiS_SetReg3(SiS_P3c9,B_DAC);
-   SiS_LongWait();
-   temp=SiS_GetReg2(SiS_P3c2);
-   if(temp&0x10) return(1);
+   SiS_SetReg3(SiS_Pr->SiS_P3c8,0x00);
+   SiS_SetReg3(SiS_Pr->SiS_P3c9,R_DAC);
+   SiS_SetReg3(SiS_Pr->SiS_P3c9,G_DAC);
+   SiS_SetReg3(SiS_Pr->SiS_P3c9,B_DAC);
+   SiS_LongWait(SiS_Pr);
+   temp=SiS_GetReg2(SiS_Pr->SiS_P3c2);
+   if(temp & 0x10) return(1);
    else return(0);
 }
 
-/* ---- test ----- */
 void
-SiS_GetSenseStatus(PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr)
+SiS_GetSenseStatus(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr)
 {
   USHORT tempax=0,tempbx,tempcx,temp;
-  USHORT P2reg0=0,SenseModeNo=0,OutputSelect=*pSiS_OutputSelect;
+  USHORT P2reg0=0,SenseModeNo=0,OutputSelect=*SiS_Pr->pSiS_OutputSelect;
   USHORT ModeIdIndex,i;
   USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
 
-  if(SiS_IF_DEF_LVDS==1){
-    SiS_GetPanelID();
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
+    SiS_GetPanelID(SiS_Pr);
     temp=LCDSense;
-    temp=temp|SiS_SenseCHTV();
+    temp=temp|SiS_SenseCHTV(SiS_Pr);
     tempbx=~(LCDSense|AVIDEOSense|SVIDEOSense);
-    SiS_SetRegANDOR(SiS_P3d4,0x32,tempbx,temp);
+    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,tempbx,temp);
   } else {       /* for 301 */
-    if(SiS_IF_DEF_HiVision==1) {  /* for HiVision */
-      tempax=SiS_GetReg1(SiS_P3c4,0x38);
+    if(SiS_Pr->SiS_IF_DEF_HiVision==1) {  /* for HiVision */
+      tempax=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x38);
       temp=tempax&0x01;
-      tempax=SiS_GetReg1(SiS_P3c4,0x3A);
+      tempax=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
       temp=temp|(tempax&0x02);
-      SiS_SetRegANDOR(SiS_P3d4,0x32,0xA0,temp);
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xA0,temp);
     } else {
-      if(SiS_BridgeIsOn(BaseAddr)==0) {    /* TW: Inserted "==0" */
-        P2reg0 = SiS_GetReg1(SiS_Part2Port,0x00);
-        if(!SiS_BridgeIsEnable(BaseAddr,HwDeviceExtension)) {
+      if(SiS_BridgeIsOn(SiS_Pr, BaseAddr)==0) {    /* TW: Inserted "==0" */
+        P2reg0 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00);
+        if(!(SiS_BridgeIsEnable(SiS_Pr, BaseAddr,HwDeviceExtension))) {
           SenseModeNo=0x2e;
-          temp = SiS_SearchModeID(ROMAddr,&SenseModeNo,&ModeIdIndex);
-          SiS_SetFlag = 0x00;
-          SiS_ModeType = ModeVGA;
-          SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode;
-          SiS_SetCRT2Group301(BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+          temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&SenseModeNo,&ModeIdIndex);
+          SiS_Pr->SiS_SetFlag = 0x00;
+          SiS_Pr->SiS_ModeType = ModeVGA;
+          SiS_Pr->SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode;
+          SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
           for(i=0;i<20;i++) {
-            SiS_LongWait();
+            SiS_LongWait(SiS_Pr);
           }
         }
-        SiS_SetReg1(SiS_Part2Port,0x00,0x1c);
+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,0x1c);
         tempax=0;
-        tempbx=*pSiS_RGBSenseData;
-	if(SiS_Is301B(BaseAddr)){
-                tempbx=*pSiS_RGBSenseData2;
+        tempbx=*SiS_Pr->pSiS_RGBSenseData;
+	if(SiS_Is301B(SiS_Pr, BaseAddr)){
+                tempbx=*SiS_Pr->pSiS_RGBSenseData2;
         }
         tempcx=0x0E08;
-        if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
-          if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+        if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
+          if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
             tempax=tempax|Monitor2Sense;
           }
         }
-        tempbx=*pSiS_YCSenseData;
-        if(SiS_Is301B(BaseAddr)){
-               tempbx=*pSiS_YCSenseData2;
+        tempbx=*SiS_Pr->pSiS_YCSenseData;
+        if(SiS_Is301B(SiS_Pr, BaseAddr)){
+               tempbx=*SiS_Pr->pSiS_YCSenseData2;
         }
         tempcx=0x0604;
-        if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
-          if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
+        if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
+          if(SiS_Sense(SiS_Pr,tempbx,tempcx)){
             tempax=tempax|SVIDEOSense;
           }
         }
 
-        if(OutputSelect&BoardTVType){
-          tempbx=*pSiS_VideoSenseData;
-        if(SiS_Is301B(BaseAddr)){
-             tempbx=*pSiS_VideoSenseData2;
+	if(ROMAddr && SiS_Pr->SiS_UseROM) {
+#ifdef SIS300
+	   if((HwDeviceExtension->jChipType==SIS_630)||
+              (HwDeviceExtension->jChipType==SIS_730)) {
+		OutputSelect = ROMAddr[0xfe];
+	   }
+#endif
+#ifdef SIS315H
+	   if(HwDeviceExtension->jChipType >= SIS_315H) {
+	        OutputSelect = ROMAddr[0xf3];
+		if(HwDeviceExtension->jChipType == SIS_330) {
+		     OutputSelect = ROMAddr[0x11b];
+		}
+	   }
+#endif
         }
-          tempcx=0x0804;
-          if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
-            if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
-              tempax=tempax|AVIDEOSense;
+        if(OutputSelect & BoardTVType){
+          tempbx = *SiS_Pr->pSiS_VideoSenseData;
+          if(SiS_Is301B(SiS_Pr, BaseAddr)){
+             tempbx = *SiS_Pr->pSiS_VideoSenseData2;
+          }
+          tempcx = 0x0804;
+          if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
+            if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
+              tempax |= AVIDEOSense;
             }
           }
         } else {
-          if(!(tempax&SVIDEOSense)){
-            tempbx=*pSiS_VideoSenseData;
-            if(SiS_Is301B(BaseAddr)){
-              tempbx=*pSiS_VideoSenseData2;
+          if(!(tempax & SVIDEOSense)){
+            tempbx = *SiS_Pr->pSiS_VideoSenseData;
+            if(SiS_Is301B(SiS_Pr, BaseAddr)){
+              tempbx = *SiS_Pr->pSiS_VideoSenseData2;
             }
-            tempcx=0x0804;
-            if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
-              if(SiS_Sense(SiS_Part4Port,tempbx,tempcx)){
-                tempax=tempax|AVIDEOSense;
+            tempcx = 0x0804;
+            if(SiS_Sense(SiS_Pr,tempbx,tempcx)){
+              if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
+                tempax |= AVIDEOSense;
               }
             }
           }
         }
       }
 
-      if(SiS_SenseLCD(HwDeviceExtension)){
-        tempax=tempax|LCDSense;
+      if(SiS_SenseLCD(SiS_Pr, HwDeviceExtension)){
+        tempax |= LCDSense;
       }
 
       tempbx=0;
       tempcx=0;
-      SiS_Sense(SiS_Part4Port,tempbx,tempcx);
-  
-      if((SiS_VBType & VB_SIS301LV)||(SiS_VBType & VB_SIS302LV)){
-         tempax &= 0x00ef;   /* 301lv to disable CRT2*/
+      SiS_Sense(SiS_Pr, tempbx,tempcx);
+
+      if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV)) {
+         tempax &= 0x00ef;   /* 30xlv have no VGA2*/
       }
-      SiS_SetRegANDOR(SiS_P3d4,0x32,~0xDF,tempax);
-      SiS_SetReg1(SiS_Part2Port,0x00,P2reg0);
-      if(!(P2reg0&0x20)) {
-        SiS_VBInfo = DisableCRT2Display;
-        SiS_SetCRT2Group301(BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,~0xDF,tempax);
+      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,P2reg0);
+      if(!(P2reg0 & 0x20)) {
+        SiS_Pr->SiS_VBInfo = DisableCRT2Display;
+        SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
       }
     }
   }
 }
 
 BOOLEAN
-SiS_Sense(USHORT Part4Port,USHORT tempbx,USHORT tempcx)
+SiS_Sense(SiS_Private *SiS_Pr, USHORT tempbx,USHORT tempcx)
 {
   USHORT temp,i,tempch;
 
-  temp=tempbx&0xFF;
-  SiS_SetReg1(SiS_Part4Port,0x11,temp);
-  temp=(tempbx&0xFF00)>>8;
-  temp=temp|(tempcx&0x00FF);
-  SiS_SetRegANDOR(SiS_Part4Port,0x10,~0x1F,temp);
-
-  for(i=0;i<10;i++) SiS_LongWait();
-
-  tempch=(tempcx&0x7F00)>>8;      /*   ynlai [05/22/2001]  */
-  temp=SiS_GetReg1(SiS_Part4Port,0x03);
-  temp=temp^(0x0E);
-  temp=temp&tempch;               /*   ynlai [05/22/2001]  */
+  temp = tempbx & 0xFF;
+  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x11,temp);
+  temp = (tempbx & 0xFF00) >> 8;
+  temp |= (tempcx & 0x00FF);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,~0x1F,temp);
+
+  for(i=0; i<10; i++) SiS_LongWait(SiS_Pr);
+
+  tempch = (tempcx & 0x7F00) >> 8;
+  temp = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x03);
+  temp ^= 0x0E;
+  temp &= tempch;
   if(temp>0) return 1;
   else return 0;
 }
 
 USHORT
-SiS_SenseLCD(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SenseLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT temp;
 
-  temp=SiS_GetPanelID();
-  if(!temp)  temp=SiS_GetLCDDDCInfo(HwDeviceExtension);
+  temp=SiS_GetPanelID(SiS_Pr);
+  if(!temp)  temp=SiS_GetLCDDDCInfo(SiS_Pr, HwDeviceExtension);
   return(temp);
 }
 
 BOOLEAN
-SiS_GetLCDDDCInfo(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT temp;
   /*add lcd sense*/
@@ -3909,77 +4860,29 @@
     	return 0;
   else{
      	temp=(USHORT)HwDeviceExtension->ulCRT2LCDType;
-     	SiS_SetReg1(SiS_P3d4,0x36,temp);
+     	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
   	return 1;
   }
 }
 
-BOOLEAN
-SiS_GetPanelID(void)
-{
-  USHORT PanelTypeTable[16]={ SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType00,
-                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType01,
-                              SyncPP | PanelRGB18Bit | Panel800x600  | _PanelType02,
-                              SyncNN | PanelRGB18Bit | Panel640x480  | _PanelType03,
-                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType04,
-                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType05,
-                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType06,
-                              SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType07,
-                              SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType08,
-                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType09,
-                              SyncNN | PanelRGB18Bit | Panel800x600  | _PanelType0A,
-                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0B,
-                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0C,
-                              SyncNN | PanelRGB24Bit | Panel1024x768 | _PanelType0D,
-                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0E,
-                              SyncNN | PanelRGB18Bit | Panel1024x768 | _PanelType0F
-                              };
-  USHORT tempax,tempbx,temp;
-
-  tempax = SiS_GetReg1(SiS_P3c4,0x18);
-  tempbx = tempax & 0x0F;
-  if(!(tempax & 0x10)){
-    if(SiS_IF_DEF_LVDS==1){
-      tempbx = 0;
-      temp = SiS_GetReg1(SiS_P3c4,0x38);
-      if(temp & 0x40) tempbx |= 0x08;
-      if(temp & 0x20) tempbx |= 0x02;
-      if(temp & 0x01) tempbx |= 0x01;
-      temp=SiS_GetReg1(SiS_P3c4,0x39);
-      if(temp & 0x80) tempbx |= 0x04;
-    } else {
-      return 0;
-    }
-  }
-
-  tempbx <<= 1;
-  tempbx = PanelTypeTable[tempbx];
-  tempbx |= LCDSync;
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_P3d4,0x36,temp);
-  temp = (tempbx & 0xFF00) >> 8;
-  SiS_SetRegANDOR(SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
-  return 1;
-}
-
 USHORT
-SiS_SenseCHTV(void)
+SiS_SenseCHTV(SiS_Private *SiS_Pr)
 {
   USHORT temp,push0e,status;
 
   status=0;
-  push0e = SiS_GetCH700x(0x0e);
+  push0e = SiS_GetCH700x(SiS_Pr, 0x0e);
   push0e = (push0e << 8) | 0x0e;
-  SiS_SetCH700x(0x0b0e);
-  SiS_SetCH700x(0x0110);
-  SiS_SetCH700x(0x0010);
-  temp = SiS_GetCH700x(0x10);
+  SiS_SetCH700x(SiS_Pr, 0x0b0e);
+  SiS_SetCH700x(SiS_Pr, 0x0110);
+  SiS_SetCH700x(SiS_Pr, 0x0010);
+  temp = SiS_GetCH700x(SiS_Pr, 0x10);
   if(temp & 0x08) status |= SVIDEOSense;
   if(temp & 0x02) status |= AVIDEOSense;
-  SiS_SetCH700x(push0e);
+  SiS_SetCH700x(SiS_Pr, push0e);
   return(status);
 }
-#endif /* LINUX_XF86 */
+#endif /* LINUXBIOS */
 
 /*  ================ for TC only =================  */
 
@@ -4081,394 +4984,736 @@
     /*ModeNo=0x4A; *//* 1024x768x 16bpp */
     /*ModeNo=0x47;*/ /* 800x600x 16bpp */
   }
- /* SiSInit(&HwDeviceExtension);*/
-  SiSSetMode(&HwDeviceExtension,ModeNo);
+ /* SiSInit(SiS_Pr, &HwDeviceExtension);*/
+  SiSSetMode(SiS_Pr, &HwDeviceExtension, ModeNo);
 }
 #endif /* TC END */
 
-/* ================ LINUX XFREE86 ====================== */
+/* ================ XFREE86 ================= */
+
+/* Helper functions */
 
 #ifdef LINUX_XF86
 USHORT
-SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
+SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
 {
-   UShort i = (pScrn->bitsPerPixel+7)/8 - 1;
-   UShort ModeIndex = 0;
    SISPtr pSiS = SISPTR(pScrn);
+   int    out_n, out_dn, out_div, out_sbit, out_scale;
+   int    depth = pSiS->CurrentLayout.bitsPerPixel;
+   
+#ifdef SISDUALHEAD
+   if( ((!pSiS->DualHeadMode) && (VBFlags & DISPTYPE_DISP2)) ||
+       ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) ) return 0;
+#else      
+   if(VBFlags & DISPTYPE_DISP2) return 0; 
+#endif   
+   
+   pSiS->SiS_Pr->CDClock = mode->Clock;
+   
+   pSiS->SiS_Pr->CHDisplay = mode->HDisplay;
+   pSiS->SiS_Pr->CHSyncStart = mode->HSyncStart;
+   pSiS->SiS_Pr->CHSyncEnd = mode->HSyncEnd;
+   pSiS->SiS_Pr->CHTotal = mode->HTotal;
+   pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
+   pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
+   
+   pSiS->SiS_Pr->CVDisplay = mode->VDisplay;
+   pSiS->SiS_Pr->CVSyncStart = mode->VSyncStart;
+   pSiS->SiS_Pr->CVSyncEnd = mode->VSyncEnd;
+   pSiS->SiS_Pr->CVTotal = mode->VTotal;
+   pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
+   pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
+   
+   pSiS->SiS_Pr->CFlags = mode->Flags;
 
-   switch(mode->HDisplay)
-   {
-     case 320:
-          if(mode->VDisplay == 480) {
-                ModeIndex = ModeIndex_320x480[i];
-	  }
-          break;
-     case 512:
-          if(mode->VDisplay == 384) {
-             ModeIndex = ModeIndex_512x384[i];
-	  }
-          break;
-     case 640:
-          if(mode->VDisplay == 480) {
-             ModeIndex = ModeIndex_640x480[i];
-	  }
-          break;
-     case 720:
-          if(mode->VDisplay == 480) {
-                ModeIndex = ModeIndex_720x480[i];
-          } else if(mode->VDisplay == 576) {
-                ModeIndex = ModeIndex_720x576[i];
-          }
-          break;
-     case 800:
-	  if(mode->VDisplay == 600) {
-             ModeIndex = ModeIndex_800x600[i];
-	  } else if(pSiS->VGAEngine == SIS_315_VGA) {
-	     if(mode->VDisplay == 480) {
-	           ModeIndex = ModeIndex_800x480[i];
-             }
-	  }
-          break;
-     case 1024:
-          if(mode->VDisplay == 768) {
-	        ModeIndex = ModeIndex_1024x768[i];
-	  } else if(pSiS->VGAEngine == SIS_315_VGA) {
-	     if(mode->VDisplay == 576) {
-	        ModeIndex = ModeIndex_1024x576[i];
-             }
-	  } else if(pSiS->VGAEngine == SIS_300_VGA) {
-	     if(mode->VDisplay == 600) {
-	        ModeIndex = ModeIndex_1024x600[i];
-             }
-	  }
-          break;
-     case 1152:
-          if(pSiS->VGAEngine == SIS_300_VGA) {
-	     if(mode->VDisplay == 768) {
-	        ModeIndex = ModeIndex_1152x768[i];
-             }
-	  }
-	  break;
-     case 1280:
-          if(mode->VDisplay == 960) {
-             if(pSiS->VGAEngine == SIS_300_VGA) {
-	        ModeIndex = ModeIndex_300_1280x960[i];
-             } else {
-                ModeIndex = ModeIndex_310_1280x960[i];
-             }
-	  } else if (mode->VDisplay == 1024) {
-	     ModeIndex = ModeIndex_1280x1024[i];
-	  } else if(pSiS->VGAEngine == SIS_315_VGA) {
-	     if (mode->VDisplay == 768) {
-	        ModeIndex = ModeIndex_1280x768[i];
-	     } else if (mode->VDisplay == 720) {
-	        ModeIndex = ModeIndex_1280x720[i];
-             }
-	  }
-          break;
-     case 1400:
-          if(pSiS->VGAEngine == SIS_315_VGA) {
-	     if(mode->VDisplay == 1050) {
-	        ModeIndex = ModeIndex_1400x1050[i];
-             }
-	  }
-          break;
-     case 1600:
-          if(mode->VDisplay == 1200) {
-             ModeIndex = ModeIndex_1600x1200[i];
-	  }
-          break;
-     case 1920:
-          if(mode->VDisplay == 1440) {
-             ModeIndex = ModeIndex_1920x1440[i];
-	  }
-          break;
-     case 2048:
-          if(pSiS->VGAEngine == SIS_315_VGA) {
-	     if(mode->VDisplay == 1536) {
-	         ModeIndex = ModeIndex_2048x1536[i];
-             }
-	  }
-          break;
-   }
+   SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale);
+   
+#ifdef TWDEBUG
+   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
+      	pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
+#endif	
+
+   pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
+   pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
+   pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
+   pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
+   pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
+   pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
+
+   pSiS->SiS_Pr->CCRT1CRTC[0]  =  ((pSiS->SiS_Pr->CHTotal >> 3) - 5) & 0xff;
+   pSiS->SiS_Pr->CCRT1CRTC[1]  =  (pSiS->SiS_Pr->CHDisplay >> 3) - 1;
+   pSiS->SiS_Pr->CCRT1CRTC[2]  =  (pSiS->SiS_Pr->CHBlankStart >> 3) - 1;
+   pSiS->SiS_Pr->CCRT1CRTC[3]  =  (((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
+   pSiS->SiS_Pr->CCRT1CRTC[4]  =  (pSiS->SiS_Pr->CHSyncStart >> 3) + 3;
+   pSiS->SiS_Pr->CCRT1CRTC[5]  =  ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | 
+       				  (((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
+   
+   pSiS->SiS_Pr->CCRT1CRTC[6]  =  (pSiS->SiS_Pr->CVTotal - 2) & 0xFF;
+   pSiS->SiS_Pr->CCRT1CRTC[7]  =  (((pSiS->SiS_Pr->CVTotal - 2) & 0x100) >> 8)
+ 	 			| (((pSiS->SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
+	 			| ((pSiS->SiS_Pr->CVSyncStart & 0x100) >> 6)
+	 			| (((pSiS->SiS_Pr->CVBlankStart - 1) & 0x100) >> 5)
+	 			| 0x10
+	 			| (((pSiS->SiS_Pr->CVTotal - 2) & 0x200)   >> 4)
+	 			| (((pSiS->SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
+	 			| ((pSiS->SiS_Pr->CVSyncStart & 0x200) >> 2);
+    
+   pSiS->SiS_Pr->CCRT1CRTC[16] = ((((pSiS->SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); 	/* cr9 */
+    
+#if 0    
+   if (mode->VScan >= 32)
+	regp->CRTC[9] |= 0x1F;
+   else if (mode->VScan > 1)
+	regp->CRTC[9] |= mode->VScan - 1;
+#endif	
+
+   pSiS->SiS_Pr->CCRT1CRTC[8] =  (pSiS->SiS_Pr->CVSyncStart - 1) & 0xFF;	/* cr10 */
+   pSiS->SiS_Pr->CCRT1CRTC[9] =  ((pSiS->SiS_Pr->CVSyncEnd - 1) & 0x0F) | 0x80;	/* cr11 */
+   pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay - 1) & 0xFF;		/* cr12 */
+   pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF;	/* cr15 */
+   pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd - 1) & 0xFF;		/* cr16 */
+   
+   pSiS->SiS_Pr->CCRT1CRTC[13] = 
+                        GETBITSTR((pSiS->SiS_Pr->CVTotal     -2), 10:10, 0:0) |
+                        GETBITSTR((pSiS->SiS_Pr->CVDisplay   -1), 10:10, 1:1) |
+                        GETBITSTR((pSiS->SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
+                        GETBITSTR((pSiS->SiS_Pr->CVSyncStart   ), 10:10, 3:3) |
+                        GETBITSTR((pSiS->SiS_Pr->CVBlankEnd  -1),   8:8, 4:4) |
+                        GETBITSTR((pSiS->SiS_Pr->CVSyncEnd   -1),   4:4, 5:5) ;  
+
+   pSiS->SiS_Pr->CCRT1CRTC[14] = 
+                        GETBITSTR((pSiS->SiS_Pr->CHTotal      >> 3) - 5, 9:8, 1:0) |
+                        GETBITSTR((pSiS->SiS_Pr->CHDisplay    >> 3) - 1, 9:8, 3:2) |
+                        GETBITSTR((pSiS->SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
+                        GETBITSTR((pSiS->SiS_Pr->CHSyncStart  >> 3) + 3, 9:8, 7:6) ;
+
+        
+   pSiS->SiS_Pr->CCRT1CRTC[15] =
+                        GETBITSTR((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
+                        GETBITSTR((pSiS->SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ; 
+			
+   switch(depth) {
+   case 8: 			
+      	pSiS->SiS_Pr->CModeFlag = 0x223b;
+	break;
+   case 16: 			
+      	pSiS->SiS_Pr->CModeFlag = 0x227d;
+	break;
+   case 32: 			
+      	pSiS->SiS_Pr->CModeFlag = 0x22ff;
+	break;		
+   default: 
+   	return 0;	
+   }	
+   
+   if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) 
+   	pSiS->SiS_Pr->CModeFlag |= DoubleScanMode;
+   if((pSiS->SiS_Pr->CVDisplay >= 1024)	|| 
+      (pSiS->SiS_Pr->CVTotal >= 1024)   || 
+      (pSiS->SiS_Pr->CHDisplay >= 1024))
+	pSiS->SiS_Pr->CModeFlag |= LineCompareOff;
+   if(pSiS->SiS_Pr->CFlags & V_CLKDIV2)
+        pSiS->SiS_Pr->CModeFlag |= HalfDCLK;
+   
+   pSiS->SiS_Pr->CInfoFlag = 0x0007;
+   if(pSiS->SiS_Pr->CFlags & V_NHSYNC) 
+   	pSiS->SiS_Pr->CInfoFlag |= 0x4000;
+   if(pSiS->SiS_Pr->CFlags & V_NVSYNC) 
+   	pSiS->SiS_Pr->CInfoFlag |= 0x8000;
+   if(pSiS->SiS_Pr->CFlags & V_INTERLACE)	
+	pSiS->SiS_Pr->CInfoFlag |= InterlaceMode;
+
+   pSiS->SiS_Pr->UseCustomMode = TRUE;
+#ifdef TWDEBUG
+   xf86DrvMsg(0, X_INFO, "Custom mode %dx%d:\n", 
+   	pSiS->SiS_Pr->CHDisplay,pSiS->SiS_Pr->CVDisplay);
+   xf86DrvMsg(0, X_INFO, "Modeflag %04x, Infoflag %04x\n",
+   	pSiS->SiS_Pr->CModeFlag, pSiS->SiS_Pr->CInfoFlag);
+   xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
+   	pSiS->SiS_Pr->CCRT1CRTC[0],
+	pSiS->SiS_Pr->CCRT1CRTC[1],
+	pSiS->SiS_Pr->CCRT1CRTC[2],
+	pSiS->SiS_Pr->CCRT1CRTC[3],
+	pSiS->SiS_Pr->CCRT1CRTC[4],
+	pSiS->SiS_Pr->CCRT1CRTC[5],
+	pSiS->SiS_Pr->CCRT1CRTC[6],
+	pSiS->SiS_Pr->CCRT1CRTC[7]);
+   xf86DrvMsg(0, X_INFO, "  0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
+   	pSiS->SiS_Pr->CCRT1CRTC[8],
+	pSiS->SiS_Pr->CCRT1CRTC[9],
+	pSiS->SiS_Pr->CCRT1CRTC[10],
+	pSiS->SiS_Pr->CCRT1CRTC[11],
+	pSiS->SiS_Pr->CCRT1CRTC[12],
+	pSiS->SiS_Pr->CCRT1CRTC[13],
+	pSiS->SiS_Pr->CCRT1CRTC[14],
+	pSiS->SiS_Pr->CCRT1CRTC[15]);
+   xf86DrvMsg(0, X_INFO, "  0x%02x}},\n", pSiS->SiS_Pr->CCRT1CRTC[16]);
+   xf86DrvMsg(0, X_INFO, "Clock: 0x%02x, 0x%02x, %d\n",
+   	pSiS->SiS_Pr->CSR2B,
+	pSiS->SiS_Pr->CSR2C,
+	pSiS->SiS_Pr->CSRClock);
+#endif   	
+   return 1;
+}
+
+/* TW: Build a list of supported modes */
+DisplayModePtr
+SiSBuildBuiltInModeList(ScrnInfoPtr pScrn)
+{
+   SISPtr         pSiS = SISPTR(pScrn);
+   unsigned short VRE, VBE, VRS, VBS, VDE, VT;
+   unsigned short HRE, HBE, HRS, HBS, HDE, HT;
+   unsigned char  sr_data, cr_data, cr_data2, cr_data3;
+   unsigned char  sr2b, sr2c;
+   float          num, denum, postscalar, divider;
+   int            A, B, C, D, E, F, temp, i, j, index, vclkindex;
+   DisplayModePtr new = NULL, current = NULL, first = NULL, backup = NULL;
 
-   return(ModeIndex);
-}
+   pSiS->backupmodelist = NULL;
+   
+   /* Initialize our pointers */
+   if(pSiS->VGAEngine == SIS_300_VGA) {
+#ifdef SIS300
+	InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
+#else
+	return NULL;
+#endif
+   } else if(pSiS->VGAEngine == SIS_315_VGA) {
+#ifdef SIS315H
+       	InitTo310Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
+#else
+	return NULL;
+#endif
+   } else return NULL;
 
-USHORT
-SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
-{
-   UShort i = (pScrn->bitsPerPixel+7)/8 - 1;
-   UShort ModeIndex = 0;
-   SISPtr pSiS = SISPTR(pScrn);
+   i = 0;
+   while(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag != 0xFFFF) {
 
-   if(VBFlags & CRT2_LCD) {
+      index = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRT1CRTC;
+#if 0 /* Not any longer */    
+      if(pSiS->VGAEngine == SIS_300_VGA) index &= 0x3F;
+#endif      
+
+      if(((pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) && (!pSiS->DSTN)) ||
+      	 ((pSiS->DSTN) &&
+	  (pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) &&
+	  (pSiS->SiS_Pr->SiS_RefIndex[i].XRes != 320) &&
+	  (pSiS->SiS_Pr->SiS_RefIndex[i].YRes != 480)))  {
+           i++;
+      	   continue;
+      }
+      
+      if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
+      memset(new, 0, sizeof(DisplayModeRec));
+      if(!(new->name = xalloc(10))) {
+      		xfree(new);
+		return first;
+      }
+      if(!first) first = new;
+      if(current) {
+         current->next = new;
+	 new->prev = current;
+      }
 
-      if( (mode->HDisplay <= pSiS->LCDwidth) &&
-          (mode->VDisplay <= pSiS->LCDheight) ) {
+      current = new;
+      
+      sprintf(current->name, "%dx%d", pSiS->SiS_Pr->SiS_RefIndex[i].XRes,
+                                      pSiS->SiS_Pr->SiS_RefIndex[i].YRes);
 
-        if(VBFlags & VB_LVDS) {        		/* LCD on LVDS */
+      current->status = MODE_OK;
 
-          switch(mode->HDisplay)
-  	  {
-	  case 512:
-		if(mode->VDisplay == 384) {
-		   ModeIndex = ModeIndex_512x384[i];
-		}
-		break;
-	  case 640:
-		if(mode->VDisplay == 480) {
-		   ModeIndex = ModeIndex_640x480[i];
-		}
-		break;
-	  case 800:
-		if(mode->VDisplay == 600) {
-		   ModeIndex = ModeIndex_800x600[i];
-		}
-		break;
-	  case 1024:
-		if(mode->VDisplay == 768) {
-		   ModeIndex = ModeIndex_1024x768[i];
-		} else if(pSiS->VGAEngine == SIS_300_VGA) {
-		   if(mode->VDisplay == 600) {
-		      ModeIndex = ModeIndex_1024x600[i];
-		   }
-		}
-		break;
-	  case 1152:
-		if(pSiS->VGAEngine == SIS_300_VGA) {
-		   if(mode->VDisplay == 768) {
-			ModeIndex = ModeIndex_1152x768[i];
-		   }
-		}
-		break;
-	  case 1280:
-		if(mode->VDisplay == 1024) {
-		   ModeIndex = ModeIndex_1280x1024[i];
-		} else if(pSiS->VGAEngine == SIS_315_VGA) {
-		   if(mode->VDisplay == 768) {
-		      ModeIndex = ModeIndex_1280x768[i];
-		   }
-		}
-		break;
-	  case 1400:
-	        if(mode->VDisplay == 1050) {
-		   if(pSiS->VGAEngine == SIS_315_VGA) {
-		      ModeIndex = ModeIndex_1400x1050[i];
-		   }
-		}
-		break;
-          }
+      current->type = M_T_DEFAULT; 
 
-        } else {                       	 	/* LCD on 301(B) */
+      vclkindex = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRTVCLK;
+      if(pSiS->VGAEngine == SIS_300_VGA) vclkindex &= 0x3F;
 
-          switch(mode->HDisplay)
-	  {
-	  case 512:
-		if(mode->VDisplay == 384) {
-		   ModeIndex = ModeIndex_512x384[i];
-		}
-		break;
-	  case 640:
-		if(mode->VDisplay == 480) {
-		   ModeIndex = ModeIndex_640x480[i];
-		}
-		break;
-	  case 800:
-		if(mode->VDisplay == 600) {
-		   ModeIndex = ModeIndex_800x600[i];
-		}
-		break;
-	  case 1024:
-		if(mode->VDisplay == 768) {
-		   ModeIndex = ModeIndex_1024x768[i];
-		} else if(pSiS->VGAEngine == SIS_300_VGA) {
-		   if(mode->VDisplay == 600) {
-			ModeIndex = ModeIndex_1024x600[i];
-		   }
-		}
-		break;
-	  case 1152:  /* ? */
-		if(pSiS->VGAEngine == SIS_300_VGA) {
-		   if(mode->VDisplay == 768) {
-			ModeIndex = ModeIndex_1152x768[i];
-		   }
-		}
-		break;
-	  case 1280:
-		if(mode->VDisplay == 960) {
-		   if(pSiS->VGAEngine == SIS_300_VGA) {
-		      ModeIndex = ModeIndex_300_1280x960[i];
-		   } else {
-		      ModeIndex = ModeIndex_310_1280x960[i];
-		   }
-                } else if (mode->VDisplay == 1024) {
-	             ModeIndex = ModeIndex_1280x1024[i];
-	        }
-	  case 1600:
-		if(mode->VDisplay == 1200) {
-		   ModeIndex = ModeIndex_1600x1200[i];
-		}
-		break;
-	  }
+      sr2b = pSiS->SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+      sr2c = pSiS->SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
 
-        }
+      divider = (sr2b & 0x80) ? 2.0 : 1.0;
+      postscalar = (sr2c & 0x80) ?
+              ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : (((sr2c >> 5) & 0x03) + 1.0);
+      num = (sr2b & 0x7f) + 1.0;
+      denum = (sr2c & 0x1f) + 1.0;
+      
+#ifdef TWDEBUG
+      xf86DrvMsg(0, X_INFO, "------------\n");
+      xf86DrvMsg(0, X_INFO, "sr2b: %x sr2c %x div %f ps %f num %f denum %f\n",
+         sr2b, sr2c, divider, postscalar, num, denum);
+#endif
 
-      }
+      current->Clock = (int)(14318 * (divider / postscalar) * (num / denum));
 
-   } else if(VBFlags & CRT2_TV) {
+      sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[14];
+	/* inSISIDXREG(SISSR, 0x0b, sr_data); */
 
-      if(VBFlags & VB_CHRONTEL) {		/* TV on Chrontel */
+      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[0];
+	/* inSISIDXREG(SISCR, 0x00, cr_data); */
 
-        switch(mode->HDisplay)
-	{
-      	case 512:
-		if(mode->VDisplay == 384) {
-		   ModeIndex = ModeIndex_512x384[i];
-		}
-		break;
-	case 640:
-		if(mode->VDisplay == 480) {
-		   ModeIndex = ModeIndex_640x480[i];
-		}
-		break;
-	case 800:
-		if(mode->VDisplay == 600) {
-		   ModeIndex = ModeIndex_800x600[i];
-		}
-		break;
-	case 1024:
-		if(mode->VDisplay == 768) {
-		   if(pSiS->VGAEngine == SIS_315_VGA) {
-		      ModeIndex = ModeIndex_1024x768[i];
-		   }
-		}
-		break;
-        }
+      /* Horizontal total */
+      HT = (cr_data & 0xff) |
+           ((unsigned short) (sr_data & 0x03) << 8);
+      A = HT + 5;
 
-      } else {				    /* TV on 301(B) */
+      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[1];
+	/* inSISIDXREG(SISCR, 0x01, cr_data); */
 
-        switch(mode->HDisplay)
-	{
-      	case 512:
-		if(mode->VDisplay == 384) {
-		   ModeIndex = ModeIndex_512x384[i];
-		}
-		break;
-	case 640:
-		if(mode->VDisplay == 480) {
-		   ModeIndex = ModeIndex_640x480[i];
-		}
-		break;
-	case 720:
-                if(mode->VDisplay == 480) {
-                   ModeIndex = ModeIndex_720x480[i];
-                } else if(mode->VDisplay == 576) {
-                   ModeIndex = ModeIndex_720x576[i];
-                }
-                break;
-	case 800:
-		if(mode->VDisplay == 600) {
-		   ModeIndex = ModeIndex_800x600[i];
-		}
-		break;
-	case 1024:
-		if(mode->VDisplay == 768) {
-		   if(VBFlags & (VB_301B|VB_301LV|VB_302B|VB_302LV)) {
-		      ModeIndex = ModeIndex_1024x768[i];
-		   }
-		}
-		break;
-        }
+      /* Horizontal display enable end */
+      HDE = (cr_data & 0xff) |
+            ((unsigned short) (sr_data & 0x0C) << 6);
+      E = HDE + 1;
 
-      }
+      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[4];
+	/* inSISIDXREG(SISCR, 0x04, cr_data); */
 
-   } else if(VBFlags & CRT2_VGA) {		/* CRT2 is VGA2 */
+      /* Horizontal retrace (=sync) start */
+      HRS = (cr_data & 0xff) |
+            ((unsigned short) (sr_data & 0xC0) << 2);
+      F = HRS - E - 3;
 
-	switch(mode->HDisplay)
-	{
-	case 512:
-		if(mode->VDisplay == 384) {
-		    ModeIndex = ModeIndex_512x384[i];
-		}
-		break;
-	case 640:
-		if(mode->VDisplay == 480) {
-		   ModeIndex = ModeIndex_640x480[i];
-		}
-		break;
-	case 800:
-		if(mode->VDisplay == 600) {
-		   ModeIndex = ModeIndex_800x600[i];
-		} else if(pSiS->VGAEngine == SIS_315_VGA) {
-		   if(mode->VDisplay == 480) {
-			ModeIndex = ModeIndex_800x480[i];
-		   }
-		}
-		break;
-	case 1024:
-		if(mode->VDisplay == 768) {
-			ModeIndex = ModeIndex_1024x768[i];
-		} else if(pSiS->VGAEngine == SIS_315_VGA) {
-		   if(mode->VDisplay == 576) {
-			ModeIndex = ModeIndex_1024x576[i];
-		   }
-		}
-		break;
-	case 1152:
-		if(pSiS->VGAEngine == SIS_300_VGA) {
-		   if(mode->VDisplay == 768) {
-			ModeIndex = ModeIndex_1152x768[i];
-		   }
-		}
-		break;
-	case 1280:
-		if (mode->VDisplay == 1024) {
-		   ModeIndex = ModeIndex_1280x1024[i];
-		} else if(pSiS->VGAEngine == SIS_315_VGA) {
-		   if (mode->VDisplay == 768) {
-			ModeIndex = ModeIndex_1280x768[i];
-		   } else if (mode->VDisplay == 720) {
-			ModeIndex = ModeIndex_1280x720[i];
-		   }
-		}
-		break;
-	case 1400:
-		if(pSiS->VGAEngine == SIS_315_VGA) {
-		   ModeIndex = ModeIndex_1400x1050[i];
-		}
-		break;
-	}
+      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[2];
+	/* inSISIDXREG(SISCR, 0x02, cr_data); */
 
-   } else {				/* CRT1 only, no CRT2 */
+      /* Horizontal blank start */
+      HBS = (cr_data & 0xff) |
+            ((unsigned short) (sr_data & 0x30) << 4);
 
-       ModeIndex = SiS_CalcModeIndex(pScrn, mode);
+      sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[15];
+	/* inSISIDXREG(SISSR, 0x0c, sr_data); */
 
-   }
+      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[3];
+	/* inSISIDXREG(SISCR, 0x03, cr_data);  */
 
-   return(ModeIndex);
-}
+      cr_data2 = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[5];
+	/* inSISIDXREG(SISCR, 0x05, cr_data2); */
 
-#define MODEID_OFF 0x449
+      /* Horizontal blank end */
+      HBE = (cr_data & 0x1f) |
+            ((unsigned short) (cr_data2 & 0x80) >> 2) |
+	    ((unsigned short) (sr_data & 0x03) << 6);
 
-unsigned char
-SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id)
-{
-    unsigned char ret;
+      /* Horizontal retrace (=sync) end */
+      HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
+
+      temp = HBE - ((E - 1) & 255);
+      B = (temp > 0) ? temp : (temp + 256);
+
+      temp = HRE - ((E + F + 3) & 63);
+      C = (temp > 0) ? temp : (temp + 64);
+
+      D = B - F - C;
 
-    unsigned char* base = xf86MapVidMem(pScrn->scrnIndex,
-					VIDMEM_MMIO, 0, 0x2000);
-    ret = *(base + MODEID_OFF);
+      current->HDisplay   = (E * 8);
+      current->HSyncStart = (E * 8) + (F * 8);
+      current->HSyncEnd   = (E * 8) + (F * 8) + (C * 8);
+      current->HTotal     = (E * 8) + (F * 8) + (C * 8) + (D * 8);
 
-    /* id != 0xff means: set mode */
-    if (id != 0xff)
-	*(base + MODEID_OFF) = id;
-    xf86UnMapVidMem(pScrn->scrnIndex,base,0x2000);
+#ifdef TWDEBUG
+      xf86DrvMsg(0, X_INFO,
+        "H: A %d B %d C %d D %d E %d F %d  HT %d HDE %d HRS %d HBS %d HBE %d HRE %d\n",
+      	A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE);
+#endif
+
+      sr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[13];
+	/* inSISIDXREG(SISSR, 0x0A, sr_data); */
+
+      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[6];
+        /* inSISIDXREG(SISCR, 0x06, cr_data); */
+
+      cr_data2 = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[7];
+        /* inSISIDXREG(SISCR, 0x07, cr_data2);  */
+
+      /* Vertical total */
+      VT = (cr_data & 0xFF) |
+           ((unsigned short) (cr_data2 & 0x01) << 8) |
+	   ((unsigned short)(cr_data2 & 0x20) << 4) |
+	   ((unsigned short) (sr_data & 0x01) << 10);
+      A = VT + 2;
+
+      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[10];
+	/* inSISIDXREG(SISCR, 0x12, cr_data);  */
+
+      /* Vertical display enable end */
+      VDE = (cr_data & 0xff) |
+            ((unsigned short) (cr_data2 & 0x02) << 7) |
+	    ((unsigned short) (cr_data2 & 0x40) << 3) |
+	    ((unsigned short) (sr_data & 0x02) << 9);
+      E = VDE + 1;
+
+      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[8];
+	/* inSISIDXREG(SISCR, 0x10, cr_data); */
+
+      /* Vertical retrace (=sync) start */
+      VRS = (cr_data & 0xff) |
+            ((unsigned short) (cr_data2 & 0x04) << 6) |
+	    ((unsigned short) (cr_data2 & 0x80) << 2) |
+	    ((unsigned short) (sr_data & 0x08) << 7);
+      F = VRS + 1 - E;
+
+      cr_data =  pSiS->SiS_Pr->SiS_CRT1Table[index].CR[11];
+	/* inSISIDXREG(SISCR, 0x15, cr_data);  */
+
+      cr_data3 = (pSiS->SiS_Pr->SiS_CRT1Table[index].CR[16] & 0x01) << 5;
+	/* inSISIDXREG(SISCR, 0x09, cr_data3);  */
+
+      /* Vertical blank start */
+      VBS = (cr_data & 0xff) |
+            ((unsigned short) (cr_data2 & 0x08) << 5) |
+	    ((unsigned short) (cr_data3 & 0x20) << 4) |
+	    ((unsigned short) (sr_data & 0x04) << 8);
+
+      cr_data =  pSiS->SiS_Pr->SiS_CRT1Table[index].CR[12];
+	/* inSISIDXREG(SISCR, 0x16, cr_data); */
+
+      /* Vertical blank end */
+      VBE = (cr_data & 0xff) |
+            ((unsigned short) (sr_data & 0x10) << 4);
+      temp = VBE - ((E - 1) & 511);
+      B = (temp > 0) ? temp : (temp + 512);
+
+      cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[9];
+	/* inSISIDXREG(SISCR, 0x11, cr_data); */
+
+      /* Vertical retrace (=sync) end */
+      VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
+      temp = VRE - ((E + F - 1) & 31);
+      C = (temp > 0) ? temp : (temp + 32);
+
+      D = B - F - C;
+
+      current->VDisplay   = VDE + 1;
+      current->VSyncStart = VRS + 1;
+      current->VSyncEnd   = ((VRS & ~0x1f) | VRE) + 1;
+      if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32;
+      current->VTotal     = E + D + C + F;
+
+#if 0
+      current->VDisplay   = E;
+      current->VSyncStart = E + D;
+      current->VSyncEnd   = E + D + C;
+      current->VTotal     = E + D + C + F;
+#endif
+
+#ifdef TWDEBUG
+      xf86DrvMsg(0, X_INFO,
+        "V: A %d B %d C %d D %d E %d F %d  VT %d VDE %d VRS %d VBS %d VBE %d VRE %d\n",
+      	A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE);
+#endif
+
+      if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x4000)
+          current->Flags |= V_NHSYNC;
+      else
+          current->Flags |= V_PHSYNC;
+
+      if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x8000)
+      	  current->Flags |= V_NVSYNC;
+      else
+          current->Flags |= V_PVSYNC;
+
+      if(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag & 0x0080)
+          current->Flags |= V_INTERLACE;
+
+      j = 0;
+      while(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
+          if(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
+	                  pSiS->SiS_Pr->SiS_RefIndex[i].ModeID) {
+              if(pSiS->SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
+	      	  current->Flags |= V_DBLSCAN;
+              }
+	      break;
+          }
+	  j++;
+      }
+
+      if(current->Flags & V_INTERLACE) {
+         current->VDisplay <<= 1;
+	 current->VSyncStart <<= 1;
+	 current->VSyncEnd <<= 1;
+	 current->VTotal <<= 1;
+	 current->VTotal |= 1; 
+      }
+      if(current->Flags & V_DBLSCAN) {
+         current->Clock >>= 1;
+	 current->VDisplay >>= 1;
+	 current->VSyncStart >>= 1;
+	 current->VSyncEnd >>= 1;
+	 current->VTotal >>= 1;
+      }
+
+      if((backup = xalloc(sizeof(DisplayModeRec)))) {
+         if(!pSiS->backupmodelist) pSiS->backupmodelist = backup;
+	 else {
+	    pSiS->backupmodelist->next = backup;
+	    backup->prev = pSiS->backupmodelist;
+	 }
+	 backup->next = NULL;
+	 backup->HDisplay = current->HDisplay;
+         backup->HSyncStart = current->HSyncStart;
+         backup->HSyncEnd = current->HSyncEnd;
+         backup->HTotal = current->HTotal;
+         backup->VDisplay = current->VDisplay;
+         backup->VSyncStart = current->VSyncStart;
+         backup->VSyncEnd = current->VSyncEnd;
+         backup->VTotal = current->VTotal;
+	 backup->Flags = current->Flags;
+	 backup->Clock = current->Clock;
+      }
+
+#ifdef TWDEBUG
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+      	"Built-in: %s %.2f %d %d %d %d %d %d %d %d\n",
+	current->name, (float)current->Clock / 1000,
+	current->HDisplay, current->HSyncStart, current->HSyncEnd, current->HTotal,
+	current->VDisplay, current->VSyncStart, current->VSyncEnd, current->VTotal);
+#endif
+
+      i++;
+   }
+
+   return first;
 
-    return ret;
 }
+#endif
 
+#ifdef LINUX_KERNEL
+int
+sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+			  unsigned char modeno, unsigned char rateindex)
+{
+    USHORT ModeNo = modeno;
+    USHORT ModeIdIndex = 0, ClockIndex = 0;
+    USHORT RefreshRateTableIndex = 0;
+    UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
+    ULONG  temp = 0;
+    int    Clock;
+    
+    if(HwDeviceExtension->jChipType < SIS_315H) {
+#ifdef SIS300
+       InitTo300Pointer(SiS_Pr, HwDeviceExtension);
+#else
+       return 65;
 #endif
+    } else {
+#ifdef SIS315H
+       InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+#else
+       return 65;
+#endif
+    }
+    
+    temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex);
+    if(!temp) {
+    	printk(KERN_ERR "Could not find mode %x\n", ModeNo);
+    	return 65;
+    }
+    
+    RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+    RefreshRateTableIndex += (rateindex - 1);
+    ClockIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+    if(HwDeviceExtension->jChipType < SIS_315H) {
+       ClockIndex &= 0x3F;
+    }
+    Clock = SiS_Pr->SiS_VCLKData[ClockIndex].CLOCK * 1000 * 1000;
+    
+    return(Clock);
+}
 
+int
+sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+			 unsigned char modeno, unsigned char rateindex,
+			 ULONG *left_margin, ULONG *right_margin, 
+			 ULONG *upper_margin, ULONG *lower_margin,
+			 ULONG *hsync_len, ULONG *vsync_len,
+			 ULONG *sync, ULONG *vmode)
+{
+    USHORT ModeNo = modeno;
+    USHORT ModeIdIndex = 0, index = 0;
+    USHORT RefreshRateTableIndex = 0;
+    UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
+    unsigned short VRE, VBE, VRS, VBS, VDE, VT;
+    unsigned short HRE, HBE, HRS, HBS, HDE, HT;
+    unsigned char  sr_data, cr_data, cr_data2, cr_data3;
+    int            A, B, C, D, E, F, temp, j;
+   
+    if(HwDeviceExtension->jChipType < SIS_315H) {
+#ifdef SIS300
+       InitTo300Pointer(SiS_Pr, HwDeviceExtension);
+#else
+       return 0;
+#endif
+    } else {
+#ifdef SIS315H
+       InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+#else
+       return 0;
+#endif
+    }
+    
+    temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex);
+    if(!temp) return 0;
+    
+    RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+    RefreshRateTableIndex += (rateindex - 1);
+    index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+
+    sr_data = SiS_Pr->SiS_CRT1Table[index].CR[14];
+
+    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[0];
+
+    /* Horizontal total */
+    HT = (cr_data & 0xff) |
+         ((unsigned short) (sr_data & 0x03) << 8);
+    A = HT + 5;
+
+    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[1];
+	
+    /* Horizontal display enable end */
+    HDE = (cr_data & 0xff) |
+          ((unsigned short) (sr_data & 0x0C) << 6);
+    E = HDE + 1;
+
+    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[4];
+	
+    /* Horizontal retrace (=sync) start */
+    HRS = (cr_data & 0xff) |
+          ((unsigned short) (sr_data & 0xC0) << 2);
+    F = HRS - E - 3;
+
+    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[2];
+	
+    /* Horizontal blank start */
+    HBS = (cr_data & 0xff) |
+          ((unsigned short) (sr_data & 0x30) << 4);
+
+    sr_data = SiS_Pr->SiS_CRT1Table[index].CR[15];
+	
+    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[3];
+
+    cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[5];
+	
+    /* Horizontal blank end */
+    HBE = (cr_data & 0x1f) |
+          ((unsigned short) (cr_data2 & 0x80) >> 2) |
+	  ((unsigned short) (sr_data & 0x03) << 6);
+
+    /* Horizontal retrace (=sync) end */
+    HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
+
+    temp = HBE - ((E - 1) & 255);
+    B = (temp > 0) ? temp : (temp + 256);
+
+    temp = HRE - ((E + F + 3) & 63);
+    C = (temp > 0) ? temp : (temp + 64);
+
+    D = B - F - C;
+    
+    *left_margin = D * 8;
+    *right_margin = F * 8;
+    *hsync_len = C * 8;
+
+    sr_data = SiS_Pr->SiS_CRT1Table[index].CR[13];
+
+    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[6];
+    
+    cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[7];
+    
+    /* Vertical total */
+    VT = (cr_data & 0xFF) |
+         ((unsigned short) (cr_data2 & 0x01) << 8) |
+	 ((unsigned short)(cr_data2 & 0x20) << 4) |
+	 ((unsigned short) (sr_data & 0x01) << 10);
+    A = VT + 2;
+
+    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[10];
+	
+    /* Vertical display enable end */
+    VDE = (cr_data & 0xff) |
+          ((unsigned short) (cr_data2 & 0x02) << 7) |
+	  ((unsigned short) (cr_data2 & 0x40) << 3) |
+	  ((unsigned short) (sr_data & 0x02) << 9);
+    E = VDE + 1;
+
+    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[8];
+
+    /* Vertical retrace (=sync) start */
+    VRS = (cr_data & 0xff) |
+          ((unsigned short) (cr_data2 & 0x04) << 6) |
+	  ((unsigned short) (cr_data2 & 0x80) << 2) |
+	  ((unsigned short) (sr_data & 0x08) << 7);
+    F = VRS + 1 - E;
+
+    cr_data =  SiS_Pr->SiS_CRT1Table[index].CR[11];
+
+    cr_data3 = (SiS_Pr->SiS_CRT1Table[index].CR[16] & 0x01) << 5;
+
+    /* Vertical blank start */
+    VBS = (cr_data & 0xff) |
+          ((unsigned short) (cr_data2 & 0x08) << 5) |
+	  ((unsigned short) (cr_data3 & 0x20) << 4) |
+	  ((unsigned short) (sr_data & 0x04) << 8);
+
+    cr_data =  SiS_Pr->SiS_CRT1Table[index].CR[12];
+
+    /* Vertical blank end */
+    VBE = (cr_data & 0xff) |
+          ((unsigned short) (sr_data & 0x10) << 4);
+    temp = VBE - ((E - 1) & 511);
+    B = (temp > 0) ? temp : (temp + 512);
+
+    cr_data = SiS_Pr->SiS_CRT1Table[index].CR[9];
+
+    /* Vertical retrace (=sync) end */
+    VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
+    temp = VRE - ((E + F - 1) & 31);
+    C = (temp > 0) ? temp : (temp + 32);
+
+    D = B - F - C;
+      
+    *upper_margin = D;
+    *lower_margin = F;
+    *vsync_len = C;
+
+    if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
+       *sync &= ~FB_SYNC_VERT_HIGH_ACT;
+    else
+       *sync |= FB_SYNC_VERT_HIGH_ACT;
+
+    if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)       
+       *sync &= ~FB_SYNC_HOR_HIGH_ACT;
+    else
+       *sync |= FB_SYNC_HOR_HIGH_ACT;
+		
+    *vmode = FB_VMODE_NONINTERLACED;       
+    if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
+       *vmode = FB_VMODE_INTERLACED;
+    else {
+      j = 0;
+      while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
+          if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
+	                  SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID) {
+              if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
+	      	  *vmode = FB_VMODE_DOUBLE;
+              }
+	      break;
+          }
+	  j++;
+      }
+    }       
+       
+#if 0  /* That's bullshit, only the resolution needs to be shifted */    
+    if((*vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+       *upper_margin <<= 1;
+       *lower_margin <<= 1;
+       *vsync_len <<= 1;
+    } else if((*vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+       *upper_margin >>= 1;
+       *lower_margin >>= 1;
+       *vsync_len >>= 1;
+    }  
+#endif
+          
+    return 1;       
+}			  
 
+#endif
 
diff -Nru a/drivers/video/sis/init.h b/drivers/video/sis/init.h
--- a/drivers/video/sis/init.h	Thu Jul 11 10:30:30 2002
+++ b/drivers/video/sis/init.h	Fri Mar  7 11:19:01 2003
@@ -24,9 +24,16 @@
 #endif
 
 #ifdef LINUX_KERNEL
+#include <linux/config.h>
+#include <linux/version.h>
 #include <linux/types.h>
 #include <asm/io.h>
+#include <linux/fb.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 #include <linux/sisfb.h>
+#else
+#include <video/sisfb.h>
+#endif
 #endif
 
 #ifdef WIN2000
@@ -42,7 +49,7 @@
 #include "tools.h"
 #endif
 
-USHORT SiS_DRAMType[17][5]={
+const USHORT SiS_DRAMType[17][5]={
 	{0x0C,0x0A,0x02,0x40,0x39},
 	{0x0D,0x0A,0x01,0x40,0x48},
 	{0x0C,0x09,0x02,0x20,0x35},
@@ -62,7 +69,7 @@
 	{0x09,0x08,0x01,0x01,0x00}
 };
 
-USHORT SiS_SDRDRAM_TYPE[13][5] =
+const USHORT SiS_SDRDRAM_TYPE[13][5] =
 {
 	{ 2,12, 9,64,0x35},
 	{ 1,13, 9,64,0x44},
@@ -79,7 +86,7 @@
 	{ 1, 9, 8, 2,0x00}
 };
 
-USHORT SiS_DDRDRAM_TYPE[4][5] =
+const USHORT SiS_DDRDRAM_TYPE[4][5] =
 {
 	{ 2,12, 9,64,0x35},
 	{ 2,12, 8,32,0x31},
@@ -87,9 +94,7 @@
 	{ 2, 9, 8, 4,0x01}
 };
 
-UCHAR SiS_ChannelAB, SiS_DataBusWidth;
-
-USHORT SiS_MDA_DAC[] =
+const USHORT SiS_MDA_DAC[] =
 {
 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
@@ -101,7 +106,7 @@
         0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F
 };
 
-USHORT SiS_CGA_DAC[] =
+const USHORT SiS_CGA_DAC[] =
 {
         0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
         0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
@@ -113,7 +118,7 @@
         0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
 };
 
-USHORT SiS_EGA_DAC[] =
+const USHORT SiS_EGA_DAC[] =
 {
         0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15,
         0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35,
@@ -125,7 +130,7 @@
         0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F
 };
 
-USHORT SiS_VGA_DAC[] =
+const USHORT SiS_VGA_DAC[] =
 {
 	0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15,
 	0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F,
@@ -139,195 +144,188 @@
 	0x0B,0x0C,0x0D,0x0F,0x10
 };
 
-USHORT   SiS_P3c4,SiS_P3d4,SiS_P3c0,SiS_P3ce,SiS_P3c2;
-USHORT   SiS_P3ca,SiS_P3c6,SiS_P3c7,SiS_P3c8,SiS_P3c9,SiS_P3da;
-USHORT   SiS_Part1Port,SiS_Part2Port;
-USHORT   SiS_Part3Port,SiS_Part4Port,SiS_Part5Port;
-USHORT   SiS_CRT1Mode;
-
-USHORT   flag_clearbuffer;
-int      SiS_RAMType;
-USHORT   SiS_ModeType;
-USHORT   SiS_IF_DEF_LVDS, SiS_IF_DEF_TRUMPION, SiS_IF_DEF_DSTN, SiS_IF_DEF_FSTN;
-USHORT   SiS_IF_DEF_CH70xx, SiS_IF_DEF_HiVision;
-USHORT	 SiS_Backup70xx=0xff;
-USHORT   SiS_VBInfo, SiS_LCDResInfo, SiS_LCDTypeInfo, SiS_LCDInfo, SiS_VBType;
-USHORT   SiS_VBExtInfo, SiS_HiVision;
-USHORT   SiS_SelectCRT2Rate;
-
-extern   USHORT   SiS_SetFlag;
-extern   USHORT   SiS_DDC_Port;
-extern   USHORT   Panel800x600,  Panel1024x768,  Panel1280x1024, Panel1600x1200;
-extern   USHORT   Panel1280x960, Panel1400x1050, Panel320x480,   Panel1152x768;
-extern   USHORT   Panel1152x864, Panel1280x768,  Panel1024x600,  Panel640x480;
-extern   USHORT   PanelMinLVDS,  PanelMin301,    PanelMax;
-extern   USHORT   SiS_ChrontelInit;
-
 void     SiS_SetReg1(USHORT, USHORT, USHORT);
-void     SiS_SetReg2(USHORT, USHORT, USHORT);
+void     SiS_SetReg2(SiS_Private *, USHORT, USHORT, USHORT);
 void     SiS_SetReg3(USHORT, USHORT);
 void     SiS_SetReg4(USHORT, ULONG);
+void     SiS_SetReg5(USHORT, USHORT);
 UCHAR    SiS_GetReg1(USHORT, USHORT);
 UCHAR    SiS_GetReg2(USHORT);
 ULONG    SiS_GetReg3(USHORT);
-void     SiS_ClearDAC(ULONG);
-void     SiS_SetMemoryClock(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetDRAMModeRegister(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN  SiS_SearchVBModeID(UCHAR *ROMAddr, USHORT *ModeNo);
-void     SiS_IsLowResolution(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-ULONG    GetDRAMSize(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT   SiS_GetReg4(USHORT);
+void     SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG);
+void     SiS_SetMemoryClock(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN  SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo);
+void     SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
 
 #ifdef SIS300
-void     InitTo300Pointer(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetDRAMSize_300(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT   SiS_ChkBUSWidth_300(ULONG FBAddress);
+void     SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT   SiS_ChkBUSWidth_300(SiS_Private *SiS_Pr, ULONG FBAddress);
 #endif
 
 #ifdef SIS315H
-void     InitTo310Pointer(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-UCHAR    SiS_Get310DRAMType(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_DDR_MRS(void);
-void     SiS_SDR_MRS(void);
-void     SiS_DisableRefresh(void);
-void     SiS_EnableRefresh(UCHAR *ROMAddr);
-void     SiS_SetDRAMSize_310(PSIS_HW_DEVICE_INFO);
-void     SiS_DisableChannelInterleaving(int index,USHORT SiS_DDRDRAM_TYPE[][5]);
-void     SiS_SetDRAMSizingType(int index,USHORT DRAMTYPE_TABLE[][5]);
-void     SiS_CheckBusWidth_310(UCHAR *ROMAddress,ULONG FBAddress,
+UCHAR    SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_DDR_MRS(SiS_Private *SiS_Pr);
+void     SiS_SDR_MRS(SiS_Private *SiS_Pr);
+void     SiS_DisableRefresh(SiS_Private *SiS_Pr);
+void     SiS_EnableRefresh(SiS_Private *SiS_Pr, UCHAR *ROMAddr);
+void     SiS_SetDRAMSize_310(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO);
+void     SiS_DisableChannelInterleaving(SiS_Private *SiS_Pr, int index,USHORT SiS_DDRDRAM_TYPE[][5]);
+void     SiS_SetDRAMSizingType(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5]);
+void     SiS_CheckBusWidth_310(SiS_Private *SiS_Pr, UCHAR *ROMAddress,ULONG FBAddress,
                                PSIS_HW_DEVICE_INFO HwDeviceExtension);
-int      SiS_SetRank(int index,UCHAR RankNo,UCHAR SiS_ChannelAB,USHORT DRAMTYPE_TABLE[][5]);
-int      SiS_SetDDRChannel(int index,UCHAR ChannelNo,UCHAR SiS_ChannelAB,
+int      SiS_SetRank(SiS_Private *SiS_Pr, int index,UCHAR RankNo,USHORT DRAMTYPE_TABLE[][5]);
+int      SiS_SetDDRChannel(SiS_Private *SiS_Pr, int index,UCHAR ChannelNo,
                            USHORT DRAMTYPE_TABLE[][5]);
-int      SiS_CheckColumn(int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
-int      SiS_CheckBanks(int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
-int      SiS_CheckRank(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
-int      SiS_CheckDDRRank(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
-int      SiS_CheckRanks(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
-int      SiS_CheckDDRRanks(int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
-int      SiS_SDRSizing(ULONG FBAddress);
-int      SiS_DDRSizing(ULONG FBAddress);
-int      Is315E(void);
-void     SiS_VerifyMclk(ULONG FBAddr);
+int      SiS_CheckColumn(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int      SiS_CheckBanks(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int      SiS_CheckRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int      SiS_CheckDDRRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int      SiS_CheckRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int      SiS_CheckDDRRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
+int      SiS_SDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress);
+int      SiS_DDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress);
+int      Is315E(SiS_Private *SiS_Pr);
+void     SiS_VerifyMclk(SiS_Private *SiS_Pr, ULONG FBAddr);
 #endif
 
-void     SetEnableDstn(void);
-void     SiS_Delay15us(ULONG);
-BOOLEAN  SiS_SearchModeID(UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
-BOOLEAN  SiS_CheckMemorySize(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+void     SiS_HandleCRT1(SiS_Private *SiS_Pr);
+void     SiS_Handle301B_1400x1050(SiS_Private *SiS_Pr, USHORT ModeNo);
+void     SiS_SetEnableDstn(SiS_Private *SiS_Pr);
+void     SiS_Delay15us(SiS_Private *SiS_Pr);
+BOOLEAN  SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
+BOOLEAN  SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
                              USHORT ModeNo,USHORT ModeIdIndex);
-UCHAR    SiS_GetModePtr(UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
-void     SiS_SetSeqRegs(UCHAR *ROMAddr,USHORT StandTableIndex);
-void     SiS_SetMiscRegs(UCHAR *ROMAddr,USHORT StandTableIndex);
-void     SiS_SetCRTCRegs(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+UCHAR    SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
+void     SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
+void     SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
                          USHORT StandTableIndex);
-void     SiS_SetATTRegs(UCHAR *ROMAddr,USHORT StandTableIndex,USHORT ModeNo,
+void     SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex,
                         PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetGRCRegs(UCHAR *ROMAddr,USHORT StandTableIndex);
-void     SiS_ClearExt1Regs(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetSync(UCHAR *ROMAddr,USHORT RefreshRateTableIndex);
-void     SiS_SetCRT1CRTC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+void     SiS_SetGRCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
+void     SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetSync(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT RefreshRateTableIndex);
+void     SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                          USHORT RefreshRateTableIndex,
 			 PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_ResetCRT1VCLK(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetCRT1VCLK(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO,
+BOOLEAN  SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                            USHORT RefreshRateTableIndex,USHORT *ResInfo,USHORT *DisplayType);
+void     SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO,
                          USHORT RefreshRateTableIndex);
-void     SiS_SetVCLKState(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO, USHORT ModeNo,
+void     SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO, USHORT ModeNo,
                           USHORT RefreshRateTableIndex, USHORT ModeIdIndex);
-void     SiS_LoadDAC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void     SiS_DisplayOn(void);
-void 	 SiS_DisplayOff(void);
-void     SiS_SetCRT1ModeRegs(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO,USHORT ModeNo,
+void     SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_WriteDAC(SiS_Private *SiS_Pr, USHORT, USHORT, USHORT, USHORT, USHORT, USHORT);
+void     SiS_DisplayOn(SiS_Private *SiS_Pr);
+void 	 SiS_DisplayOff(SiS_Private *SiS_Pr);
+void     SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO,USHORT ModeNo,
                              USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
-void     SiS_WriteDAC(USHORT, USHORT, USHORT, USHORT);
-void     SiS_GetVBType(USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
-USHORT   SiS_ChkBUSWidth(UCHAR *ROMAddr);
-USHORT   SiS_GetModeIDLength(UCHAR *ROMAddr, USHORT);
-USHORT   SiS_GetRefindexLength(UCHAR *ROMAddr, USHORT);
-void     SiS_SetInterlace(UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex);
-USHORT   SiS_CalcDelay2(UCHAR *ROMAddr, UCHAR);
-USHORT   SiS_CalcDelay(UCHAR *ROMAddr, USHORT);
-void     SiS_Set_LVDS_TRUMPION(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetCRT1Offset(UCHAR *ROMAddr,USHORT,USHORT,USHORT,PSIS_HW_DEVICE_INFO);
+void     SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
+USHORT   SiS_ChkBUSWidth(SiS_Private *SiS_Pr, UCHAR *ROMAddr);
+USHORT   SiS_GetModeIDLength(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT);
+USHORT   SiS_GetRefindexLength(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT);
+void     SiS_SetInterlace(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex);
+void     SiS_Set_LVDS_TRUMPION(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT1Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT,USHORT,USHORT,PSIS_HW_DEVICE_INFO);
 #ifdef SIS315H
-void     SiS_SetCRT1FIFO_310(UCHAR *ROMAddr,USHORT,USHORT,PSIS_HW_DEVICE_INFO);
+void     SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT,USHORT,PSIS_HW_DEVICE_INFO);
 #endif
 #ifdef SIS300
-void     SiS_SetCRT1FIFO_300(UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO,
+void     SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO,
+                             USHORT RefreshRateTableIndex);
+void     SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO,
                              USHORT RefreshRateTableIndex);
+USHORT   SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT VCLK,
+                       USHORT colordepth, USHORT MCLK);
+USHORT   SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key);
+USHORT   SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, UCHAR,PSIS_HW_DEVICE_INFO HwDeviceExtension);
 #endif
-void     SiS_ClearBuffer(PSIS_HW_DEVICE_INFO,USHORT ModeNo);
-void     SiS_SetCRT1Group(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+void     SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT ModeNo);
+void     SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
                           USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr);
-void     SiS_DetectMonitor(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
-void     SiS_GetSenseStatus(PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr);
-USHORT   SiS_TestMonitorType(UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC);
-USHORT   SiS_SenseCHTV(VOID);
-BOOLEAN  SiS_Sense(USHORT Part4Port,USHORT tempbx,USHORT tempcx);
-BOOLEAN  SiS_GetPanelID(VOID);
-BOOLEAN  SiS_GetLCDDDCInfo(PSIS_HW_DEVICE_INFO);
-USHORT   SiS_SenseLCD(PSIS_HW_DEVICE_INFO);
-void     SiSRegInit(USHORT BaseAddr);
-void     SiSInitPtr(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiSSetLVDSetc(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo);
-void     SiSInitPCIetc(PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_DetectMonitor(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+void     SiS_GetSenseStatus(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr);
+USHORT   SiS_TestMonitorType(SiS_Private *SiS_Pr, UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC);
+USHORT   SiS_SenseCHTV(SiS_Private *SiS_Pr);
+BOOLEAN  SiS_Sense(SiS_Private *SiS_Pr, USHORT tempbx,USHORT tempcx);
+BOOLEAN  SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO);
+BOOLEAN  SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO);
+USHORT   SiS_SenseLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO);
+void     SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr);
+void     SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo);
+void     SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr);
 
 #ifdef LINUX_XF86
-USHORT  	SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
-USHORT  	SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
-void    	SiS_SetPitch(ScrnInfoPtr pScrn, UShort BaseAddr);
-void    	SiS_SetPitchCRT1(ScrnInfoPtr pScrn, UShort BaseAddr);
-void    	SiS_SetPitchCRT2(ScrnInfoPtr pScrn, UShort BaseAddr);
-unsigned char 	SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
+USHORT 		SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
+void    	SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr);
+void    	SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr);
+void    	SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr);
+extern int      SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
+	     	 		    int *out_sbit, int *out_scale);
+extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value);
+extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
+extern USHORT 	     SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
 #endif
 
-extern USHORT    SiS_GetOffset(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+extern USHORT    SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                        USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern USHORT    SiS_GetColorDepth(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-extern void      SiS_DisableBridge(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-extern BOOLEAN   SiS_SetCRT2Group301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+extern USHORT    SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+extern void      SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+extern BOOLEAN   SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
                                      PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void      SiS_PresetScratchregister(USHORT SiS_P3d4,
+extern void      SiS_PresetScratchregister(SiS_Private *SiS_Pr, USHORT SiS_P3d4,
                                            PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void      SiS_UnLockCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
-extern void      SiS_LockCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
-extern BOOLEAN   SiS_BridgeIsOn(USHORT BaseAddr);
-extern BOOLEAN   SiS_BridgeIsEnable(USHORT BaseAddr,PSIS_HW_DEVICE_INFO );
-extern void      SiS_SetTVSystem301(VOID);
-extern BOOLEAN   SiS_GetLCDDDCInfo301(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN   SiS_GetSenseStatus301(PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                                       USHORT BaseAddr,UCHAR *ROMAddr);
-extern USHORT    SiS_GetVCLKLen(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN   SiS_SetCRT2Group302(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                                     PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void      SiS_GetVBInfo301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                                  USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN   SiS_GetLCDResInfo301(UCHAR *ROMAddr,USHORT P3d4,USHORT ModeNo,
-                                      USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void      SiS_SetHiVision(USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-/* extern USHORT  SiS_VBInfo,LCDResInfo,LCDTypeInfo,LCDInfo; */  /* TW: redundant */
-extern USHORT    SiS_GetRatePtrCRT2(UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
-extern void      SiS_LongWait(VOID);
+extern void      SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+extern void      SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
+extern BOOLEAN   SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr);
+extern BOOLEAN   SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO );
+extern void      SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                               USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension, int chkcrt2mode);
+extern BOOLEAN   SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+                                   USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void      SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern USHORT    SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+                                    PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern void      SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo);
+extern void      SiS_LongWait(SiS_Private *SiS_Pr);
 extern void      SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR);
 extern void      SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND);
 extern void      SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR);
-extern USHORT    SiS_GetResInfo(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-extern void      SiS_SetCH700x(USHORT tempax);
-extern USHORT    SiS_GetCH700x(USHORT tempax);
-extern void      SiS_SetCH701x(USHORT tempax);
-extern USHORT    SiS_GetCH701x(USHORT tempax);
-extern void      SiS_SetCH70xx(USHORT tempax);
-extern USHORT    SiS_GetCH70xx(USHORT tempax);
-extern BOOLEAN   SiS_GetLVDSCRT1Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                                    USHORT RefreshRateTableIndex,
-		                    USHORT *ResInfo,USHORT *DisplayType);
-extern BOOLEAN   SiS_GetLCDACRT1Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+extern USHORT    SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+extern void      SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
+extern USHORT    SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
+extern void      SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
+extern USHORT    SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
+extern void      SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
+extern USHORT    SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
+extern BOOLEAN   SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                                     USHORT RefreshRateTableIndex,
 		                    USHORT *ResInfo,USHORT *DisplayType);
-extern USHORT    SiS_GetVCLK2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+extern USHORT    SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                                  USHORT RefreshRateTableIndex,
 				 PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN   SiS_Is301B(USHORT BaseAddr);
-extern BOOLEAN   SiS_LowModeStuff(USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN   SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr);
+extern BOOLEAN   SiS_IsM650(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+extern BOOLEAN   SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN   SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+extern BOOLEAN   SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+extern USHORT    SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+#ifdef LINUX_KERNEL
+int    sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+			      unsigned char modeno, unsigned char rateindex);
+int    sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+			 unsigned char modeno, unsigned char rateindex,
+			 ULONG *left_margin, ULONG *right_margin, 
+			 ULONG *upper_margin, ULONG *lower_margin,
+			 ULONG *hsync_len, ULONG *vsync_len,
+			 ULONG *sync, ULONG *vmode);
+#endif
 
 #endif
 
diff -Nru a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
--- a/drivers/video/sis/init301.c	Thu Jul 11 10:30:30 2002
+++ b/drivers/video/sis/init301.c	Fri Mar  7 11:19:01 2003
@@ -1,17 +1,27 @@
 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.3 2002/22/04 01:16:16 dawes Exp $ */
 /*
- * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740
+ * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740/330
  * (Universal module for Linux kernel framebuffer, XFree86 4.x)
  *
  * Assembler-To-C translation
- * Parts Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net>
+ * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net>
+ * Minor parts Copyright SiS, Inc.
  *
  * Based on BIOS
- *     1.10.07, 1.10a for SiS650/LVDS+CH7019
- *     1.07.1b for SiS650/301(B/LV)
- *     2.04.50 (I) and 2.04.5c (II) for SiS630/301(B)
- *     2.02.3b, 2.03.02, 2.04.2c and 2.04.5c for 630/LVDS/LVDS+CH7005
+ *     1.10.07, 1.10a for 650/CH7019
+ *     1.11.21a for 740/CH7019
+ *     1.11.05 for 650/LVDS (w/o Chrontel)
+ *     1.07.1b, 1.10.6s, 1.11.6w, 1.11.7w, 1.11.8r for 650/301(B/LV), 650/302LV
+ *     2.04.50 (I) and 2.04.5c (II) for 630/301(B)
+ *     2.02.3b, 2.03.02, 2.04.2c, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
+ *     2.04.5c, 2.04.6c for 730+LVDS+CH7005
  *     1.09b for 315/301(B)
+ *     1.16.51 for 300+301LV (ECS A907)
+ *     1.01.03 for 330 (Xabre 400)
+ *
+ * Known bugs:
+ *   1024x768 panel, expanding (CR37=1): Mode 640x480 does not work on SOME panels
+ *       therefore, we always do the scaling ourselves for now.
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -31,16 +41,24 @@
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  *
+ * TW says: This code looks awful, I know. But please don't do anything about
+ * this otherwise debugging will be hell.
+ * The code is extremely fragile as regards the different chipsets, different
+ * video bridges and combinations thereof. If anything is changed, extreme
+ * care has to be taken that that change doesn't break it for other chipsets,
+ * bridges or combinations thereof.
+ * All comments in this file are by me, regardless if they are marked TW or not.
+ *
  */
+ 
+#if 1 
+#define NEWCH701x
+#endif
 
 #include "init301.h"
 
 #if 0
-#define TWPANEL
-#endif
-
-#if 0	/* TW: Emulate 650/LVDS BIOS 1.10a (1) or 1.10.07 (0) */
-#define TEST1400
+#define TWNEWPANEL
 #endif
 
 #ifdef SIS300
@@ -51,289 +69,335 @@
 #include "oem310.h"
 #endif
 
-#define SiS_I2CDELAY 1000
-#define SiS_I2CDELAYSHORT 333
+#define SiS_I2CDELAY      1000
+#define SiS_I2CDELAYSHORT  150
 
 BOOLEAN
-SiS_SetCRT2Group301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
                     PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
    USHORT ModeIdIndex;
    USHORT RefreshRateTableIndex;
 
-   SiS_SetFlag |= ProgrammingCRT2;
+   SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
 
-   SiS_SearchModeID(ROMAddr,&ModeNo,&ModeIdIndex);
+   if(!SiS_Pr->UseCustomMode) {
+      SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
+   } else {
+      ModeIdIndex = 0;
+   }      
 
    /* TW: Used for shifting CR33 */
-   SiS_SelectCRT2Rate = 4;
+   SiS_Pr->SiS_SelectCRT2Rate = 4;
 
-   SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
 
-   RefreshRateTableIndex = SiS_GetRatePtrCRT2(ROMAddr,ModeNo,ModeIdIndex);
+   RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
 
-   SiS_SaveCRT2Info(ModeNo);
+   SiS_SaveCRT2Info(SiS_Pr,ModeNo);
 
-   if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
-      SiS_DisableBridge(HwDeviceExtension,BaseAddr);
-      SiS_SetCRT2ModeRegs(BaseAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+      SiS_DisableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
+      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwDeviceExtension->jChipType == SIS_730)) {
+         SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,0x80);
+      }
+      SiS_SetCRT2ModeRegs(SiS_Pr,BaseAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
    }
 
-   if(SiS_VBInfo & DisableCRT2Display) {
-      SiS_LockCRT2(HwDeviceExtension, BaseAddr);
-      SiS_DisplayOn();
-      return(FALSE);
+   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+      SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+      SiS_DisplayOn(SiS_Pr);
+      return(TRUE);
    }
 
-   SiS_GetCRT2Data(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+   if(SiS_Pr->UseCustomMode) return(FALSE);
+   
+   SiS_GetCRT2Data(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                    HwDeviceExtension);
 
-   /* LVDS, 650/301LV(LCDA) and 630/301B BIOS set up Panel Link */
-   if((SiS_IF_DEF_LVDS == 1) || (SiS_VBType & VB_SIS301BLV302BLV)) {
-   	SiS_GetLVDSDesData(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+   /* Set up Panel Link for LVDS, 301BDH and 650/30xLV(for LCDA) */
+   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
+       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
+       ((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
+   	SiS_GetLVDSDesData(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
 	                   HwDeviceExtension);
+   } else {
+        SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
    }
 
-   if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
-      SiS_SetGroup1(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+#ifdef LINUX_XF86
+#ifdef TWDEBUG
+  xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
+  xf86DrvMsg(0, X_INFO, "(init301: HDE     0x%03x VDE     0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
+  xf86DrvMsg(0, X_INFO, "(init301: VGAHDE  0x%03x VGAVDE  0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
+  xf86DrvMsg(0, X_INFO, "(init301: HT      0x%03x VT      0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
+  xf86DrvMsg(0, X_INFO, "(init301: VGAHT   0x%03x VGAVT   0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
+#endif
+#endif
+
+   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+      SiS_SetGroup1(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
                     HwDeviceExtension,RefreshRateTableIndex);
    }
 
-   if( (SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo & SetCRT2ToLCDA) ) {
-
-     	if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV))
-	      	SiS_SetReg1(SiS_Part4Port,0x24,0x0e);
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-   } else if((SiS_IF_DEF_LVDS == 0) && (!(SiS_VBInfo & SetCRT2ToLCDA))) {
+        if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
 
-        if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
-
-	   SiS_SetGroup2(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	              RefreshRateTableIndex,HwDeviceExtension);
-      	   SiS_SetGroup3(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	              HwDeviceExtension);
-      	   SiS_SetGroup4(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	              RefreshRateTableIndex,HwDeviceExtension);
-      	   SiS_SetGroup5(BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-
-	   /* TW: 630/301B BIOS does all this: */
-	   if(HwDeviceExtension->jChipType < SIS_315H) {
-	      if(SiS_VBType & VB_SIS301BLV302BLV) {
-	         if(SiS_VBInfo & SetCRT2ToLCD) {
-		    if(SiS_LCDResInfo != Panel640x480) {
-		       SiS_ModCRT1CRTC(ROMAddr,ModeNo,ModeIdIndex,
+	   SiS_SetGroup2(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	                 RefreshRateTableIndex,HwDeviceExtension);
+      	   SiS_SetGroup3(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	                 HwDeviceExtension);
+      	   SiS_SetGroup4(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	                 RefreshRateTableIndex,HwDeviceExtension);
+      	   SiS_SetGroup5(SiS_Pr,HwDeviceExtension, BaseAddr,ROMAddr,
+	                 ModeNo,ModeIdIndex);
+
+	   /* TW: For 301BDH (Panel link initialization): */
+	   if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {	 
+		 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo = 0x10)))) {
+		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+		       SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
 		                       RefreshRateTableIndex,HwDeviceExtension);
-                    }
-		    SiS_SetCRT2ECLK(ROMAddr,ModeNo,ModeIdIndex,
-		                    RefreshRateTableIndex,HwDeviceExtension);
-		 }
-              }
+		    }
+                 }
+	      }
+	      SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+		              RefreshRateTableIndex,HwDeviceExtension);
 	   }
-
         }
 
    } else {
 
-        if(SiS_LCDResInfo != Panel640x480) {
-	        if (SiS_IF_DEF_TRUMPION == 0) {
-    	 	        SiS_ModCRT1CRTC(ROMAddr,ModeNo,ModeIdIndex,
-		                        RefreshRateTableIndex,HwDeviceExtension);
-	        }
+        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+	   if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+    	      SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+	                      RefreshRateTableIndex,HwDeviceExtension);
+	   }
 	}
-        if(SiS_IF_DEF_FSTN == 0) {
-     	 	SiS_SetCRT2ECLK(ROMAddr,ModeNo,ModeIdIndex,
-		          RefreshRateTableIndex,HwDeviceExtension);
-	}
-	if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
-     	  if(SiS_IF_DEF_CH70xx != 0) {
-	     /* TW: Inserted from 650/LVDS BIOS */
-	     if (SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-	        if(SiS_IF_DEF_CH70xx == 2) {
-		    SiS_SetCHTVForLCD(HwDeviceExtension,BaseAddr);
-		}
-	     }
-	     if(SiS_VBInfo & SetCRT2ToTV) {
-	        /* TW: Set Chrontel registers only if CRT2 is TV */
-       		SiS_SetCHTVReg(ROMAddr,ModeNo,ModeIdIndex,
+        if(SiS_Pr->SiS_IF_DEF_FSTN == 0) {
+     	   SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+	 	           RefreshRateTableIndex,HwDeviceExtension);
+	}
+	if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+     	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+	      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+	         if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+#ifdef SIS315H		 
+		    SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
+#endif		    
+		 }
+	      }
+	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+       		 SiS_SetCHTVReg(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
 		               RefreshRateTableIndex);
-	     }
-     	  }
+	      }
+     	   }
 	}
 
    }
 
 #ifdef SIS300
-   if ( (HwDeviceExtension->jChipType==SIS_540)||
-        (HwDeviceExtension->jChipType==SIS_630)||
-        (HwDeviceExtension->jChipType==SIS_730)||
-        (HwDeviceExtension->jChipType==SIS_300) )
+   if ( (HwDeviceExtension->jChipType == SIS_540) ||
+        (HwDeviceExtension->jChipType == SIS_630) ||
+        (HwDeviceExtension->jChipType == SIS_730) ||
+        (HwDeviceExtension->jChipType == SIS_300) )
     {
-	if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
-       	   SiS_OEM300Setting(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+	if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+	   if(SiS_Pr->SiS_UseOEM) {
+	      if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
+	         if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+	            SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+	         }
+	      } else {
+       	         SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+	      }
+	   }
 	}
     }
 #endif
 
 #ifdef SIS315H
-   if ( (HwDeviceExtension->jChipType==SIS_315H)||
-        (HwDeviceExtension->jChipType==SIS_315PRO)||
-        (HwDeviceExtension->jChipType==SIS_550) ||
-        (HwDeviceExtension->jChipType==SIS_640) ||
-        (HwDeviceExtension->jChipType==SIS_740) ||
-        (HwDeviceExtension->jChipType==SIS_650))
+   if ( (HwDeviceExtension->jChipType == SIS_315H)  ||
+        (HwDeviceExtension->jChipType == SIS_315)   ||
+	(HwDeviceExtension->jChipType == SIS_315PRO)||
+        (HwDeviceExtension->jChipType == SIS_550)   ||
+        (HwDeviceExtension->jChipType == SIS_740)   ||
+        (HwDeviceExtension->jChipType == SIS_650)   ||
+	(HwDeviceExtension->jChipType == SIS_330) )
    {
-        if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
-	   SiS_OEMLCD(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-           SiS_OEM310Setting(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-           SiS_CRT2AutoThreshold(BaseAddr);
+        if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+	   SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);
+#if 0      /* Instead of FinalizeLCD(), older BIOSes (A92x) used OEMLCD() */
+	   SiS_OEMLCD(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+#endif
+           if(SiS_Pr->SiS_UseOEM) {
+              SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+           }
+           SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr);
         }
    }
 #endif
 
-   if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
-      SiS_DisplayOn();
-      SiS_EnableBridge(HwDeviceExtension,BaseAddr);
+   if(HwDeviceExtension->jChipType < SIS_315H) {
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+          if(HwDeviceExtension->jChipType != SIS_730) {
+             SiS_DisplayOn(SiS_Pr);
+	  }
+      }
    }
 
-   if(SiS_IF_DEF_CH70xx == 1) {
-	if(SiS_VBInfo & SetCRT2ToTV) {
+   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+         if(HwDeviceExtension->jChipType == SIS_730) {
+            SiS_DisplayOn(SiS_Pr);
+	 }
+      }
+      SiS_EnableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
+   }
+
+   SiS_DisplayOn(SiS_Pr);
+
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
 	     /* TW: Disable LCD panel when using TV */
-	     SiS_SetRegOR(SiS_P3c4,0x11,0x0C);
+	     SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C);
 	} else {
 	     /* TW: Disable TV when using LCD */
-	     SiS_SetCH70xxANDOR(0x010E,0xF8);
+	     SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
 	}
    }
 
-   SiS_DisplayOn();
-
-   if(SiS_LowModeStuff(ModeNo,HwDeviceExtension)) {
-      SiS_LockCRT2(HwDeviceExtension, BaseAddr);
+   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+      SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
    }
 
    return 1;
 }
 
-/* TW: Checked with 650/LVDS (1.10.07) and 630+301B/LVDS BIOS */
 BOOLEAN
-SiS_LowModeStuff(USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,
+                 PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
     USHORT temp,temp1,temp2;
 
     if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
          return(1);
-    temp = SiS_GetReg1(SiS_P3d4,0x11);
-    SiS_SetRegOR(SiS_P3d4,0x11,0x80);
-    temp1 = SiS_GetReg1(SiS_P3d4,0x00);
-    SiS_SetReg1(SiS_P3d4,0x00,0x55);
-    temp2 = SiS_GetReg1(SiS_P3d4,0x00);
-    SiS_SetReg1(SiS_P3d4,0x00,temp1);
-    SiS_SetReg1(SiS_P3d4,0x11,temp);
-    if(HwDeviceExtension->jChipType >= SIS_315H) {
+    temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x11);
+    SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
+    temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00);
+    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,0x55);
+    temp2 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00);
+    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,temp1);
+    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x11,temp);
+    if((HwDeviceExtension->jChipType >= SIS_315H) ||
+       (HwDeviceExtension->jChipType == SIS_300)) {
        if(temp2 == 0x55) return(0);
        else return(1);
     } else {
        if(temp2 != 0x55) return(1);
        else {
-          SiS_SetRegOR(SiS_P3d4,0x35,0x01);
+          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
           return(0);
        }
     }
 }
 
 /* TW: Set Part1 registers */
-/* TW: Checked with 650/LVDS (1.10.07), 650/301LV (II) and 630/301B (II) BIOS */
 void
-SiS_SetGroup1(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-              PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
+SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+              USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+	      USHORT RefreshRateTableIndex)
 {
-  USHORT  temp=0,tempax=0,tempbx=0,tempcx=0,tempbl=0;
-  USHORT  pushbx=0,CRT1Index=0;
-  USHORT  modeflag,resinfo=0;
+  USHORT  temp=0, tempax=0, tempbx=0, tempcx=0;
+  USHORT  pushbx=0, CRT1Index=0;
+#ifdef SIS315H
+  USHORT  pushcx=0, tempbl=0;
+#endif
+  USHORT  modeflag, resinfo=0;
 
   if(ModeNo<=0x13) {
-	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   } else {
-    	CRT1Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
-  /* TW: Removed 301B301LV.. check here; LCDA exists with LVDS as well */
-  if(SiS_VBInfo & SetCRT2ToLCDA) {
-
-	   /* TW: From 650/LVDS BIOS; 301(B+LV) version does not set Sync  */
-	   if (SiS_IF_DEF_LVDS == 1) {
-	       SiS_SetCRT2Sync(BaseAddr,ROMAddr,ModeNo,
-                               RefreshRateTableIndex,HwDeviceExtension);
-	   }
-
-	   SiS_SetGroup1_LCDA(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-     	                   HwDeviceExtension,RefreshRateTableIndex);
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
 
+	   SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
+                           RefreshRateTableIndex,HwDeviceExtension);
+#ifdef SIS315H
+	   SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+     	                      HwDeviceExtension,RefreshRateTableIndex);
+#endif
   } else {
 
      if( (HwDeviceExtension->jChipType >= SIS_315H) &&
-         (SiS_IF_DEF_LVDS == 1) &&
-	 (SiS_VBInfo & SetInSlaveMode)) {
+         (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
+	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
 
-        SiS_SetCRT2Sync(BaseAddr,ROMAddr,ModeNo,
+        SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
                         RefreshRateTableIndex,HwDeviceExtension);
 
      } else {
 
-        SiS_SetCRT2Offset(SiS_Part1Port,ROMAddr,ModeNo,ModeIdIndex,
-      		       RefreshRateTableIndex,HwDeviceExtension);
+        SiS_SetCRT2Offset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+      		          RefreshRateTableIndex,HwDeviceExtension);
 
         if (HwDeviceExtension->jChipType < SIS_315H ) {
 #ifdef SIS300
-    	      SiS_SetCRT2FIFO_300(ROMAddr,ModeNo,HwDeviceExtension);
+    	      SiS_SetCRT2FIFO_300(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension);
 #endif
         } else {
 #ifdef SIS315H
-              SiS_SetCRT2FIFO_310(ROMAddr,ModeNo,HwDeviceExtension);
+              SiS_SetCRT2FIFO_310(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension);
 #endif
 	}
 
-        SiS_SetCRT2Sync(BaseAddr,ROMAddr,ModeNo,
+        SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
                         RefreshRateTableIndex,HwDeviceExtension);
 
 	/* 1. Horizontal setup */
 
         if (HwDeviceExtension->jChipType < SIS_315H ) {
 
-                /* ------------- 300 series --------------*/
+#ifdef SIS300   /* ------------- 300 series --------------*/
 
-    		temp = (SiS_VGAHT - 1) & 0x0FF;   			/* BTVGA2HT 0x08,0x09 */
-    		SiS_SetReg1(SiS_Part1Port,0x08,temp);                   /* TW: CRT2 Horizontal Total */
+    		temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   			/* BTVGA2HT 0x08,0x09 */
+    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                   /* TW: CRT2 Horizontal Total */
 
-    		temp = (((SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
-    		SiS_SetRegANDOR(SiS_Part1Port,0x09,0x0f,temp);          /* TW: CRT2 Horizontal Total Overflow [7:4] */
+    		temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
+    		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);          /* TW: CRT2 Horizontal Total Overflow [7:4] */
 
-    		temp = (SiS_VGAHDE + 12) & 0x0FF;                       /* BTVGA2HDEE 0x0A,0x0C */
-    		SiS_SetReg1(SiS_Part1Port,0x0A,temp);                   /* TW: CRT2 Horizontal Display Enable End */
+    		temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                       /* BTVGA2HDEE 0x0A,0x0C */
+    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                   /* TW: CRT2 Horizontal Display Enable End */
 
-    		pushbx = SiS_VGAHDE + 12;                               /* bx  BTVGA@HRS 0x0B,0x0C */
-    		tempcx = (SiS_VGAHT - SiS_VGAHDE) >> 2;
+    		pushbx = SiS_Pr->SiS_VGAHDE + 12;                               /* bx  BTVGA@HRS 0x0B,0x0C */
+    		tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
     		tempbx = pushbx + tempcx;
     		tempcx <<= 1;
     		tempcx += tempbx;
 
-    		if(SiS_IF_DEF_LVDS == 0) {
-      			if(SiS_VBInfo & SetCRT2ToRAMDAC){
-			        CRT1Index &= 0x3F;
-        			tempbx = SiS_CRT1Table[CRT1Index].CR[4];
-        			tempbx |= ((SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
+    		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+      			if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+			        /* CRT1Index &= 0x3F; - Not any longer */
+        			tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+        			tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
         			tempbx = (tempbx - 1) << 3;
-        			tempcx = SiS_CRT1Table[CRT1Index].CR[5];
+        			tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
         			tempcx &= 0x1F;
-        			temp = SiS_CRT1Table[CRT1Index].CR[15];
+        			temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
         			temp = (temp & 0x04) << (6-2);
-        			tempcx = ((tempcx | temp) - 1) << 3;
+        			tempcx = (tempcx | temp);
+				tempcx--;
+				tempcx <<= 3;
       			}
 
-    			if((SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
-        			if(!(SiS_VBInfo & SetPALTV)){
+    			if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
+        			if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
       					tempbx = 1040;
       					tempcx = 1042;
       				}
@@ -341,101 +405,99 @@
 	        }
 
     		temp = tempbx & 0x00FF;
-    		SiS_SetReg1(SiS_Part1Port,0x0B,temp);                   /* TW: CRT2 Horizontal Retrace Start */
+    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* TW: CRT2 Horizontal Retrace Start */
+#endif /* SIS300 */
 
  	} else {
 
-     	   /* ---------------------- 310 series ------------------*/    /* (BIOS label Gr1_301) */
+#ifdef SIS315H  /* ----------------- 310/325/330 series ------------- */
 
-     	   if (modeflag & HalfDCLK) {  /* for low resolution modes */
-
-         	temp = ((SiS_VGAHT / 2) - 1) & 0xFF;                    /* BTVGA2HT 0x08,0x09 */
-         	SiS_SetReg1(SiS_Part1Port,0x08,temp);                   /* TW: CRT2 Horizontal Total */
-
-		temp = ((((SiS_VGAHT / 2) - 1) & 0xFF00) >> 8) << 4;
-        	SiS_SetRegANDOR(SiS_Part1Port,0x09,0x0F,temp);        /* TW: CRT2 Horizontal Total Overflow [7:4] */
-
-         	temp = ((SiS_VGAHDE / 2) + 16) & 0xFF;                  /* BTVGA2HDEE 0x0A,0x0C */
-         	SiS_SetReg1(SiS_Part1Port,0x0A,temp);                   /* TW: CRT2 Horizontal Display Enable End */
-
-         	pushbx = (SiS_VGAHDE / 2) + 16;
-         	tempcx = ((SiS_VGAHT - SiS_VGAHDE) / 2) >> 2;           /* cx */
-		if(SiS_IF_DEF_LVDS == 1)
-		           tempcx >>= 1;    /* TW: From LVDS 1.10.07; not done on 301(LV) */
-         	tempbx = pushbx + tempcx;                               /* bx  BTVGA@HRS 0x0B,0x0C */
-         	tempcx += tempbx;
-
-         	if(SiS_IF_DEF_LVDS == 0) {
-                   if(SiS_VBInfo & SetCRT2ToRAMDAC){
-                	tempbx = SiS_CRT1Table[CRT1Index].CR[4];
-                	tempbx |= ((SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
-                	tempbx = (tempbx - 3) << 3;         		/*(VGAHRS-3)*8 */
-                	tempcx = SiS_CRT1Table[CRT1Index].CR[5];
-               		tempcx &= 0x1F;
-                	temp = SiS_CRT1Table[CRT1Index].CR[15];
-                	temp = (temp & 0x04) << (5-2);      		/* VGAHRE D[5]  */
-                	tempcx =((tempcx | temp) - 3) << 3;    		/* (VGAHRE-3)*8 */
-             	   }
-                   /* TW: The following is not done in 650/LVDS BIOS  */
-         	   tempbx += 4;
-         	   tempcx += 4;
+	        tempcx = SiS_Pr->SiS_VGAHT;				       /* BTVGA2HT 0x08,0x09 */
+		pushcx = tempcx;
+		if(modeflag & HalfDCLK) {
+#ifndef NEWCH701x		
+		    if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_IF_DEF_CH70xx == 0)) {
+#endif		    
+		          tempax = SiS_Pr->SiS_VGAHDE >> 1;
+			  tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
+			  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+			      tempcx = SiS_Pr->SiS_HT - tempax;
+			  }
+#ifndef NEWCH701x					  
+		    } else {
+			  tempcx >>= 1;
+		    }
+#endif		    
+		}
+		tempcx--;
 
-         	   if (tempcx > (SiS_VGAHT / 2))
-              		   tempcx = SiS_VGAHT / 2;
-         	}
+		temp = tempcx & 0xff;
+		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* TW: CRT2 Horizontal Total */
 
-                temp = tempbx & 0x00FF;
-         	SiS_SetReg1(SiS_Part1Port,0x0B,temp);                  /* TW: CRT2 Horizontal Retrace Start */
+		temp = ((tempcx & 0xff00) >> 8) << 4;
+		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* TW: CRT2 Horizontal Total Overflow [7:4] */
 
-    	   } else {			/* for high resolution modes */
+		tempcx = pushcx;					       /* BTVGA2HDEE 0x0A,0x0C */
+		tempbx = SiS_Pr->SiS_VGAHDE;
+		tempcx -= tempbx;
+		tempcx >>= 2;
+		if(modeflag & HalfDCLK) {
+		    tempbx >>= 1;
+		    tempcx >>= 1;
+		}
+		tempbx += 16;
 
-         	temp = (SiS_VGAHT - 1) & 0xFF;                       	/* BTVGA2HT 0x08,0x09 */
-         	SiS_SetReg1(SiS_Part1Port,0x08,temp);                  /* TW: CRT2 Horizontal Total */
+		temp = tempbx & 0xff;
+		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* TW: CRT2 Horizontal Display Enable End */
 
-         	temp = (((SiS_VGAHT - 1) & 0xFF00) >> 8 ) << 4;
-	 	SiS_SetRegANDOR(SiS_Part1Port,0x09,0x0F,temp);         /* TW: CRT2 Horizontal Total Overflow [7:4] */
-
-         	temp = (SiS_VGAHDE + 16) & 0xFF;                       /* BTVGA2HDEE 0x0A,0x0C */
-	 	SiS_SetReg1(SiS_Part1Port,0x0A,temp);                  /* TW: CRT2 Horizontal Display Enable End */
-
-         	pushbx = SiS_VGAHDE + 16;
-         	tempcx = (SiS_VGAHT - SiS_VGAHDE) >> 2;                /* cx */
-		if(SiS_IF_DEF_LVDS == 1)
-		           tempcx >>= 1;    /* TW: From LVDS 1.10.07; not done on 301(LV) */
-         	tempbx = pushbx + tempcx;                              /* bx  BTVGA@HRS 0x0B,0x0C */
-         	tempcx += tempbx;
-
-         	if(SiS_IF_DEF_LVDS==0) {
-             	   if(SiS_VBInfo & SetCRT2ToRAMDAC){
-                	tempbx = SiS_CRT1Table[CRT1Index].CR[4];
-                	tempbx |= ((SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
+		pushbx = tempbx;
+		tempcx >>= 1;
+		tempbx += tempcx;
+		tempcx += tempbx;
+
+		if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
+             	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+                	tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+                	tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
                 	tempbx = (tempbx - 3) << 3;         		/*(VGAHRS-3)*8 */
-                	tempcx = SiS_CRT1Table[CRT1Index].CR[5];
+                	tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
                		tempcx &= 0x1F;
-                	temp = SiS_CRT1Table[CRT1Index].CR[15];
+                	temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
                 	temp = (temp & 0x04) << (5-2);      		/* VGAHRE D[5] */
-                	tempcx = ((tempcx | temp) - 3) << 3;    	/* (VGAHRE-3)*8 */
+                	tempcx = (tempcx | temp);	  	  	/* (VGAHRE-3)*8 */
+			tempcx -= 3;
+			tempcx <<= 3;
+			tempcx &= 0x00FF;
+			tempcx |= (tempbx & 0xFF00);
                 	tempbx += 16;
                 	tempcx += 16;
+			tempax = SiS_Pr->SiS_VGAHT;
+			if(modeflag & HalfDCLK)  tempax >>= 1;
+			tempax--;
+			if(tempcx > tempax)  tempcx = tempax;
              	   }
-		   /* TW: The entire following section is not done in 650/LVDS BIOS */
-         	   if (tempcx > SiS_VGAHT)
-        		tempcx = SiS_VGAHT;
-
-         	   if((SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
-             	      if(!(SiS_VBInfo & SetPALTV)){
+         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
+             	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
       		 	 tempbx = 1040;
       		 	 tempcx = 1042;
       	     	      }
          	   }
+		   /* TW: Makes no sense, but is in 650/302LV 1.10.6s */
+         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
+		      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+             	         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+      		 	    tempbx = 1040;
+      		 	    tempcx = 1042;
+      	     	         }
+		      }
+         	   }
                 }
 
-         	temp = tempbx & 0x00FF;
-	 	SiS_SetReg1(SiS_Part1Port,0x0B,temp);                 /* TW: CRT2 Horizontal Retrace Start */
-
-     	   } /* halfdclk */
+		temp = tempbx & 0xff;
+	 	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* TW: CRT2 Horizontal Retrace Start */
+#endif  /* SIS315H */
 
-     	}  /* 310 series */
+     	}  /* 310/325/330 series */
 
   	/* TW: The following is done for all bridge/chip types/series */
 
@@ -444,368 +506,420 @@
   	tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
   	tempax |= (tempbx & 0xFF00);
   	temp = (tempax & 0xFF00) >> 8;
-  	SiS_SetReg1(SiS_Part1Port,0x0C,temp);                        /* TW: Overflow */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);                        /* TW: Overflow */
 
   	temp = tempcx & 0x00FF;
-  	SiS_SetReg1(SiS_Part1Port,0x0D,temp);                        /* TW: CRT2 Horizontal Retrace End */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* TW: CRT2 Horizontal Retrace End */
 
   	/* 2. Vertical setup */
 
-  	tempcx = SiS_VGAVT - 1;
+  	tempcx = SiS_Pr->SiS_VGAVT - 1;
   	temp = tempcx & 0x00FF;
 
-	/* TW: Matches 650/301LV, 650/LVDS, 630/LVDS(CLEVO), 630/LVDS(no-Ch7005) */
-        if(SiS_IF_DEF_LVDS == 1) {
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
 	     if(HwDeviceExtension->jChipType < SIS_315H) {
-	          if(SiS_IF_DEF_CH70xx != 0) {
-#ifndef TWPANEL
-		       if(SiS_VBInfo & (SetCRT2ToSVIDEO|SetCRT2ToAVIDEO)) {
+	          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+		       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
 		           temp--;
 		       }
-#else
-		       temp--;
-#endif
                   }
 	     } else {
-	          if(SiS_IF_DEF_CH70xx != 0) {
  		      temp--;
-                  }
              }
-        }
-  	SiS_SetReg1(SiS_Part1Port,0x0E,temp);                        /* TW: CRT2 Vertical Total */
+        } else if(HwDeviceExtension->jChipType >= SIS_315H) {
+	    /* TW: 650/30xLV 1.10.6s */
+	    temp--;
+	}
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* TW: CRT2 Vertical Total */
 
-  	tempbx = SiS_VGAVDE - 1;
+  	tempbx = SiS_Pr->SiS_VGAVDE - 1;
   	temp = tempbx & 0x00FF;
-  	SiS_SetReg1(SiS_Part1Port,0x0F,temp);                        /* TW: CRT2 Vertical Display Enable End */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* TW: CRT2 Vertical Display Enable End */
 
   	temp = ((tempbx & 0xFF00) << 3) >> 8;
   	temp |= ((tempcx & 0xFF00) >> 8);
-  	SiS_SetReg1(SiS_Part1Port,0x12,temp);                        /* TW: Overflow (and HWCursor Test Mode) */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* TW: Overflow (and HWCursor Test Mode) */
 
-	/* TW: For 650/LVDS */
-	if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_IF_DEF_LVDS == 1)) {
+	/* TW: 650/LVDS (1.10.07), 650/30xLV (1.10.6s) */
+	if(HwDeviceExtension->jChipType >= SIS_315H) {
            tempbx++;
    	   tempax = tempbx;
 	   tempcx++;
-	   tempcx = tempcx - tempax;
+	   tempcx -= tempax;
 	   tempcx >>= 2;
-	   tempbx = tempbx + tempcx;
+	   tempbx += tempcx;
 	   if(tempcx < 4) tempcx = 4;
 	   tempcx >>= 2;
-	   tempcx = tempcx + tempbx;
+	   tempcx += tempbx;
 	   tempcx++;
 	} else {
-	   /* TW: For 630/LVDS/301B and 650/301LV: */
-  	   tempbx = (SiS_VGAVT + SiS_VGAVDE) >> 1;                      /*  BTVGA2VRS     0x10,0x11   */
-  	   tempcx = ((SiS_VGAVT - SiS_VGAVDE) >> 4) + tempbx + 1;       /*  BTVGA2VRE     0x11        */
+	   /* TW: 300 series, LVDS/301B: */
+  	   tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
+  	   tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
 	}
 
-  	if(SiS_IF_DEF_LVDS == 0) {
-    	   if(SiS_VBInfo & SetCRT2ToRAMDAC){
-      		tempbx = SiS_CRT1Table[CRT1Index].CR[8];
-      		temp = SiS_CRT1Table[CRT1Index].CR[7];
+  	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+    	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+      		tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
+      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
       		if(temp & 0x04) tempbx |= 0x0100;
       		if(temp & 0x80) tempbx |= 0x0200;
-      		temp = SiS_CRT1Table[CRT1Index].CR[13];
+      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
       		if(temp & 0x08) tempbx |= 0x0400;
-      		temp = SiS_CRT1Table[CRT1Index].CR[9];
+      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
       		tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
     	   }
   	}
   	temp = tempbx & 0x00FF;
-  	SiS_SetReg1(SiS_Part1Port,0x10,temp);                        /* TW: CRT2 Vertical Retrace Start */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);           /* TW: CRT2 Vertical Retrace Start */
 
   	temp = ((tempbx & 0xFF00) >> 8) << 4;
   	temp |= (tempcx & 0x000F);
-  	SiS_SetReg1(SiS_Part1Port,0x11,temp);                        /* TW: CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp);           /* TW: CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
 
-  	/* 3. Paneldelay */
+  	/* 3. Panel compensation delay */
 
-  	if (HwDeviceExtension->jChipType < SIS_315H ) {
+  	if(HwDeviceExtension->jChipType < SIS_315H) {
 
-    	   /* ---------- 300 series -------------- */
+#ifdef SIS300  /* ---------- 300 series -------------- */
 
-	   if(SiS_IF_DEF_LVDS == 0) {
+	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 	        temp = 0x20;
-		if(SiS_LCDResInfo == Panel1280x960) temp = 0x24;     /* TW: Not in 630/301B BIOS */
-		if(SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
-		if(SiS_VBInfo & SetCRT2ToHiVisionTV) {		     /* TW: Not in 630/301B BIOS */
-      		    if(SiS_VBInfo & SetInSlaveMode) temp = 0x2c;     /* TW: Not in 630/301B BIOS */
-      		    else temp = 0x20;                                /* TW: Not in 630/301B BIOS */
+
+		if(HwDeviceExtension->jChipType == SIS_300) {
+		   temp = 0x10;
+		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
+		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
+		}
+		if(SiS_Pr->SiS_VBType & VB_SIS301) {
+		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+		}
+		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)     temp = 0x24;
+		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 		temp = 0x08;
+		if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+      		   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	temp = 0x2c;
+      		   else 					temp = 0x20;
     	        }
-		if((ROMAddr) && (SiS_VBType & VB_SIS301BLV302BLV)) {
+		if((ROMAddr) && (SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
 		    if(ROMAddr[0x220] & 0x80) {
-		        if(SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV)) temp = ROMAddr[0x221];
-			else if(SiS_VBInfo & SetCRT2ToHiVisionTV) temp = ROMAddr[0x222];
-		        else if(SiS_LCDResInfo == Panel1280x1024) temp = ROMAddr[0x223];
-			else temp = ROMAddr[0x224];
+		        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))
+				temp = ROMAddr[0x221];
+			else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)
+				temp = ROMAddr[0x222];
+		        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)
+				temp = ROMAddr[0x223];
+			else
+				temp = ROMAddr[0x224];
 			temp &= 0x3c;
 		    }
 		}
-		if(HwDeviceExtension->pdc) {
+		if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+		   if(HwDeviceExtension->pdc) {
 			temp = HwDeviceExtension->pdc & 0x3c;
+		   }
 		}
 	   } else {
 	        temp = 0x20;
-		if(SiS_LCDResInfo == Panel640x480) temp = 0x04;
-		if(ROMAddr) {
+		if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) temp = 0x04;
+		}
+		if((ROMAddr) && SiS_Pr->SiS_UseROM) {
 		    if(ROMAddr[0x220] & 0x80) {
 		        temp = ROMAddr[0x220] & 0x3c;
 		    }
 		}
-		if(HwDeviceExtension->pdc) {
+		if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+		   if(HwDeviceExtension->pdc) {
 			temp = HwDeviceExtension->pdc & 0x3c;
+		   }
 		}
 	   }
 
-    	   SiS_SetRegANDOR(SiS_Part1Port,0x13,~0x03C,temp);         /* TW: Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
-	   /* TW: This register will be adapted according to LCD
-	    *     panel type later in the OEM setup functions.
-	    *     (Various panel types require a different delay
-	    *     such as Clevo 2202; however, on most panels,
-	    *     0x20 does nicely.)
-	    */
+    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* TW: Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
+
+#endif  /* SIS300 */
 
   	} else {
 
-      	   /* ----------- 310/325 series ---------------*/
-	   if(SiS_IF_DEF_LVDS == 0) {
-                temp = 0x10;                                        /* TW: Modified (650/301 BIOS) */
-                if(SiS_LCDResInfo == Panel1024x768)  temp = 0x2c;   /* TW: Modified (650/301 BIOS) */
-    	        if(SiS_LCDResInfo == Panel1280x1024) temp = 0x20;
-    	        if(SiS_LCDResInfo == Panel1280x960)  temp = 0x24;
-		if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
-      		   if(SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
-      		   else temp = 0x20;
-    	        }
-		tempbl = 0xF0;
+#ifdef SIS315H   /* ----------- 310/325/330 series ---------------*/
+
+	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+                temp = 0x10;
+                if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
+    	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+    	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
+		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+		   temp = 0x08;
+		   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+		      switch(SiS_Pr->SiS_HiVision) {
+		      case 2:
+		      case 1:
+		      case 0:
+		         temp = 0x08;
+			 break;
+		      default:
+      		         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  temp = 0x2c;
+      		         else 					  temp = 0x20;
+		      }
+    	           }
+		}
+		if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+		   tempbl = 0x00;
+		   if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+		      if(HwDeviceExtension->jChipType < SIS_330) {
+		         if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
+		      } else {
+		         if(ROMAddr[0x1bc] & 0x80) tempbl = 0xf0;
+		      }
+		   }
+		} else {  /* LV (550/301LV checks ROM byte, other LV BIOSes do not) */
+		   tempbl = 0xF0;
+		}
 	   } else {
-	        temp = 0x00;
-		if(SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
+	        if(HwDeviceExtension->jChipType == SIS_740) {
+		   temp = 0x03;
+	        } else {
+		   temp = 0x00;
+		}
+		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
 		tempbl = 0xF0;
-		if(!(SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
-	   }
-
-           if(SiS_IF_DEF_LVDS == 0) {
-                 temp >>= 2;         				    /* TW: Only in 650/301LV BIOS */
+		if(HwDeviceExtension->jChipType == SIS_650) {
+		   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+		      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
+		   }
+		}
 	   }
-
-	   SiS_SetRegANDOR(SiS_Part1Port,0x2D,tempbl,temp);	    /* TW: Panel Link Delay Compensation */
-           /* TW: This register will be adapted according to LCD
-	    *     panel type later in the OEM setup functions.
-	    *     (Various panel types require a different delay)
-	    */
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* TW: Panel Link Delay Compensation */
 
     	   tempax = 0;
     	   if (modeflag & DoubleScanMode) tempax |= 0x80;
     	   if (modeflag & HalfDCLK)       tempax |= 0x40;
-    	   SiS_SetRegANDOR(SiS_Part1Port,0x2C,0x3f,tempax);
+    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
+
+#endif  /* SIS315H */
 
   	}
 
      }  /* Slavemode */
 
-     if(SiS_IF_DEF_LVDS == 0) {
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-        /* TW: 630/301B BIOS sets up Panel Link, too! (650/LV does not) */
-        if( (SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo & SetCRT2ToLCD)
-	                       && (HwDeviceExtension->jChipType < SIS_315H)) {
+        /* TW: For 301BDH, we set up the Panel Link */
+        if( (SiS_Pr->SiS_VBType & VB_NoLCD) &&
+	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
 
-	    SiS_SetGroup1_LVDS(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	    SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
 	                       HwDeviceExtension,RefreshRateTableIndex);
 
-        } else if(SiS_VBInfo & SetInSlaveMode) {                              /* Inserted (650/301 BIOS) */
+        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {                             
 
-    	    SiS_SetGroup1_301(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+    	    SiS_SetGroup1_301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
 	                      HwDeviceExtension,RefreshRateTableIndex);
         }
 
      } else {
 
         if(HwDeviceExtension->jChipType < SIS_315H) {
-	     SiS_SetGroup1_LVDS(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	
+	   SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
 	                        HwDeviceExtension,RefreshRateTableIndex);
 	} else {
-	    /* TW: For 650/LVDS */
-            if((!(SiS_VBInfo & SetCRT2ToTV)) || (SiS_VBInfo & SetInSlaveMode)) {
-    	         SiS_SetGroup1_LVDS(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	                            HwDeviceExtension,RefreshRateTableIndex);
-            }
+	
+	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+              if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+    	          SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	                              HwDeviceExtension,RefreshRateTableIndex);
+              }
+	   } else {
+	      SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+	                         HwDeviceExtension,RefreshRateTableIndex);
+	   }
+	
 	}
 
      }
    } /* LCDA */
 }
 
-/* TW: Checked against 650/301LV and 630/301B (II) BIOS */
 void
-SiS_SetGroup1_301(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                   PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
 {
   USHORT  push1,push2;
   USHORT  tempax,tempbx,tempcx,temp;
   USHORT  resinfo,modeflag;
 
-  if(ModeNo<=0x13) {
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  if(ModeNo <= 0x13) {
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   } else {
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
 
   /* TW: The following is only done if bridge is in slave mode: */
 
   tempax = 0xFFFF;
-  if(!(SiS_VBInfo & SetCRT2ToTV))  tempax = SiS_GetVGAHT2();
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempax = SiS_GetVGAHT2(SiS_Pr);
 
-  /* TW: 630/301B does not check this flag, assumes it is set */
-  /*     650/LV BIOS does not check this either; so we set it... */
-  if(SiS_VBType & VB_SIS301BLV302BLV) {
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
   	modeflag |= Charx8Dot;
   }
 
   if(modeflag & Charx8Dot) tempcx = 0x08;
-  else tempcx = 0x09;
+  else                     tempcx = 0x09;
 
-  if(tempax >= SiS_VGAHT) tempax = SiS_VGAHT;
+  if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
 
   if(modeflag & HalfDCLK) tempax >>= 1;
 
   tempax = (tempax / tempcx) - 5;
-  tempbx = tempax & 0xFF;
+  tempbx = tempax & 0x00FF;
 
-  temp = 0xFF;                                          /* set MAX HT */
-  SiS_SetReg1(SiS_Part1Port,0x03,temp);
+  temp = 0xFF;                                                  /* set MAX HT */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,temp);
 
-  tempax = SiS_VGAHDE;                                 	/* 0x04 Horizontal Display End */
+  tempax = SiS_Pr->SiS_VGAHDE;                                 	/* 0x04 Horizontal Display End */
   if(modeflag & HalfDCLK) tempax >>= 1;
   tempax = (tempax / tempcx) - 1;
   tempbx |= ((tempax & 0x00FF) << 8);
-  temp = tempax & 0xFF;
-  SiS_SetReg1(SiS_Part1Port,0x04,temp);
+  temp = tempax & 0x00FF;
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,temp);
 
   temp = (tempbx & 0xFF00) >> 8;
-  if(SiS_VBInfo & SetCRT2ToTV){
-        if(!(SiS_VBType & VB_SIS301BLV302BLV)) {        /* TW: Inserted from 650/301, 630/301 BIOS */
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {        
     	    temp += 2;
-        }                                               /* TW: Inserted from 650/301, 630/301 BIOS */
-#ifdef oldHV
-    	if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
-            if(resinfo == 7) temp -= 2;
-    	}
-#endif
+        }
+  }	
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+     if(SiS_Pr->SiS_HiVision == 3) {
+              if(resinfo == 7) temp -= 2;
+     }
   }
-  SiS_SetReg1(SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
 
-  SiS_SetReg1(SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
 
-#ifdef oldHV
-  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+     (SiS_Pr->SiS_HiVision == 3)) {
     temp = (tempbx & 0x00FF) - 1;
     if(!(modeflag & HalfDCLK)) {
       temp -= 6;
-      if(SiS_SetFlag & TVSimuMode) {
-        temp -= 2;					/* Modified according to 650/301 BIOS; was 4 */
+      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+        temp -= 2;
         if(ModeNo > 0x13) temp -= 10;
       }
     }
   } else {
-#endif
     tempcx = tempbx & 0x00FF;
     tempbx = (tempbx & 0xFF00) >> 8;
     tempcx = (tempcx + tempbx) >> 1;
     temp = (tempcx & 0x00FF) + 2;
-    if(SiS_VBInfo & SetCRT2ToTV){
+    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV){
        temp--;
        if(!(modeflag & HalfDCLK)){
           if((modeflag & Charx8Dot)){
              temp += 4;
-             if(SiS_VGAHDE >= 800) temp -= 6;
-	     /* TW: Inserted from 650/301 BIOS, 630/301B/301 don't do this */
+             if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
              if(HwDeviceExtension->jChipType >= SIS_315H) {
-	         if(SiS_VGAHDE == 800) temp += 2;
+	        if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
              }
           }
        }
     } else {
-       if(!(modeflag & HalfDCLK)){
-         temp -= 4;
-         if(SiS_LCDResInfo != Panel1280x960) {
-           if(SiS_VGAHDE >= 800){
-             temp -= 7;
-             if(SiS_ModeType == ModeEGA){                         /* 650/301LV does not do this */
-               if(SiS_VGAVDE == 1024){                            /* 650/301LV does not do this */
-                 temp += 15;                                      /* 650/301LV does not do this */
-                 if(SiS_LCDResInfo != Panel1280x1024) temp += 7;  /* 650/301LV does not do this */
-               }
-             }
-             if(SiS_VGAHDE >= 1280){
-               if(SiS_LCDResInfo != Panel1280x960) {
-                 if(SiS_LCDInfo & LCDNonExpanding) temp += 28;
-               }
+       if(!(modeflag & HalfDCLK)) {
+          temp -= 4;
+          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+             if(SiS_Pr->SiS_VGAHDE >= 800) {
+                temp -= 7;
+	        if(HwDeviceExtension->jChipType < SIS_315H) {
+	           /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
+                   if(SiS_Pr->SiS_ModeType == ModeEGA) {
+                      if(SiS_Pr->SiS_VGAVDE == 1024) {
+                         temp += 15;
+                         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) 
+			    temp += 7;
+                      }
+                   }
+	        }
+                if(SiS_Pr->SiS_VGAHDE >= 1280) {
+                   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+                      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
+                   }
+                }
              }
-           }
-         }
+          }
        }
     }
-#ifdef oldHV
   }
-#endif
-  SiS_SetReg1(SiS_Part1Port,0x07,temp);               	/* 0x07 Horizontal Retrace Start */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);               	/* 0x07 Horizontal Retrace Start */
 
-  SiS_SetReg1(SiS_Part1Port,0x08,0x00);                 /* 0x08 Horizontal Retrace End   */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);                 /* 0x08 Horizontal Retrace End   */
 
-  if(SiS_VBInfo & SetCRT2ToTV) {
-        if(SiS_SetFlag & TVSimuMode) {
-            if((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo == 0x11) ||
-	                           (ModeNo == 0x13) || (ModeNo == 0x0F)){
-             	SiS_SetReg1(SiS_Part1Port,0x07,0x5b);
-             	SiS_SetReg1(SiS_Part1Port,0x08,0x03);
-            }
-            if((ModeNo == 0x00) || (ModeNo == 0x01)) {
-             	if(SiS_VBInfo & SetNTSCTV) {
-             		SiS_SetReg1(SiS_Part1Port,0x07,0x2A);
-             		SiS_SetReg1(SiS_Part1Port,0x08,0x61);
-              	} else {
-             		SiS_SetReg1(SiS_Part1Port,0x07,0x2A);
-             		SiS_SetReg1(SiS_Part1Port,0x08,0x41);
-             		SiS_SetReg1(SiS_Part1Port,0x0C,0xF0);
-            	}
-           }
-           if((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo == 0x07)){
-            	if(SiS_VBInfo & SetNTSCTV) {
-           		SiS_SetReg1(SiS_Part1Port,0x07,0x54);
-           		SiS_SetReg1(SiS_Part1Port,0x08,0x00);
-            	} else {
-           		SiS_SetReg1(SiS_Part1Port,0x07,0x55);
-           		SiS_SetReg1(SiS_Part1Port,0x08,0x00);
-           		SiS_SetReg1(SiS_Part1Port,0x0C,0xF0);
-           	}
-           }
-           if((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo == 0x0D)
-	                                           || (ModeNo == 0x50)){
-            	if(SiS_VBInfo & SetNTSCTV) {
-            		SiS_SetReg1(SiS_Part1Port,0x07,0x30);
-            		SiS_SetReg1(SiS_Part1Port,0x08,0x03);
-            	} else {
-           		SiS_SetReg1(SiS_Part1Port,0x07,0x2f);
-           		SiS_SetReg1(SiS_Part1Port,0x08,0x02);
-                }
-           }
-       }
-  }
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+            if(ModeNo <= 0x01) {
+	        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2a);
+		if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x61);
+		} else {
+		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x41);
+		}
+	    } else if(SiS_Pr->SiS_ModeType == ModeText) {
+	        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x54);
+		} else {
+		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x55);
+		}
+		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);
+	    } else if(ModeNo <= 0x13) {
+	        if(modeflag & HalfDCLK) {
+		    if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+		        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
+			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+		    } else {
+		        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
+			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x02);
+		    }
+		} else {
+		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x5b);
+		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+		}
+	    } else if( ((HwDeviceExtension->jChipType >= SIS_315H) && (ModeNo == 0x50)) ||
+	               ((HwDeviceExtension->jChipType < SIS_315H) && (resinfo == 0 || resinfo == 1)) ) {
+	        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
+		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+		} else {
+		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
+		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
+		}
+	    }
 
-  SiS_SetReg1(SiS_Part1Port,0x18,0x03);                	/* 0x18 SR08    */
+     }
+  }
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+     if(SiS_Pr->SiS_HiVision & 0x03) {
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0xb2);
+	if(SiS_Pr->SiS_HiVision & 0x02) {
+	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0xab);
+	}
+     }
+  }
 
-  SiS_SetRegANDOR(SiS_Part1Port,0x19,0xF0,0x00);
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x03);                	/* 0x18 SR08 (FIFO Threshold?)   */
 
-  SiS_SetReg1(SiS_Part1Port,0x09,0xFF);                	/* 0x09 Set Max VT    */
+  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
 
-  tempbx = SiS_VGAVT;
+  tempbx = SiS_Pr->SiS_VGAVT;
   push1 = tempbx;
+
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,0xFF);                	/* 0x09 Set Max VT    */
+
   tempcx = 0x121;
-  tempbx = SiS_VGAVDE;                               	/* 0x0E Vertical Display End */
+  tempbx = SiS_Pr->SiS_VGAVDE;                               	/* 0x0E Vertical Display End */
   if(tempbx == 357) tempbx = 350;
   if(tempbx == 360) tempbx = 350;
   if(tempbx == 375) tempbx = 350;
@@ -813,9 +927,9 @@
   if(tempbx == 420) tempbx = 400;
   if(tempbx == 525) tempbx = 480;
   push2 = tempbx;
-  if(SiS_VBInfo & SetCRT2ToLCD) {  /* TW: Entire if statement not in 630/301 BIOS */
-    	if(SiS_LCDResInfo == Panel1024x768) {
-      		if(!(SiS_SetFlag & LCDVESATiming)) {
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+    	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+      		if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
         		if(tempbx == 350) tempbx += 5;
         		if(tempbx == 480) tempbx += 5;
       		}
@@ -823,18 +937,24 @@
   }
   tempbx--;
   temp = tempbx & 0x00FF;
-  tempbx--;			/* Not in 630/301 BIOS */
-  temp = tempbx & 0x00FF;	/* Not in 630/301 BIOS */
-  SiS_SetReg1(SiS_Part1Port,0x10,temp);        		/* 0x10 vertical Blank Start */
+  tempbx--;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);        		/* 0x10 vertical Blank Start */
 
   tempbx = push2;
   tempbx--;
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Part1Port,0x0E,temp);
+#if 0
+  /* TW: Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
+  if(xxx()) {
+      if(temp == 0xdf) temp = 0xda;
+  }
+#endif
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);
 
   if(tempbx & 0x0100) {
   	tempcx |= 0x0002;
-	if(SiS_VBType & VB_SIS301) tempcx |=0x000a;
+	if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x000a;
   }
 
   tempax = 0x000B;
@@ -842,12 +962,12 @@
 
   if(tempbx & 0x0200) {
   	tempcx |= 0x0040;
-	if(SiS_VBType & VB_SIS301) tempax |= 0x2000;
+	if(SiS_Pr->SiS_VBType & VB_SIS301) tempax |= 0x2000;
   }
 
-  if(SiS_VBType & VB_SIS301) {
-        if(SiS_VBInfo & SetPALTV) {
-	      if(SiS_VGAVDE == 480) {
+  if(SiS_Pr->SiS_VBType & VB_SIS301) {
+        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+	      if(SiS_Pr->SiS_VGAVDE == 480) {
 	             tempax = (tempax & 0x00ff) | 0x2000;
 		     if(modeflag & DoubleScanMode)  tempax |= 0x8000;
 	      }
@@ -855,161 +975,175 @@
   }
 
   temp = (tempax & 0xFF00) >> 8;
-  SiS_SetReg1(SiS_Part1Port,0x0B,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);
 
   if(tempbx & 0x0400) tempcx |= 0x0600;
 
-  SiS_SetReg1(SiS_Part1Port,0x11,0x00);                	/* 0x11 Vertical Blank End */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,0x00);                	/* 0x11 Vertical Blank End */
 
   tempax = push1;
   tempax -= tempbx;
   tempax >>= 2;
   push1 = tempax;
 
-  if((resinfo != 0x09) || (SiS_VBType & VB_SIS301)) {
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+        /* TW: 650/30xLV 1.10.6s */
+        if(ModeNo > 0x13) {
+	    if(resinfo != 0x09) {  /* 1280x1024 */
+	        tempax <<= 1;
+		tempbx += tempax;
+	    }
+	} else {
+	    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+	        tempax <<= 1;
+		tempbx += tempax;
+	    }
+	}
+  } else if((resinfo != 0x09) || (SiS_Pr->SiS_VBType & VB_SIS301)) {
     	tempax <<= 1;
     	tempbx += tempax;
   }
-#ifdef oldHV
-  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+
+  if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+      (SiS_Pr->SiS_HiVision == 3) ) {
     	tempbx -= 10;
   } else {
-#endif
-    	if(SiS_SetFlag & TVSimuMode) {
-      	   if(SiS_VBInfo & SetPALTV) {
-	       if(!(SiS_HiVision & 0x03)) {
+    	if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+      	   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+	       if(!(SiS_Pr->SiS_HiVision & 0x03)) {
                     tempbx += 40;
 		    if(HwDeviceExtension->jChipType >= SIS_315H) {
-		       if(SiS_VGAHDE == 800) tempbx += 10;
+		       if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
 		    }
       	       }
 	   }
     	}
-#ifdef oldHV
   }
-#endif
   tempax = push1;
   tempax >>= 2;
   tempax++;
   tempax += tempbx;
   push1 = tempax;
-  if((SiS_VBInfo & SetPALTV)) {
+  if(SiS_Pr->SiS_VBInfo & SetPALTV) {
     	if(tempbx <= 513)  {
       		if(tempax >= 513) tempbx = 513;
     	}
   }
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Part1Port,0x0C,temp);			/* 0x0C Vertical Retrace Start */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);			/* 0x0C Vertical Retrace Start */
 
-  if(!(SiS_VBType & VB_SIS301)) {
+  if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
   	tempbx--;
   	temp = tempbx & 0x00FF;
-  	SiS_SetReg1(SiS_Part1Port,0x10,temp);
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);
 
 	if(tempbx & 0x0100) tempcx |= 0x0008;
 
-  	if(tempbx & 0x0200)
-    		SiS_SetRegOR(SiS_Part1Port,0x0B,0x20);
+  	if(tempbx & 0x0200) {
+    	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
+	}
 
   	tempbx++;
   }
   if(tempbx & 0x0100) tempcx |= 0x0004;
   if(tempbx & 0x0200) tempcx |= 0x0080;
   if(tempbx & 0x0400) {
-        if(SiS_VBType & VB_SIS301) tempcx |= 0x0800;
-  	else                       tempcx |= 0x0C00;
+        if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
+  	else                               tempcx |= 0x0C00;
   }
 
   tempbx = push1;
   temp = tempbx & 0x00FF;
   temp &= 0x0F;
-  SiS_SetReg1(SiS_Part1Port,0x0D,temp);        		/* 0x0D vertical Retrace End */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);        		/* 0x0D vertical Retrace End */
 
   if(tempbx & 0x0010) tempcx |= 0x2000;
 
   temp = tempcx & 0x00FF;
-
-  if(SiS_VBType & VB_SIS301) {
-	if(SiS_VBInfo & SetPALTV) {
-	      if(SiS_VGAVDE == 480)  temp = 0xa3;
+  if(SiS_Pr->SiS_VBType & VB_SIS301) {
+	if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+	      if(SiS_Pr->SiS_VGAVDE == 480)  temp = 0xa3;
 	}
   }
-  SiS_SetReg1(SiS_Part1Port,0x0A,temp);                    		/* 0x0A CR07 */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);              	/* 0x0A CR07 */
 
   temp = (tempcx & 0xFF00) >> 8;
-  SiS_SetReg1(SiS_Part1Port,0x17,temp);                    		/* 0x17 SR0A */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);              	/* 0x17 SR0A */
 
   tempax = modeflag;
   temp = (tempax & 0xFF00) >> 8;
   temp = (temp >> 1) & 0x09;
-  /* TW: Inserted from 650/301 BIOS; not in 630/301B+301 BIOS */
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
+  if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
+       /* Only use 8 dot clock */
        temp |= 0x01;
   }
-  SiS_SetReg1(SiS_Part1Port,0x16,temp);                    		/* 0x16 SR01 */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* 0x16 SR01 */
 
-  SiS_SetReg1(SiS_Part1Port,0x0F,0x00);                        		/* 0x0F CR14 */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,0x00);              	/* 0x0F CR14 */
 
-  SiS_SetReg1(SiS_Part1Port,0x12,0x00);                        		/* 0x12 CR17 */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* 0x12 CR17 */
 
-  if(SiS_LCDInfo & LCDRGB18Bit) temp = 0x80;
-  else                          temp = 0x00;
-  SiS_SetReg1(SiS_Part1Port,0x1A,temp);                         	/* 0x1A SR0E */
+  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+       if(IS_SIS650) {
+           /* TW: 650/30xLV 1.10.6s */
+           if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
+	       temp = 0x80;
+	   }
+       } else temp = 0x80;
+  } else  temp = 0x00;
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* 0x1A SR0E */
 
   return;
 }
 
-/* TW: Checked against 650/LVDS 1.10.07, 630/301B (I,II) and 630/LVDS BIOS */
 void
-SiS_SetGroup1_LVDS(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-		   USHORT ModeIdIndex,
-                   PSIS_HW_DEVICE_INFO HwDeviceExtension,
+SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+		   USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
 		   USHORT RefreshRateTableIndex)
 {
-  USHORT modeflag,resinfo;
-  USHORT push1,push2,tempax,tempbx,tempcx,temp,pushcx;
-  ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
+  USHORT modeflag, resinfo;
+  USHORT push1, push2, tempax, tempbx, tempcx, temp;
+#ifdef SIS315H
+  USHORT pushcx;
+#endif
+  ULONG  tempeax=0, tempebx, tempecx, tempvcfact=0;
 
-  if(ModeNo<=0x13) {
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  if(ModeNo <= 0x13) {
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   } else {
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
 
-#ifdef LINUX_XF86
-#ifdef TWDEBUG
-  xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_LCDHDES, SiS_LCDVDES);
-  xf86DrvMsg(0, X_INFO, "(init301: HDE     0x%03x VDE     0x%03x)\n", SiS_HDE, SiS_VDE);
-  xf86DrvMsg(0, X_INFO, "(init301: VGAHDE  0x%03x VGAVDE  0x%03x)\n", SiS_VGAHDE, SiS_VGAVDE);
-  xf86DrvMsg(0, X_INFO, "(init301: HT      0x%03x VT      0x%03x)\n", SiS_HT, SiS_VT);
-  xf86DrvMsg(0, X_INFO, "(init301: VGAHT   0x%03x VGAVT   0x%03x)\n", SiS_VGAHT, SiS_VGAVT);
-#endif
-#endif
-
   /* TW: Set up Panel Link */
 
   /* 1. Horizontal setup */
 
-  tempax = SiS_LCDHDES;
-   /* TW: Inserted (650/LVDS,630/301B/LVDS) BIOS) */
-  if((SiS_LCDResInfo == Panel640x480) && (!(SiS_VBInfo & SetInSlaveMode)))
+  tempax = SiS_Pr->SiS_LCDHDES;
+
+  if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
+      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
   	tempax -= 8;
+  }
 
-  tempcx = SiS_HT;    				  /* Horiz. Total */
+  tempcx = SiS_Pr->SiS_HT;    				  /* Horiz. Total */
 
-  tempbx = SiS_HDE;                               /* Horiz. Display End */
+  tempbx = SiS_Pr->SiS_HDE;                               /* Horiz. Display End */
 
-  if(SiS_LCDInfo & LCDNonExpanding) {
-    if(!SiS_IF_DEF_DSTN) {
- 	if(SiS_LCDResInfo == Panel800x600)        tempbx = 800;
-    	else if(SiS_LCDResInfo == Panel1024x768)  tempbx = 1024;
-/*	else if(SiS_LCDResInfo == Panel1024x600)  tempbx = 1024;  - not done in BIOS */
-/*	else if(SiS_LCDResInfo == Panel1152x768)  tempbx = 1152;  - not done in BIOS */
-	else if(SiS_LCDResInfo == Panel1280x1024) tempbx = 1280;  /* TW */
-        else if(SiS_LCDResInfo != Panel640x480)   tempbx = 1400;  /* TW */
-    }
+  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        if((!SiS_Pr->SiS_IF_DEF_DSTN) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
+ 	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempbx =  800;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempbx = 1024;  /* TW */
+    	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempbx = 1024;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)  tempbx = 1152;  /* TW */
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempbx = 1280;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1280; 
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400; 
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600; 
+        }
+     }
   }
   tempcx = (tempcx - tempbx) >> 2;		 /* HT-HDE / 4 */
 
@@ -1017,198 +1151,202 @@
 
   tempax += tempbx;
 
-  if(tempax >= SiS_HT) tempax -= SiS_HT;
+  if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
 
   push2 = tempax;
-
-  /* TW: Inserted this entire "if"-section from 650/LVDS, 630/301B and 630/LVDS BIOS */
-  if(SiS_VBInfo & SetCRT2ToLCD) {
-       if(!SiS_IF_DEF_DSTN){
-     	  if(SiS_LCDResInfo == Panel800x600)        tempcx = 0x0028;
-     	  else if(SiS_LCDResInfo == Panel1400x1050) tempcx = 0x0030;
-     	  else if( (SiS_LCDResInfo == Panel1024x768) ||
-	           (SiS_LCDResInfo == Panel1024x600) ||
-		   (SiS_LCDResInfo == Panel1152x768) ) {
-	  	if(HwDeviceExtension->jChipType < SIS_315H) {
-		     if(SiS_IF_DEF_LVDS == 1) {
-		           tempcx = 0x0017;
-#ifdef TWPANEL
-			   tempcx++;
+  
+  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if((!SiS_Pr->SiS_IF_DEF_DSTN) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
+     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0028;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0018;
+     	   else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
+	            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
+	  	   if(HwDeviceExtension->jChipType < SIS_315H) {
+		      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+		         tempcx = 0x0017;
+#ifdef TWNEWPANEL
+			 tempcx = 0x0018;
 #endif
-		     } else {
-		           tempcx = 0x0017;  /* A901; other 301B BIOS 0x0018; */
-		     }
-		} else {
-		     tempcx = 0x0018;
-		}
-	  }
-     	  else if(SiS_LCDResInfo != Panel640x480)   tempcx = 0x0030;
-       }
+		      } else {
+		         tempcx = 0x0017;  /* A901; sometimes 0x0018; */
+		      }
+		   } else {
+		      tempcx = 0x0018;
+		   }
+	   }
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0028;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
+        }
+     }
   }
 
   tempcx += tempax;                              /* lcdhrs  */
-  if(tempcx >= SiS_HT) tempcx -= SiS_HT;
+  if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
 
   tempax = tempcx >> 3;                          /* BPLHRS */
   temp = tempax & 0x00FF;
-  SiS_SetReg1(SiS_Part1Port,0x14,temp);		 /* Part1_14h; TW: Panel Link Horizontal Retrace Start  */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp);		 /* Part1_14h; TW: Panel Link Horizontal Retrace Start  */
 
-  temp = (tempax & 0x00FF) + 10;
-
-  /* TW: Inserted this entire "if"-section from 650/LVDS BIOS */
-  if(SiS_VBInfo & SetCRT2ToLCD) {
-      if(!SiS_IF_DEF_DSTN){
-        if(SiS_LCDResInfo != Panel640x480) {
-	  temp += 6;
-          if(SiS_LCDResInfo != Panel800x600) {
-	    temp++;
-	    if(HwDeviceExtension->jChipType > SIS_315H) {
-	       if(SiS_LCDResInfo != Panel1024x768) {
-	          temp -= 3;
-#ifdef TEST1400
-		  temp = 0x0e;
-#endif
-	       }
-	    }
-	  }
+  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+     temp = (tempax & 0x00FF) + 2;
+  } else {
+     temp = (tempax & 0x00FF) + 10;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if(!SiS_Pr->SiS_IF_DEF_DSTN) {
+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+	      temp += 6;
+              if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
+	         temp++;
+	         if(HwDeviceExtension->jChipType >= SIS_315H) {
+	            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
+	               temp += 7;
+		       if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+		          temp -= 0x14;
+			  if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x768) {
+			     temp -= 10;
+			  }
+		       }
+	            }
+	         }
+	      }
+           }
         }
-      }
+     }
   }
 
   temp &= 0x1F;
   temp |= ((tempcx & 0x0007) << 5);
-  if(SiS_IF_DEF_FSTN) temp=0x20;
-  SiS_SetReg1(SiS_Part1Port,0x15,temp);    	 /* Part1_15h; TW: Panel Link Horizontal Retrace End/Skew */
+  if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp);    	 /* Part1_15h; TW: Panel Link Horizontal Retrace End/Skew */
 
   tempbx = push2;
   tempcx = push1;                                /* lcdhdes  */
 
   temp = (tempcx & 0x0007);                      /* BPLHDESKEW  */
-  SiS_SetReg1(SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; TW: Panel Link Vertical Retrace Start (2:0) */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; TW: Panel Link Vertical Retrace Start (2:0) */
 
   tempcx >>= 3;                                  /* BPLHDES */
   temp = (tempcx & 0x00FF);
-  if(ModeNo==0x5b) temp--;                       /* fix fstn mode=5b */
-  SiS_SetReg1(SiS_Part1Port,0x16,temp);    	 /* Part1_16h; TW: Panel Link Horizontal Display Enable Start  */
+  if(ModeNo == 0x5b) temp--;                     
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);    	 /* Part1_16h; TW: Panel Link Horizontal Display Enable Start  */
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {  /* TW: Not done in LVDS BIOS 1.10.07 */
-     if(tempbx & 0x07) tempbx += 8;              /* TW: Done in 630/301B and 630/LVDS BIOSes */
+  if(HwDeviceExtension->jChipType < SIS_315H) {  
+     if(tempbx & 0x07) tempbx += 8;              
   }
   tempbx >>= 3;                                  /* BPLHDEE  */
   temp = tempbx & 0x00FF;
-  if(ModeNo==0x5b) temp--;                    	 /* fix fstn mode=5b */
-  SiS_SetReg1(SiS_Part1Port,0x17,temp);   	 /* Part1_17h; TW: Panel Link Horizontal Display Enable End  */
+  if(ModeNo == 0x5b) temp--;			 
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);   	 /* Part1_17h; TW: Panel Link Horizontal Display Enable End  */
 
   /* 2. Vertical setup */
 
   if(HwDeviceExtension->jChipType < SIS_315H) {
-
-      /* TW: This entire section from 630/301B and 630/LVDS/LVDS+CH BIOS */
-      tempcx = SiS_VGAVT;
-      tempbx = SiS_VGAVDE;
-      if(SiS_LCDInfo & LCDNonExpanding) {
-         if(SiS_LCDResInfo != Panel640x480) {
-	    tempbx = 600;
-	    if(SiS_LCDResInfo != Panel800x600) {
-	       tempbx = 768;
-	       if( (SiS_LCDResInfo != Panel1024x768) && (SiS_LCDResInfo != Panel1152x768) ) {
-	 	    tempbx = 600;
-	       }
-	    }
-         }
-      }
-      tempcx -= tempbx;
+     tempcx = SiS_Pr->SiS_VGAVT;
+     tempbx = SiS_Pr->SiS_VGAVDE;
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)       tempbx =  600;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempbx =  600;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx =  768;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempbx =  768;
+	   else								tempbx = 1024;
+        }
+     }
+     tempcx -= tempbx;
 
   } else {
 
-      tempcx = SiS_VGAVT - SiS_VGAVDE;                  /* VGAVT-VGAVDE  */
+     tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;          /* VGAVT-VGAVDE  */
 
   }
 
-  tempbx = SiS_LCDVDES;	   		 	 	/* VGAVDES  */
+  tempbx = SiS_Pr->SiS_LCDVDES;	   		 	 	/* VGAVDES  */
   push1 = tempbx;
 
-  tempax = SiS_VGAVDE;
+  tempax = SiS_Pr->SiS_VGAVDE;
 
-  if((SiS_IF_DEF_TRUMPION == 0) && (!(SiS_LCDInfo & 0x0100))
-                                && (SiS_LCDResInfo != Panel640x480)) {
-    	if(SiS_VBInfo & SetCRT2ToLCD) {
-	    if(!SiS_IF_DEF_DSTN){
-      		if(SiS_LCDResInfo == Panel800x600)        tempax = 600;
-      		else if(SiS_LCDResInfo == Panel1024x768)  tempax = 768;
-		else if(SiS_LCDResInfo == Panel1024x600)  tempax = 600;   /* TW */
-      		else if(SiS_LCDResInfo == Panel1152x768)  tempax = 768;   /* TW */
-		else if(SiS_LCDResInfo == Panel1280x1024) tempax = 1024;  /* TW */
-		else if(SiS_LCDResInfo == Panel1400x1050) tempax = 1050;  /* TW */
-		else                                      tempax = 600;
-            }
-    	}
+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+     if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0)   && 
+         (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
+         (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempax =  600;
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempax =  600;  
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempax =  768;
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)  tempax =  768;  
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempax =  768;  
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempax = 1024; 
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempax = 1050; 
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempax = 1200; 
+     }
   }
 
-  tempbx = tempbx + tempax;
-  if(tempbx >= SiS_VT) tempbx -= SiS_VT;
+  tempbx += tempax;
+  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
 
-  push2 = tempbx;                             	 /* push bx  temppush  */
+  push2 = tempbx;
 
   tempcx >>= 1;
 
-  /* TW: Inserted this entire "if" section (650/LVDS; 630/301B; 630/LVDS) */
-  if((SiS_VBInfo & SetCRT2ToLCD) && (SiS_LCDResInfo != Panel640x480)){
-     if(!SiS_IF_DEF_DSTN){
-     	if(SiS_LCDResInfo == Panel800x600)        tempcx = 0x0001;
-     	else if( (SiS_LCDResInfo == Panel1024x768) ||
-	         (SiS_LCDResInfo == Panel1152x768) ) {
-		if(HwDeviceExtension->jChipType < SIS_315H) {
-		      if(SiS_IF_DEF_LVDS == 1) {
+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
+     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+        if(!SiS_Pr->SiS_IF_DEF_DSTN) {
+     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0001;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0001;
+     	   else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
+	           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)) {
+		   if(HwDeviceExtension->jChipType < SIS_315H) {
+		      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
 			    tempcx = 0x0002;
-#ifdef TWPANEL
-			    tempcx++;
+#ifdef TWNEWPANEL
+			    tempcx = 0x0003;
 #endif
 		      } else {
-		            tempcx = 0x0002;   /* TW: A901; other 301B BIOS sets 0x0003; */
+		            tempcx = 0x0002;   /* TW: A901; sometimes 0x0003; */
 		      }
-		} else tempcx = 0x0003;
-        }
-     	else if(SiS_LCDResInfo == Panel1280x768)  tempcx = 0x0003;
-     	else if(SiS_LCDResInfo == Panel1280x1024) tempcx = 0x0001;
-     	else if(SiS_LCDResInfo == Panel1400x1050) tempcx = 0x0001;
-     	else 				          tempcx = 0x0057;
+		   } else tempcx = 0x0003;
+           }
+     	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0003;
+     	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0001;
+     	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0001;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0001;
+     	   else 							 tempcx = 0x0057;
+	}
      }
   }
 
   tempbx += tempcx;			 	/* BPLVRS  */
 
   if(HwDeviceExtension->jChipType < SIS_315H) {
-#ifdef TWPANEL
-      if(SiS_IF_DEF_CH70xx == 0)
-#endif
-   	  tempbx++;
+      tempbx++;
   }
 
-#ifdef TEST1400  /* Not done on 650/LVDS 1.10.07, done in 650/LVDS 1.10a */
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-          tempbx++;
-  }
-#endif
+  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
 
-  if(tempbx >= SiS_VT) tempbx -= SiS_VT;
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Part1Port,0x18,temp);       	 /* Part1_18h; TW: Panel Link Vertical Retrace Start  */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);       	 /* Part1_18h; TW: Panel Link Vertical Retrace Start  */
 
   tempcx >>= 3;
 
-  /* TW: Inserted this entire "if" section (650/LVDS, 630/LVDS, 630/301B) */
-  if(SiS_VBInfo & SetCRT2ToLCD) {
-     if( (HwDeviceExtension->jChipType < SIS_315H) &&
-         (SiS_LCDResInfo == Panel640x480) )     tempcx = 0x0001;
-     else if(SiS_LCDResInfo == Panel1400x1050)  tempcx = 0x0002;
-     else if(SiS_LCDResInfo == Panel800x600)    tempcx = 0x0003;
-     else if(SiS_LCDResInfo != Panel640x480)  {
+  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if( (HwDeviceExtension->jChipType < SIS_315H) &&
+            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) )     tempcx = 0x0001;
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)    tempcx = 0x0003;
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0005;
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)   tempcx = 0x0005;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 0x0011;
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0005;	 
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0002;
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 0x0011;
+        else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
      		if(HwDeviceExtension->jChipType < SIS_315H) {
-		        if(SiS_IF_DEF_LVDS == 1) {
+		        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
 				tempcx = 0x0004;
-#ifdef TWPANEL
-				tempcx++;
+#ifdef TWNEWPANEL
+				tempcx = 0x0005;
 #endif
 		        } else {
 				tempcx = 0x0004;   /* A901; Other BIOS sets 0x0005; */
@@ -1216,19 +1354,20 @@
 		} else {
 			tempcx = 0x0005;
 		}
+        }
      }
   }
 
   tempcx = tempcx + tempbx + 1;                  /* BPLVRE  */
   temp = tempcx & 0x000F;
-  SiS_SetRegANDOR(SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; TW: Panel Link Vertical Retrace End (3:0); Misc.  */
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; TW: Panel Link Vertical Retrace End (3:0); Misc.  */
 
   temp = ((tempbx & 0x0700) >> 8) << 3;          /* BPLDESKEW =0 */
-  if(SiS_VGAVDE != SiS_VDE)	  temp |= 0x40;
-  if(SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
-  if(SiS_LCDInfo & LCDRGB18Bit)   {
+  if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)    temp |= 0x40;
+  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
       if(HwDeviceExtension->jChipType >= SIS_315H) {
-         if(SiS_GetReg1(SiS_Part1Port,0x00) & 0x01) {	/* TW: Inserted from 650/LVDS 1.10.07 */
+         if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
             temp |= 0x80;
          }
       } else {
@@ -1239,88 +1378,105 @@
 	    }
 	 }
       }
-  }         /* TW: in follwing line, 0x87 was 0x07 (modified according to 650/LVDS BIOS) */
-  SiS_SetRegANDOR(SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; TW: Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
+  }
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; TW: Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
 
   if (HwDeviceExtension->jChipType < SIS_315H) {
 
-        /* 300 series */
+#ifdef SIS300      /* 300 series */
 
-        tempeax = SiS_VGAVDE << 6;
-        temp = (USHORT)(tempeax % (ULONG)SiS_VDE);
-        tempeax = tempeax / (ULONG)SiS_VDE;
+        tempeax = SiS_Pr->SiS_VGAVDE << 6;
+        temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
+        tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
         if(temp != 0) tempeax++;
         tempebx = tempeax;                         /* BPLVCFACT  */
 
-  	if(SiS_SetFlag & EnableLVDSDDA) {
-	     tempebx = 0x003F;    
+  	if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
+	   tempebx = 0x003F;
 	}
 
   	temp = (USHORT)(tempebx & 0x00FF);
-  	SiS_SetReg1(SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; TW: Panel Link Vertical Scaling Factor */
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; TW: Panel Link Vertical Scaling Factor */
+
+#endif /* SIS300 */
 
   } else {
 
-        /* 310 series */
+#ifdef SIS315H  /* 310/325 series */
 
-	SiS_SetReg1(SiS_Part1Port,0x1E,0x23);      /* Inserted from 650/LVDS BIOS */
+#ifdef NEWCH701x
+        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
+#else
+	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23);
+#endif	
 
-	tempeax = SiS_VGAVDE << 18;
-    	temp = (USHORT)(tempeax % (ULONG)SiS_VDE);
-    	tempeax = tempeax / SiS_VDE;
+	tempeax = SiS_Pr->SiS_VGAVDE << 18;
+    	temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
+    	tempeax = tempeax / SiS_Pr->SiS_VDE;
     	if(temp != 0) tempeax++;
     	tempebx = tempeax;                         /* BPLVCFACT  */
         tempvcfact = tempeax;
     	temp = (USHORT)(tempebx & 0x00FF);
-    	SiS_SetReg1(SiS_Part1Port,0x37,temp);      /* Part1_37h; TW: Panel Link Vertical Scaling Factor */
+    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp);      /* Part1_37h; TW: Panel Link Vertical Scaling Factor */
     	temp = (USHORT)((tempebx & 0x00FF00) >> 8);
-    	SiS_SetReg1(SiS_Part1Port,0x36,temp);      /* Part1_36h; TW: Panel Link Vertical Scaling Factor */
+    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);      /* Part1_36h; TW: Panel Link Vertical Scaling Factor */
     	temp = (USHORT)((tempebx & 0x00030000) >> 16);
-    	if(SiS_VDE == SiS_VGAVDE) temp |= 0x04;
-    	SiS_SetReg1(SiS_Part1Port,0x35,temp);      /* Part1_35h; TW: Panel Link Vertical Scaling Factor */
+    	if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
+    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);      /* Part1_35h; TW: Panel Link Vertical Scaling Factor */
+
+#endif /* SIS315H */
 
   }
 
-  tempbx = push2;                                  /* p bx temppush1 BPLVDEE  */
+  tempbx = push2;                                  /* BPLVDEE  */
   tempcx = push1;
 
-  push1 = temp;					   /* TW: For 630/301B and 630/LVDS */
+  push1 = temp;					   
 
-  if(!(SiS_VBInfo & SetInSlaveMode)) {
-   	if(!SiS_IF_DEF_DSTN){
-    		if(SiS_LCDResInfo == Panel800x600) {
-      			if(resinfo == 7) tempcx++;
-		}
-		if(HwDeviceExtension->jChipType < SIS_315H) {   /* TW: Not done in 650/LVDS 1.10.07 */
-	    	    if(resinfo == 8) tempcx++;			/* TW: But in 630/301B and 630/LVDS */
+  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+   	if(!SiS_Pr->SiS_IF_DEF_DSTN){
+		if(HwDeviceExtension->jChipType < SIS_315H) {
+			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+      				if(resinfo == 15) tempcx++;
+				if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+					if(resinfo == 7) tempcx++;
+		    		}
+			} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+      				if(resinfo == 7) tempcx++;
+				if(resinfo == 8) tempcx++; /* TW: Doesnt make sense anyway... */
+			} else  if(resinfo == 8) tempcx++;
+		} else {
+			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+      				if(resinfo == 7) tempcx++;
+			}
 		}
 	}
   }
-  /* TW: Inserted (650/LVDS, 630/LVDS, 630/301B) */
-  if(SiS_LCDResInfo == Panel640x480) {
-     tempcx = SiS_VGAVDE;
-     tempbx = SiS_VGAVDE - 1;
+
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+     tempcx = SiS_Pr->SiS_VGAVDE;
+     tempbx = SiS_Pr->SiS_VGAVDE - 1;
   }
 
   temp = ((tempbx & 0x0700) >> 8) << 3;
   temp |= ((tempcx & 0x0700) >> 8);
-  SiS_SetReg1(SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; TW: Vertical Display Overflow; Control Signal */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; TW: Vertical Display Overflow; Control Signal */
 
   temp = tempbx & 0x00FF;
-  if(SiS_IF_DEF_FSTN) temp++;
-  SiS_SetReg1(SiS_Part1Port,0x1C,temp);      	/* Part1_1Ch; TW: Panel Link Vertical Display Enable End  */
+  if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);      	/* Part1_1Ch; TW: Panel Link Vertical Display Enable End  */
 
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; TW: Panel Link Vertical Display Enable Start  */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; TW: Panel Link Vertical Display Enable Start  */
 
   /* 3. Additional horizontal setup (scaling, etc) */
 
-  tempecx = SiS_VGAHDE;
+  tempecx = SiS_Pr->SiS_VGAHDE;
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-     if(modeflag & HalfDCLK)			/* TW: Added this entire if statement */
+     if(modeflag & HalfDCLK)
         tempecx >>= 1;
   }
-  tempebx = SiS_HDE;
+  tempebx = SiS_Pr->SiS_HDE;
   if(tempecx == tempebx) tempeax = 0xFFFF;
   else {
      tempeax = tempecx;
@@ -1328,135 +1484,136 @@
      temp = (USHORT)(tempeax % tempebx);
      tempeax = tempeax / tempebx;
      if(HwDeviceExtension->jChipType >= SIS_315H) {
-         if(temp) tempeax++;			/* TW: Not done in 630/301B or 630/LVDS, but for 650/LVDS */
+         if(temp) tempeax++;
      }
   }
   tempecx = tempeax;
 
-  if (HwDeviceExtension->jChipType >= SIS_315H) {
-      tempeax = SiS_VGAHDE;
-      if(modeflag & HalfDCLK)			/* TW: Added this entire if statement */
-          tempeax >>= 1;
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+      tempeax = SiS_Pr->SiS_VGAHDE;
+      if(modeflag & HalfDCLK) tempeax >>= 1;
       tempeax <<= 16;
       tempeax = (tempeax / tempecx) - 1;
   } else {
-      tempeax = ((SiS_VGAHT << 16) / tempecx) - 1;    
+      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
   }
   tempecx <<= 16;
   tempecx |= (tempeax & 0xFFFF);
   temp = (USHORT)(tempecx & 0x00FF);
-  SiS_SetReg1(SiS_Part1Port,0x1F,temp);  	 /* Part1_1Fh; TW: Panel Link DDA Operational Number in each horiz. line */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp);  	 /* Part1_1Fh; TW: Panel Link DDA Operational Number in each horiz. line */
 
-  tempbx = SiS_VDE;                              /* TW: added following if statement */
-  if (HwDeviceExtension->jChipType >= SIS_315H) {
-      tempeax = (SiS_VGAVDE << 18) / tempvcfact;
+  tempbx = SiS_Pr->SiS_VDE;
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
       tempbx = (USHORT)(tempeax & 0x0FFFF);
   } else {
-      tempax = SiS_VGAVDE << 6;
+      tempax = SiS_Pr->SiS_VGAVDE << 6;
       tempbx = push1;
       tempbx &= 0x3f;
       if(tempbx == 0) tempbx = 64;
       tempax = tempax / tempbx;
       tempbx = tempax;
   }
-  if(SiS_LCDResInfo == Panel1024x768) tempbx--;
-  if(SiS_SetFlag & EnableLVDSDDA)     tempbx = 1;
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)                 tempbx = 1;
 
   temp = ((tempbx & 0xFF00) >> 8) << 3;
   temp |= (USHORT)((tempecx & 0x0700) >> 8);
-  SiS_SetReg1(SiS_Part1Port,0x20,temp);  	/* Part1_20h; TW: Overflow register */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);  	/* Part1_20h; TW: Overflow register */
 
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Part1Port,0x21,temp);  	/* Part1_21h; TW: Panel Link Vertical Accumulator Register */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);  	/* Part1_21h; TW: Panel Link Vertical Accumulator Register */
 
   tempecx >>= 16;                               /* BPLHCFACT  */
-  if(HwDeviceExtension->jChipType < SIS_315H) { /* TW: Added this entire if statement from 630/301B+LVDS BIOSes */
+  if(HwDeviceExtension->jChipType < SIS_315H) {
       if(modeflag & HalfDCLK) tempecx >>= 1;
   }
   temp = (USHORT)((tempecx & 0xFF00) >> 8);
-  SiS_SetReg1(SiS_Part1Port,0x22,temp);     	/* Part1_22h; TW: Panel Link Horizontal Scaling Factor High */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);     	/* Part1_22h; TW: Panel Link Horizontal Scaling Factor High */
 
   temp = (USHORT)(tempecx & 0x00FF);
-  SiS_SetReg1(SiS_Part1Port,0x23,temp);         /* Part1_22h; TW: Panel Link Horizontal Scaling Factor Low */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; TW: Panel Link Horizontal Scaling Factor Low */
 
   /* 630/301B and 630/LVDS do something for 640x480 panels here */
 
-  /* add dstn new register */
-  if(SiS_IF_DEF_DSTN){
-     	SiS_SetReg1(SiS_Part1Port,0x1E,0x01);
-     	SiS_SetReg1(SiS_Part1Port,0x25,0x00);
-     	SiS_SetReg1(SiS_Part1Port,0x26,0x00);
-     	SiS_SetReg1(SiS_Part1Port,0x27,0x00);
-     	SiS_SetReg1(SiS_Part1Port,0x28,0x87);
-     	SiS_SetReg1(SiS_Part1Port,0x29,0x5A);
-     	SiS_SetReg1(SiS_Part1Port,0x2A,0x4B);
-     	SiS_SetRegANDOR(SiS_Part1Port,0x44,~0x007,0x03);
-     	tempbx = SiS_HDE + 64;                       /*Blps = lcdhdee(lcdhdes+HDE) + 64*/
+#ifdef SIS315H
+  /* TW: DSTN/FSTN initialisation - hardcoded for 320x480 panel */
+  if(SiS_Pr->SiS_IF_DEF_DSTN) {
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x01);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x25,0x00);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x26,0x00);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x27,0x00);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x28,0x87);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x29,0x5A);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
+     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
+     	tempbx = SiS_Pr->SiS_HDE + 64;                       	/*Blps = lcdhdee(lcdhdes+HDE) + 64*/
      	temp = tempbx & 0x00FF;
-     	SiS_SetReg1(SiS_Part1Port,0x38,temp);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,temp);
      	temp=((tempbx & 0xFF00) >> 8) << 3;
-     	SiS_SetRegANDOR(SiS_Part1Port,0x35,~0x078,temp);
-     	tempbx += 32;		                     /*Blpe=lBlps+32*/
+     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
+     	tempbx += 32;		                     		/*Blpe=lBlps+32*/
      	temp = tempbx & 0x00FF;
-     	if(SiS_IF_DEF_FSTN)  temp=0;
-     	SiS_SetReg1(SiS_Part1Port,0x39,temp);
-     	SiS_SetReg1(SiS_Part1Port,0x3A,0x00);        /*Bflml=0*/
-     	SiS_SetRegANDOR(SiS_Part1Port,0x3C,~0x007,0x00);
-     	tempbx = SiS_VDE / 2;
+     	if(SiS_Pr->SiS_IF_DEF_FSTN)  temp=0;
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,temp);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3A,0x00);        	/*Bflml=0*/
+     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
+     	tempbx = SiS_Pr->SiS_VDE / 2;
      	temp = tempbx & 0x00FF;
-     	SiS_SetReg1(SiS_Part1Port,0x3B,temp);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp);
      	temp = ((tempbx & 0xFF00) >> 8) << 3;
-     	SiS_SetRegANDOR(SiS_Part1Port,0x3C,~0x038,temp);
-     	tempeax = SiS_HDE << 2;                       /* BDxFIFOSTOP = (HDE*4)/128 */
+     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
+     	tempeax = SiS_Pr->SiS_HDE << 2;                       	/* BDxFIFOSTOP = (HDE*4)/128 */
      	tempebx = 128;
      	temp = (USHORT)(tempeax % tempebx);
      	tempeax = tempeax / tempebx;
      	if(temp != 0)  tempeax++;
      	temp = (USHORT)(tempeax & 0x003F);
-     	SiS_SetRegANDOR(SiS_Part1Port,0x45,~0x0FF,temp);
-     	SiS_SetReg1(SiS_Part1Port,0x3F,0x00);         /* BDxWadrst0 */
-     	SiS_SetReg1(SiS_Part1Port,0x3E,0x00);
-     	SiS_SetReg1(SiS_Part1Port,0x3D,0x10);
-     	SiS_SetRegANDOR(SiS_Part1Port,0x3C,~0x040,0x00);
-     	tempax = SiS_HDE >> 4;                        /* BDxWadroff = HDE*4/8/8 */
+     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3F,0x00);         	/* BDxWadrst0 */
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3E,0x00);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3D,0x10);
+     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
+     	tempax = SiS_Pr->SiS_HDE >> 4;                        	/* BDxWadroff = HDE*4/8/8 */
      	pushcx = tempax;
      	temp = tempax & 0x00FF;
-     	SiS_SetReg1(SiS_Part1Port,0x43,temp);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,temp);
      	temp = ((tempax & 0xFF00) >> 8) << 3;
-     	SiS_SetRegANDOR(SiS_Part1Port,0x44,~0x0F8,temp);
-     	tempax = SiS_VDE;                             /*BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
+     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
+     	tempax = SiS_Pr->SiS_VDE;                             /*BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
      	tempeax = (tempax * pushcx);
      	tempebx = 0x00100000 + tempeax;
      	temp = (USHORT)tempebx & 0x000000FF;
-     	SiS_SetReg1(SiS_Part1Port,0x42,temp);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,temp);
      	temp = (USHORT)((tempebx & 0x0000FF00)>>8);
-     	SiS_SetReg1(SiS_Part1Port,0x41,temp);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,temp);
      	temp = (USHORT)((tempebx & 0x00FF0000)>>16);
-     	SiS_SetReg1(SiS_Part1Port,0x40,temp);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,temp);
      	temp = (USHORT)(((tempebx & 0x01000000)>>24) << 7);
-     	SiS_SetRegANDOR(SiS_Part1Port,0x3C,~0x080,temp);
-     	SiS_SetReg1(SiS_Part1Port,0x2F,0x03);
-     	SiS_SetReg1(SiS_Part1Port,0x03,0x50);
-     	SiS_SetReg1(SiS_Part1Port,0x04,0x00);
-     	SiS_SetReg1(SiS_Part1Port,0x2F,0x01);
-     	SiS_SetReg1(SiS_Part1Port,0x13,0x00);
-     	SiS_SetReg1(SiS_P3c4,0x05,0x86);        /* Unlock */
-     	SiS_SetReg1(SiS_P3c4,0x1e,0x62);
-     	if(SiS_IF_DEF_FSTN){
-         	SiS_SetReg1(SiS_P3c4,0x2b,0x1b);
-         	SiS_SetReg1(SiS_P3c4,0x2c,0xe3);
-         	SiS_SetReg1(SiS_P3c4,0x1e,0x62);
-         	SiS_SetReg1(SiS_P3c4,0x2e,0x04);
-         	SiS_SetReg1(SiS_P3c4,0x2f,0x42);
-         	SiS_SetReg1(SiS_P3c4,0x32,0x01);
-         	SiS_SetReg1(SiS_Part1Port,0x2b,0x02);
-         	SiS_SetReg1(SiS_Part1Port,0x2c,0x00);
-         	SiS_SetReg1(SiS_Part1Port,0x2d,0x00);
+     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x03);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x50);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,0x00);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x01);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x13,0x00);
+     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);        /* Unlock */
+     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
+     	if(SiS_Pr->SiS_IF_DEF_FSTN){
+         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2b,0x1b);
+         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2c,0xe3);
+         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
+         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2e,0x04);
+         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2f,0x42);
+         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,0x01);
+         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2b,0x02);
+         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2c,0x00);
+         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x00);
      	}
-     	SiS_SetRegANDOR(SiS_Part1Port,0x19,0x0f,0x30);
-     	SiS_SetReg1(SiS_Part1Port,0x1e,0x7d);
-     	SiS_SetReg1(SiS_Part1Port,0x2e,0xe0);
+     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,0x30);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x7d);
+     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2e,0xe0);
   }
+#endif  /* SIS315H */
 
   return;
 
@@ -1464,302 +1621,383 @@
 
 #ifdef SIS315H
 void
-SiS_CRT2AutoThreshold(USHORT BaseAddr)
+SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr, USHORT BaseAddr)
 {
-  SiS_SetRegOR(SiS_Part1Port,0x01,0x40);
+  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
 }
 #endif
 
 
-/* TW: For LVDS / 302b/lv - LCDA (this must only be called on 310/325 series!) */
-/* TW: Double-checked against 650/LVDS and 650/301 BIOS */
+#ifdef SIS315H
+/* TW: For LVDS / 302B/30xLV - LCDA (this must only be called on 310/325 series!) */
 void
-SiS_SetGroup1_LCDA(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                    PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
 {
   USHORT modeflag,resinfo;
   USHORT push1,push2,tempax,tempbx,tempcx,temp;
   ULONG tempeax=0,tempebx,tempecx,tempvcfact;
 
-  if(SiS_IF_DEF_LVDS == 1)					/* TW: From 650/LVDS BIOS */
-      SiS_SetRegANDOR(SiS_Part1Port,0x13,0xfb,0x04);      	/* TW: From 650/LVDS BIOS */
-
-  if(SiS_IF_DEF_LVDS == 1)					/* TW: From 650/LVDS 1.10.07 */
-     SiS_SetRegOR(SiS_Part1Port,0x2D,0x00);			/* TW: From 650/LVDS 1.10.07 */
-  else
-     SiS_SetRegOR(SiS_Part1Port,0x2D,0x20);
+  if(IS_SIS330) {
+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* Xabre 1.01.03 */
+  } else if(IS_SIS740) {
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* 740/LVDS */
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);      	/* 740/LVDS */
+	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
+     } else {
+        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* 740/301LV 1.10.1i */
+     }
+  } else {
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* 650/LVDS */
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);      	/* 650/LVDS */
+	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);			/* 650/LVDS 1.10.07 */
+     } else {
+        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);			/* 650/30xLv 1.10.6s */
+     }
+  }
 
-  if(ModeNo<=0x13) {
-    modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  if(ModeNo <= 0x13) {
+    modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   } else {
-    modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
 
-  tempax = SiS_LCDHDES;
-  tempbx = SiS_HDE;
-  tempcx = SiS_HT;
-  
-  if(SiS_LCDInfo & LCDNonExpanding) {
-    	if(SiS_LCDResInfo == Panel1280x1024)     tempbx = 1280;
-    	else if(SiS_LCDResInfo == Panel1024x768) tempbx = 1024;
-	else tempbx = 1400;                                     /* TW: From 650/LVDS BIOS; OK with 650/301 */
+  tempax = SiS_Pr->SiS_LCDHDES;
+  tempbx = SiS_Pr->SiS_HDE;
+  tempcx = SiS_Pr->SiS_HT;
+
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx = 1024;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600;
+	else 							      tempbx = 1280;
   }
-  tempcx = tempcx - tempbx;                                    	/* HT-HDE  */
+  tempcx -= tempbx;                        	            	/* HT-HDE  */
   push1 = tempax;
-  tempax = tempax + tempbx;                                    	/* lcdhdee  */
-  tempbx = SiS_HT;
-  if(tempax >= tempbx)	tempax = tempax-tempbx;
-  push2=tempax;
-                                                           	/* push ax   lcdhdee  */
-  tempcx >>= 2;                                        	        /* temp  */
-  tempcx = tempcx + tempax;                                    	/* lcdhrs  */
-  if(tempcx >= tempbx) tempcx = tempcx - tempbx;
+  tempax += tempbx;	                                    	/* lcdhdee  */
+  tempbx = SiS_Pr->SiS_HT;
+  if(tempax >= tempbx)	tempax -= tempbx;
+
+  push2 = tempax;						/* push ax   lcdhdee  */
+
+  tempcx >>= 2;
+
+  /* TW: 650/30xLV 1.10.6s, 740/LVDS */
+  if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
+      ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
+     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x28;
+ 	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempcx = 0x18;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x30;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x40;
+	else                                                          tempcx = 0x30;
+     }
+  }
+
+  tempcx += tempax;  	                                  	/* lcdhrs  */
+  if(tempcx >= tempbx) tempcx -= tempbx;
                                                            	/* v ah,cl  */
   tempax = tempcx;
-  tempax = tempax >> 3;                                        	/* BPLHRS */
+  tempax >>= 3;   	                                     	/* BPLHRS */
   temp = tempax & 0x00FF;
-  SiS_SetReg1(SiS_Part1Port,0x14,temp);                         /* Part1_14h  */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp);                 	/* Part1_14h  */
 
-  temp = (tempax & 0x00FF) + 10;
-  temp = temp & 0x01F;
-  temp = temp | (((tempcx & 0x00ff) & 0x07) << 5);
-  SiS_SetReg1(SiS_Part1Port,0x15,temp);                         /* Part1_15h  */
+  temp += 10;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+	   temp += 6;
+	   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
+	      temp++;
+	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
+	         temp += 7;
+		 if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+		    temp -= 10;
+		 }
+	      }
+	   }
+	}
+     }
+  }
+  temp &= 0x1F;
+  temp |= ((tempcx & 0x07) << 5);
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp);                         /* Part1_15h  */
 
   tempbx = push2;                                          	/* lcdhdee  */
   tempcx = push1;                                          	/* lcdhdes  */
   temp = (tempcx & 0x00FF);
-  temp = temp & 0x07;                                  		/* BPLHDESKEW  */
-  SiS_SetReg1(SiS_Part1Port,0x1A,temp);                         /* Part1_1Ah  */
+  temp &= 0x07;                                  		/* BPLHDESKEW  */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);                         /* Part1_1Ah  */
 
-  tempcx = tempcx >> 3;                                        	/* BPLHDES */
-  temp = (tempcx & 0x00FF);
-  SiS_SetReg1(SiS_Part1Port,0x16,temp);                         /* Part1_16h  */
+  tempcx >>= 3;   	                                     	/* BPLHDES */
+  temp = tempcx & 0x00FF;
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);                         /* Part1_16h  */
 
-  if(tempbx & 0x07) tempbx += 8;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+     if(tempbx & 0x07) tempbx += 8;
+  }
   tempbx >>= 3;                                        		/* BPLHDEE  */
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Part1Port,0x17,temp);                        	/* Part1_17h  */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);                        	/* Part1_17h  */
 
-  tempcx = SiS_VGAVT;
-  tempbx = SiS_VGAVDE;
-  tempcx = tempcx-tempbx;                                    	/* GAVT-VGAVDE  */
-  tempbx = SiS_LCDVDES;                                        	/* VGAVDES  */
-  push1 = tempbx;                                      		/* push bx temppush1 */
-  if(SiS_IF_DEF_TRUMPION == 0){
-    if(SiS_LCDResInfo == Panel1024x768)   tempax = 768;
-    if(SiS_LCDResInfo == Panel1280x1024)  tempax = 1024;
-    if(SiS_LCDResInfo == Panel1400x1050)  tempax = 1050;        /* TW: Inserted from 650/LVDS BIOS */
-    else                                  tempax = 960;         /* TW: Inserted from 650/301 BIOS */
-#if 0                                                           /* TW: Removed (650/LVDS BIOS) */
-    if(SiS_IF_DEF_CH70xx == 1) {
-      if(SiS_VBInfo & SetCRT2ToTV) {
-        tempax = SiS_VGAVDE;
-      }
-    }
-#endif
-  } else tempax = SiS_VGAVDE;  /* Trumpion */
-  tempbx = tempbx + tempax;
-  tempax = SiS_VT;                                             	/* VT  */
-  if(tempbx >= SiS_VT)  tempbx = tempbx - tempax;
+  tempcx = SiS_Pr->SiS_VGAVT;
+  tempbx = SiS_Pr->SiS_VGAVDE;
+  tempcx -= tempbx; 	                                   	/* GAVT-VGAVDE  */
+  tempbx = SiS_Pr->SiS_LCDVDES;                                	/* VGAVDES  */
+  push1 = tempbx;                                      		
+  if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)        tempax = 768;
+    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempax = 768;
+    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempax = 1024;
+    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempax = 1050;
+    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempax = 1200;
+    else                                                           tempax = 960;
+  } else tempax = SiS_Pr->SiS_VGAVDE;  /* Trumpion */
+
+  tempbx += tempax;
+  tempax = SiS_Pr->SiS_VT;                                    	/* VT  */
+  if(tempbx >= tempax)  tempbx -= tempax;
+
+  push2 = tempbx;                                      		
+ 
+  tempcx >>= 2;	
+
+  /* TW: 650/30xLV 1.10.6s, 740/LVDS */
+  if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
+      ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
+     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 1;
+   	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)   tempcx = 3;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 3;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 1;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 1;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 1;
+	else                                                           tempcx = 0x0057;
+     }
+  }
 
-  push2 = tempbx;                                      		/* push bx  temppush2  */
-  tempcx >>= 1;
-  tempbx = tempbx + tempcx;
-  tempbx++;                                                	/* BPLVRS  */
-  if(tempbx >= tempax)   tempbx = tempbx - tempax;
-  temp = tempbx&0x00FF;
-  SiS_SetReg1(SiS_Part1Port,0x18,temp);                         /* Part1_18h  */
+  tempbx += tempcx;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+     tempbx++;                                                	/* BPLVRS  */
+  }
+  if(tempbx >= tempax)   tempbx -= tempax;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);                             /* Part1_18h  */
 
   tempcx >>= 3;
-  tempcx = tempcx + tempbx;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 3;
+   	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)   tempcx = 5;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 5;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 5;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 2;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 2;
+	}
+     }
+  }
+  tempcx += tempbx;
   tempcx++;                                                	/* BPLVRE  */
   temp = tempcx & 0x00FF;
   temp &= 0x0F;
-  if(SiS_IF_DEF_LVDS == 1) {
-     SiS_SetRegANDOR(SiS_Part1Port,0x19,0xf0,temp);             /* TW: Inserted from 650/LVDS BIOS */
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);
   } else {
-     temp |= 0x30;                                              /* TW: Inserted from 650/301 BIOS */
-     SiS_SetRegANDOR(SiS_Part1Port,0x19,0xC0,temp);             /* Part1_19h  (Was ~0x0f) */
+     /* TW: 650/30xLV 1.10.6s, Xabre */
+     temp |= 0xC0;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);             /* Part1_19h  */
   }
 
   temp = (tempbx & 0xFF00) >> 8;
   temp &= 0x07;
   temp <<= 3;  		                               		/* BPLDESKEW =0 */
-  tempbx = SiS_VGAVDE;
-  if(tempbx != SiS_VDE)              temp |= 0x40;
-  if(SiS_SetFlag & EnableLVDSDDA)    temp |= 0x40;
-  if(SiS_IF_DEF_LVDS == 1) {
-      if(SiS_LCDInfo & LCDRGB18Bit)  temp |= 0x80;              /* TW: 650/301 BIOS does not check this! */
-      SiS_SetRegANDOR(SiS_Part1Port,0x1A,0x87,temp);            /* Part1_1Ah */
+  tempbx = SiS_Pr->SiS_VGAVDE;
+  if(tempbx != SiS_Pr->SiS_VDE)              temp |= 0x40;
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)    temp |= 0x40;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+        if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
+     }
   } else {
-      SiS_SetRegANDOR(SiS_Part1Port,0x1A,0x07,temp);            /* Part1_1Ah */
+     if(IS_SIS650) {
+        /* TW: 650/30xLV 1.10.6s */
+        if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+           if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
+        }
+     } else {
+	if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)  temp |= 0x80;
+     }
   }
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);            /* Part1_1Ah */
 
-  tempbx = push2;                                      		/* p bx temppush2 BPLVDEE  */
-  tempcx = push1;                                      		/* pop cx temppush1 NPLVDES */
+  tempbx = push2;                                      		/* BPLVDEE  */
+  tempcx = push1;                                      		/* NPLVDES */
   push1 = (USHORT)(tempeax & 0xFFFF);
 
-  if(!(SiS_VBInfo & SetInSlaveMode)) {
-    if(SiS_LCDResInfo == Panel800x600) {
+  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
       if(resinfo == 7) tempcx++;
     }
-    if(SiS_IF_DEF_LVDS == 0) {	                                /* TW: Inserted from 650/LVDS BIOS */
-        if(resinfo == 8) tempcx++;				/* TW: Modified according to 650/301 BIOSes */
-    }
-    if(SiS_LCDResInfo == Panel640x480) {                        /* TW: Inserted from 650/301+LVDS BIOSes */
-        tempbx = SiS_VGAVDE;                                    /* TW: Inserted from 650/301+LVDS BIOS */
-	tempcx = tempbx;					/* TW: Inserted from 650/301+LVDS BIOS */
-        tempbx--;						/* TW: Inserted from 650/301+LVDS BIOS */
-    }
+  }
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+    tempbx = SiS_Pr->SiS_VGAVDE;
+    tempcx = tempbx;
+    tempbx--;
   }
 
   temp = (tempbx & 0xFF00) >> 8;
   temp &= 0x07;
   temp <<= 3;
   temp = temp | (((tempcx & 0xFF00) >> 8) & 0x07);
-  SiS_SetReg1(SiS_Part1Port,0x1D,temp);                          /* Part1_1Dh */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);                          /* Part1_1Dh */
 
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Part1Port,0x1C,temp);                          /* Part1_1Ch  */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);                          /* Part1_1Ch  */
 
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Part1Port,0x1B,temp);                          /* Part1_1Bh  */ 
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);                          /* Part1_1Bh  */
 
-  tempecx = SiS_VGAVT;
-  tempebx = SiS_VDE;
-  tempeax = SiS_VGAVDE;
-  tempecx = tempecx-tempeax;                                 	/* VGAVT-VGAVDE  */
+  tempecx = SiS_Pr->SiS_VGAVT;
+  tempebx = SiS_Pr->SiS_VDE;
+  tempeax = SiS_Pr->SiS_VGAVDE;
+  tempecx -= tempeax;    	                             	/* VGAVT-VGAVDE  */
   tempeax <<= 18;
   temp = (USHORT)(tempeax % tempebx);
   tempeax = tempeax / tempebx;
-  if(temp != 0)  tempeax++;
+  if(temp)  tempeax++;
   tempebx = tempeax;                                        	/* BPLVCFACT  */
   tempvcfact = tempeax;
-  temp=(USHORT)(tempebx & 0x00FF);
-  SiS_SetReg1(SiS_Part1Port,0x37,temp);
+  temp = (USHORT)(tempebx & 0x00FF);
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp);
 
-  temp=(USHORT)((tempebx & 0x00FF00) >> 8);
-  SiS_SetReg1(SiS_Part1Port,0x36,temp);
+  temp = (USHORT)((tempebx & 0x00FF00) >> 8);
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);
 
   temp = (USHORT)((tempebx & 0x00030000) >> 16);
-  if(SiS_VDE==SiS_VGAVDE) temp |= 0x04;
-  SiS_SetReg1(SiS_Part1Port,0x35,temp);
-  
-  tempecx = SiS_VGAHDE;
-  tempebx = SiS_HDE;
+  if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);
+
+  tempecx = SiS_Pr->SiS_VGAHDE;
+  if(modeflag & HalfDCLK) tempecx >>= 1;
+  tempebx = SiS_Pr->SiS_HDE;
   tempeax = tempecx;
   tempeax <<= 16;
+  temp = tempeax % tempebx;
   tempeax = tempeax / tempebx;
+  if(temp) tempeax++;
   if(tempebx == tempecx)  tempeax = 0xFFFF;
   tempecx = tempeax;
-  tempeax = SiS_VGAHDE;
+  tempeax = SiS_Pr->SiS_VGAHDE;
+  if(modeflag & HalfDCLK) tempeax >>= 1;
   tempeax <<= 16;
   tempeax = tempeax / tempecx;
   tempecx <<= 16;
   tempeax--;
   tempecx = tempecx | (tempeax & 0xFFFF);
-  temp=(USHORT)(tempecx & 0x00FF);
-  SiS_SetReg1(SiS_Part1Port,0x1F,temp);                          /* Part1_1Fh  */
+  temp = (USHORT)(tempecx & 0x00FF);
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp);                          /* Part1_1Fh  */
 
-  tempeax = SiS_VGAVDE;
+  tempeax = SiS_Pr->SiS_VGAVDE;
   tempeax <<= 18;
   tempeax = tempeax / tempvcfact;
   tempbx = (USHORT)(tempeax & 0x0FFFF);
 
-  if(SiS_LCDResInfo == Panel1024x768) tempbx--;
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
 
-  if(SiS_SetFlag & EnableLVDSDDA)  tempbx = 1;
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)  tempbx = 1;
 
   temp = ((tempbx & 0xFF00) >> 8) << 3;
   temp = temp | (USHORT)(((tempecx & 0x0000FF00) >> 8) & 0x07);
-  SiS_SetReg1(SiS_Part1Port,0x20,temp);                         /* Part1_20h */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);                         /* Part1_20h */
 
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Part1Port,0x21,temp);                         /* Part1_21h */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);                         /* Part1_21h */
 
   tempecx >>= 16;   	                                  	/* BPLHCFACT  */
-  if(!(modeflag & HalfDCLK)) tempecx >>= 1;			/* TW: Inserted from BIOS */
-  temp=(USHORT)((tempecx & 0x0000FF00) >> 8);
-  SiS_SetReg1(SiS_Part1Port,0x22,temp);                         /* Part1_22h */
+  if(modeflag & HalfDCLK) tempecx >>= 1;
+  temp = (USHORT)((tempecx & 0x0000FF00) >> 8);
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);                         /* Part1_22h */
 
   temp=(USHORT)(tempecx & 0x000000FF);
-  SiS_SetReg1(SiS_Part1Port,0x23,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);
+
+#if 0
+  /* TW: Missing code (calles int 2f) (650/302LV 1.10.6s; 1.10.7w doesn't do this) */
+  if(xxx()) {
+      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0e,0xda);
+  }
+#endif
 
-  /* TW: Only for 650/LVDS and 301LV/302LV */
-  if((SiS_IF_DEF_LVDS == 1) || (SiS_VBInfo & (VB_SIS301LV|VB_SIS302LV))){
-  	SiS_SetReg1(SiS_Part1Port,0x1e,0x20);
+  /* TW: Only for LVDS and 301LV/302LV */
+  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)){
+  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x20);
   }
 
   return;
 }
+#endif  /* SIS 315 */
 
-/* TW: Double-checked against 650/LVDS (1.10.07) and 650/301 BIOS */
-void SiS_SetCRT2Offset(USHORT SiS_Part1Port,UCHAR *ROMAddr,USHORT ModeNo,
+void SiS_SetCRT2Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
                        USHORT ModeIdIndex ,USHORT RefreshRateTableIndex,
 		       PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT offset;
   UCHAR temp;
 
-  if(SiS_VBInfo & SetInSlaveMode) return;
+  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
 
-  offset = SiS_GetOffset(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+  offset = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                          HwDeviceExtension);
+#if 0
+  if(SiS_Pr->LCDResInfo == 13) offset >>= 1;
+  if(SiS_Pr->LCDResInfo == 12) offset >>= 1;
+#endif			 
   temp = (UCHAR)(offset & 0xFF);
-  SiS_SetReg1(SiS_Part1Port,0x07,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);
   temp = (UCHAR)((offset & 0xFF00) >> 8);
-  SiS_SetReg1(SiS_Part1Port,0x09,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,temp);
   temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
-  SiS_SetReg1(SiS_Part1Port,0x03,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,temp);
 }
 
-/* TW: Checked with 650/LVDS and 650/301 BIOS */
 USHORT
-SiS_GetOffset(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
               USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT temp,colordepth;
   USHORT modeinfo,index,infoflag;
-  USHORT mode960low, mode960high;
-#if 0
-  USHORT ColorDepth[] = { 0x01, 0x02, 0x04 };
-#endif
 
-  modeinfo = SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
-  infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-  if (HwDeviceExtension->jChipType < SIS_315H ) {
+  if(SiS_Pr->UseCustomMode) {
+     infoflag = SiS_Pr->CInfoFlag;
+     temp = SiS_Pr->CHDisplay / 16;
+  } else {
+     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+     modeinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+  
+     if(HwDeviceExtension->jChipType < SIS_315H ) {
     	index = (modeinfo >> 4) & 0xFF;
-	/* TW: Modes 1280x960 changed number, so this is redundant */
-	mode960low = 0x7c;
-	mode960high = 0x7e;
-  } else {
-    	index = (modeinfo >> 8) & 0xFF;       /* TW: In 650 BIOS (LVDS AND 301), 1280x960 modes are 7b-7d! */
-	mode960low = 0x7c;                    /* TW: This is a bug in both BIOS versions ! */
-	mode960high = 0x7e;		      /* TW: Corrected here in LVDS BIOS 1.10.07, but not in tables! */
-  }
+     } else {
+    	index = (modeinfo >> 8) & 0xFF;
+     }
 
-#if 0
-  /* TW: Not doing this strange stuff makes 1280x960 at least work on CRT1 */
-  if((ModeNo >= mode960low) && (ModeNo <= mode960high)) {
-    	temp = ModeNo - mode960low;
-    	colordepth = ColorDepth[temp];
-    	temp = 0x6b;  /* TW: Why the heck? */
-  } else {
-#endif
-        temp = SiS_ScreenOffset[index];
-        colordepth = SiS_GetColorDepth(ROMAddr,ModeNo,ModeIdIndex);
-#if 0
+     temp = SiS_Pr->SiS_ScreenOffset[index];
   }
-#endif
+  
+  colordepth = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
 
   if(infoflag & InterlaceMode) temp <<= 1;
 
   temp *= colordepth;
 
-  /* TW: Added this entire "if"-section from 650/LVDS BIOS */
-  if((ModeNo >= 0x26) && (ModeNo <= 0x28)) {
+  /* TW: For 1400x1050 and 856x480 */
+  if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) || 
+        ModeNo == 0x3f || 
+	ModeNo == 0x42 || 
+	ModeNo == 0x45 ) ||
+      (SiS_Pr->UseCustomMode && (SiS_Pr->CHDisplay % 16)) ) {
         colordepth >>= 1;
 	temp += colordepth;
   }
@@ -1767,93 +2005,158 @@
   return(temp);
 }
 
-/* Checked with 650/LVDS BIOS */
 USHORT
-SiS_GetColorDepth(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
   USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8};
   SHORT  index;
   USHORT modeflag;
 
-  if(ModeNo <= 0x13)
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  else
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
+  } else {
+     if(ModeNo <= 0x13)
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     else
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }	
 
   index = (modeflag & ModeInfoFlag) - ModeEGA;
   if(index < 0) index = 0;
   return(ColorDepth[index]);
 }
 
-/* TW: Checked against 650/LVDS (1.10.07), 650/301 and 630/301B BIOS */
 void
-SiS_SetCRT2Sync(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT tempah=0,tempbl,infoflag,flag;
 
   flag = 0;
-  tempbl = 0xC0;   /* TW: Severe BIOS bug in all BIOSes except 650/LVDS 1.10.07 */
+  tempbl = 0xC0;
 
-  infoflag = SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+  infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
 
-  if(SiS_IF_DEF_LVDS == 1) {				     /* LVDS */
-    if(SiS_VBInfo & SetCRT2ToLCD) {
-      tempah = SiS_LCDInfo;
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
-              tempbl = tempah & 0xc0;
-      }
-      if(SiS_LCDInfo & LCDSync) {
-        flag = 1;
-      }
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
+
+    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+       tempah = 0;
+    } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
+       tempah = SiS_Pr->SiS_LCDInfo;
+    } else tempah = infoflag >> 8;
+    
+    tempah &= 0xC0;
+    
+    tempah |= 0x20;
+    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+
+    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+       if(HwDeviceExtension->jChipType >= SIS_315H) {
+          tempah >>= 3;
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
+       }
+    } else {
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
     }
-  } else if ( (HwDeviceExtension->jChipType < SIS_315H) &&   /* 630/301B */
-              (SiS_VBType & VB_SIS301BLV302BLV) ) {
-     if(SiS_VBInfo & SetCRT2ToLCD) {
-        tempah = SiS_LCDInfo;
-	if(SiS_LCDInfo & LCDSync) {
-           flag = 1;
-        }
-     }
-  } else if (HwDeviceExtension->jChipType < SIS_315H) {      /* 630/301 */
-     if(SiS_VBInfo & SetCRT2ToLCD) {
-         tempah = SiS_LCDInfo;
-	 if(SiS_LCDInfo & LCDNonExpandingShift) {
-	    flag = 1;
-	 }
-     }
-  }
 
-  if(flag != 1) tempah = infoflag >> 8;
+  } else {
 
-  tempah &= 0xC0;
-  tempah |= 0x20;
+     if(HwDeviceExtension->jChipType < SIS_315H) {
 
-  if(!(SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+#ifdef SIS300  /* ---- 300 series --- */
 
-  if (SiS_LCDResInfo == Panel640x480) {
-	/* TW: BIOS does something here (301, 301LV and LVDS) @@@ */
-  }
+        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {			/* 630 - 301B(-DH) */
 
-  if(!(SiS_VBType & VB_SIS301)) {
-  	tempah &= 0x3f;
-  	tempah |= tempbl;
-  }
+            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+               tempah = SiS_Pr->SiS_LCDInfo;
+	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+                  flag = 1;
+               }
+            }
+            if(flag != 1) tempah = infoflag >> 8;
+            tempah &= 0xC0;
+	    
+            tempah |= 0x20;
+            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
 
-  SiS_SetRegANDOR(SiS_Part1Port,0x19,0x3F,tempah);
+            if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+	       	/* TW: BIOS does something here @@@ */
+            }
+
+ 	    tempah &= 0x3f;
+  	    tempah |= tempbl;
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+
+         } else {							/* 630 - 301 */
+
+            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+               tempah = SiS_Pr->SiS_LCDInfo;
+	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCDShift) { /* ! */
+	          flag = 1;
+	       }
+            }
+            if(flag != 1) tempah = infoflag >> 8;
+            tempah &= 0xC0;
+            tempah |= 0x30;
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x3F,tempah);
+
+         }
+
+#endif /* SIS300 */
+
+      } else {
+
+#ifdef SIS315H  /* ----- 310/325 series ---- */
+
+         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	  		/* 310/325 - 30xLV */
+
+            tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
+            tempah &= 0xC0;
+            tempah |= 0x20;
+            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+
+         } else {							/* 310/325 - 301, 301B */
+
+            tempah = infoflag >> 8;
+            tempah &= 0xC0;
+	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+	          tempah = SiS_Pr->SiS_LCDInfo;
+	          tempah &= 0xC0;
+	       }
+	    }
+	    
+            tempah |= 0x20;
+            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+#if 0
+            if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+		/* TW: BIOS does something here @@@ */
+            }
+#endif	    
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+
+         } 
+	 
+#endif  /* SIS315H */
+      }
+   }
 }
 
-/* TW: Set FIFO on 300 series */
-/* TW: Checked against 630/301B BIOS; does not set PCI registers */
+/* TW: Set CRT2 FIFO on 300/630/730 */
+#ifdef SIS300
 void
-SiS_SetCRT2FIFO_300(UCHAR *ROMAddr,USHORT ModeNo,
+SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
                     PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT temp,index;
   USHORT modeidindex,refreshratetableindex;
-  USHORT VCLK,MCLK,colorth=0,data2;
+  USHORT VCLK=0,MCLK,colorth=0,data2=0;
+  USHORT tempal, tempah, tempbx, tempcl, tempax;
+  USHORT CRT1ModeNo,CRT2ModeNo;
+  USHORT SelectRate_backup;
   ULONG  data,eax;
-  UCHAR  LatencyFactor[] = {
+  const UCHAR  LatencyFactor[] = {
   	97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
         00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
         97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
@@ -1861,88 +2164,247 @@
         80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
         00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
         86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
-        00, 68, 66, 59, 57, 37};      /*; 128 bit    BQ=1   */
+        00, 68, 66, 59, 57, 37        /*; 128 bit    BQ=1   */
+  };
+  const UCHAR  LatencyFactor730[] = {
+         69, 63, 61, 
+	 86, 79, 77,
+	103, 96, 94,
+	120,113,111,
+	137,130,128,    /* <-- last entry, data below */
+	137,130,128,	/* to avoid using illegal values */
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+  };
+  const UCHAR ThLowB[]   = {
+  	81, 4, 72, 6, 88, 8,120,12,
+        55, 4, 54, 6, 66, 8, 90,12,
+        42, 4, 45, 6, 55, 8, 75,12
+  };
+  const UCHAR ThTiming[] = {
+  	1, 2, 2, 3, 0, 1, 1, 2
+  };
+  
+  SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
 
-  SiS_SearchModeID(ROMAddr,&ModeNo,&modeidindex);
-  SiS_SetFlag &= (~ProgrammingCRT2);
-  SiS_SelectCRT2Rate = 0;
-  refreshratetableindex = SiS_GetRatePtrCRT2(ROMAddr,ModeNo,modeidindex);
-
-  if(ModeNo >= 0x13) {
-    index = SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
-    index &= 0x3F;
-    VCLK = SiS_VCLKData[index].CLOCK;
-    index = SiS_GetReg1(SiS_P3c4,0x1A);
+  if(!SiS_Pr->CRT1UsesCustomMode) {
+  
+     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
+     SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&modeidindex);
+     SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+     SiS_Pr->SiS_SelectCRT2Rate = 0;
+     refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo,
+						modeidindex,HwDeviceExtension);
+
+     if(CRT1ModeNo >= 0x13) {
+       index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
+       index &= 0x3F;
+       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;			/* Get VCLK */
+       data2 = SiS_Pr->SiS_ModeType - 2;
+     }
+     
+  } else {
+  
+     CRT1ModeNo = 0xfe;
+     VCLK = SiS_Pr->CSRClock;						/* Get VCLK */
+     data2 = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
+  
+  }			
+     
+  if(CRT1ModeNo >= 0x13) {
+    if(HwDeviceExtension->jChipType == SIS_300) {
+       index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
+    } else {
+       index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
+    }
     index &= 0x07;
-    MCLK = SiS_MCLKData_0[index].CLOCK;
-    data2 = SiS_ModeType - 0x02;
-    switch (data2) {
+    MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;				/* Get MCLK */
+    
+#ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO, "FIFO2: CRT1Mode 0x%x VCLK %d MCLK %d modetype-2 = %d\n",
+    	CRT1ModeNo, VCLK, MCLK, data2);
+#endif  
+  
+    switch(data2) {							/* Get color depth */
       case 0 : 	colorth = 1; break;
       case 1 : 	colorth = 1; break;
       case 2 : 	colorth = 2; break;
       case 3 : 	colorth = 2; break;
       case 4 : 	colorth = 3; break;
       case 5 : 	colorth = 4; break;
+      default:  colorth = 2; break;
     }
-    /* data2=(data2*VCLK)/MCLK;   */  /*  bx */
-    data2 = (colorth * VCLK) / MCLK;  /* TW */
+    data2 = (colorth * VCLK) / MCLK;  
 
-    temp = SiS_GetReg1(SiS_P3c4,0x14);
-    temp = ((temp&0x00FF)>>6)<<1;
-    if(temp == 0) temp=1;
+    temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+    temp = ((temp & 0x00FF) >> 6) << 1;
+    if(temp == 0) temp = 1;
     temp <<= 2;
+    temp &= 0xff;
 
     data2 = temp - data2;
+    
+#ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step1) = %d\n",
+    	data2);
+#endif    
 
-/*  if(data2%(28*16)) {		 TW: WRONG
-      	data2=data2/(28*16);
-      	data2++;
-    } else {
-      	data2=data2/(28*16);
-    } */
-    if((28*16) % data2) {		/* TW */
+    if((28 * 16) % data2) {
       	data2 = (28 * 16) / data2;
       	data2++;
     } else {
       	data2 = (28 * 16) / data2;
     }
+    
+#ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step2) = %d\n",
+    	data2);
+#endif
 
-    index = 0;
-    temp = SiS_GetReg1(SiS_P3c4,0x14);
-    if(temp & 0x0080) index += 12;
+    if(HwDeviceExtension->jChipType == SIS_300) {
 
+	tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
+	tempah &= 0x62;
+	tempah >>= 1;
+	tempal = tempah;
+	tempah >>= 3;
+	tempal |= tempah;
+	tempal &= 0x07;
+	tempcl = ThTiming[tempal];
+	tempbx = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
+	tempbx >>= 6;
+	tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+	tempah >>= 4;
+	tempah &= 0x0c;
+	tempbx |= tempah;
+	tempbx <<= 1;
+	tempal = ThLowB[tempbx + 1];
+	tempal *= tempcl;
+	tempal += ThLowB[tempbx];
+	data = tempal;
+
+    } else if(HwDeviceExtension->jChipType == SIS_730) {
+       
 #ifndef LINUX_XF86
-    SiS_SetReg4(0xcf8,0x800000A0);
-    eax=SiS_GetReg3(0xcfc);
+       SiS_SetReg4(0xcf8,0x80000050);
+       eax = SiS_GetReg3(0xcfc);
 #else
-  /* TW: We use pci functions X offers. We use tag 0, because
-   * we want to read/write to the host bridge (which is always
-   * 00:00.0 on 630, 730 and 540), not the VGA device.
-   */
-    eax = pciReadLong(0x00000000, 0xA0);
+       eax = pciReadLong(0x00000000, 0x50);
+#endif
+       tempal = (USHORT)(eax >> 8);
+       tempal &= 0x06;
+       tempal <<= 5;
+
+#ifndef LINUX_XF86
+       SiS_SetReg4(0xcf8,0x800000A0);
+       eax = SiS_GetReg3(0xcfc);
+#else
+       eax = pciReadLong(0x00000000, 0xA0);
+#endif
+       temp = (USHORT)(eax >> 28);
+       temp &= 0x0F;   
+       tempal |= temp;
+
+#ifdef TWDEBUG
+       xf86DrvMsg(0, X_INFO, "FIFO2: Latencyfactorindex = 0x%x\n", tempal);
+#endif
+      
+       tempbx = tempal;   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
+       tempbx = 0;        /* -- do it like the BIOS anyway... */
+       tempax = tempbx;
+       tempbx &= 0xc0;
+       tempbx >>= 6;
+       tempax &= 0x0f;
+       tempax *= 3;
+       tempbx += tempax;
+       
+       data = LatencyFactor730[tempbx];
+       data += 15;
+       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+       if(!(temp & 0x80)) data += 5;
+       
+    } else {
+
+       index = 0;
+       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+       if(temp & 0x0080) index += 12;
+
+#ifndef LINUX_XF86
+       SiS_SetReg4(0xcf8,0x800000A0);
+       eax = SiS_GetReg3(0xcfc);
+#else
+       /* TW: We use pci functions X offers. We use tag 0, because
+        * we want to read/write to the host bridge (which is always
+        * 00:00.0 on 630, 730 and 540), not the VGA device.
+        */
+       eax = pciReadLong(0x00000000, 0xA0);
 #endif
-    temp=(USHORT)(eax>>24);
-    if(!(temp&0x01)) index += 24;
+       temp = (USHORT)(eax >> 24);
+       if(!(temp&0x01)) index += 24;
 
 #ifndef LINUX_XF86
-    SiS_SetReg4(0xcf8,0x80000050);
-    eax=SiS_GetReg3(0xcfc);
+       SiS_SetReg4(0xcf8,0x80000050);
+       eax = SiS_GetReg3(0xcfc);
 #else
-    eax = pciReadLong(0x00000000, 0x50);
+       eax = pciReadLong(0x00000000, 0x50);
+#endif
+       temp=(USHORT)(eax >> 24);
+       if(temp & 0x01) index += 6;
+
+       temp = (temp & 0x0F) >> 1;
+       index += temp;
+       
+       data = LatencyFactor[index];
+       data += 15;
+       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
+       if(!(temp & 0x80)) data += 5;
+    }
+    
+#ifdef TWDEBUG    
+    xf86DrvMsg(0, X_INFO, "FIFO2: latencyfactor (CRT1) = %d\n", data);
 #endif
-    temp=(USHORT)(eax >> 24);
-    if(temp & 0x01) index += 6;
 
-    temp = (temp & 0x0F) >> 1;
-    index += temp;
-    data = LatencyFactor[index];
-    data += 15;
-    temp = SiS_GetReg1(SiS_P3c4,0x14);
-    if(!(temp & 0x80)) data += 5;
+    data += data2;				/* CRT1 Request Period */
+    
+#ifdef TWDEBUG    
+    xf86DrvMsg(0, X_INFO, "FIFO2: CRT1 request period = %d\n", data);
+#endif
 
-    data += data2;
+    CRT2ModeNo = ModeNo;
+    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+    SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+    SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&modeidindex);    
 
-    SiS_SetFlag |= ProgrammingCRT2;
+    refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
+                                               modeidindex,HwDeviceExtension);
+
+    index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex,
+                            refreshratetableindex,HwDeviceExtension);
+    VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                         	/* Get VCLK  */
+    
+    data2 = SiS_Pr->SiS_ModeType - 2;
+    switch(data2) {							/* Get color depth */
+      case 0 : 	colorth = 1; break;
+      case 1 : 	colorth = 1; break;
+      case 2 : 	colorth = 2; break;
+      case 3 : 	colorth = 2; break;
+      case 4 : 	colorth = 3; break;
+      case 5 : 	colorth = 4; break;
+      default:  colorth = 2; break;
+    }
+    
+#ifdef TWDEBUG    
+    xf86DrvMsg(0, X_INFO, "FIFO2: CRT2Mode 0x%x VCLK %d MCLK %d modetype-2 = %d, colorth %d\n",
+    	CRT2ModeNo, VCLK, MCLK, data2, colorth);
+#endif
 
     data = data * VCLK * colorth;
     if(data % (MCLK << 4)) {
@@ -1951,35 +2413,53 @@
     } else {
       	data = data / (MCLK << 4);
     }
+    
+#ifdef TWDEBUG    
+    xf86DrvMsg(0, X_INFO, "FIFO2: data (unclipped) = 0x%x\n", data);
+#endif    
+    
+    if(data <= 6) data = 6;
+    if(data > 0x14) data = 0x14;
 
-    /* TW: Inserted this entire section */
-    temp = SiS_GetReg1(SiS_Part1Port,0x01);
-    if( ( (HwDeviceExtension->jChipType == SIS_630) ||
-         (HwDeviceExtension->jChipType == SIS_730) ) &&
-       (HwDeviceExtension->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
-    {
-	temp = (temp & (~0x1F)) | 0x1b;
+    temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x01);
+    if(HwDeviceExtension->jChipType == SIS_300) {
+       if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
+       else             temp = (temp & (~0x1F)) | 0x16;
+       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+       		temp = (temp & (~0x1F)) | 0x13;
+       }
     } else {
-	temp = (temp & (~0x1F)) | 0x16;
+       if( ( (HwDeviceExtension->jChipType == SIS_630) ||
+             (HwDeviceExtension->jChipType == SIS_730) )  &&
+           (HwDeviceExtension->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
+      {
+	  temp = (temp & (~0x1F)) | 0x1b;
+      } else {
+	  temp = (temp & (~0x1F)) | 0x16;
+      }
     }
-    SiS_SetRegANDOR(SiS_Part1Port,0x01,0xe0,temp);
+    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
 
-    if(data <= 6) data = 6;
-    if(data > 0x14) data = 0x14;
     if( (HwDeviceExtension->jChipType == SIS_630) &&
         (HwDeviceExtension->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
     {
    	if(data > 0x13) data = 0x13;
     }
-    SiS_SetRegANDOR(SiS_Part1Port,0x02,~0x01F,data);
-   /* TW end */
+    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
+    
+  } else {  /* If mode <= 0x13, we just restore everything */
+  
+    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+    SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
+    
   }
 }
+#endif
 
-/* TW: Set FIFO on 310 series */
+/* TW: Set FIFO on 310/325/330 series */
 #ifdef SIS315H
 void
-SiS_SetCRT2FIFO_310(UCHAR *ROMAddr,USHORT ModeNo,
+SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
                     PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
 
@@ -1994,38 +2474,57 @@
   USHORT ModeIdIndex;
   USHORT RefreshRateTableIndex;
   USHORT SelectRate_backup;
+  
+  SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
+  
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,0x3B);
 
-  SiS_SetReg1(SiS_Part1Port,0x01,0x3B);
-
-  CRT1ModeNo = SiS_CRT1Mode;                             /* get CRT1 ModeNo */
-  SiS_SearchModeID(ROMAddr,&CRT1ModeNo,&ModeIdIndex);
+  if(!SiS_Pr->CRT1UsesCustomMode) {
+  
+     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
+     SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&ModeIdIndex);
 
-  SiS_SetFlag &= (~ProgrammingCRT2);
-  SelectRate_backup = SiS_SelectCRT2Rate;
-  SiS_SelectCRT2Rate = 0;
+     SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);   
+     SiS_Pr->SiS_SelectCRT2Rate = 0;
 
-  /* Set REFIndex for crt1 refreshrate */
-  RefreshRateTableIndex = SiS_GetRatePtrCRT2(ROMAddr,CRT1ModeNo,
-                                             ModeIdIndex);
+     /* Get REFIndex for crt1 refreshrate */
+     RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo,
+                                             ModeIdIndex,HwDeviceExtension);
 
-  index = SiS_GetVCLK2Ptr(ROMAddr,CRT1ModeNo,ModeIdIndex,
+     index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex,
                           RefreshRateTableIndex,HwDeviceExtension);
-  tempax = SiS_VCLKData[index].CLOCK;                         /* Get DCLK (VCLK?) */
-
-  tempbx = SiS_GetColorDepth(ROMAddr,CRT1ModeNo,ModeIdIndex); /* Get colordepth */
-  tempbx >>= 1;
-  if(!tempbx) tempbx++;
-
+     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                        /* Get VCLK */
+     
+     tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex); /* Get colordepth */
+     tempbx >>= 1;
+     if(!tempbx) tempbx++; 
+     
+  } else {
+  
+     tempax = SiS_Pr->CSRClock;						/* Get VCLK */
+     tempbx = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
+     switch(tempbx) {							/* Get color depth */
+       case 0 : 	tempbx = 1; break;
+       case 1 : 	tempbx = 1; break;
+       case 2 : 	tempbx = 2; break;
+       case 3 : 	tempbx = 2; break;
+       case 4 : 	tempbx = 3; break;
+       case 5 : 	tempbx = 4; break;
+       default:  	tempbx = 2; break;
+     }
+  
+  }
+    
   tempax *= tempbx;
 
-  tempbx = SiS_GetMCLK(ROMAddr, HwDeviceExtension);		     /* Get MCLK */
+  tempbx = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);     		/* Get MCLK */
 
   tempax /= tempbx;
 
   tempbx = tempax;
 
 #if 0 /* TW: BIOS code is skrewed */
-  if(SiS_GetReg1(SiS_P3c4,0x14) & 0x02) {
+  if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x02) {
    	tempax = 16;
   } else {
     	tempax = 8;
@@ -2046,8 +2545,8 @@
   tempcx += 40;
 
   /* get DRAM latency */
-  tempcl = (SiS_GetReg1(SiS_P3c4,0x17) >> 3) & 0x7;     /* SR17[5:3] DRAM Queue depth */
-  tempch = (SiS_GetReg1(SiS_P3c4,0x17) >> 6) & 0x3;     /* SR17[7:6] DRAM Grant length */
+  tempcl = (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) >> 3) & 0x7;     /* SR17[5:3] DRAM Queue depth */
+  tempch = (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) >> 6) & 0x3;     /* SR17[7:6] DRAM Grant length */
 
   for (temp3 = 0; temp3 < 16; temp3 += 2) {
     if ((CombCode[temp3] == tempcl) && (CombCode[temp3+1] == tempch)) {
@@ -2057,20 +2556,24 @@
 
   tempcx +=  temp3;                                      /* CRT1 Request Period */
 
-  CRT2ModeNo = ModeNo;                                   /* get CRT2 ModeNo */
-  SiS_SearchModeID(ROMAddr,&CRT2ModeNo,&ModeIdIndex);    /* Get ModeID Table */
+  CRT2ModeNo = ModeNo;                                                 /* get CRT2 ModeNo */
+  SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex);           /* Get ModeID Table */
 
-  SiS_SetFlag |= ProgrammingCRT2;
-  SiS_SelectCRT2Rate = SelectRate_backup;
+  SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+  SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
 
-  RefreshRateTableIndex=SiS_GetRatePtrCRT2(ROMAddr,CRT1ModeNo,
-                                           ModeIdIndex);
+  RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
+                                           ModeIdIndex,HwDeviceExtension);
 
-  index = SiS_GetVCLK2Ptr(ROMAddr,CRT2ModeNo,ModeIdIndex,
+  index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex,
                           RefreshRateTableIndex,HwDeviceExtension);
-  tempax = SiS_VCLKData[index].CLOCK;                          /* Get VCLK  */
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                       /* Get VCLK  */
+  } else {
+     tempax = SiS_Pr->SiS_VBVCLKData[index].CLOCK;                     /* Get VCLK  */
+  }
 
-  tempbx = SiS_GetColorDepth(ROMAddr,CRT2ModeNo,ModeIdIndex);  /* Get colordepth */
+  tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex);   /* Get colordepth */
   tempbx >>= 1;
   if(!tempbx) tempbx++;
 
@@ -2078,7 +2581,7 @@
 
   tempax *= tempcx;
 
-  tempbx = SiS_GetMCLK(ROMAddr, HwDeviceExtension);		       /* Get MCLK */
+  tempbx = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);	       /* Get MCLK */
   tempbx <<= 4;
 
   tempcx = tempax;
@@ -2087,412 +2590,469 @@
 
   if (tempax > 0x37)  tempax = 0x37;
 
-  /* TW: 650/LVDS (1.10.07, 1.10.00), 650/301LV overrule calculated value; 315 does not */
-  if(HwDeviceExtension->jChipType == SIS_650) {
+  /* TW: 650/LVDS (1.10.07, 1.10.00), 650/301LV, 740, 330 overrule calculated value; 315 does not */
+  if(HwDeviceExtension->jChipType >= SIS_650) {
   	tempax = 0x04;
   }
-
-  SiS_SetRegANDOR(SiS_Part1Port,0x02,~0x3F,tempax);
+  
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,tempax);
 }
 
 USHORT
-SiS_GetMCLK(UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT index;
 
-  index = SiS_Get310DRAMType(ROMAddr,HwDeviceExtension);
+  index = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension);
   if(index >= 4) {
     index -= 4;
-    return(SiS_MCLKData_1[index].CLOCK);
+    return(SiS_Pr->SiS_MCLKData_1[index].CLOCK);
   } else {
-    return(SiS_MCLKData_0[index].CLOCK);
+    return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
   }
 }
 #endif
 
 /* TW: Checked against 650/LVDS 1.10.07 BIOS */
 void
-SiS_GetLVDSDesData(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_GetLVDSDesData(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                    USHORT RefreshRateTableIndex,
 		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT modeflag;
   USHORT PanelIndex,ResIndex;
-  SiS_LVDSDesStruct  *PanelDesPtr=NULL;
+  const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
 
-  if((SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo & SetCRT2ToLCDA) ) {
+  if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) {
 
-     SiS_GetLVDSDesPtrA(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+#ifdef SIS315H  
+     SiS_GetLVDSDesPtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                         &PanelIndex,&ResIndex);
+			
      switch (PanelIndex)
      {
-     	case  0: PanelDesPtr = LVDS1024x768Des_1;   break;  /* --- expanding --- */
-     	case  1: PanelDesPtr = LVDS1280x1024Des_1;  break;
-     	case  2: PanelDesPtr = LVDS1280x960Des_1;   break;
-     	case  3: PanelDesPtr = LVDS1024x768Des_2;   break;  /* --- non expanding --- */
-     	case  4: PanelDesPtr = LVDS1280x1024Des_2;  break;
-     	case  5: PanelDesPtr = LVDS1280x960Des_2;   break;
+     	case  0: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1;   break;  /* --- expanding --- */
+     	case  1: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_1;  break;
+	case  2: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_1;  break;
+	case  3: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_1;  break;
+     	case  4: PanelDesPtr = SiS_Pr->LVDS1024x768Des_2;   break;  /* --- non expanding --- */
+     	case  5: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_2;  break;
+	case  6: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_2;  break;
+	case  7: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_2;  break;
+	default: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1;   break;
      }
+#endif
 
   } else {
 
-     SiS_GetLVDSDesPtr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+     SiS_GetLVDSDesPtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                        &PanelIndex,&ResIndex,HwDeviceExtension);
 
      switch (PanelIndex)
      {
-     	case  0: PanelDesPtr = SiS_PanelType00_1;   break; /* --- expanding --- | Gericom 1st supersonic (310) */
-     	case  1: PanelDesPtr = SiS_PanelType01_1;   break;
-     	case  2: PanelDesPtr = SiS_PanelType02_1;   break;
-     	case  3: PanelDesPtr = SiS_PanelType03_1;   break;
-     	case  4: PanelDesPtr = SiS_PanelType04_1;   break;
-     	case  5: PanelDesPtr = SiS_PanelType05_1;   break;
-     	case  6: PanelDesPtr = SiS_PanelType06_1;   break;
-     	case  7: PanelDesPtr = SiS_PanelType07_1;   break;
-     	case  8: PanelDesPtr = SiS_PanelType08_1;   break;
-     	case  9: PanelDesPtr = SiS_PanelType09_1;   break;
-     	case 10: PanelDesPtr = SiS_PanelType0a_1;   break;
-     	case 11: PanelDesPtr = SiS_PanelType0b_1;   break;
-     	case 12: PanelDesPtr = SiS_PanelType0c_1;   break;	/* TW: Clevo 2202 (300)  */
-     	case 13: PanelDesPtr = SiS_PanelType0d_1;   break;
-     	case 14: PanelDesPtr = SiS_PanelType0e_1;   break;	/* TW: Uniwill N271S2 (300) */
-     	case 15: PanelDesPtr = SiS_PanelType0f_1;   break;
-     	case 16: PanelDesPtr = SiS_PanelType00_2;   break;  /* --- non-expanding --- */
-     	case 17: PanelDesPtr = SiS_PanelType01_2;   break;
-     	case 18: PanelDesPtr = SiS_PanelType02_2;   break;
-     	case 19: PanelDesPtr = SiS_PanelType03_2;   break;
-     	case 20: PanelDesPtr = SiS_PanelType04_2;   break;
-     	case 21: PanelDesPtr = SiS_PanelType05_2;   break;
-     	case 22: PanelDesPtr = SiS_PanelType06_2;   break;
-     	case 23: PanelDesPtr = SiS_PanelType07_2;   break;
-     	case 24: PanelDesPtr = SiS_PanelType08_2;   break;
-     	case 25: PanelDesPtr = SiS_PanelType09_2;   break;
-     	case 26: PanelDesPtr = SiS_PanelType0a_2;   break;
-     	case 27: PanelDesPtr = SiS_PanelType0b_2;   break;
-     	case 28: PanelDesPtr = SiS_PanelType0c_2;   break;     /* TW: Gericom 2200C (300) */
-     	case 29: PanelDesPtr = SiS_PanelType0d_2;   break;
-     	case 30: PanelDesPtr = SiS_PanelType0e_2;   break;
-     	case 31: PanelDesPtr = SiS_PanelType0f_2;   break;
-     	case 32: PanelDesPtr = SiS_CHTVUNTSCDesData;   break;
-     	case 33: PanelDesPtr = SiS_CHTVONTSCDesData;   break;
-     	case 34: PanelDesPtr = SiS_CHTVUPALDesData;    break;
-     	case 35: PanelDesPtr = SiS_CHTVOPALDesData;    break;
-     }
-  }
-  SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
-  SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
-
-  if(SiS_LCDInfo & LCDNonExpanding){
-    if(!(SiS_SetFlag & CRT2IsVGA)) {
-      if((HwDeviceExtension->jChipType < SIS_315H) || (SiS_LCDResInfo != Panel1280x1024)) {  /* TW: New from 650/LVDS 1.10.07 */
-        if(SiS_LCDResInfo >= Panel1024x768){
-          if(ModeNo <= 0x13){
-	    modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	    if(HwDeviceExtension->jChipType < SIS_315H) {
-	         if(!(modeflag & HalfDCLK)) {
-                     SiS_LCDHDES = 320;
-		 }
-	    } else {
-	         /* TW: New from 650/LVDS 1.10.07 */
-	         if(SiS_LCDResInfo == Panel1024x768)
-	             SiS_LCDHDES = 480;
-                 if(SiS_LCDResInfo == Panel1400x1050)
-	             SiS_LCDHDES = 804;
-                 if(!(modeflag & HalfDCLK)) {
-                     SiS_LCDHDES = 320;
-	             if(SiS_LCDResInfo == Panel1400x1050)
-	                SiS_LCDHDES = 632;
+     	case  0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1;   break;   /* ---  */
+     	case  1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1;   break;
+     	case  2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1;   break;
+     	case  3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1;   break;
+     	case  4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1;   break;
+     	case  5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1;   break;
+     	case  6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1;   break;
+     	case  7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1;   break;
+     	case  8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1;   break;
+     	case  9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1;   break;
+     	case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1;   break;
+     	case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1;   break;
+     	case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1;   break;
+     	case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1;   break;
+     	case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;   break;
+     	case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1;   break;
+     	case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2;   break;    /* --- */
+     	case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2;   break;
+     	case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2;   break;
+     	case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2;   break;
+     	case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2;   break;
+     	case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2;   break;
+     	case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2;   break;
+     	case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2;   break;
+     	case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2;   break;
+     	case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2;   break;
+     	case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2;   break;
+     	case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2;   break;
+     	case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2;   break;
+     	case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2;   break;
+     	case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2;   break;
+     	case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2;   break;
+	case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1;   break;    /* pass 1:1 */
+	case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2;   break;
+     	case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData;   break; /* TV */
+     	case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData;   break;
+     	case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;    break;
+     	case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;    break;
+	default:
+		if(HwDeviceExtension->jChipType < SIS_315H)
+		   PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
+		else
+		   PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
+		break;
+     }
+  }
+  SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
+  SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
+
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD){
+     if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+        if(ModeNo <= 0x13) {
+           modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+	   if(!(modeflag & HalfDCLK)) {
+	      SiS_Pr->SiS_LCDHDES = 632;
+	   }
+        }
+     } else {
+        if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+           if( (HwDeviceExtension->jChipType < SIS_315H) || 
+	       (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) ) {  
+              if(SiS_Pr->SiS_LCDResInfo >= SiS_Pr->SiS_Panel1024x768){
+                 if(ModeNo <= 0x13) {
+	            modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+	            if(HwDeviceExtension->jChipType < SIS_315H) {
+	               if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
+	            } else {
+	               if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
+	                  SiS_Pr->SiS_LCDHDES = 480;
+                       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
+	                  SiS_Pr->SiS_LCDHDES = 804;
+		       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
+	                  SiS_Pr->SiS_LCDHDES = 704;
+                       if(!(modeflag & HalfDCLK)) {
+                          SiS_Pr->SiS_LCDHDES = 320;
+	                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
+	                     SiS_Pr->SiS_LCDHDES = 632;
+		          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
+	                     SiS_Pr->SiS_LCDHDES = 542;
+                       }
+                    }
                  }
-            }
-          }
+              }
+           }
         }
-      }
-    }
+     }
   }
   return;
 }
 
-/* TW: Checked against 630/LVDS (2.04.5c) and 650/LVDS (1.10.07) BIOS */
 void
-SiS_GetLVDSDesPtr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                   USHORT RefreshRateTableIndex,USHORT *PanelIndex,
 		  USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT tempbx,tempal,modeflag;
 
-  if(ModeNo<=0x13) {
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  if(ModeNo <= 0x13) {
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+	tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   } else {
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   }
 
   tempbx = 0;
-  if(SiS_IF_DEF_CH70xx != 0) {
-    if(!(SiS_VBInfo & SetCRT2ToLCD)) {
-      tempbx = 32;
-      if(SiS_VBInfo & SetPALTV) tempbx += 2;
-      if(SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-    }
-  }
-  if(SiS_VBInfo & SetCRT2ToLCD) {
-    tempbx = SiS_LCDTypeInfo;
-    if(SiS_LCDInfo & LCDNonExpanding) tempbx += 16;
-    /* TW: Inserted from 650/LVDS (1.10.07) BIOS */
-    if(SiS_LCDInfo & 0x0100) {
-       if(modeflag & HalfDCLK) tempbx += 16;
-    }
-  }
-  /* TW: Inserted from 630/LVDS and 650/LVDS (1.10.07) BIOS */
-  if(SiS_SetFlag & CRT2IsVGA) {
-    if(SiS_LCDResInfo != Panel640x480)  {
-       tempal = 0x07;
-       if(HwDeviceExtension->jChipType < SIS_315H) {
-          if(SiS_GetReg1(SiS_P3c4,0x13) & 0x80) tempal++;
-       }
-    }
+  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+        tempbx = 50;
+        if((SiS_Pr->SiS_VBInfo & SetPALTV) && (!SiS_Pr->SiS_CHPALM)) tempbx += 2;
+        if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+        /* TW: Nothing special needed for SOverscan    */
+        /*     PALM uses NTSC data, PALN uses PAL data */
+     }
+  }
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+     tempbx = SiS_Pr->SiS_LCDTypeInfo;
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 16;
+     if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+        tempbx = 32;
+        if(modeflag & HalfDCLK) tempbx++;
+     }
+  }
+  /* TW: 630/LVDS and 650/LVDS (1.10.07) BIOS */
+  if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
+        tempal = 0x07;
+        if(HwDeviceExtension->jChipType < SIS_315H) {
+           if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
+        }
+     }
   }
 
   *PanelIndex = tempbx;
   *ResIndex = tempal & 0x1F;
 }
 
+#ifdef SIS315H
 void
-SiS_GetLVDSDesPtrA(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex,USHORT *PanelIndex,
-		   USHORT *ResIndex)
+SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex)
 {
   USHORT tempbx=0,tempal;
 
-  tempbx = SiS_LCDResInfo - PanelMin301;  /* TW: *not* PanelMinLVDS! */
-  if(SiS_LCDInfo & LCDNonExpanding)  tempbx += 3;
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)      tempbx = 2;
+  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 3;
+  else tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
 
-  if(ModeNo<=0x13)
-    	tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 4;
+
+  if(ModeNo <= 0x13)
+     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   else
-    	tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 
   *PanelIndex = tempbx;
   *ResIndex = tempal & 0x1F;
 }
+#endif
 
-/* TW: Checked against 650/LVDS (1.10.07), 650/301LV, 630/301 and 630/301B (II) BIOS */
 void
-SiS_SetCRT2ModeRegs(USHORT BaseAddr,USHORT ModeNo, USHORT ModeIdIndex,
+SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT BaseAddr, USHORT ModeNo, USHORT ModeIdIndex,
                     PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT i,j,modeflag;
-  USHORT tempcl,tempah,tempbl,temp;
+  USHORT tempcl,tempah=0;
+#ifdef SIS300
+  USHORT temp;
+#endif
+#ifdef SIS315H
+  USHORT tempbl;
+#endif
 
-  if(ModeNo<=0x13) {
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   } else {
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+     } else {
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     }
   }
   
   /* TW: BIOS does not do this (neither 301 nor LVDS) */
   /*     (But it's harmless; see SetCRT2Offset) */
-  SiS_SetReg1(SiS_Part1Port,0x03,0x00);   /* fix write part1 index 0  BTDRAM bit Bug */
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x00);   /* fix write part1 index 0  BTDRAM bit Bug */
 
   /* TW: Removed 301B302B301LV302LV check here to match 650/LVDS BIOS */
-  if(SiS_VBInfo & SetCRT2ToLCDA) {
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
 
 	/* TW:   1. for LVDS/302B/302LV **LCDA** */
 
-      SiS_SetRegANDOR(SiS_Part1Port,0x00,0xAF,0x40); /* FUNCTION CONTROL */
-      SiS_SetRegAND(SiS_Part1Port,0x2E,0xF7);
-#if 0  /* TW: Not done in 650/301, 650/LVDS or 650/301LV BIOS*/
-      SiS_SetRegANDOR(SiS_Part1Port,0x13,0xFB,0x04);
-      SiS_SetRegANDOR(SiS_Part1Port,0x2c,0xCF,0x30);
-      SiS_SetRegANDOR(SiS_Part4Port,0x21,0x3F,0xC0);
-      SiS_SetRegANDOR(SiS_Part4Port,0x23,0x7F,0x00);
-#endif
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); /* FUNCTION CONTROL */
+      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
 
   } else {
 
-    for(i=0,j=4;i<3;i++,j++) SiS_SetReg1(SiS_Part1Port,j,0);
+    for(i=0,j=4; i<3; i++,j++) SiS_SetReg1(SiS_Pr->SiS_Part1Port,j,0);
 
-    tempcl = SiS_ModeType;
+    tempcl = SiS_Pr->SiS_ModeType;
 
     if(HwDeviceExtension->jChipType < SIS_315H) {
 
-      /* ---- 300 series ---- */
+#ifdef SIS300    /* ---- 300 series ---- */
 
-      /* TW: Inserted entire if-section from 630/301B BIOS */
-      if(SiS_VBType & VB_SIS301BLV302BLV) {
-	  temp = SiS_GetReg1(SiS_P3c4,0x32);
+      /* For 301BDH: */
+      if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+	  temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32);
 	  temp &= 0xef;
 	  temp |= 0x02;
-	  if(SiS_VBInfo & SetCRT2ToTV) {
+	  if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
 	     temp |= 0x10;
 	     temp &= 0xfd;
 	  }
-	  SiS_SetReg1(SiS_P3c4,0x32,temp);
+	  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
       }
 
-      if(ModeNo > 0x13){
+      if(ModeNo > 0x13) {
         tempcl -= ModeVGA;
-        if((tempcl > 0) || (tempcl == 0)) {  /* TW: tempcl is USHORT -> always true! */
-           tempah = ((0x010 >> tempcl) | 0x080);
+        if((tempcl > 0) || (tempcl == 0)) {      /* TW: tempcl is USHORT -> always true! */
+           tempah = ((0x10 >> tempcl) | 0x80);
         }
-      } else  tempah = 0x080;
+      } else tempah = 0x80;
+
+      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
 
-      if(SiS_VBInfo & SetInSlaveMode)  tempah = (tempah ^ 0x0A0);
+#endif  /* SIS300 */
 
     } else {
 
-    /* ---- 310 series ---- */
+#ifdef SIS315H    /* ---- 310/325/330 series ---- */
 
-      /* TW: Inserted from 650/301/301LV BIOS */
-      if(SiS_VBType & VB_SIS301BLV302BLV) {
-        if(SiS_VBInfo & CRT2DisplayFlag) {
-	   SiS_SetRegOR(SiS_Part1Port,0x2e,0x08);
-        }
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+         if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) {
+	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
+         }
       }
 
       if(ModeNo > 0x13) {
         tempcl -= ModeVGA;
         if((tempcl > 0) || (tempcl == 0)) {  /* TW: tempcl is USHORT -> always true! */
-           tempah = (0x008 >> tempcl);
+           tempah = (0x08 >> tempcl);
            if (tempah == 0) tempah = 1;
-           tempah |= 0x040;
+           tempah |= 0x40;
         }
-      } else  tempah = 0x040;
+      } else tempah = 0x40;
+
+      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0x50;
 
-      if(SiS_VBInfo & SetInSlaveMode)  tempah = (tempah ^ 0x050);
+#endif  /* SIS315H */
 
     }
 
-    if(SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
+    if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
 
-    SiS_SetReg1(SiS_Part1Port,0x00,tempah);  	/* FUNCTION CONTROL */
+    if(HwDeviceExtension->jChipType < SIS_315H) {
+       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,tempah);  		/* FUNCTION CONTROL */
+    } else {
+       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);  	/* FUNCTION CONTROL */
+       } else {
+          if(IS_SIS740) {
+	     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,tempah);  		/* FUNCTION CONTROL */
+	  } else {
+             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);  	/* FUNCTION CONTROL */
+	  }
+       }
+    }
 
-    if(SiS_IF_DEF_LVDS == 0) {
+    if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
 	/* TW:   2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
 
     	tempah = 0x01;
-    	if(!(SiS_VBInfo & SetInSlaveMode)) {
+    	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
       		tempah |= 0x02;
     	}
-    	if(!(SiS_VBInfo & SetCRT2ToRAMDAC)) {
-      		tempah = (tempah ^ 0x05);
-      		if(!(SiS_VBInfo & SetCRT2ToLCD)) {
-        		tempah = (tempah ^ 0x01);
+    	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+      		tempah ^= 0x05;
+      		if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+        		tempah ^= 0x01;
       		}
     	}
 
-    	tempcl = tempah;
+	if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
 
     	if(HwDeviceExtension->jChipType < SIS_315H) {
 
 		/* --- 300 series --- */
-      		tempah = (tempah << 5) & 0xFF;
-      		if(SiS_VBInfo & CRT2DisplayFlag)  tempah=0;
-      		SiS_SetReg1(SiS_Part1Port,0x01,tempah);
 
-      		tempah = tempcl;
+      		tempah = (tempah << 5) & 0xFF;
+      		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
+      		tempah = (tempah >> 5) & 0xFF;
 
     	} else {
 
 		/* --- 310 series --- */
-      		if(SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
-      		tempah = (SiS_GetReg1(SiS_Part1Port,0x2E) & 0xF8) | tempah;
-      		SiS_SetReg1(SiS_Part1Port,0x2E,tempah);
 
-      		tempah = tempcl;
+      		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
+
     	}
 
-    	if((SiS_ModeType == ModeVGA) && (!(SiS_VBInfo & SetInSlaveMode))) {
-      		tempah |= 0x010;
+    	if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
+      		tempah |= 0x10;
 	}
 
-	/* TW: Inserted from 630/301 BIOS */
-	if(SiS_VBType & VB_SIS301) {
-		if(SiS_LCDResInfo == Panel1280x1024) {
+	/* TW: 630/301 BIOS */
+	if((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
+		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
 			tempah |= 0x80;
 		}
 	} else {
 		tempah |= 0x80;
 	}
 
-    	if(SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)){   /* TW: Added -HiVision like in BIOS (650+630) */
-      		if(SiS_VBInfo & SetInSlaveMode) {
-          		tempah |= 0x20;
+    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
+      		if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+			if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+          			tempah |= 0x20;
+			}
       		}
     	}
-    	SiS_SetRegANDOR(SiS_Part4Port,0x0D,0x40,tempah);
 
-    	tempah=0;
-    	if(SiS_VBInfo & SetCRT2ToTV) {
-      		if(SiS_VBInfo & SetInSlaveMode) {
-       			if(SiS_VBType & VB_SIS301BLV302BLV) {
-            			SiS_SetFlag |= RPLLDIV2XO;
-            			tempah |= 0x40;
-       			} else {
-        			if(!(SiS_SetFlag & TVSimuMode)) {
-          				if(!(SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-            					SiS_SetFlag |= RPLLDIV2XO;
-            					tempah |= 0x40;
-          				}
-        			}
-      			}
-     		} else {
-        		SiS_SetFlag |= RPLLDIV2XO;
-        		tempah |= 0x40;
-      		}
+    	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
+
+    	tempah = 0;
+    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+	   if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+      	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+	         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+       		    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+            	       SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
+            	       tempah |= 0x40;
+       		    } else {
+        	       if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) {
+          		  SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
+            		  tempah |= 0x40;
+        	       }
+      		    }
+		 }
+     	      } else {
+        	SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
+        	tempah |= 0x40;
+      	      }
+	   }
     	}
+	/* TW: For 302LV dual-channel */
+	if(HwDeviceExtension->jChipType >= SIS_315H) {
+	    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)
+		    tempah |= 0x40;
+	    }
+	}
 
-	if(SiS_LCDResInfo == Panel1280x1024 || SiS_LCDResInfo == Panel1280x960) {
+	if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+	   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
 		tempah |= 0x80;
 	}
 
-    	SiS_SetReg1(SiS_Part4Port,0x0C,tempah);
+    	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0C,tempah);
 
     } else {
 
     	/* TW: 3. for LVDS */
 
-	/* TW: Inserted if-statement - Part1Port 0x2e not assigned on 300 series */
 	if(HwDeviceExtension->jChipType >= SIS_315H) {
 
 	   /* TW: Inserted this entire section (BIOS 650/LVDS); added ModeType check
 	    *     (LVDS can only be slave in 8bpp modes)
 	    */
 	   tempah = 0x80;
-	   if( (modeflag & CRT2Mode) && (SiS_ModeType > ModeVGA) ) {
-	       if (SiS_VBInfo & DriverMode) {
+	   if( (modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
+	       if (SiS_Pr->SiS_VBInfo & DriverMode) {
 	           tempah |= 0x02;
 	       }
 	   }
 
-	   if(!(SiS_VBInfo & SetInSlaveMode)) {
+	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
                tempah |= 0x02;
     	   }
 
-	   if(SiS_VBInfo & SetCRT2ToTV) {
-	       tempah = tempah ^ 0x01;
+	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+	       tempah ^= 0x01;
 	   }
 
-	   if(SiS_VBInfo & DisableCRT2Display) {
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
 	       tempah = 1;
 	   }
 
-    	   SiS_SetRegANDOR(SiS_Part1Port,0x2e,0xF0,tempah);
+    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
 
 	} else {
 
-	   /* TW: Inserted entire section from 630/LVDS BIOS (added ModeType check) */
+	   /* TW: (added ModeType check) */
 	   tempah = 0;
-	   if( (!(SiS_VBInfo & SetInSlaveMode)) && (SiS_ModeType > ModeVGA) ) {
+	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
                	  tempah |= 0x02;
     	   }
 	   tempah <<= 5;
-	   if(SiS_VBInfo & DisableCRT2Display)
-	       tempah = 0;
 
-	   SiS_SetReg1(SiS_Part1Port,0x01,tempah);
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
+
+	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
 
 	}
 
@@ -2502,221 +3062,337 @@
 
   /* TW: Inserted the entire following section */
 
-  if(SiS_IF_DEF_LVDS == 0) {
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-      if(HwDeviceExtension->jChipType >= SIS_315H) {             /* TW: From 650/301 BIOS */
+      if(HwDeviceExtension->jChipType >= SIS_315H) {
 
-#if 0    /* TW: This is not done in 650/301LV BIOS */
-         tempah = 0x04;
-         tempbl = 0xfb;
-         if(!(SiS_VBInfo & SetCRT2ToLCDA)) {
-            tempah = 0x00;
-	    if(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))
-	       tempbl = 0xff;
-         }
-         SiS_SetRegANDOR(SiS_Part1Port,0x13,tempbl,tempah);
+#ifdef SIS315H
+         if(!(IS_SIS740)) {
+            tempah = 0x04;						   /* For all bridges */
+            tempbl = 0xfb;
+            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+               tempah = 0x00;
+	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
+	          tempbl = 0xff;
+            }
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);   
+	 }
+	 
+	 if(IS_SIS740) {						
+	    tempah = 0x30;
+	    tempbl = 0xcf;
+	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	       tempah = 0x00;
+	    }
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);    
+	 } else {
+	    /* TW: This in order to fix "TV-blue-bug" on 315+301 */
+            if(SiS_Pr->SiS_VBType & VB_SIS301) {
+	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF);             /* For 301   */
+	    } else {
+	       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);   /* For 30xLV */
+	       } else {
+	          tempah = 0x30;					   /* For 301B  */
+	          tempbl = 0xcf;
+	          if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+	             tempah = 0x00;
+		     if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+		        tempbl = 0xff;
+		     }
+	          }
+	          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);    
+	       }
+	    }
+	 }
 
-         SiS_SetRegANDOR(SiS_Part1Port,0x2c,0xCF,0x30);
-#endif
-         /* This is done instead: */
-         tempah = 0x30;
-	 if(SiS_VBInfo & DisableCRT2Display) tempah = 0;
-	 SiS_SetRegANDOR(SiS_Part1Port,0x2c,0xcf,tempah);
-
-#if 0    /* TW: This is not done in 650/301LV BIOS */
-	 SiS_SetRegANDOR(SiS_Part4Port,0x21,0x3f,0xc0);
-#endif
-	 /* This is done instead: */
-	 tempah = 0xc0;
-	 if(SiS_VBInfo & DisableCRT2Display) tempah = 0;
-	 SiS_SetRegANDOR(SiS_Part4Port,0x21,0x3f,tempah);
-
-#if 0    /* TW: This is not done in 650/301LV BIOS */
-	 tempah = 0x00;
-         tempbl = 0x7f;
-         if(!(SiS_VBInfo & SetCRT2ToLCDA)) {
-            tempbl = 0xff;
-	    if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr)))
-	       tempah = 0x80;
-         }
-         SiS_SetRegANDOR(SiS_Part4Port,0x23,tempbl,tempah);
-#endif
-	 /* This is done instead: */
-	 tempah = 0x80;
-	 if(SiS_VBInfo & DisableCRT2Display) tempah = 0;
-	 SiS_SetRegANDOR(SiS_Part4Port,0x23,0x7F,tempah);
+	 if(IS_SIS740) {
+	    tempah = 0xc0;
+  	    tempbl = 0x3f;
+	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	       tempah = 0x00;
+	    } 
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);     
+	 } else {
+	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {			/* For 30xLV */
+	       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);
+	    } else {							/* For 301, 301B */ 
+	        tempah = 0xc0;
+	        tempbl = 0x3f;
+	        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+	           tempah = 0x00;
+		   if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
+		      tempbl = 0xff;
+		   }
+	        }
+	        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);     
+	    }
+	 }
+
+	 if(IS_SIS740) {						
+	    tempah = 0x80;
+	    tempbl = 0x7f;
+	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	       tempah = 0x00;
+	    } 
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
+	 } else {
+	    tempah = 0x00;						/* For all bridges */	
+            tempbl = 0x7f;
+            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+               tempbl = 0xff;
+	       if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)))
+	          tempah |= 0x80;
+            }
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
+	 }
 
-      } else if(SiS_VBType & VB_SIS301BLV302BLV) {		/* TW: From 630/301B BIOS */
+#endif /* SIS315H */
 
-         SiS_SetRegAND(SiS_Part4Port,0x21,0x3f);
+      } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 
-         if(SiS_VBInfo & (SetCRT2ToLCD | DisableCRT2Display))
-	    SiS_SetRegAND(SiS_Part4Port,0x23,0x7F);
-	 else
-	    SiS_SetRegOR(SiS_Part4Port,0x23,0x80);
+         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
+
+         if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
+            (   (SiS_Pr->SiS_VBType & VB_NoLCD) &&
+	        (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ) {
+	    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
+	 } else {
+	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
+	 }
 
       }
 
-  } else {  							/* TW: From 650/LVDS BIOS */
+  } else {  /* LVDS */
 
+#ifdef SIS315H
       if(HwDeviceExtension->jChipType >= SIS_315H) {
-         tempah = 0x04;
-	 tempbl = 0xfb;
-         if(!(SiS_VBInfo & SetCRT2ToLCDA)) {
-            tempah = 0x00;
-	    if(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))
-	       tempbl = 0xff;
-         }
-	 SiS_SetRegANDOR(SiS_Part1Port,0x13,tempbl,tempah);
 
-	 if(SiS_VBInfo & DisableCRT2Display)
-	    SiS_SetRegANDOR(SiS_Part1Port,0x13,0xfb,0x00);
+         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+
+            tempah = 0x04;
+	    tempbl = 0xfb;
+            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+               tempah = 0x00;
+	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
+	          tempbl = 0xff;
+            }
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
+
+	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)
+	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x00);
+
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
+
+	 }
 
-	 SiS_SetRegANDOR(SiS_Part1Port,0x2c,0xcf,0x30);
       }
+#endif
 
   }
 
 }
 
 void
-SiS_GetCRT2Data(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_GetCRT2Data(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                 USHORT RefreshRateTableIndex,
 		PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-  if(SiS_IF_DEF_LVDS == 0) {
-     if(SiS_VBType & VB_SIS301BLV302BLV) {
-        if(SiS_VBInfo & SetCRT2ToLCDA) {
-          SiS_GetCRT2DataLVDS(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+
+           SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+	                      HwDeviceExtension);
         } else {
-	  if((HwDeviceExtension->jChipType < SIS_315H) && (SiS_VBInfo & SetCRT2ToLCD)){
-              SiS_GetCRT2Data301(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
-	      /* TW: Need LVDS Data for LCD on 630/301B! */
-	      SiS_GetCRT2DataLVDS(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
-	  } else {
-	      SiS_GetCRT2Data301(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
-          }
+
+	   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+	       (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+	       
+	      /* TW: Need LVDS Data for LCD on 301BDH */
+	      SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+	                          HwDeviceExtension);
+				  
+	   } else {
+	
+	      SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+	                         HwDeviceExtension);
+           }
+
         }
-     } else
-     	SiS_GetCRT2Data301(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+
+     } else {
+
+     	SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+	                   HwDeviceExtension);
+     }
+
   } else {
-     SiS_GetCRT2DataLVDS(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+  
+     SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                         HwDeviceExtension);
   }
 }
 
 /* Checked with 650/LVDS 1.10.07 BIOS */
 void
-SiS_GetCRT2DataLVDS(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                     USHORT RefreshRateTableIndex,
 		    PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
    USHORT CRT2Index, ResIndex;
-   SiS_LVDSDataStruct *LVDSData = NULL;
+   const SiS_LVDSDataStruct *LVDSData = NULL;
 
-   SiS_GetCRT2ResInfo(ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+   SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+   
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      SiS_Pr->SiS_RVBHCMAX  = 1;
+      SiS_Pr->SiS_RVBHCFACT = 1;
+      SiS_Pr->SiS_NewFlickerMode = 0;
+      SiS_Pr->SiS_RVBHRS = 50;
+      SiS_Pr->SiS_RY1COE = 0;
+      SiS_Pr->SiS_RY2COE = 0;
+      SiS_Pr->SiS_RY3COE = 0;
+      SiS_Pr->SiS_RY4COE = 0;
+   }
 
-   if((SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo & SetCRT2ToLCDA)) {
+   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
-      SiS_GetCRT2PtrA(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+#ifdef SIS315H   
+      SiS_GetCRT2PtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                       &CRT2Index,&ResIndex);
 
       switch (CRT2Index) {
-      	case  0:  LVDSData = SiS_LVDS1024x768Data_1;    break;
-      	case  1:  LVDSData = SiS_LVDS1280x1024Data_1;   break;
-        case  2:  LVDSData = SiS_LVDS1280x960Data_1;    break;
-      	case  3:  LVDSData = SiS_LVDS1024x768Data_2;    break;
-      	case  4:  LVDSData = SiS_LVDS1280x1024Data_2;   break;
-      	case  5:  LVDSData = SiS_LVDS1280x960Data_2;    break;
+      	case  0:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;    break;
+      	case  1:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1;   break;
+        case  2:  LVDSData = SiS_Pr->SiS_LVDS1280x960Data_1;    break;
+	case  3:  LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_1;   break;
+	case  4:  LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_1;   break;
+      	case  5:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2;    break;
+      	case  6:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2;   break;
+      	case  7:  LVDSData = SiS_Pr->SiS_LVDS1280x960Data_2;    break;
+	case  8:  LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_2;   break;
+	case  9:  LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_2;   break;
+	default:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;    break;
       }
+#endif      
 
    } else {
 
-      /* TW: SiS630/301B needs LVDS Data! */
-      if( (HwDeviceExtension->jChipType < SIS_315H) &&
-          (SiS_VBType & VB_SIS301BLV302BLV) &&
-	  (SiS_VBInfo & SetCRT2ToLCD) )
-              SiS_IF_DEF_LVDS = 1;
+      /* TW: 301BDH needs LVDS Data */
+      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+          (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+	      SiS_Pr->SiS_IF_DEF_LVDS = 1;
+      }
 
-      SiS_GetCRT2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+      SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                      &CRT2Index,&ResIndex,HwDeviceExtension);
 
-      /* TW: SiS630/301B needs LVDS Data! */
-      if( (HwDeviceExtension->jChipType < SIS_315H) &&
-          (SiS_VBType & VB_SIS301BLV302BLV) &&
-	  (SiS_VBInfo & SetCRT2ToLCD) )
-              SiS_IF_DEF_LVDS = 0;
+      /* TW: 301BDH needs LVDS Data */
+      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+          (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+              SiS_Pr->SiS_IF_DEF_LVDS = 0;
+      }
 
       switch (CRT2Index) {
-      	case  0:  LVDSData = SiS_LVDS800x600Data_1;    break;
-      	case  1:  LVDSData = SiS_LVDS1024x768Data_1;   break;
-      	case  2:  LVDSData = SiS_LVDS1280x1024Data_1;  break;
-      	case  3:  LVDSData = SiS_LVDS800x600Data_2;    break;
-      	case  4:  LVDSData = SiS_LVDS1024x768Data_2;   break;
-      	case  5:  LVDSData = SiS_LVDS1280x1024Data_2;  break;
-	case  6:  LVDSData = SiS_LVDS640x480Data_1;    break;
-        case  7:  LVDSData = SiS_LVDSXXXxXXXData_1;    break;  /* TW: New */
-	case  8:  LVDSData = SiS_LVDS1400x1050Data_1;  break;  /* TW: New */
-	case  9:  LVDSData = SiS_LVDS1400x1050Data_2;  break;  /* TW: New */
-      	case 10:  LVDSData = SiS_CHTVUNTSCData;        break;
-      	case 11:  LVDSData = SiS_CHTVONTSCData;        break;
-      	case 12:  LVDSData = SiS_CHTVUPALData;         break;
-      	case 13:  LVDSData = SiS_CHTVOPALData;         break;
-      	case 14:  LVDSData = SiS_LVDS320x480Data_1;    break;
-	case 15:  LVDSData = SiS_LVDS1024x600Data_1;   break;  /* TW: New */
-	case 16:  LVDSData = SiS_LVDS1152x768Data_1;   break;  /* TW: New */
-	case 17:  LVDSData = SiS_LVDS1024x600Data_2;   break;  /* TW: New */
-	case 18:  LVDSData = SiS_LVDS1152x768Data_2;   break;  /* TW: New */
+      	case  0:  LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
+      	case  1:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
+      	case  2:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1;  break;
+      	case  3:  LVDSData = SiS_Pr->SiS_LVDS800x600Data_2;    break;
+      	case  4:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2;   break;
+      	case  5:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2;  break;
+	case  6:  LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
+        case  7:  LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1;    break;
+	case  8:  LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1;  break;
+	case  9:  LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2;  break;
+      	case 10:  LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
+      	case 11:  LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
+      	case 12:  LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
+      	case 13:  LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
+      	case 14:  LVDSData = SiS_Pr->SiS_LVDS320x480Data_1;    break;
+	case 15:  LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
+	case 16:  LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1;   break;
+	case 17:  LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2;   break;
+	case 18:  LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2;   break;
+	case 19:  LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1;   break;
+	case 20:  LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2;   break;
+	case 21:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1;  break;
+	case 22:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2;  break;
+	case 90:  LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
+      	case 91:  LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
+      	case 92:  LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
+      	case 93:  LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
+	case 99:  LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;  /* TW: Super Overscan */
+	default:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
      }
    }
 
-   SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
-   SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
-   SiS_HT = (LVDSData+ResIndex)->LCDHT;
-   SiS_VT = (LVDSData+ResIndex)->LCDVT;
-
-  if( (SiS_IF_DEF_LVDS == 0) && (SiS_VBType & VB_SIS301BLV302BLV)) {
-
-    if(!(SiS_LCDInfo & LCDNonExpanding)){
-         if(SiS_LCDResInfo == Panel1024x768){
-           SiS_HDE = 1024;
-           SiS_VDE = 768;
-         } else if(SiS_LCDResInfo == Panel1280x1024){
-           SiS_HDE = 1280;
-           SiS_VDE = 1024;
+   SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
+   SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
+   SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
+   SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
+
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+    if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)){
+         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
+           SiS_Pr->SiS_HDE = 1024;
+           SiS_Pr->SiS_VDE =  768;
+         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024){
+           SiS_Pr->SiS_HDE = 1280;
+           SiS_Pr->SiS_VDE = 1024;
+	 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050){
+           SiS_Pr->SiS_HDE = 1400;
+           SiS_Pr->SiS_VDE = 1050;
+	 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200){
+           SiS_Pr->SiS_HDE = 1600;
+           SiS_Pr->SiS_VDE = 1200;
          } else {
-	   SiS_HDE = 1280;
-	   SiS_VDE = 960;
+	   SiS_Pr->SiS_HDE = 1280;
+	   SiS_Pr->SiS_VDE =  960;
 	 }
     }
 
   } else {
 
-    if(SiS_IF_DEF_TRUMPION == 0) {
-      if((SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_LCDInfo & 0x0100))) {
-        if(SiS_LCDResInfo != Panel640x480) {
-          if((!(SiS_LCDInfo & LCDNonExpanding)) || (SiS_SetFlag & CRT2IsVGA)) {
-            if(SiS_LCDResInfo == Panel800x600) {
-              SiS_HDE = 800;
-              SiS_VDE = 600;
-            } else if(SiS_LCDResInfo == Panel1024x768) {
-              SiS_HDE = 1024;
-              SiS_VDE = 768;
-            } else if(SiS_LCDResInfo == Panel1280x1024) {
-              SiS_HDE = 1280;
-              SiS_VDE = 1024;
-            } else if(SiS_LCDResInfo == Panel1024x600){
-	      SiS_HDE = 1024;
-              SiS_VDE = 600;
-	    } else if(SiS_LCDResInfo == Panel1400x1050){
-	      SiS_HDE = 1400;
-              SiS_VDE = 1050;
+    if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+          if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+            if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+              SiS_Pr->SiS_HDE =  800;
+              SiS_Pr->SiS_VDE =  600;
+	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+	      SiS_Pr->SiS_HDE = 1024;
+              SiS_Pr->SiS_VDE =  600;  
+            } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+              SiS_Pr->SiS_HDE = 1024;
+              SiS_Pr->SiS_VDE =  768;
+ 	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+	      SiS_Pr->SiS_HDE = 1152;
+	      SiS_Pr->SiS_VDE =  768;	
+	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x864) {
+	      SiS_Pr->SiS_HDE = 1152;
+	      SiS_Pr->SiS_VDE =  864;  
+	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+	      SiS_Pr->SiS_HDE = 1280;
+	      SiS_Pr->SiS_VDE =  768;        
+            } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+              SiS_Pr->SiS_HDE = 1280;
+              SiS_Pr->SiS_VDE = 1024;
+	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+	      SiS_Pr->SiS_HDE = 1400;
+              SiS_Pr->SiS_VDE = 1050;
 	    } else {
-	      SiS_HDE = 1152;
-	      SiS_VDE = 768;
+	      SiS_Pr->SiS_HDE = 1600;
+	      SiS_Pr->SiS_VDE = 1200;
 	    }
-            if(SiS_IF_DEF_FSTN) {
-              SiS_HDE = 320;
-              SiS_VDE = 480;
+            if(SiS_Pr->SiS_IF_DEF_FSTN) {
+              SiS_Pr->SiS_HDE = 320;
+              SiS_Pr->SiS_VDE = 480;
             }
           }
         }
@@ -2725,111 +3401,130 @@
   }
 }
 
-/* TW: Checked against 630/301B BIOS; does not check VDE values for LCD */
 void
-SiS_GetCRT2Data301(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                        USHORT RefreshRateTableIndex,
-			PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_GetCRT2Data301(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex,
+		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT tempax,tempbx,modeflag;
   USHORT resinfo;
   USHORT CRT2Index,ResIndex;
-  SiS_LCDDataStruct *LCDPtr=NULL;
-  SiS_TVDataStruct  *TVPtr=NULL;
+  const SiS_LCDDataStruct *LCDPtr = NULL;
+  const SiS_TVDataStruct  *TVPtr  = NULL;
 
-  if(ModeNo<=0x13) {
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  if(ModeNo <= 0x13) {
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   } else {
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
-  SiS_NewFlickerMode = 0;
-  SiS_RVBHRS = 50;
-  SiS_RY1COE = 0;
-  SiS_RY2COE = 0;
-  SiS_RY3COE = 0;
-  SiS_RY4COE = 0;
+  
+  SiS_Pr->SiS_NewFlickerMode = 0;
+  SiS_Pr->SiS_RVBHRS = 50;
+  SiS_Pr->SiS_RY1COE = 0;
+  SiS_Pr->SiS_RY2COE = 0;
+  SiS_Pr->SiS_RY3COE = 0;
+  SiS_Pr->SiS_RY4COE = 0;
 
-  SiS_GetCRT2ResInfo(ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+  SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
 
   /* TW: For VGA2 ("RAMDAC2") */
 
-  if(SiS_VBInfo & SetCRT2ToRAMDAC){
-     SiS_GetRAMDAC2DATA(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
+     SiS_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                         HwDeviceExtension);
      return;
   }
 
   /* TW: For TV */
 
-  if(SiS_VBInfo & SetCRT2ToTV) {
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
 
-    SiS_GetCRT2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+    SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                    &CRT2Index,&ResIndex,HwDeviceExtension);
 
     switch (CRT2Index) {
-      case  2:  TVPtr = SiS_ExtHiTVData;   break;
-      case  3:  TVPtr = SiS_ExtPALData;    break;
-      case  4:  TVPtr = SiS_ExtNTSCData;   break;
-      case  7:  TVPtr = SiS_St1HiTVData;   break;
-      case  8:  TVPtr = SiS_StPALData;     break;
-      case  9:  TVPtr = SiS_StNTSCData;    break;
-      case 12:  TVPtr = SiS_St2HiTVData;   break;
-      default:  TVPtr = SiS_StPALData;     break;  /* TW: Just to avoid a crash */
-    }
-
-    SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
-    SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
-    SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
-    SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
-    SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
-    SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
-    SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
-    SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
-
-    if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
-
-      	if(resinfo == 0x08) SiS_NewFlickerMode = 0x40;
-      	if(resinfo == 0x09) SiS_NewFlickerMode = 0x40;
-	if(resinfo == 0x12) SiS_NewFlickerMode = 0x40;   /* TW: Was resinfo == 0x10 */
-
-        if(SiS_VGAVDE == 350) SiS_SetFlag |= TVSimuMode;
-
-        SiS_HT = ExtHiTVHT;
-        SiS_VT = ExtHiTVVT;
-        if(SiS_VBInfo & SetInSlaveMode) {
-          if(SiS_SetFlag & TVSimuMode) {
-            SiS_HT = StHiTVHT;
-            SiS_VT = StHiTVVT;
-            if(!(modeflag & Charx8Dot)){
-              SiS_HT = StHiTextTVHT;
-              SiS_VT = StHiTextTVVT;
-            }
+      case  2:  TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
+/*    case  7:  TVPtr = SiS_Pr->SiS_St1HiTVData;   break;  */
+      case 12:  TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
+      case  3:  TVPtr = SiS_Pr->SiS_ExtPALData;    break;
+      case  4:  TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
+      case  8:  TVPtr = SiS_Pr->SiS_StPALData;     break;
+      case  9:  TVPtr = SiS_Pr->SiS_StNTSCData;    break;
+      default:  TVPtr = SiS_Pr->SiS_StPALData;     break;  /* TW: Just to avoid a crash */
+    }
+
+    SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
+    SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
+    SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
+    SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
+    SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
+    SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
+    SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
+    SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
+    if(modeflag & HalfDCLK) {
+	SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->HALFRVBHRS;
+    }
+
+    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {  
+    
+       if(SiS_Pr->SiS_HiVision != 3) {
+       
+      	  if(resinfo == 0x08) SiS_Pr->SiS_NewFlickerMode = 0x40;
+      	  if(resinfo == 0x09) SiS_Pr->SiS_NewFlickerMode = 0x40;
+	  if(resinfo == 0x12) SiS_Pr->SiS_NewFlickerMode = 0x40;
+	  
+       } 
+       
+       switch(SiS_Pr->SiS_HiVision) {
+       case 2:
+       case 1:
+       case 0:
+          SiS_Pr->SiS_HT = 0x6b4;
+          SiS_Pr->SiS_VT = 0x20d;
+	  /* Don't care about TVSimuMode */
+          break;
+       default:
+          if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_SetFlag |= TVSimuMode;
+
+          SiS_Pr->SiS_HT = ExtHiTVHT;
+          SiS_Pr->SiS_VT = ExtHiTVVT;
+          if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+             if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+                SiS_Pr->SiS_HT = StHiTVHT;
+                SiS_Pr->SiS_VT = StHiTVVT;
+                if(!(modeflag & Charx8Dot)){
+                   SiS_Pr->SiS_HT = StHiTextTVHT;
+                   SiS_Pr->SiS_VT = StHiTextTVVT;
+                }
+             }
           }
-        }
+       }
 
     } else {
 
-      SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
-      SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
-      SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
-      SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
+      SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
+      SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
+      SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
+      SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
 
       if(modeflag & HalfDCLK) {
-         SiS_RY1COE = 0x00;
-         SiS_RY2COE = 0xf4;
-         SiS_RY3COE = 0x10;
-         SiS_RY4COE = 0x38;
+         SiS_Pr->SiS_RY1COE = 0x00;
+         SiS_Pr->SiS_RY2COE = 0xf4;
+         SiS_Pr->SiS_RY3COE = 0x10;
+         SiS_Pr->SiS_RY4COE = 0x38;
       }
 
-      if(!(SiS_VBInfo & SetPALTV)){
-        SiS_HT = NTSCHT;
-	if((ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_HT = NTSC2HT;
-        SiS_VT = NTSCVT;
+      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+        SiS_Pr->SiS_HT = NTSCHT;
+	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {  
+	   if((ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_Pr->SiS_HT = NTSC2HT;
+	}  
+        SiS_Pr->SiS_VT = NTSCVT;
       } else {
-        SiS_HT = PALHT;
-        SiS_VT = PALVT;
+        SiS_Pr->SiS_HT = PALHT;
+        SiS_Pr->SiS_VT = PALVT;
       }
 
     }
@@ -2838,115 +3533,134 @@
   }
 
   /* TW: For LCD */
-  /* TW: Checked against 650/301LV; CRT2Index different (but does not matter) */
 
-  if(SiS_VBInfo & SetCRT2ToLCD) {
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
 
-    SiS_GetCRT2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+    SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                    &CRT2Index,&ResIndex,HwDeviceExtension);
 
     switch (CRT2Index) {
-      case  0: LCDPtr = SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
-      case  1: LCDPtr = SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
-      case  5: LCDPtr = SiS_StLCD1024x768Data;         break; /* Obviously unused */
-      case  6: LCDPtr = SiS_StLCD1280x1024Data;        break; /* Obviously unused */
-      case 10: LCDPtr = SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
-      case 11: LCDPtr = SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
-      case 13: LCDPtr = SiS_NoScaleData1024x768;       break; /* Non-expanding */
-      case 14: LCDPtr = SiS_NoScaleData1280x1024;      break; /* Non-expanding */
-      case 15: LCDPtr = SiS_LCD1280x960Data;           break; /* 1280x960 */
-      default: LCDPtr = SiS_ExtLCD1024x768Data;	       break; /* Just to avoid a crash */
-    }
-
-    SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
-    SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
-    SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
-    SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
-    SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
-    SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
+      case  0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
+      case  1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
+      case  5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data;         break; /* Obviously unused */
+      case  6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data;        break; /* Obviously unused */
+      case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
+      case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
+      case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768;       break; /* Non-expanding */
+      case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;      break; /* Non-expanding */
+      case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;           break; /* 1280x960 */
+      case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;       break; /* VESA Timing */
+      case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050;      break; /* Non-expanding (let panel scale) */
+      case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;	       break; /* Non-VESA Timing (let panel scale) */
+      case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;       break; /* VESA Timing */
+      case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200;      break; /* Non-expanding */
+      case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;	       break; /* Non-VESA Timing */
+      default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;	       break; /* Just to avoid a crash */
+    }
+
+    SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
+    SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
+    SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
+    SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
+    SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
+    SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
+    
+#ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO,
+    	"GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
+#endif    
 
     tempax = 1024;
-    if(SiS_SetFlag & LCDVESATiming) {
-      if     (SiS_VGAVDE == 350) tempbx = 560;
-      else if(SiS_VGAVDE == 400) tempbx = 640;
-      else                       tempbx = 768;
+    if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+      if(HwDeviceExtension->jChipType < SIS_315H) {
+         if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+         else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+         else                               tempbx = 768;
+      } else {      
+         tempbx = 768; 
+      }
     } else {
-      if     (SiS_VGAVDE == 357) tempbx = 527;
-      else if(SiS_VGAVDE == 420) tempbx = 620;
-      else if(SiS_VGAVDE == 525) tempbx = 775;
-      else if(SiS_VGAVDE == 600) tempbx = 775;
-      else if(SiS_VGAVDE == 350) tempbx = 560;
-      else if(SiS_VGAVDE == 400) tempbx = 640;
-      else                       tempbx = 768;
+      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
+      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
+      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
+      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
+      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+      else                               tempbx = 768;
     }
-    if(SiS_LCDResInfo == Panel1280x1024){
+    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
       tempax = 1280;
-      if     (SiS_VGAVDE == 360) tempbx = 768;
-      else if(SiS_VGAVDE == 375) tempbx = 800;
-      else if(SiS_VGAVDE == 405) tempbx = 864;
-      else                       tempbx = 1024;
+      if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
+      else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
+      else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
+      else                               tempbx = 1024;
     }
-    if(SiS_LCDResInfo == Panel1280x960){
+    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
       tempax = 1280;
-      if     (SiS_VGAVDE == 350)  tempbx = 700;
-      else if(SiS_VGAVDE == 400)  tempbx = 800;
-      else if(SiS_VGAVDE == 1024) tempbx = 960;
-      else                        tempbx = 960;
-    }
-    if(SiS_LCDInfo & LCDNonExpanding) {
-       tempax = SiS_VGAHDE;
-       tempbx = SiS_VGAVDE;
+      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
+      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
+      else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
+      else                                tempbx = 960;
+    }
+    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+      tempax = 1400;
+      tempbx = 1050;
+    }
+    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+      tempax = 1600;
+      tempbx = 1200;
+    }
+    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+       tempax = SiS_Pr->SiS_VGAHDE;
+       tempbx = SiS_Pr->SiS_VGAVDE;
     }
-    SiS_HDE = tempax;
-    SiS_VDE = tempbx;
+    SiS_Pr->SiS_HDE = tempax;
+    SiS_Pr->SiS_VDE = tempbx;
     return;
   }
 }
 
 USHORT
-SiS_GetResInfo(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
   USHORT resindex;
 
-  if(ModeNo<=0x13)
-    	resindex=SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  if(ModeNo <= 0x13)
+    	resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   else
-    	resindex=SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    	resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
 
   return(resindex);
 }
 
-/* TW: Checked against 650/301LV, 650/LVDS, 630/LVDS, 630/301 and 630/301B BIOS */
 void
-SiS_GetCRT2ResInfo(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT xres,yres,modeflag=0,resindex;
 
-  resindex = SiS_GetResInfo(ROMAddr,ModeNo,ModeIdIndex);
+  resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
 
   if(ModeNo <= 0x13) {
-    	xres = SiS_StResInfo[resindex].HTotal;
-    	yres = SiS_StResInfo[resindex].VTotal;
+    	xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
+    	yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
   } else {
-	xres = SiS_ModeResInfo[resindex].HTotal;
-    	yres = SiS_ModeResInfo[resindex].VTotal;
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+    	yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
-  /* TW: Inserted entire if-section from 650/LVDS BIOS 1.10.07: */
-  if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_IF_DEF_LVDS == 1)) {
-      if((ModeNo != 0x03) && (SiS_SetFlag & CRT2IsVGA)) {
+  if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
+      if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
           if(yres == 350) yres = 400;
       }
-      if(SiS_GetReg1(SiS_P3d4,0x3a) & 0x01) {
- 	  if(SiS_GetReg1(SiS_P3d4,0x34) == 0x12)
-	      yres = 400;
+      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
+ 	  if(ModeNo == 0x12) yres = 400;
       }
   }
 
   if(ModeNo > 0x13) {
-      if(SiS_IF_DEF_FSTN == 1){
+      if(SiS_Pr->SiS_IF_DEF_FSTN == 1){
             xres *= 2;
             yres *= 2;
       } else {
@@ -2955,178 +3669,239 @@
       }
   }
 
-  if(SiS_IF_DEF_LVDS == 0) {
-        /* TW: Inserted from 650/301LV BIOS */
-        if(SiS_VBInfo & SetCRT2ToLCDA) {
-                if(xres == 720) xres = 640;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+           if(xres == 720) xres = 640;
 	} else {
-	   if(xres == 720) xres = 640;
-    	   if(SiS_LCDResInfo == Panel1280x1024) {
-      		if(yres == 400) yres = 405;
-      		if(yres == 350) yres = 360;
-      		if(SiS_SetFlag & LCDVESATiming) {
-        		if(yres == 360) yres = 375;
-      		}
-   	   }
-    	   if(SiS_LCDResInfo == Panel1024x768){
-      		if(!(SiS_SetFlag & LCDVESATiming)) {
-        		if(!(SiS_LCDInfo & LCDNonExpanding)) {
-          			if(yres == 350) yres = 357;
-          			if(yres == 400) yres = 420;
-            			if(yres == 480) yres = 525;
-        		}
-      		}
-    	   }
-	   /* TW: Inserted for 630/301B */
-	   if(HwDeviceExtension->jChipType < SIS_315H) {
-	      if(SiS_VBType & VB_SIS301BLV302BLV) {
-                  if(xres == 720) xres = 640;
+	   if(SiS_Pr->SiS_VBType & VB_NoLCD) {           /* TW: 301BDH */
+	        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+                   if(xres == 720) xres = 640;
+		}
+		if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+	           yres = 400;
+	           if(HwDeviceExtension->jChipType >= SIS_315H) {
+	              if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
+	           } else {
+	              if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
+	           }
+	        }
+	   } else {
+	      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO |           /* (Allow 720 for VGA2) */
+	      			       SetCRT2ToSVIDEO |
+	                               SetCRT2ToSCART  | 
+				       SetCRT2ToLCD    | 
+				       SetCRT2ToHiVisionTV)) {
+	         if(xres == 720) xres = 640;
+	      }
+	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+    	         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+		    if(ModeNo <= 0x13) {
+		       /* TW: This is wrong for 640x400 *graphics* mode */
+      		       if(yres == 400) yres = 405;
+		    }
+      		    if(yres == 350) yres = 360;
+      		    if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+        	       if(yres == 360) yres = 375;
+      		    }
+   	         }
+    	         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
+      		    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+        	       if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+          	          if(yres == 350) yres = 357;
+          	          if(yres == 400) yres = 420;
+            	          if(yres == 480) yres = 525;
+        	       }
+      		    }
+    	         }
 	      }
 	   }
 	}
   } else {
     	if(xres == 720) xres = 640;
-	/* TW: Inserted from 650/LVDS and 630/LVDS BIOS */
-	if(SiS_SetFlag & CRT2IsVGA) {
+	if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
 	      yres = 400;
 	      if(HwDeviceExtension->jChipType >= SIS_315H) {
-	          if(SiS_GetReg1(SiS_P3c4,0x17) & 0x80) yres = 480;
+	          if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
 	      } else {
-	          if(SiS_GetReg1(SiS_P3c4,0x13) & 0x80) yres = 480;
+	          if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
 	      }
 	}
   }
-  SiS_VGAHDE = SiS_HDE = xres;
-  SiS_VGAVDE = SiS_VDE = yres;
+  SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
+  SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
 }
 
-/* TW: Checked against 650/301 and 650/LVDS (1.10.07) BIOS; modified for new panel resolutions */
-/* TW: Done differently in 630/301B BIOS; but same effect; checked against 630/301 */
 void
-SiS_GetCRT2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
 	       USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
 	       PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT tempbx=0,tempal=0;
   USHORT Flag,resinfo=0;
 
-  if(SiS_IF_DEF_LVDS == 0) {
-    	if(SiS_VBInfo & SetCRT2ToLCD){                            /* LCD */
-	        if(SiS_LCDResInfo == Panel1280x960)  tempbx = 14;
-		else if(SiS_LCDInfo & LCDNonExpanding) {
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
+
+	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+			tempbx = 15;
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+		        tempbx = 20;
+			if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 21;
+			else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 22;
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+		        tempbx = 23;
+			if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 24;
+			else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 25;
+		} else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
 			tempbx = 13;
-			if(SiS_LCDResInfo == Panel1280x1024) tempbx++;
+			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx++;
 		} else {
-      		   tempbx = SiS_LCDResInfo - Panel1024x768;
-      		   if(!(SiS_SetFlag & LCDVESATiming)) {
+      		   tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_Panel1024x768;
+      		   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
         		tempbx += 5;
                         /* GetRevisionID();  */
 			/* TW: BIOS only adds 5 once */
         		tempbx += 5;
        		   }
 	        }
-     	} else {						/* TV */
-       		if(SiS_VBInfo & SetCRT2ToHiVisionTV){
-         		if(SiS_VGAVDE > 480) SiS_SetFlag &= (~TVSimuMode); /* TW: Was "(!TVSimuMode)" - WRONG */
+
+     	} else {						  	/* TV */
+	
+       		if((SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+		   (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+         		if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_SetFlag &= (~TVSimuMode);
          		tempbx = 2;
-         		if(SiS_VBInfo & SetInSlaveMode) {
-            			if(!(SiS_SetFlag & TVSimuMode)) tempbx = 12;  /* TW: Was 10! - WRONG */
+         		if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+            			if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) tempbx = 12; 
          		}
        		} else {
-         		if(SiS_VBInfo & SetPALTV) tempbx = 3;
+         		if(SiS_Pr->SiS_VBInfo & SetPALTV) tempbx = 3;
          		else tempbx = 4;
-         		if(SiS_SetFlag & TVSimuMode) tempbx += 5;
+         		if(SiS_Pr->SiS_SetFlag & TVSimuMode) tempbx += 5;
        		}
+		
      	}
 
-     	if(ModeNo <= 0x13)
-       		tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-     	else
-       		tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+     	if(ModeNo <= 0x13) {
+       		tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+     	} else {
+       		tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+		resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+        }
 
      	tempal &= 0x3F;
 
-      	if((SiS_VBType & VB_SIS301BLV302BLV)
-                     && (SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))) {  /* TW: Added -Hivision (BIOS) */
+      	if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+           (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))) {
       		if(tempal == 0x06) tempal = 0x07;
         }
 
-        if(SiS_VBInfo & SetCRT2ToTV) {
-            if((ModeNo == 0x31) || (ModeNo == 0x32)) tempal = 6;
+	/* TW: 300/301LV BIOS */
+	if((HwDeviceExtension->jChipType == SIS_300) &&
+	   (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+	    if(ModeNo > 0x13) {
+	        if((resinfo == 0x0c) || (resinfo == 0x0d))  /* 720 (index diff. on 310/325!) */
+		    tempal = 6;
+	    }
+	}
+
+	if(HwDeviceExtension->jChipType != SIS_300) {
+           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+              if((ModeNo == 0x31) || (ModeNo == 0x32)) tempal = 6;
+	   }
 	}
 
      	*CRT2Index = tempbx;
      	*ResIndex = tempal;
 
-  } else {   /* LVDS */
+  } else {   /* LVDS, 301B-DH (if running on LCD) */
 
     	Flag = 1;
     	tempbx = 0;
-    	if(SiS_IF_DEF_CH70xx != 0) {
-      		if(!(SiS_VBInfo & SetCRT2ToLCD)) {
+    	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+	
+      		if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
         		Flag = 0;
         		tempbx = 10;
-        		if(SiS_VBInfo & SetPALTV)        tempbx += 2;
-        		if(SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+			if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+        		if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+				tempbx += 2;
+				if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
+				if(SiS_Pr->SiS_CHPALM) {
+					tempbx = 90;
+					if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+				} else if(SiS_Pr->SiS_CHPALN) {
+					tempbx = 92;
+					if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+				}
+				
+			}
       		}
+		
     	}
 
-    	if(Flag == 1) {
-      		tempbx = SiS_LCDResInfo - PanelMinLVDS;
-		if(SiS_LCDResInfo <= Panel1280x1024) {
-   	      	    if(SiS_LCDInfo & LCDNonExpanding)  tempbx += 3;
-		} else {
-		    if(SiS_LCDResInfo == Panel1400x1050) {
-			tempbx = 8;
-			if(SiS_LCDInfo & LCDNonExpanding)  tempbx++;
-		    }
-        	    if(SiS_LCDInfo & 0x0100) {
-			tempbx = 7;
-        	    }
-
-     		    if(SiS_LCDResInfo == Panel640x480)  tempbx = 6;
-
-		    /* TW: Inserted from 630/LVDS 2.04.5c BIOS */
-		    if(SiS_LCDResInfo == Panel1024x600) {
-			tempbx = 15;
-  		        if(SiS_LCDInfo & LCDNonExpanding)  tempbx += 2;
-		    }
-		    if(SiS_LCDResInfo == Panel1152x768) {
-		        tempbx = 16;
-			if(SiS_LCDInfo & LCDNonExpanding)  tempbx += 2;
-		    }
-		 }
+    	if(Flag) {
+      		
+		if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
+		   tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
+   	      	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 3;
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+		   tempbx = 18;
+		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++; 
+	        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) { 
+		   tempbx = 6;
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+		   tempbx = 15;
+  		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 2;
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+		   tempbx = 16;
+		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 2;
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+		   tempbx = 8;
+		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+		   tempbx = 21;
+		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+		}
+		
+		if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+		   tempbx = 7;
+        	}
+		
 	}
 
     	if(ModeNo <= 0x13)
-      		tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+      		tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
     	else {
-      		tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-		resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+      		tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+		resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
 	}
 
-	if(SiS_IF_DEF_FSTN){
-       	 	if(SiS_LCDResInfo == Panel320x480){
+	if(SiS_Pr->SiS_IF_DEF_FSTN){
+       	 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
          		tempbx = 14;
          		tempal = 6;
         	}
     	}
 
-	/* TW: Inserted from 650/LVDS BIOS */
-	if(SiS_SetFlag & CRT2IsVGA) {
-	        if(SiS_LCDResInfo != Panel640x480) tempal = 7;
+	if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+	        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempal = 7;
 		if(HwDeviceExtension->jChipType < SIS_315H) {
-		    /* TW: Inserted from 630/LVDS (2.04.5c) and 630/301B (II) BIOS */
-		    if(SiS_GetReg1(SiS_P3c4,0x13) & 0x80) tempal++;
+		    if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
 		}
 
 	}
 
-	/* TW: Inserted from 630/301B BIOS */
-	if(SiS_VBType & VB_SIS301BLV302BLV) {
+	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 	    if(ModeNo > 0x13) {
-	        if((resinfo == 0x0c) || (resinfo == 0x0d))
-		    tempal = 6;
+	        if(HwDeviceExtension->jChipType < SIS_315H) {
+	           if((resinfo == 0x0c) || (resinfo == 0x0d))  /* 720 */
+		       tempal = 6;
+	        } else {
+		   if((resinfo == 0x0d) || (resinfo == 0x0e))  /* 720 */
+		       tempal = 6;
+		}
 	    }
 	}
 
@@ -3135,64 +3910,74 @@
   }
 }
 
+#ifdef SIS315H
 void
-SiS_GetCRT2PtrA(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_GetCRT2PtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
 		USHORT RefreshRateTableIndex,USHORT *CRT2Index,
 		USHORT *ResIndex)
 {
   USHORT tempbx,tempal;
 
-  tempbx = SiS_LCDResInfo - Panel1024x768;
+  tempbx = SiS_Pr->SiS_LCDResInfo;
+
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)      tempbx = 4;
+  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 3;
+  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  tempbx = 2;
+  else tempbx -= SiS_Pr->SiS_Panel1024x768;
 
-  if(SiS_LCDInfo & LCDNonExpanding)  tempbx += 3;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 5;
 
   if(ModeNo <= 0x13)
-      	tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+      	tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   else
-      	tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+      	tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 
   *CRT2Index = tempbx;
   *ResIndex = tempal & 0x1F;
 }
+#endif
 
-/* TW: New from 650/301LV BIOS */
 void
-SiS_GetCRT2Part2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
 		    USHORT RefreshRateTableIndex,USHORT *CRT2Index,
 		    USHORT *ResIndex)
 {
   USHORT tempbx,tempal;
 
   if(ModeNo <= 0x13)
-      	tempal = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+      	tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   else
-      	tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+      	tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 
-  tempbx = SiS_LCDResInfo - Panel1024x768;
+  tempbx = SiS_Pr->SiS_LCDResInfo;
 
-  if(SiS_LCDInfo & LCDNonExpanding)  tempbx += 2;
-  else if(SiS_SetFlag & LCDVESATiming) tempbx += 4;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx += 16;
+  else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx += 32;
 
   *CRT2Index = tempbx;
   *ResIndex = tempal & 0x3F;
 }
 
-/* TW: Checked against 650/LVDS (1.10.07) and 630/301B BIOS */
 USHORT
-SiS_GetRatePtrCRT2(UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
+                   PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   SHORT  LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01,
-                               0x01, 0x01, 0x01, 0x01 };
+                               0x01, 0x01, 0x01, 0x01,
+			       0x01, 0x01, 0x01, 0x01,
+			       0x01, 0x01, 0x01, 0x01 };
   USHORT RefreshRateTableIndex,i,backup_i;
-  USHORT modeflag,index,temp;
+  USHORT modeflag,index,temp,backupindex;
 
-  if (ModeNo <= 0x13)
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  if(SiS_Pr->UseCustomMode) return 0;
+  
+  if(ModeNo <= 0x13)
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   else
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-  if(SiS_IF_DEF_CH70xx != 0) {
-    	if(SiS_VBInfo & SetCRT2ToTV) {
+  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
       		if(modeflag & HalfDCLK) return(0);
     	}
   }
@@ -3205,74 +3990,82 @@
   *     to take the first non-interlaced mode in SiS_Ext2Struct
   */
 
-  index = SiS_GetReg1(SiS_P3d4,0x33);
-  index >>= SiS_SelectCRT2Rate;
+  index = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x33);
+  index >>= SiS_Pr->SiS_SelectCRT2Rate;
   index &= 0x0F;
+  backupindex = index;
 
   if(index > 0) index--;
 
-  /* TW: Added SetFlag and VBInfo checks; we don't care about index if we
-   *     are setting CRT1 rate!
-   */
-  if( (SiS_SetFlag & ProgrammingCRT2) &&
-      (SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) )
-  	 index = 0;
-
-  if(SiS_SetFlag & ProgrammingCRT2) {
-    	if(SiS_IF_DEF_CH70xx != 0) {
-      		if(SiS_VBInfo & SetCRT2ToTV) {
+  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))  index = 0;
+      } else {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+	    if(SiS_Pr->SiS_VBType & VB_NoLCD)
+	       	    index = 0;
+	    else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)
+	    	    index = backupindex = 0;
+	}
+      }
+  }
+
+  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+    	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+      		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
         		index = 0;
       		}
     	}
-    	if(SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-      		if(SiS_IF_DEF_LVDS == 0) {
-		        /* TW: This is not done in 630/301B BIOS */
-           		temp = LCDRefreshIndex[SiS_LCDResInfo];
-        		if(index > temp) index = temp;
+    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+      		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+			if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
+           		   temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
+        		   if(index > temp) index = temp;
+			}
       		} else {
-        		index=0;
+        		index = 0;
       		}
     	}
   }
 
-  RefreshRateTableIndex = SiS_EModeIDTable[ModeIdIndex].REFindex;
-  ModeNo = SiS_RefIndex[RefreshRateTableIndex].ModeID;
+  RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+  ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
 
-  /* TW: Inserted from 650/LVDS 1.10.07 */
-  if(SiS_IF_DEF_LVDS == 1) {
-    if(!(SiS_VBInfo & DriverMode)) {
-      if( (SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
-          (SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
-            if(SiS_LCDResInfo <= Panel800x600)
-	       RefreshRateTableIndex++;
-      }
-    }
+  /* TW: 650/LVDS 1.10.07, 650/30xLV 1.10.6s */
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
+        if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
+            (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
+           if(backupindex <= 1) RefreshRateTableIndex++;
+        }
+     }
   }
 
   i = 0;
   do {
-    	if (SiS_RefIndex[RefreshRateTableIndex+i].ModeID != ModeNo) break;
-    	temp = SiS_RefIndex[RefreshRateTableIndex+i].Ext_InfoFlag;
+    	if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo) break;
+    	temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
     	temp &= ModeInfoFlag;
-    	if(temp < SiS_ModeType) break;
+    	if(temp < SiS_Pr->SiS_ModeType) break;
     	i++;
     	index--;
   } while(index != 0xFFFF);
 
-  if(!(SiS_VBInfo & SetCRT2ToRAMDAC)) {
-    	if(SiS_VBInfo & SetInSlaveMode) {
-      		temp = SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
-      			if(temp & InterlaceMode) {
-        			i++;
-      			}
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+    	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+      		temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
+      		if(temp & InterlaceMode) {
+        		i++;
+      		}
     	}
   }
+
   i--;
 
-  if((SiS_SetFlag & ProgrammingCRT2) && (!(SiS_VBInfo & DisableCRT2Display))) {
+  if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
     	backup_i = i;
-    	if (!(SiS_AdjustCRT2Rate(ROMAddr,ModeNo,ModeIdIndex,
-	                             RefreshRateTableIndex,&i))) {
+    	if (!(SiS_AdjustCRT2Rate(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
+	                             RefreshRateTableIndex,&i,HwDeviceExtension))) {
 		/* TW: This is for avoiding random data to be used; i is
 		 *     in an undefined state if no matching CRT2 mode is
 		 *     found.
@@ -3284,93 +4077,233 @@
   return(RefreshRateTableIndex + i);
 }
 
-/* Checked against 650/LVDS (1.10.07) BIOS */
+/* Checked against all (incl 650/LVDS (1.10.07), 630/301) BIOSes */
 BOOLEAN
-SiS_AdjustCRT2Rate(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex,USHORT *i)
+SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex,USHORT *i,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT tempax,tempbx,resinfo;
   USHORT modeflag,infoflag;
 
   if (ModeNo <= 0x13)
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   else
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-  resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-  tempbx = SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+  resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
 
   tempax = 0;
-  if(SiS_IF_DEF_LVDS == 0) {
-  	/* TW: For 301, 301B, 302B, 301LV, 302LV */
-    	if(SiS_VBInfo & SetCRT2ToRAMDAC) {
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
       		tempax |= SupportRAMDAC2;
+		if(HwDeviceExtension->jChipType >= SIS_315H) {
+		    tempax |= SupportTV;
+		    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+		        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+			    if(resinfo == 0x0a) tempax |= SupportTV1024;
+			}
+		    }
+		}
     	}
-    	if(SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
       		tempax |= SupportLCD;
-      		if(SiS_LCDResInfo != Panel1280x1024) {
-        		if(SiS_LCDResInfo != Panel1280x960) {
-           			if(SiS_LCDInfo & LCDNonExpanding) {
-             				if(resinfo >= 9) {
-               					tempax = 0;
-               					return(0);
-             				}
+		if(HwDeviceExtension->jChipType >= SIS_315H) {
+                   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+		      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+		         if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+			    (*i) = 0;
+                            return(1);
+		         } else {
+      		            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
+        		      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+           			if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+				    return(0);
+				} else {
+             			    if((resinfo >= 9) && (resinfo != 0x14)) {
+               				return(0);
+             			    }
            			}
-        		}
-      		}
+        		      }
+		            }
+		         }
+		      }
+      		   }
+		} else {
+		  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+		     if((resinfo != 0x0f) && ((resinfo == 4) || (resinfo >= 8))) return(0);
+		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+		     if((resinfo != 0x10) && (resinfo > 8)) return(0);
+		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+		     if((resinfo != 0x0e) && (resinfo > 8)) return(0);
+		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+		     if(resinfo > 9) return(0);
+		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+		     if(resinfo > 8) return(0);
+		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+		     if((resinfo == 4) || (resinfo > 7)) return(0);
+		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+		     if((resinfo == 4) || (resinfo == 3) || (resinfo > 6)) return(0);
+		  }
+		}
     	}
-    	if(SiS_VBInfo & SetCRT2ToHiVisionTV) {    /* for HiTV */
-      		tempax |= SupportHiVisionTV;
-      		if(SiS_VBInfo & SetInSlaveMode){
-        		if(resinfo == 4) return(0);
-        		if(resinfo == 3) {
-          			if(SiS_SetFlag & TVSimuMode) return(0);
-        		}
-        		if(resinfo > 7) return(0);
-      		}
+    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { 
+	        if(SiS_Pr->SiS_HiVision == 3) {
+		      	tempax |= SupportHiVisionTV2;
+      			if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
+        			if(resinfo == 4) return(0);
+        			if(resinfo == 3) return(0);
+				if(resinfo == 7) {
+	          			if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
+        			}
+        			if(resinfo > 7) return(0);
+			}
+		} else {  
+      			tempax |= SupportHiVisionTV;
+      			if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
+        			if(resinfo == 4) return(0);
+        			if((resinfo == 3) || (resinfo == 7)) {
+	          			if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
+        			}
+        			if(resinfo > 7) return(0);
+			}
+		}
     	} else {
-      		if(SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
-        		tempax |= SupportTV;
-         		if(SiS_VBType & VB_SIS301BLV302BLV) {
-             			tempax |= SupportTV1024;
-         		}
-        		if(!(SiS_VBInfo & SetPALTV)) {
-          			if(modeflag & NoSupportSimuTV) {
-            				if(SiS_VBInfo & SetInSlaveMode) {
-              					if(!(SiS_VBInfo & SetNotSimuMode)) {
-                					return 0;
-              					}
-            				}
-          			}
-        		}
-      		}
+      	   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
+        	tempax |= SupportTV;
+		tempax |= SupportTV1024;
+		if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+		        if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) {
+			     if(resinfo != 8) {
+			         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+				     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4)) ) {
+				     tempax &= ~(SupportTV1024);
+				     if(HwDeviceExtension->jChipType >= SIS_315H) {
+                                         if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+				             if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+			                         ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+			                         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+		                             }
+				         }
+		                     } else {
+				         if( (resinfo != 3) ||
+					     (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+					     (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+					     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+						 if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+						     if(resinfo == 3) return(0);
+						     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+						 }
+		                             }
+                                         } else return(0);
+				     }
+				 }
+			     }
+			} else {
+			    tempax &= ~(SupportTV1024);
+			    if(HwDeviceExtension->jChipType >= SIS_315H) {
+			        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+			            if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+			                ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+			                if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+		                    }
+		                }
+			    } else {
+			        if( (resinfo != 3) ||
+				    (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+				    (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+				     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+					 if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+					     if(resinfo == 3) return(0);
+					     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+					 }
+		                     }
+                                } else return(0);
+                            }
+			}
+		    } else {  /* slavemode */
+			if(resinfo != 8) {
+			    if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4) ) ) {
+				 tempax &= ~(SupportTV1024);
+				 if(HwDeviceExtension->jChipType >= SIS_315H) {
+				     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+				         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+			                     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+			                     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode))  return(0);
+		                         }
+		                     }
+			        } else {
+				    if( (resinfo != 3) ||
+				        (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+				        (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+				         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+					     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+					         if(resinfo == 3) return(0);
+					         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+					     }
+		                         }
+                                    } else return(0);
+				}
+			    }
+			}
+		    }
+		} else {   /* 301 */
+		    tempax &= ~(SupportTV1024);
+		    if(HwDeviceExtension->jChipType >= SIS_315H) {
+		        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+		            if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
+			        if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+		            }
+		        }
+		    } else {
+		        if( (resinfo != 3) ||
+			    (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+			    (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+			    if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+			        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+				    if(resinfo == 3) return(0);
+				    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+				}
+		            }
+                        } else return(0);
+		    }
+		}
+           }
     	}
-  } else {
-  	/* TW: for LVDS  */
-    	if(SiS_IF_DEF_CH70xx != 0) {
-      		if(SiS_VBInfo & SetCRT2ToTV) {
+	
+  } else {	/* TW: for LVDS  */
+
+    	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+      		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
         		tempax |= SupportCHTV;
       		}
     	}
-    	if(SiS_VBInfo & SetCRT2ToLCD) {
+    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
       		tempax |= SupportLCD;
-		if(SiS_LCDResInfo == Panel1280x768) {
-		     /* TW: Bios code makes no sense */
-		} else if(SiS_LCDResInfo == Panel1400x1050) {
+		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+		     if((resinfo != 0x14) && (resinfo > 0x09)) return(0);
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+		     if((resinfo != 0x0f) && (resinfo > 0x08)) return(0);
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+		     if((resinfo != 0x10) && (resinfo > 0x08)) return(0);
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
 		     if((resinfo != 0x15) && (resinfo > 0x09)) return(0);
-		} else if(SiS_LCDResInfo == Panel1280x1024) {
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
                      if(resinfo > 0x09) return(0);
-                } else if(SiS_LCDResInfo == Panel1024x768) {
+                } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
 		     if(resinfo > 0x08) return(0);
-		} else if(SiS_LCDResInfo == Panel800x600){
+		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600){
 		     if(resinfo > 0x07) return(0);
 		     if(resinfo == 0x04) return(0);
 		}
     	}
   }
   /* TW: Look backwards in table for matching CRT2 mode */
-  for(; SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
-     	infoflag = SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+  for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
+     	infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
      	if(infoflag & tempax) {
        		return(1);
      	}
@@ -3380,8 +4313,8 @@
    *     for a matching CRT2 mode if no mode was found yet.
    */
   for((*i) = 0; ; (*i)++) {
-     	infoflag = SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
-     	if(SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
+     	infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+     	if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
        		return(0);
      	}
      	if(infoflag & tempax) {
@@ -3391,91 +4324,143 @@
   return(1);
 }
 
-/* Checked against 650/LVDS (1.10.07) and 650/301LV BIOS */
 void
-SiS_SaveCRT2Info(USHORT ModeNo)
+SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
 {
   USHORT temp1,temp2;
 
   /* TW: We store CRT1 ModeNo in CR34 */
-  SiS_SetReg1(SiS_P3d4,0x34,ModeNo);
-  temp1 = (SiS_VBInfo & SetInSlaveMode) >> 8;
+  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,ModeNo);
+  temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
   temp2 = ~(SetInSlaveMode >> 8);
-  SiS_SetRegANDOR(SiS_P3d4,0x31,temp2,temp1);
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
 }
 
-/* TW: Checked against 650+301, 650/LVDS (1.10.07) and 650/301LV BIOS */
 void
-SiS_GetVBInfo301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                 USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+              USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+	      int checkcrt2mode)
 {
   USHORT tempax,tempbx,temp;
   USHORT modeflag, resinfo=0;
-  UCHAR  OutputSelect = *pSiS_OutputSelect;
+  UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
 
-  if (ModeNo<=0x13)
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  else {
-   	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-  }
+  if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+  } else {
+    if (ModeNo <= 0x13)
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    else {
+   	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    }
+  }    
 
-  SiS_SetFlag = 0;
+  SiS_Pr->SiS_SetFlag = 0;
 
-  SiS_ModeType = modeflag & ModeInfoFlag;
+  SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
 
   tempbx = 0;
-  if(SiS_BridgeIsOn(BaseAddr,HwDeviceExtension) == 0) {              /* TW: "== 0" inserted from 630/301B BIOS */
-    	temp = SiS_GetReg1(SiS_P3d4,0x30);
-    	if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) {               /* TW: Not in (301B) BIOS */
-       		temp &= 0xbf;   /* 301lvds disable CRT2RAMDAC */
-    	}
-    	if(SiS_IF_DEF_FSTN) {   /* fstn must set CR30=0x21 */
-       		temp = 0x21;
-       		SiS_SetReg1(SiS_P3d4,0x30,temp);
+  if(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension) == 0) {  
+    	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+#if 0	
+	/* SiS_HiVision is only used on 310/325/330+30xLV */
+	if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV)) {
+	   if(SiS_Pr->SiS_HiVision & 0x03) {	/* TW: New from 650/30xLV 1.10.6s */
+	      temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
+	      temp |= SetCRT2ToHiVisionTV;   					/* 0x80 */
+	   }
+	   if(SiS_Pr->SiS_HiVision & 0x04) {	/* TW: New from 650/30xLV 1.10.6s */
+	      temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
+	      temp |= SetCRT2ToSVIDEO;  					/* 0x08 */
+	   }
+	}
+#endif	
+    	if(SiS_Pr->SiS_IF_DEF_FSTN) {   /* fstn must set CR30=0x21 */
+       		temp = (SetCRT2ToLCD | SetSimuScanMode);
+       		SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,temp);
     	}
     	tempbx |= temp;
-    	temp = SiS_GetReg1(SiS_P3d4,0x31);
-	tempax = temp << 8;
-        tempax &= (LoadDACFlag | DriverMode | SetDispDevSwitch |        /* TW: Inserted from 650/LVDS+301LV BIOS */
-		         SetNotSimuMode | SetPALTV);                    /* TW: Inserted from 650/LVDS+301LV BIOS */
+    	tempax = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) << 8;
+        tempax &= (LoadDACFlag | DriverMode | SetDispDevSwitch | SetNotSimuMode | SetPALTV);
     	tempbx |= tempax;
-    	temp = SetCHTVOverScan | SetInSlaveMode | DisableCRT2Display;
-   	temp = 0xFFFF ^ temp;
-    	tempbx &= temp;
-#ifdef SIS315H
-	if(HwDeviceExtension->jChipType >= SIS_315H) {       /* TW: Inserted this "if" */
-	   temp = SiS_GetReg1(SiS_P3d4,0x38);
-    	   if(SiS_VBType & (VB_SIS302B | VB_SIS302LV)) {
-       		if((temp & (EnableDualEdge | SetToLCDA))
-		          == (EnableDualEdge | SetToLCDA))   /* TW: BIOS only tests these bits, added "& ..." */
+    	tempbx &= ~(SetCHTVOverScan | SetInSlaveMode | DisableCRT2Display);;
+
+#ifdef SIS315H
+
+	if(HwDeviceExtension->jChipType >= SIS_315H) {
+    	   if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS301LV | VB_SIS302LV)) {
+	      /* From 1.10.7w, not in 1.10.8r */
+	      if(ModeNo == 0x03) {   
+	         /* Mode 0x03 is never in driver mode */
+		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
+	      }
+	      /* From 1.10.7w, not in 1.10.8r */
+	      if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
+	         /* Reset LCDA setting */
+		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
+	      }
+	      if(IS_SIS650) {
+	         if(SiS_Pr->SiS_UseLCDA) {
+		    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
+		       if((ModeNo <= 0x13) || (!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
+		          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));  /* 3 */
+		       }
+		    }
+		 }
+#if 0		 /* We can't detect it this way; there are machines which do not use LCDA despite
+                  * the chip revision
+		  */      	      
+		 if((tempbx & SetCRT2ToLCD) && (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD)) {
+                    if((SiS_GetReg1(SiS_Pr->SiS_P3d4, 0x36) & 0x0f) == SiS_Pr->SiS_Panel1400x1050) {
+		       if((ModeNo <= 0x13) || (!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
+		          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
+			     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));  /* 3 */
+			  }
+		       }
+		    } else {
+		       if((ModeNo <= 0x13) || (!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
+			  if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
+			     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));  /* 3 */
+		          }
+		       }
+		    }
+		 }
+#endif		 
+	      }
+	      temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+       	      if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
           		tempbx |= SetCRT2ToLCDA;
+	      }
     	   }
-	   /* TW: Inserted from 650/LVDS BIOS: */
-	   if(SiS_IF_DEF_LVDS == 1) {
+
+	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+	        temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
 	        if(temp & SetToLCDA)
-		        tempbx |= SetCRT2ToLCDA;
-	        if(temp & 0x08)
-		        tempbx |= SetCRT2ToHiVisionTV;
+		   tempbx |= SetCRT2ToLCDA;
+		if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+	           if(temp & EnableLVDSHiVision)
+		      tempbx |= SetCRT2ToHiVisionTV;
+		}
 	   }
 	}
-#endif
-    	if(SiS_IF_DEF_LVDS == 0) {
-	        temp = SetCRT2ToLCDA   | SetCRT2ToSCART      | SetCRT2ToLCD |
-		       SetCRT2ToRAMDAC | SetCRT2ToSVIDEO     | SetCRT2ToAVIDEO; /* = 0x807C; */
-      		if(SiS_IF_DEF_HiVision == 1)
-                     temp |= SetCRT2ToHiVisionTV; /* = 0x80FC; */
+
+#endif  /* SIS315H */
+
+    	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+	        temp = SetCRT2ToLCDA   | SetCRT2ToSCART      | SetCRT2ToLCD    |
+		       SetCRT2ToRAMDAC | SetCRT2ToSVIDEO     | SetCRT2ToAVIDEO |  /* = 0x807C; */
+                       SetCRT2ToHiVisionTV; 					  /* = 0x80FC; */
     	} else {
-	        /* TW: Inserted entire 315-section */
                 if(HwDeviceExtension->jChipType >= SIS_315H) {
-                    if(SiS_IF_DEF_CH70xx != 0)
+                    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0)
         		temp = SetCRT2ToLCDA   | SetCRT2ToSCART |
 			       SetCRT2ToLCD    | SetCRT2ToHiVisionTV |
-			       SetCRT2ToAVIDEO | SetCRT2ToSVIDEO;  /* 0x80bc */
+			       SetCRT2ToAVIDEO | SetCRT2ToSVIDEO;  /* = 0x80bc */
       		    else
         		temp = SetCRT2ToLCDA | SetCRT2ToLCD;
 		} else {
-      		    if(SiS_IF_DEF_CH70xx != 0)
+      		    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0)
         		temp = SetCRT2ToTV | SetCRT2ToLCD;
       		    else
         		temp = SetCRT2ToLCD;
@@ -3487,27 +4472,31 @@
       		tempbx = 0;
     	}
 
-   	if(SiS_IF_DEF_LVDS==0) {
+   	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
       		if(tempbx & SetCRT2ToLCDA) {
         		tempbx &= (0xFF00|SwitchToCRT2|SetSimuScanMode);
-      		} else if(tempbx & SetCRT2ToRAMDAC) {
+      		}
+		if(tempbx & SetCRT2ToRAMDAC) {
         		tempbx &= (0xFF00|SetCRT2ToRAMDAC|SwitchToCRT2|SetSimuScanMode);
-      		} else if((tempbx & SetCRT2ToLCD) && (!(SiS_VBType & VB_NoLCD)) ){
+      		}
+		if((tempbx & SetCRT2ToLCD) /* && (!(SiS_Pr->SiS_VBType & VB_NoLCD)) */ ) {
+		        /* We initialize the Panel Link of the type of bridge is DH */
         		tempbx &= (0xFF00|SetCRT2ToLCD|SwitchToCRT2|SetSimuScanMode);
-      		} else if(tempbx & SetCRT2ToSCART){
+      		}
+		if(tempbx & SetCRT2ToSCART) {
         		tempbx &= (0xFF00|SetCRT2ToSCART|SwitchToCRT2|SetSimuScanMode);
         		tempbx |= SetPALTV;
-      		} else if(tempbx & SetCRT2ToHiVisionTV){
+      		}
+		if(tempbx & SetCRT2ToHiVisionTV) {
         		tempbx &= (0xFF00|SetCRT2ToHiVisionTV|SwitchToCRT2|SetSimuScanMode);
         		tempbx |= SetPALTV;
       		}
    	} else { /* LVDS */
-	        /* TW: Inserted entire 315/325 section */
 	        if(HwDeviceExtension->jChipType >= SIS_315H) {
 		    if(tempbx & SetCRT2ToLCDA)
 		        tempbx &= (0xFF00|SwitchToCRT2|SetSimuScanMode);
 		}
-      		if(SiS_IF_DEF_CH70xx != 0) {
+      		if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
         	    if(tempbx & SetCRT2ToTV)
           		 tempbx &= (0xFF00|SetCRT2ToTV|SwitchToCRT2|SetSimuScanMode);
       		}
@@ -3519,424 +4508,717 @@
 		        tempbx |= SetCRT2ToLCD;
 		}
 	}
+
     	if(tempax & DisableCRT2Display) {
       		if(!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) {
         		tempbx = SetSimuScanMode | DisableCRT2Display;
       		}
     	}
+
     	if(!(tempbx & DriverMode)){
       		tempbx |= SetSimuScanMode;
     	}
 
-	/* TW: LVDS (LCD/TV) and 630+301B (LCD) can only be slave in 8bpp modes */
-	if( (SiS_IF_DEF_LVDS == 1) && (SiS_ModeType <= ModeVGA) ) {
-		modeflag &= (~CRT2Mode);
-	}
-	if( (HwDeviceExtension->jChipType < SIS_315H) && (SiS_VBType & VB_SIS301BLV302BLV)) {
-	        if(SiS_ModeType <= ModeVGA) {
-			if(tempbx & SetCRT2ToLCD) {
-		    		modeflag &= (~CRT2Mode);
-			}
-	        }
+	/* TW: LVDS (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
+	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
+	       ((tempbx & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD)) ) {
+	       modeflag &= (~CRT2Mode);
+	   }
 	}
-	/* TW end */
-
+	
     	if(!(tempbx & SetSimuScanMode)){
-      		if(tempbx & SwitchToCRT2) {
-        		if(!(modeflag & CRT2Mode)) {
-			     if( (HwDeviceExtension->jChipType >= SIS_315H) &&
-			         (SiS_VBType & VB_SIS301BLV302BLV) ) {
-			        if(resinfo != 0x0a)
-                                   tempbx |= SetSimuScanMode;
-			     } else {
-            			tempbx |= SetSimuScanMode;
-	                     }
-
-        		}
-      		} else {
-        		if(!(SiS_BridgeIsEnable(BaseAddr,HwDeviceExtension))) {
-          			if(!(tempbx & DriverMode)) {
-            				if(SiS_BridgeInSlave()) {
-						tempbx |= SetSimuScanMode; /* TW: from BIOS 650/301/301LV/LVDS */
-            				}
-          			}
-        		}
-      		}
+      	    if(tempbx & SwitchToCRT2) {
+        	if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+		     if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+			 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
+			 if(resinfo != 0x0a)
+                              tempbx |= SetSimuScanMode;
+		     } else {
+            		      tempbx |= SetSimuScanMode;
+	             }
+        	}
+      	    } else {
+        	if(!(SiS_BridgeIsEnable(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+          	     if(!(tempbx & DriverMode)) {
+            		  if(SiS_BridgeInSlave(SiS_Pr)) {
+			      tempbx |= SetSimuScanMode;
+            		  }
+                     }
+                }
+      	    }
     	}
 
     	if(!(tempbx & DisableCRT2Display)) {
-     		 if(tempbx & DriverMode) {
-        		if(tempbx & SetSimuScanMode) {
-          			if(!(modeflag & CRT2Mode)) {
-				        if( (HwDeviceExtension->jChipType >= SIS_315H) &&
-					    (SiS_VBType & VB_SIS301BLV302BLV) ) {
-					        if(resinfo != 0x0a) {  /* TW: Inserted from 650/301 BIOS */
-						    tempbx |= SetInSlaveMode;
-            					    if(SiS_IF_DEF_LVDS == 0) {
-              						if(tempbx & SetCRT2ToTV) {
-                						if(!(tempbx & SetNotSimuMode))
-									SiS_SetFlag |= TVSimuMode;
-              						}
-            					    }
-					        }                      /* TW: Inserted from 650/301 BIOS */
-					} else {
-            					tempbx |= SetInSlaveMode;
-            					if(SiS_IF_DEF_LVDS == 0) {
-              						if(tempbx & SetCRT2ToTV) {
-                						if(!(tempbx & SetNotSimuMode))
-									SiS_SetFlag |= TVSimuMode;
-              						}
-            					}
-         				}
-				}
-        		}
-      		} else {
-        		tempbx |= SetInSlaveMode;
-        		if(SiS_IF_DEF_LVDS == 0) {
-          			if(tempbx & SetCRT2ToTV) {
-            				if(!(tempbx & SetNotSimuMode))
-						SiS_SetFlag |= TVSimuMode;
-          			}
-        		}
-      		}
-    	}
-    	if(SiS_IF_DEF_CH70xx == 1) {
-      		temp = SiS_GetReg1(SiS_P3d4,0x35);
-      		if(temp & TVOverScan) tempbx |= SetCHTVOverScan;
-    	}
-	if(SiS_IF_DEF_CH70xx == 2) {
-      		temp = SiS_GetReg1(SiS_P3d4,0x79);
-      		if(temp & 0x80) tempbx |= SetCHTVOverScan;
+            if(tempbx & DriverMode) {
+                if(tempbx & SetSimuScanMode) {
+          	    if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+	                if( (HwDeviceExtension->jChipType >= SIS_315H) &&
+			    (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
+			     if(resinfo != 0x0a) {  /* TW: 650/301 BIOS */
+			          tempbx |= SetInSlaveMode;
+            		          if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+              		 	     if(tempbx & SetCRT2ToTV) {
+                		         if(!(tempbx & SetNotSimuMode))
+					     SiS_Pr->SiS_SetFlag |= TVSimuMode;
+              			     }
+                                  }
+			     }                      /* TW: 650/301 BIOS */
+		        } else {
+            		    tempbx |= SetInSlaveMode;
+            		    if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+              		        if(tempbx & SetCRT2ToTV) {
+                		    if(!(tempbx & SetNotSimuMode))
+					SiS_Pr->SiS_SetFlag |= TVSimuMode;
+              			}
+            		    }
+                        }
+	            }
+                }
+            } else {
+                tempbx |= SetInSlaveMode;
+        	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+          	    if(tempbx & SetCRT2ToTV) {
+            		if(!(tempbx & SetNotSimuMode))
+			    SiS_Pr->SiS_SetFlag |= TVSimuMode;
+          	    }
+        	}
+      	    }
     	}
+	
+	if(SiS_Pr->SiS_CHOverScan) {
+    	   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+      		temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+      		if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1) )
+		      tempbx |= SetCHTVOverScan;
+    	   }
+	   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+      		temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79);
+      		if( (temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1) )
+		      tempbx |= SetCHTVOverScan;
+    	   }
+	}
   }
 
-  if(SiS_IF_DEF_LVDS==0) {
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 #ifdef SIS300
-     	if((HwDeviceExtension->jChipType==SIS_630)||
+     	if((HwDeviceExtension->jChipType==SIS_630) ||
            (HwDeviceExtension->jChipType==SIS_730)) {
+	   	if(ROMAddr && SiS_Pr->SiS_UseROM) {
+			OutputSelect = ROMAddr[0xfe];
+                }
            	if(!(OutputSelect & EnablePALMN))
-             		SiS_SetRegAND(SiS_P3d4,0x35,0x3F);
+             		SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0x3F);
            	if(tempbx & SetCRT2ToTV) {
               		if(tempbx & SetPALTV) {
-                  		temp=SiS_GetReg1(SiS_P3d4,0x35);
-                  		temp &= 0xC0;
-                  		if(temp == 0x40)
-                    			tempbx &= (~SetPALTV);
+                  		temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+                  		if(temp & EnablePALM) tempbx &= (~SetPALTV);
              		}
           	}
       	}
 #endif
 #ifdef SIS315H
      	if(HwDeviceExtension->jChipType >= SIS_315H) {
+	        if(ROMAddr && SiS_Pr->SiS_UseROM) {
+		    OutputSelect = ROMAddr[0xf3];
+		    if(HwDeviceExtension->jChipType == SIS_330) {
+			OutputSelect = ROMAddr[0x11b];
+		    }
+                }
 		if(!(OutputSelect & EnablePALMN))
-        		SiS_SetRegAND(SiS_P3d4,0x38,0x3F);
+        		SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0x3F);
    		if(tempbx & SetCRT2ToTV) {
     			if(tempbx & SetPALTV) {
-               			temp = SiS_GetReg1(SiS_P3d4,0x38);
-               			/* temp &= 0xC0;  */ /* TW: BIOS only tests 0x40, not 0x80 */
-               			if(temp & 0x40)
-               				tempbx &= (~SetPALTV);
+               			temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+               			if(temp & EnablePALM) tempbx &= (~SetPALTV);
               		}
         	}
   	}
 #endif
   }
+  
+  /* PALM/PALN on Chrontel 7019 */
+  SiS_Pr->SiS_CHPALM = SiS_Pr->SiS_CHPALN = FALSE;
+  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+  	if(tempbx & SetCRT2ToTV) {
+    		if(tempbx & SetPALTV) {
+        		temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+        		if(temp & EnablePALM)      SiS_Pr->SiS_CHPALM = TRUE;
+			else if(temp & EnablePALN) SiS_Pr->SiS_CHPALN = TRUE;
+        	}
+        }
+  }
 
-  SiS_VBInfo=tempbx;
+  SiS_Pr->SiS_VBInfo = tempbx;
 
-  /* TW: DevSwitch not supported here */
+  if(HwDeviceExtension->jChipType == SIS_630) {
+       SiS_WhatIsThis(SiS_Pr, SiS_Pr->SiS_VBInfo);
+  }
 
 #ifdef TWDEBUG
 #ifdef LINUX_KERNEL
-  printk(KERN_INFO "sisfb: (VBInfo = %x, SetFlag = %x)\n", SiS_VBInfo, SiS_SetFlag);
+  printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n", 
+      SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
 #endif
 #ifdef LINUX_XF86
-  xf86DrvMsg(0, X_INFO, "(init301: VBInfo = %x, SetFlag = %x)\n", SiS_VBInfo, SiS_SetFlag);
+  xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n", 
+      SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
 #endif
 #endif
 
-#if 0
-  /* From 650/301LV BIOS: */
-  if(ModeNo == 0x13) bp+4 = 0x03
-  else bp+4 = ModeNo;
+#if 0  /* TW: Incomplete! (But does not seem to be required) */
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+     /* TW: From A901/630+301B BIOS */
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
+     }
+     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
+	     if( [si] == 3) ModeIdIndex = 0x3f2b;
+	 }
+     }
+     SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
+     if(ModeNo == 0x13) bp+4 = 0x03;
+  } else {
+     /* From 650/30xLV BIOS: */
+     SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
+     if(ModeNo == 0x13) bp+4 = 0x03;
+     else bp+4 = ModeNo;
+  }
 #endif
 
-  /* TW: 630/301B and 650/301 (not 301LV!) BIOS do more here, but this seems for DOS mode */
+  /* TW: 630/301B and 650/301 (not 301LV!) BIOSes do more here, but this seems for DOS mode */
 
 }
 
 void
-SiS_GetRAMDAC2DATA(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex,
-		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo)
 {
-  USHORT tempax,tempbx,temp;
-  USHORT temp1,temp2,modeflag=0,tempcx;
+   unsigned long eax, temp;
+   unsigned short temp1;
+
+   if(!(SiS_Pr->SiS_ChSW)) return;
+
+#ifndef LINUX_XF86
+   SiS_SetReg4(0xcf8,0x80000874);
+   eax = SiS_GetReg3(0xcfc);
+#else
+   eax = pciReadLong(0x00000800, 0x74);
+#endif
+   eax &= 0xFFFF;
+   temp = eax;
+   eax += 0x3c;
+   temp1 = SiS_GetReg4((USHORT)eax);
+   temp1 &= 0xFEFF;
+   SiS_SetReg5((USHORT)eax, temp1);
+   temp1 = SiS_GetReg4((USHORT)eax);
+   eax = temp;
+   eax += 0x3a;
+   temp1 = SiS_GetReg4((USHORT)eax);
+   temp1 &= 0xFEFF;
+   if(!(myvbinfo & SetCRT2ToTV)) {
+      temp1 |= 0x0100;
+   }
+   SiS_SetReg5((USHORT)eax, temp1);
+   temp1 = SiS_GetReg4((USHORT)eax);
+}
+
+void
+SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT tempax=0,tempbx=0;
+  USHORT temp1=0,modeflag=0,tempcx=0;
   USHORT StandTableIndex,CRT1Index;
-  USHORT ResInfo,DisplayType;
-  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+#ifdef SIS315H   
+  USHORT ResInfo,DisplayType,temp=0;
+  const  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
+#endif
 
-  SiS_RVBHCMAX=1;
-  SiS_RVBHCFACT=1;
+  SiS_Pr->SiS_RVBHCMAX  = 1;
+  SiS_Pr->SiS_RVBHCFACT = 1;
 
   if(ModeNo <= 0x13){
 
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	StandTableIndex = SiS_GetModePtr(ROMAddr,ModeNo,ModeIdIndex);
-    	tempax = SiS_StandTable[StandTableIndex].CRTC[0];
-    	tempbx = SiS_StandTable[StandTableIndex].CRTC[6];
-    	temp1 = SiS_StandTable[StandTableIndex].CRTC[7];
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+    	tempax = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[0];
+    	tempbx = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[6];
+	temp1 = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[7];
 
   } else {
 
-     if( (SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo&SetCRT2ToLCDA) ) {
+     if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) {
 
-    	temp=SiS_GetLVDSCRT1Ptr(ROMAddr,ModeNo,ModeIdIndex,
+#ifdef SIS315H     
+    	temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
 			RefreshRateTableIndex,&ResInfo,&DisplayType);
 
-    	if(temp==0)  return;
+    	if(temp == 0)  return;
 
     	switch(DisplayType) {
-    		case 0 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;		break;
-    		case 1 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;          break;
-    		case 2 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;         break;
-    		case 3 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;         break;
-    		case 4 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;        break;
-    		case 5 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;       break;
-    		case 6 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;           break;
-    		case 7 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;          break;
-    		case 8 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;         break;
-    		case 9 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;         break;
-    		case 10: LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;        break;
-    		case 11: LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;       break;
-		case 12: LVDSCRT1Ptr = SiS_LVDSCRT1XXXxXXX_1;           break;
-		case 13: LVDSCRT1Ptr = SiS_LVDSCRT1XXXxXXX_1_H;         break;
-		case 14: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_1;         break;
-		case 15: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_1_H;       break;
-		case 16: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_2;         break;
-		case 17: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_2_H;       break;
-    		case 18: LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;               break;
-    		case 19: LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;               break;
-    		case 20: LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;                break;
-    		case 21: LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;                break;
-    		case 22: LVDSCRT1Ptr = SiS_LVDSCRT1320x480_1;           break;
-
+    		case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1;		break;
+    		case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
+    		case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1;         break;
+    		case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H;         break;
+    		case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H;        break;
+    		case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H;       break;
+    		case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2;           break;
+    		case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2;          break;
+    		case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2;         break;
+    		case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H;         break;
+    		case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H;        break;
+    		case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H;       break;
+		case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1;           break;
+		case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H;         break;
+		case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1;         break;
+		case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H;       break;
+		case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2;         break;
+		case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H;       break;
+    		case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
+    		case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
+    		case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
+    		case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
+    		case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1;           break;
+		case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
+    		case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
+    		case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
+    		case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
+    		case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1;          break;
+    		case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H;        break;
+    		case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2;          break;
+    		case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H;        break;
+		case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1;         break;
+		case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H;       break;
+		case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2;         break;
+		case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H;       break;
+		case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
+		default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
     	}
-    	temp1=(LVDSCRT1Ptr+ResInfo)->CR[0];
-    	temp2=(LVDSCRT1Ptr+ResInfo)->CR[14];
-    	tempax=(temp1&0xFF)|((temp2&0x03)<<8);
-    	tempbx=(LVDSCRT1Ptr+ResInfo)->CR[6];
-    	tempcx=(LVDSCRT1Ptr+ResInfo)->CR[13]<<8;
-    	tempcx = tempcx&0x0100;
-    	tempcx = tempcx << 2;
-    	tempbx = tempbx | tempcx;
-    	temp1=(LVDSCRT1Ptr+ResInfo)->CR[7];
+	tempax = (LVDSCRT1Ptr+ResInfo)->CR[0];
+	tempax |= (LVDSCRT1Ptr+ResInfo)->CR[14] << 8;
+	tempax &= 0x03FF;
+    	tempbx = (LVDSCRT1Ptr+ResInfo)->CR[6];
+    	tempcx = (LVDSCRT1Ptr+ResInfo)->CR[13] << 8;
+    	tempcx &= 0x0100;
+    	tempcx <<= 2;
+    	tempbx |= tempcx;
+	temp1  = (LVDSCRT1Ptr+ResInfo)->CR[7];
+#endif	
 
     } else {
 
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	CRT1Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-	if(HwDeviceExtension->jChipType < SIS_315H) {
-    	   CRT1Index &= 0x3F;
-	}
-    	temp1 = (USHORT)SiS_CRT1Table[CRT1Index].CR[0];
-    	temp2 = (USHORT)SiS_CRT1Table[CRT1Index].CR[14];
-    	tempax=(temp1&0xFF)|((temp2&0x03)<<8);
-    	tempbx = (USHORT)SiS_CRT1Table[CRT1Index].CR[6];
-    	tempcx = (USHORT)SiS_CRT1Table[CRT1Index].CR[13]<<8;
-    	tempcx = tempcx&0x0100;
-    	tempcx = tempcx << 2;
-    	tempbx = tempbx | tempcx;
-    	temp1 = (USHORT)SiS_CRT1Table[CRT1Index].CR[7];
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+#if 0   /* Not any longer */	
+	if(HwDeviceExtension->jChipType < SIS_315H)  CRT1Index &= 0x3F;
+#endif	
+	tempax = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
+	tempax |= SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] << 8;
+        tempax &= 0x03FF;
+    	tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
+    	tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13] << 8;
+    	tempcx &= 0x0100;
+    	tempcx <<= 2;
+    	tempbx |= tempcx;
+	temp1  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
 
     }
 
   }
 
-  if(temp1&0x01) tempbx |= 0x0100;
-  if(temp1&0x20) tempbx |= 0x0200;
+  if(temp1 & 0x01) tempbx |= 0x0100;
+  if(temp1 & 0x20) tempbx |= 0x0200;
+  
   tempax += 5;
+
+  /* Charx8Dot is no more used (and assumed), so we set it */
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      modeflag |= Charx8Dot;
+  }
+
   if(modeflag & Charx8Dot) tempax *= 8;
-  else tempax *= 9;
+  else                     tempax *= 9;
 
-  SiS_VGAHT = SiS_HT = tempax;
+  /* TW: From 650/30xLV 1.10.6s */
+  if(modeflag & HalfDCLK)  tempax <<= 1;
+
+  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
   tempbx++;
-  SiS_VGAVT = SiS_VT = tempbx;
+  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
 }
 
 void
-SiS_UnLockCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
 {
   if(HwDeviceExtension->jChipType >= SIS_315H)
-    	SiS_SetRegOR(SiS_Part1Port,0x2f,0x01);
+    	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
   else
-    	SiS_SetRegOR(SiS_Part1Port,0x24,0x01);
+    	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
 }
 
 void
-SiS_LockCRT2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
 {
   if(HwDeviceExtension->jChipType >= SIS_315H)
-    	SiS_SetRegAND(SiS_Part1Port,0x2F,0xFE);
+    	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
   else
-     	SiS_SetRegAND(SiS_Part1Port,0x24,0xFE);
+     	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
 }
 
 void
-SiS_EnableCRT2()
+SiS_EnableCRT2(SiS_Private *SiS_Pr)
 {
-  SiS_SetRegOR(SiS_P3c4,0x1E,0x20);
+  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
 }
 
-/* Checked against 650/LVDS(1.10.07)/301 and 630/301B BIOS */
+/* Checked against all BIOSes */
 void
-SiS_DisableBridge(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
 {
-  USHORT tempah,temp;
+#ifdef SIS315H
+  USHORT tempah,pushax=0,modenum;
+#endif
+  USHORT temp=0;
   UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
 
-  if (SiS_IF_DEF_LVDS == 0) {
+  if (SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-      if(SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== TW: For 30xB/LV ===== */
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== TW: For 30xB/LV ===== */
 
         if(HwDeviceExtension->jChipType < SIS_315H) {
 
-	   /* 300 series */
+#ifdef SIS300	   /* 300 series */
+
+           if(HwDeviceExtension->jChipType == SIS_300) {  /* New for 300+301LV */
+
+	      if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+	         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
+		    SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+		 }
+	      }
+	      if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
+	         SiS_ShortDelay(SiS_Pr,1);
+	      }
+	      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+	      SiS_DisplayOff(SiS_Pr);
+	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	      if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ||
+	          (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
+	         SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+                 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
+	      }
+
+	   } else {
 
-	   if(!(SiS_CR36BIOSWord23b(HwDeviceExtension))) {
-	      SiS_SetRegANDOR(SiS_P3c4,0x11,0xF7,0x08);
-	      SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 3);
-	   }
-	   if(SiS_Is301B(BaseAddr)) {
-	      SiS_SetRegAND(SiS_Part4Port,0x1f,0x3f);
-	      SiS_ShortDelay(1);
-	   }
-	   SiS_SetRegAND(SiS_Part2Port,0x00,0xDF);
-	   SiS_DisplayOff();
-	   SiS_SetRegAND(SiS_P3c4,0x32,0xDF);
-	   SiS_SetRegAND(SiS_P3c4,0x1E,0xDF);
-	   SiS_UnLockCRT2(HwDeviceExtension,BaseAddr);
-	   SiS_SetRegOR(SiS_Part1Port,0x01,0x80);
-	   SiS_SetRegOR(SiS_Part1Port,0x02,0x40);
-/*	   SiS_DoSomeThingPCI();    */  /* TW: Is this really required ? */
-	   if( (!(SiS_CRT2IsLCD(BaseAddr))) || (!(SiS_CR36BIOSWord23d(HwDeviceExtension))) ) {
-	      SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
-              SiS_SetRegANDOR(SiS_P3c4,0x11,0xFB,0x04);
+	      if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+	         SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+	         SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+	      }
+	      if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
+	         SiS_ShortDelay(SiS_Pr,1);
+	      }
+	      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+	      SiS_DisplayOff(SiS_Pr);
+	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	      SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
+	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
+	      if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ||
+	          (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
+	         SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+                 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
+	      }
 	   }
 
+#endif  /* SIS300 */
+
         } else {
 
-	   /* 310 series */
+#ifdef SIS315H	   /* 310/325 series */
+
+           if(IS_SIS650740) {		/* 650, 740 */
 
 #if 0
-           if(SiS_Is301B(BaseAddr)) {
+	      if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return;	/* From 1.10.7w */
 #endif
-             /* TW: Inserted from 650/301LV BIOS */
-	     if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
-	     	   SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFE,0x00);
-		   SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 3);
-	     } else if (SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-		   SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFE,0x00);
-		   SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 3);
-             }
-	     /* TW end */
-           /* TW: 301B dependent code starts here in 650/301LV BIOS */
-	   if(SiS_Is301B(BaseAddr)) {
-	     tempah = 0x3f;
-#if 0        /* TW: This is not done in 650/301LV BIOS, instead 0x3f is used in any case */
-             if(SiS_IsDualEdge(HwDeviceExtension, BaseAddr)) {
-	        tempah = 0x7f;
-	        if(!(SiS_IsVAMode(HwDeviceExtension, BaseAddr))) {
-		   tempah = 0xbf;
-                }
+
+	      modenum = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
+
+              if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	      
+	         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+		 
+		 if( (modenum <= 0x13) ||
+		     (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
+		     (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
+	     	      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
+	         }
+		 SiS_DDC2Delay(SiS_Pr,0xff00);
+		 SiS_DDC2Delay(SiS_Pr,0x6000);
+		 SiS_DDC2Delay(SiS_Pr,0x8000);
+
+	         SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
+
+                 pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+		 
+		 if(IS_SIS740) {
+		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+		 }
+
+	         SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+		 
+		 if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	            tempah = 0xef;
+	            if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	               tempah = 0xf7;
+                    }
+	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+	         }
+
+              }
+
+              if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+	         tempah = 0x3f;
+	         if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	            tempah = 0x7f;
+	            if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		       tempah = 0xbf;
+                    }
+	         }
+	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+	      }
+
+              if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+	         ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
+
+	         if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+		    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
+		    SiS_DisplayOff(SiS_Pr);
+		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+		 } else {
+	            SiS_DisplayOff(SiS_Pr);
+	            SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+	            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
+		    if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13)) {
+		       SiS_DisplayOff(SiS_Pr);
+	               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+	               SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+	               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+	               temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+                       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+	               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	               SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+		    }
+		 }
+
+	      } else {
+
+	         if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+		    if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		       SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+		       SiS_DisplayOff(SiS_Pr);
+		    }
+		    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+		    temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+                    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+	            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	            SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+		 } else {
+                    SiS_DisplayOff(SiS_Pr);
+	            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+	            SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+	            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+	            temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+                    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+	            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	            SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+		 }
+
+	      }
+
+	      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+
+		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);    /* 1.10.8r */
+		 
+	         tempah = 0x3f;
+	         if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	            tempah = 0x7f;
+	            if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		       tempah = 0xbf;
+                    }
+	         }
+	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+
+		 if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {   /* 1.10.8r */
+	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+		 }								/* 1.10.8r */
+
+	         if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	            SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+	         }
+
+	         if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	            if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+	               if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
+                       }
+                    }
+	         }
+
+	         SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+
+  	      }
+
+#if 0
+          } else if(IS_SIS740) {	/* 740 */
+	  
+	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {   /* 30xLV */
+	     
+	        if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
+		    (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
+	     	      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
+	        }
+		
+		SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
+
+                pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+		
+		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+
+	        SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+		
+		if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+		   SiS_DisplayOff(SiS_Pr);
+	           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+	           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
+		} else {
+		   SiS_DisplayOff(SiS_Pr);
+	           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+	           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+	           temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+                   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	           SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+		}
+		
+		SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0x3F);
+		SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xEF);  /* (from 650) */
+		
+		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+		
+		if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+	        }
+		
+		if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		   if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	              if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+	                 if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
+                         }
+                      }
+	           }
+		}
+	        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+	     
+	     } else {	/* (301,) 301B */
+	  
+	        if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+	           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0x3F);
+	        }
+	     
+	        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+	        SiS_DisplayOff(SiS_Pr);
+	        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+	        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+
+	        temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+	        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+		
 	     }
-#endif
-             SiS_SetRegAND(SiS_Part4Port,0x1F,tempah);
-           } /* 301B dependent code ends here in 650/301V BIOS */
-#if 0        /* TW: This is not done in 650/301LV BIOS */
-	     if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-                SiS_SetRegAND(SiS_Part1Port,0x1E,0xDF);
-	        SiS_DisplayOff();
-	        SiS_SetRegAND(SiS_P3c4,0x32,0xDF);
-	        return;
-	     } else {
-	        if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
-                    SiS_SetRegAND(SiS_Part2Port,0x00,0xDF);
-		    SiS_DisplayOff();
+#endif	  
+	  } else {			/* 315, 330 - all bridge types */
+
+	     if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+	        tempah = 0x3f;
+	        if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	           tempah = 0x7f;
+	           if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		      tempah = 0xbf;
+                   }
+	        }
+	        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+	        if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	           SiS_DisplayOff(SiS_Pr);
+		   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
 	        }
 	     }
-           } else {
-#endif
-                 SiS_SetRegAND(SiS_Part2Port,0x00,0xDF);
-		 SiS_DisplayOff();
-#if 0
-	   }
-#endif
+	     if( (!(SiS_Is301B(SiS_Pr,BaseAddr))) ||
+	         (!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) ) {
 
-           SiS_SetRegOR(SiS_Part1Port,0x00,0x80);
+ 	 	if( (!(SiS_Is301B(SiS_Pr,BaseAddr))) ||
+		    (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ) {
 
-           SiS_SetRegAND(SiS_P3c4,0x32,0xDF);
+	           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+	           SiS_DisplayOff(SiS_Pr);
 
-	   temp = SiS_GetReg1(SiS_Part1Port,0x00);
-           SiS_SetRegOR(SiS_Part1Port,0x00,0x10);
-	   SiS_SetRegAND(SiS_P3c4,0x1E,0xDF);
-	   SiS_SetReg1(SiS_Part1Port,0x00,temp);
-
-	   /* TW: Inserted from 650/301LV BIOS */
-	   if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-	       if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {
-	           if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
-		          SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
-			  SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFD,0x00);
-			  SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 4);
-                   } else if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-                          SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
-			  SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFD,0x00);
-			  SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 4);
-		   }
-	       }
-	    } else if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
-	       if (!(SiS_CRT2IsLCD(BaseAddr))) {
-	            SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
-		    SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFD,0x00);
-		    SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 4);
-               } else if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {
-	           if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
-		          SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
-			  SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFD,0x00);
-			  SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 4);
-                   } else if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-                          SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
-			  SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFD,0x00);
-			  SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 4);
-		   }
-	       }
-	   }
-	   /* TW: 650/301LV end */
+		}
 
-	}
+                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
 
-      } else {     /* ============ TW: For 301 ================ */
+                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
 
-        if(HwDeviceExtension->jChipType < SIS_315H)
-             SiS_SetRegANDOR(SiS_P3c4,0x11,0xF7,0x08);
+	        temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+	        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
 
-        SiS_SetRegAND(SiS_Part2Port,0x00,0xDF);           /* disable VB */
-        SiS_DisplayOff();
+	     }
 
-        if(HwDeviceExtension->jChipType >= SIS_315H)
-            SiS_SetRegOR(SiS_Part1Port,0x00,0x80);
+	  }    /* 315/330 */
 
-        SiS_SetRegAND(SiS_P3c4,0x32,0xDF);                /* disable lock mode */
+#endif /* SIS315H */
 
-        temp = SiS_GetReg1(SiS_Part1Port,0x00);
-        SiS_SetRegOR(SiS_Part1Port,0x00,0x10);
+	}
+
+      } else {     /* ============ TW: For 301 ================ */
 
-        SiS_SetRegAND(SiS_P3c4,0x1E,0xDF);                /* disable CRT2 */
-        SiS_SetReg1(SiS_Part1Port,0x00,temp);
+        if(HwDeviceExtension->jChipType < SIS_315H) {
+            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
+	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
+	    }
+	}
+
+        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
+        SiS_DisplayOff(SiS_Pr);
+
+        if(HwDeviceExtension->jChipType >= SIS_315H) {
+            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+	}
 
-	if(HwDeviceExtension->jChipType < SIS_315H)
-	     SiS_SetRegANDOR(SiS_P3c4,0x11,0xFB,0x04);
+        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
+
+	if(HwDeviceExtension->jChipType >= SIS_315H) {
+            temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+	    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+	} else {
+            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
+	}
 
       }
 
@@ -3944,115 +5226,160 @@
 
     if(HwDeviceExtension->jChipType < SIS_315H) {
 
-	/* 300 series */
+#ifdef SIS300	/* 300 series */
 
-	if(SiS_IF_DEF_CH70xx == 1) {
-	    if(SiS_Backup70xx == 0xff) {
-		SiS_Backup70xx = SiS_GetCH700x(0x0e);
-	    }
-	    SiS_SetCH700x(0x090E);
+	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+	    SiS_SetCH700x(SiS_Pr,0x090E);
 	}
 
-	if(!(SiS_GetReg1(SiS_P3c4,0x11) & 0x08)) {
-
-	    if(!(SiS_GetReg1(SiS_P3c4,0x13) & 0x40)) {
+	if(HwDeviceExtension->jChipType == SIS_730) {
+	   if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
+	      SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+	   }
+	   if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+	      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+	      SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+	   }
+	} else {
+	   if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
 
-	        if(!(SiS_CR36BIOSWord23b(HwDeviceExtension))) {
+	      if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+  
+  	          if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
 
-                     SiS_WaitVBRetrace(HwDeviceExtension);
+                     SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
 
-		     if(!(SiS_GetReg1(SiS_P3c4,0x06) & 0x1c)) {
-		         SiS_DisplayOff();
+		     if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
+		         SiS_DisplayOff(SiS_Pr);
 	             }
 
-	             SiS_SetRegANDOR(SiS_P3c4,0x11,0xF7,0x08);
-	             SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 3);
-                }
-            }
+	             SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+	             SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+                  }
+              }
+	   }
 	}
 
-	SiS_DisplayOff();
+	SiS_DisplayOff(SiS_Pr);
 
-	SiS_SetRegAND(SiS_P3c4,0x32,0xDF);
+	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
 
-	SiS_SetRegAND(SiS_P3c4,0x1E,0xDF);
-	SiS_UnLockCRT2(HwDeviceExtension,BaseAddr);
-	SiS_SetRegOR(SiS_Part1Port,0x01,0x80);
-	SiS_SetRegOR(SiS_Part1Port,0x02,0x40);
-
-	if( (!(SiS_CRT2IsLCD(BaseAddr))) ||
-	              (!(SiS_CR36BIOSWord23d(HwDeviceExtension))) ) {
-		SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 2);
-		SiS_SetRegANDOR(SiS_P3c4,0x11,0xFB,0x04);
+	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
+	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
+
+	if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ||
+	              (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
+		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+		SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
 	}
 
+#endif  /* SIS300 */
+
     } else {
 
-	/* 310 series */
+#ifdef SIS315H	/* 310/325 series */
 
-	if(SiS_IF_DEF_CH70xx == 2) {
-		if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
-			SiS_Chrontel701xOff();
-			SiS_Chrontel701xOff2();
-		} else if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-			SiS_Chrontel701xOff();
-			SiS_Chrontel701xOff2();
+	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+		temp =  temp = SiS_GetCH701x(SiS_Pr,0x61);
+		if(temp < 1) {
+		   SiS_SetCH701x(SiS_Pr,0xac76);
+		   SiS_SetCH701x(SiS_Pr,0x0066);
 		}
-
-		if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
-			SiS_SetCH701x(0x0149);
-		} else if(SiS_IsTVOrSomething(HwDeviceExtension, BaseAddr))  {
-			SiS_SetCH701x(0x0149);
+		
+		if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+			SiS_SetCH701x(SiS_Pr,0x3e49);
+		} else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))  {
+			SiS_SetCH701x(SiS_Pr,0x3e49);
+		}
+		
+		if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+			SiS_Chrontel701xBLOff(SiS_Pr);
+			SiS_Chrontel701xOff(SiS_Pr);
+		} else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+			SiS_Chrontel701xBLOff(SiS_Pr);
+			SiS_Chrontel701xOff(SiS_Pr);
 		}
+		
 	}
 
-	if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
-		SiS_DisplayOff();
-	} else if(!(SiS_IsTVOrSomething(HwDeviceExtension, BaseAddr))) {
-		SiS_DisplayOff();
+	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+		SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
 	}
 
-	if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
-		SiS_SetRegOR(SiS_Part1Port,0x00,0x80);
-	} else if(!(SiS_IsVAMode(HwDeviceExtension, BaseAddr))) {
-		SiS_SetRegOR(SiS_Part1Port,0x00,0x80);
+	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+		SiS_DisplayOff(SiS_Pr);
+	} else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		SiS_DisplayOff(SiS_Pr);
+	} else if(!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		SiS_DisplayOff(SiS_Pr);
 	}
 
-	SiS_SetRegAND(SiS_P3c4,0x32,0xDF);
+	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+	} else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+	} else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+	}
 
-	if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
-		SiS_SetRegAND(SiS_P3c4,0x1E,0xDF);
-	} else if(!(SiS_IsVAMode(HwDeviceExtension, BaseAddr))) {
-		SiS_SetRegAND(SiS_P3c4,0x1E,0xDF);
+	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+
+	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	} else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	} else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
 	}
 
-	if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-		SiS_SetRegAND(SiS_Part1Port,0x1e,0xdf);
+	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+	        if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr,HwDeviceExtension)) {
+			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+		}
+	} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
 	}
 
-	if(SiS_IsDualEdge(HwDeviceExtension, BaseAddr)) {
-		SiS_SetRegAND(SiS_Part1Port,0x13,0xff);
-	} else {
-		SiS_SetRegAND(SiS_Part1Port,0x13,0xfb);
+	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+	    	if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff);
+		} else {
+			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+		}
 	}
 
-	SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+	SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
 
-	if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
-		SiS_SetRegAND(SiS_Part1Port,0x2e,0xf7);
-	} else if(!(SiS_IsVAMode(HwDeviceExtension, BaseAddr))) {
-		SiS_SetRegAND(SiS_Part1Port,0x2e,0xf7);
+	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+	} else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+	} else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
 	}
 
 #if 0  /* TW: BIOS code makes no sense */
-       if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-           if(!(SiS_IsDualEdge(HwDeviceExtension, BaseAddr))) {
-	        if(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr)) {
+       if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+           if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
 		  /* Nothing there! */
 		}
            }
        }
 #endif
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+		if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr,HwDeviceExtension)) {
+			if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+				SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+				SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
+			}
+		}
+       }
+
+#endif  /* SIS315H */
 
     }  /* 310 series */
 
@@ -4060,181 +5387,440 @@
 
 }
 
-/* TW: Checked against 650/LVDS(1.10.07)/301 and 630/301B BIOS */
+/* TW: Checked against all BIOSes */
 void
-SiS_EnableBridge(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT  BaseAddr)
+SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
-  USHORT temp=0,tempah,temp1;
+  USHORT temp=0,tempah;
+#ifdef SIS315H
+  USHORT temp1,pushax=0;
+  BOOLEAN delaylong = FALSE;
+#endif
   UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
 
-  if(SiS_IF_DEF_LVDS == 0) {
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-    if(SiS_VBType & VB_SIS301BLV302BLV) {   /* TW: ====== For 301B ====== */
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* TW: ====== For 301B et al  ====== */
 
       if(HwDeviceExtension->jChipType < SIS_315H) {
 
-         /* 300 series */
+#ifdef SIS300     /* 300 series */
 
-	 if(SiS_CRT2IsLCD(BaseAddr)) {
-	    SiS_SetRegAND(SiS_P3c4,0x11,0xFB);
-	    if(!(SiS_CR36BIOSWord23d(HwDeviceExtension))) {
-	       SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 0);
+         if(HwDeviceExtension->jChipType == SIS_300) {
+
+	    if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+	       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 
+	          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+	          if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) {
+	             SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
+	          }
+	       }
 	    }
-	    SiS_SetRegOR(SiS_P3c4,0x1E,0x20);   /* Enable CRT2 */
-/*	    DoSomeThingPCI_On() */
-            SiS_DisplayOn();
-	    SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
-	    SiS_SetRegAND(SiS_Part1Port,0x02,0xBF);
-	    if(SiS_BridgeInSlave()) {
-      		SiS_SetRegAND(SiS_Part1Port,0x01,0x1F);
-      	    } else {
-      		SiS_SetRegANDOR(SiS_Part1Port,0x01,0x1F,0x40);
+	    temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
+            if(SiS_BridgeInSlave(SiS_Pr)) {
+               tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+               if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
             }
-	    if(!(SiS_GetReg1(SiS_P3c4,0x13) & 0x40)) {
-	        if(!(SiS_GetReg1(SiS_P3c4,0x16) & 0x10)) {
-		    if(!(SiS_CR36BIOSWord23b(HwDeviceExtension))) {
-		        SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 1);
-                    }
-		    SiS_WaitVBRetrace(HwDeviceExtension);
-                    SiS_SetRegANDOR(SiS_P3c4,0x11,0xF7,0x00);
-                }
+            SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
+	    if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+               SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
+	       SiS_DisplayOn(SiS_Pr);
+	    } else {
+	       SiS_VBLongWait(SiS_Pr);
+	       SiS_DisplayOn(SiS_Pr);
+	       SiS_VBLongWait(SiS_Pr);
 	    }
-         } else {
-	   temp = SiS_GetReg1(SiS_P3c4,0x32) & 0xDF;             /* lock mode */
-           if(SiS_BridgeInSlave()) {
-              tempah = SiS_GetReg1(SiS_P3d4,0x30);
-              if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
-           }
-           SiS_SetReg1(SiS_P3c4,0x32,temp);
-	   SiS_SetRegOR(SiS_P3c4,0x1E,0x20);
-	   SiS_SetRegANDOR(SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
-	   if(SiS_Is301B(BaseAddr)) {
-              SiS_SetRegOR(SiS_Part4Port,0x1F,0xC0);
-	      SiS_DisplayOn();
-	   } else {
-	      SiS_VBLongWait();
-	      SiS_DisplayOn();
-	      SiS_VBLongWait();
-	   }
-	 }
+	    if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+	       if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+		  if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+		     if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+		           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+                     }
+		     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 
+		         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
+	 	     }
+		  }
+               }
+	    }
+
+	 } else {
+
+	    if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
+	       (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+	       /* This is only for LCD output on 301B-DH via LVDS */
+	       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
+	       if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) {
+	          SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
+	       }
+	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   /* Enable CRT2 */
+/*	       DoSomeThingPCI_On(SiS_Pr) */
+               SiS_DisplayOn(SiS_Pr);
+	       SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
+	       if(SiS_BridgeInSlave(SiS_Pr)) {
+      		  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
+      	       } else {
+      		  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
+               }
+	       if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+	           if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+		       if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+		           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+                       }
+		       SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+                       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x00);
+                   }
+	       }
+            } else {
+	       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
+               if(SiS_BridgeInSlave(SiS_Pr)) {
+                  tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+                  if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+               }
+               SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+	       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
+	       if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+                  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
+	          SiS_DisplayOn(SiS_Pr);
+	       } else {
+	          SiS_VBLongWait(SiS_Pr);
+	          SiS_DisplayOn(SiS_Pr);
+	          SiS_VBLongWait(SiS_Pr);
+	       }
+	    }
+
+         }
+#endif /* SIS300 */
 
       } else {
 
-         /* 310 series */
+#ifdef SIS315H    /* 310/325 series */
 
-	 /* TW: Inserted from 650/301LV BIOS */
-	 if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-	     SiS_SetRegANDOR(SiS_Part4Port,0x26,0xfd,0x02);
-	     SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 0);
-	 } else if(SiS_CRT2IsLCD(BaseAddr)) {
-	     SiS_SetRegANDOR(SiS_Part4Port,0x26,0xfd,0x02);
-	     SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 0);
-	 }
-	 /* TW: --- end --- */
+	 if(IS_SIS650740) {		/* 650 */
 
-         if(!(SiS_IsVAMode(HwDeviceExtension, BaseAddr))) {
-            temp = SiS_GetReg1(SiS_P3c4,0x32) & 0xDF;
-	    if(SiS_BridgeInSlave()) {
-               tempah = SiS_GetReg1(SiS_P3d4,0x30);
-               if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
-            }
-            SiS_SetReg1(SiS_P3c4,0x32,temp);
+#if 0
+	    if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return;	/* From 1.10.7w */
+#endif
 
-	    SiS_SetRegOR(SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
+	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	    
+	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);  /* 1.10.7u */
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);    /* 1.10.7u */
+
+	       if(!(IS_SIS740)) {
+                  if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	             tempah = 0x10;
+	             if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	                tempah = 0x08;
+                     }
+	             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+	          }
+	       }
 
-/*          SiS_SetRegAND(SiS_Part1Port,0x2E,0x7F);   */ 	/* TW: Not done in 650/301LV BIOS */
-            temp=SiS_GetReg1(SiS_Part1Port,0x2E);
-            if (!(temp & 0x80))
-                   SiS_SetRegOR(SiS_Part1Port,0x2E,0x80);
-          }
+	       SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
+	       SiS_DisplayOff(SiS_Pr);
+	       pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+	       if(IS_SIS740) {
+	          SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+	       }
 
-          SiS_SetRegANDOR(SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
+	       if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+	           (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+                   if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+		      SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2);
+		      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+	              SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2);
+	           }
+	       }
 
-          if(SiS_Is301B(BaseAddr)) {
-#if 0	     /* TW: This is not done in 630/301LV BIOS */
-	     if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-                SiS_SetRegOR(SiS_P3c4,0x1E,0x20);               /* enable CRT2 */
-	     }
+	       if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
+                  SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+		  delaylong = TRUE;
+	       }
+
+	    }
+
+	    if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+               temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+	       if(SiS_BridgeInSlave(SiS_Pr)) {
+                  tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+                  if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+               }
+               SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+
+	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
+	       
+	       if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+	          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+		  temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2e);
+		  if(!(temp & 0x80)) {
+		     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+		  }
+	       } else {
+	          SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+	       }
+	    }
+
+	    if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+	    }
+
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+
+	    if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+	       temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2e);
+	       if(!(temp & 0x80)) {
+		  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+	       }
+	    }
+
+	    tempah = 0xc0;
+	    if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	       tempah = 0x80;
+	       if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	          tempah = 0x40;
+               }
+	    }
+            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+
+	    if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+	    }
+
+	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	    
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);	/* All this from 1.10.7u */
+	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);  
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);  
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);  
+	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); 
+	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); 
+	       
+	       SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+	    
+	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);  /* 1.10.8r */
+
+	       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+
+	       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	          if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+	              ((SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ) {
+		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+		    if(delaylong) {
+			SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+		    }
+                    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+		    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
+	         }
+	      }
+
+	      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+	      SiS_DisplayOn(SiS_Pr);
+	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+
+	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+	      }
+#if 0
+              SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);   /* 1.10.8r: 0x0d */
+	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);   /* 1.10.8r: 0x70 */
+	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);   /* 1.10.8r: 0x40 */
+	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); 
+	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); 
+#endif	      
+
+	  }
+
+#if 0
+         } else if(IS_SIS740) {		/* 740 */
+	 
+	   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {  /* 30xLV */
+	   
+	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
+	      SiS_DisplayOff(SiS_Pr);
+	      pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
+	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+	      
+	      if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+	          (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+                   if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+		      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+	              SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+		   }
+	      }
+	      
+	      if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	         temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+	         if(SiS_BridgeInSlave(SiS_Pr)) {
+                    tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+                    if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+                 }
+                 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+
+	         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);  	
+		 SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
+	      }
+	      
+	      if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+	      }
+	      
+	      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
+	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0x10);  /* (taken from 650 1.10.8r) */
+	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+	      
+	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	         if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+	             (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+		    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
+		       SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+		    }
+		    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
+		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
+		    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+	         }
+              }
+	      
+	      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
+	      SiS_DisplayOn(SiS_Pr);
+	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+	      
+	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+	      }
+	   
+	   } else {	/* (301), 301B */
+	 
+	      if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	         temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+	         if(SiS_BridgeInSlave(SiS_Pr)) {
+                    tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+                    if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+                 }
+                 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+
+	         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
+
+	         temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+                 if(!(temp & 0x80))
+                    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+              }
+
+	      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+
+	      if(SiS_Is301B(SiS_Pr,BaseAddr)) { 
+	         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
+	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+	      } else {
+	         SiS_VBLongWait(SiS_Pr);
+                 SiS_DisplayOn(SiS_Pr);
+	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
+                 SiS_VBLongWait(SiS_Pr);
+	      }
+	      
+	   }
 #endif
-             /* TW: This is done instead: */
-             SiS_SetRegOR(SiS_Part4Port,0x1F,0xc0);
+	  
+	 } else {			/* 315, 330 */
+
+	   if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	      temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+	      if(SiS_BridgeInSlave(SiS_Pr)) {
+                 tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+                 if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+              }
+              SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+
+	      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
+
+	      temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+              if(!(temp & 0x80))
+                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+           }
+
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
 
-#if 0	     /* TW: This is not done in 630/301LV BIOS */
-	     temp=SiS_GetReg1(SiS_Part1Port,0x2E);
-             if (!(temp & 0x80))
-                SiS_SetRegOR(SiS_Part1Port,0x2E,0x80);
+	   if(SiS_Is301B(SiS_Pr,BaseAddr)) {
 
-	     tempah = 0xC0;
-	     if(SiS_IsDualEdge(HwDeviceExtension, BaseAddr)) {
+	      temp=SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+              if (!(temp & 0x80))
+                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+
+	      tempah = 0xc0;
+	      if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
 	         tempah = 0x80;
-	         if(!(SiS_IsVAMode(HwDeviceExtension, BaseAddr))) {
-	             tempah = 0x40;
+	         if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	            tempah = 0x40;
                  }
-	     }
-             SiS_SetRegOR(SiS_Part4Port,0x1F,tempah);
-#endif
-             if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr)))   /* TW: "if" new from 650/301LV BIOS */
-	        SiS_SetRegAND(SiS_Part1Port,0x00,0x7F);
+	      }
+              SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
 
-          } else {
+	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
 
-             SiS_VBLongWait();
-             SiS_DisplayOn();
-	     if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr)))  {  /* TW: "if" new from 650/301LV BIOS */
-	        SiS_SetRegAND(SiS_Part1Port,0x00,0x7F);
-                SiS_VBLongWait();
-	     }
+	   } else {
+	   
+	      SiS_VBLongWait(SiS_Pr);
+              SiS_DisplayOn(SiS_Pr);
+	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
+              SiS_VBLongWait(SiS_Pr);
 
-          }
+	   }
 
-	  /* TW: Entire section from 650/301LV BIOS */
-	  if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {
-	     if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-/*	        if (!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {  */ /* TW: BIOS code makes no sense */
-		   SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 1);
-		   SiS_WaitVBRetrace(HwDeviceExtension);
-		   SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFE,0x01);
-/*              }   */
-             } else if(SiS_CRT2IsLCD(BaseAddr)) {
-/*	        if (!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {  */ /* TW: BIOS code makes no sense */
-		   SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 1);
-		   SiS_WaitVBRetrace(HwDeviceExtension);
-		   SiS_SetRegANDOR(SiS_Part4Port,0x26,0xFE,0x01);
-/*              }   */
-	     }
-	  }
-	  /* TW: --- end --- */
+	 }   /* 315, 330 */
+
+#endif /* SIS315H */
 
       }
 
     } else {	/* ============  TW: For 301 ================ */
 
-       if(HwDeviceExtension->jChipType < SIS_315H)
-            SiS_SetRegANDOR(SiS_P3c4,0x11,0xFB,0x00);
+       if(HwDeviceExtension->jChipType < SIS_315H) {
+            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
+	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
+	    }
+       }
 
-       temp = SiS_GetReg1(SiS_P3c4,0x32) & 0xDF;             /* lock mode */
-       if(SiS_BridgeInSlave()) {
-         tempah = SiS_GetReg1(SiS_P3d4,0x30);
+       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
+       if(SiS_BridgeInSlave(SiS_Pr)) {
+         tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
          if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
        }
-       SiS_SetReg1(SiS_P3c4,0x32,temp);
+       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
 
-       SiS_SetRegANDOR(SiS_P3c4,0x1E,0xFF,0x20);             /* enable CRT2 */
+       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
 
-       if(HwDeviceExtension->jChipType >= SIS_315H) {        /* 310 series */
-         temp=SiS_GetReg1(SiS_Part1Port,0x2E);
-         if (!(temp & 0x80))
-           SiS_SetRegOR(SiS_Part1Port,0x2E,0x80);            /* by alan,BVBDOENABLE=1 */
+       if(HwDeviceExtension->jChipType >= SIS_315H) {
+         temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
+         if(!(temp & 0x80))
+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
        }
 
-       SiS_SetRegANDOR(SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
 
-       SiS_VBLongWait();
-       SiS_DisplayOn();
-       SiS_VBLongWait();
+       SiS_VBLongWait(SiS_Pr);
+       SiS_DisplayOn(SiS_Pr);
+       if(HwDeviceExtension->jChipType >= SIS_315H) {
+           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+       }
+       SiS_VBLongWait(SiS_Pr);
 
-       if(HwDeviceExtension->jChipType < SIS_315H)
-            SiS_SetRegANDOR(SiS_P3c4,0x11,0xF7,0x00);
+       if(HwDeviceExtension->jChipType < SIS_315H) {
+            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
+                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x03);
+	    }
+       }
 
     }
 
@@ -4242,50 +5828,54 @@
 
     if(HwDeviceExtension->jChipType < SIS_315H) {
 
-      /* 300 series */
+#ifdef SIS300    /* 300 series */
 
-      if(SiS_CRT2IsLCD(BaseAddr)) {
-         SiS_SetRegAND(SiS_P3c4,0x11,0xFB);
-	 if(!(SiS_CR36BIOSWord23d(HwDeviceExtension))) {
-	    SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 0);
+      if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+         if(HwDeviceExtension->jChipType == SIS_730) {
+	    SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+	    SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+	    SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+	 }
+         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
+	 if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) {
+	    SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 0);
 	 }
       }
 
-      SiS_EnableCRT2();
-      SiS_DisplayOn();
-      SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
-      SiS_SetRegAND(SiS_Part1Port,0x02,0xBF);
-      if(SiS_BridgeInSlave()) {
-      	SiS_SetRegAND(SiS_Part1Port,0x01,0x1F);
+      SiS_EnableCRT2(SiS_Pr);
+      SiS_DisplayOn(SiS_Pr);
+      SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
+      if(SiS_BridgeInSlave(SiS_Pr)) {
+      	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
       } else {
-      	SiS_SetRegANDOR(SiS_Part1Port,0x01,0x1F,0x40);
+      	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
       }
 
-      if(SiS_IF_DEF_CH70xx == 1) {
-        if(!(SiS_CRT2IsLCD(BaseAddr))) {
-           if (SiS_Backup70xx != 0xff) {
-		SiS_SetCH700x(((SiS_Backup70xx<<8)|0x0E));
-		SiS_Backup70xx = 0xff;
-	   } else SiS_SetCH700x(0x0B0E);
+      if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+        if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+	        SiS_SetCH700x(SiS_Pr,0x0B0E);
         }
       }
 
-      if(SiS_CRT2IsLCD(BaseAddr)) {
-          if(!(SiS_GetReg1(SiS_P3c4,0x13) & 0x40)) {
-              if(!(SiS_GetReg1(SiS_P3c4,0x16) & 0x10)) {
-	          if(!(SiS_CR36BIOSWord23b(HwDeviceExtension))) {
-			SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 1);
-        		SiS_SetPanelDelay(ROMAddr, HwDeviceExtension, 1);
+      if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+          if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+              if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+	          if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+			SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+        		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
 		  }
-		  SiS_WaitVBRetrace(HwDeviceExtension);
-                  SiS_SetRegAND(SiS_P3c4,0x11,0xF7);
+		  SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+                  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
               }
 	  }
       }
 
+#endif  /* SIS300 */
+
     } else {
 
-       /* 310 series */
+#ifdef SIS315H    /* 310/325 series */
 
 #if 0  /* BIOS code makes no sense */
        if(SiS_IsVAMode()) {
@@ -4294,79 +5884,146 @@
        }
 #endif
 
-       SiS_EnableCRT2();
-       SiS_UnLockCRT2(HwDeviceExtension, BaseAddr);
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+	    if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+	     	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
+	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
+            }
+       }
+
+       SiS_EnableCRT2(SiS_Pr);
+       SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
 
-       SiS_SetRegAND(SiS_Part1Port,0x2e,0xf7);
+       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
 
-       if(SiS_IF_DEF_CH70xx == 2) {
-          temp = SiS_GetCH701x(0x66);
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+          temp = SiS_GetCH701x(SiS_Pr,0x66);
 	  temp &= 0x20;
-	  SiS_Chrontel701xOff();
+	  SiS_Chrontel701xBLOff(SiS_Pr);
        }
 
-       SiS_SetRegAND(SiS_Part1Port,0x2e,0x7f);
+       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+       
+#ifdef NEWCH701x
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+           if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension,BaseAddr)) {
+	   	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+	   }
+       }
+#endif       
 
-       temp1 = SiS_GetReg1(SiS_Part1Port,0x2E);
+       temp1 = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
        if (!(temp1 & 0x80))
-           SiS_SetRegOR(SiS_Part1Port,0x2E,0x80);
+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
 
-       if(SiS_IF_DEF_CH70xx == 2) {
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
            if(temp) {
-	       SiS_Chrontel701xOn();
+	       SiS_Chrontel701xBLOn(SiS_Pr);
 	   }
        }
 
-       if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-           SiS_SetRegOR(SiS_Part1Port,0x1E,0x20);
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+           if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+	   	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+	   }
+       } 
+#ifndef NEWCH701x       
+         else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
        }
+#endif       
 
-       if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {
-           SiS_SetRegAND(SiS_Part1Port,0x00,0x7f);
+       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
        }
 
-       if(SiS_IF_DEF_CH70xx == 2) {
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
 
-       		if(SiS_IsTVOrSomething(HwDeviceExtension, BaseAddr)) {
-           		SiS_Chrontel701xOn2(HwDeviceExtension, BaseAddr);
+       		if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+           		SiS_Chrontel701xOn(SiS_Pr,HwDeviceExtension, BaseAddr);
          	}
 
-         	if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-           		SiS_ChrontelDoSomething1(HwDeviceExtension, BaseAddr);
-         	} else if(SiS_IsLCDOrLCDA(HwDeviceExtension, BaseAddr)) {
-           		SiS_ChrontelDoSomething1(HwDeviceExtension, BaseAddr);
+         	if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+           		SiS_ChrontelDoSomething1(SiS_Pr,HwDeviceExtension, BaseAddr);
+         	} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+           		SiS_ChrontelDoSomething1(SiS_Pr,HwDeviceExtension, BaseAddr);
         	}
 
        }
 
-       if(SiS_IF_DEF_CH70xx == 2) {
-       	 	if(!(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr))) {
- 	   		if(SiS_IsVAMode(HwDeviceExtension, BaseAddr)) {
-	            		SiS_Chrontel701xOn();
-	            		SiS_ChrontelDoSomething4(HwDeviceExtension, BaseAddr);
-           		} else if(SiS_IsLCDOrLCDA(HwDeviceExtension, BaseAddr))  {
-/*	      			if(!SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr)) {  */ /* TW: makes no sense */
-            				SiS_Chrontel701xOn();
-            				SiS_ChrontelDoSomething4(HwDeviceExtension, BaseAddr);
-/*            			}   */
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+       	 	if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+ 	   		if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	            		SiS_Chrontel701xBLOn(SiS_Pr);
+	            		SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
+           		} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr))  {
+       				SiS_Chrontel701xBLOn(SiS_Pr);
+       				SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
 	   		}
        		}
+       } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+       		if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+			if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
+				SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
+				SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
+			}
+		}
        }
 
+#endif  /* SIS315H */
+
     } /* 310 series */
 
   }  /* LVDS */
 
 }
 
+void
+SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+
+  /* TW: Switch on LCD backlight on SiS30xLV */
+  if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
+      (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
+    if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+	SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+	SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+    }
+    if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
+        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+    }
+  }
+}
+
+void
+SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+
+  /* TW: Switch off LCD backlight on SiS30xLV */
+  if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
+      (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
+	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
+  }
+
+  if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+      if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+          if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+  	      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
+          }
+      }
+  }
+}
+
 BOOLEAN
-SiS_CR36BIOSWord23b(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT temp,temp1;
   UCHAR *ROMAddr;
 
-  if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase)) {
-     temp = SiS_GetReg1(SiS_P3d4,0x36) & 0xff;
+  if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
      temp >>= 4;
      temp = 1 << temp;
      temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
@@ -4378,13 +6035,13 @@
 }
 
 BOOLEAN
-SiS_CR36BIOSWord23d(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT temp,temp1;
   UCHAR *ROMAddr;
 
-  if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase)) {
-     temp = SiS_GetReg1(SiS_P3d4,0x36) & 0xff;
+  if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
      temp >>= 4;
      temp = 1 << temp;
      temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
@@ -4396,95 +6053,161 @@
 }
 
 void
-SiS_SetPanelDelay(UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+SiS_SetPanelDelayLoop(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                      USHORT DelayTime, USHORT DelayLoop)
+{
+   int i;
+   for(i=0; i<DelayLoop; i++) {
+      SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, DelayTime);
+   }
+}		     
+
+void
+SiS_SetPanelDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
                   USHORT DelayTime)
 {
-  USHORT PanelID, DelayIndex, Delay, temp;
+  USHORT PanelID, DelayIndex, Delay;
+#ifdef SIS300
+  USHORT temp;
+#endif
 
   if(HwDeviceExtension->jChipType < SIS_315H) {
-     if(SiS_VBType & VB_SIS301BLV302BLV) {
-         if(ROMAddr) {
-	     if(!(ROMAddr[0x235] & 0x40)) return;
-	 }
-     }
-  }
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-      temp = SiS_GetReg1(SiS_P3c4,0x18);
-  } else {
-      temp = SiS_GetReg1(SiS_P3c4,0x1b);
-  }
+#ifdef SIS300
 
-  if( (SiS_VBType & VB_SIS301BLV302BLV) && (!(temp & 0x10)) ) {
-       PanelID = 0x12;
-  } else {
-       PanelID = SiS_GetReg1(SiS_P3d4,0x36);
-  }
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 300 series, LVDS */
 
-  DelayIndex = PanelID >> 4;
+	  PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
 
-  if((DelayTime >= 2) && (PanelID & 0x0f) == 1) {
-    Delay = 3;
-  } else {
-    if(DelayTime >= 2) DelayTime -= 2;
-    if(SiS_IF_DEF_LVDS == 0) {
-       if(!(DelayTime & 0x01)) {
-       		Delay = SiS_PanelDelayTbl[DelayIndex].timer[0];
-       } else {
-       		Delay = SiS_PanelDelayTbl[DelayIndex].timer[1];
-		if(HwDeviceExtension->jChipType >= SIS_315H) {
-                    if(DelayTime & 0x04) Delay = 0x190;
-                }
-       }
-    } else {
-       if(!(DelayTime & 0x01)) {
-       		Delay = SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
-       } else {
-       		Delay = SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
-       }
-    }
-    if(ROMAddr) {
-        if(HwDeviceExtension->jChipType < SIS_315H) {
-          if(ROMAddr[0x220] & 0x40) {
-            if(!(DelayTime & 0x01)) {
-	    	Delay = (USHORT)ROMAddr[0x225];
-            } else {
-	    	Delay = (USHORT)ROMAddr[0x226];
-            }
+	  DelayIndex = PanelID >> 4;
+
+	  if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
+              Delay = 3;
+          } else {
+              if(DelayTime >= 2) DelayTime -= 2;
+
+              if(!(DelayTime & 0x01)) {
+       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+              } else {
+       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+              }
+	      if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+                  if(ROMAddr[0x220] & 0x40) {
+                      if(!(DelayTime & 0x01)) {
+	    	          Delay = (USHORT)ROMAddr[0x225];
+                      } else {
+	    	          Delay = (USHORT)ROMAddr[0x226];
+                      }
+                  }
+              }
           }
-        } else {
-	  if(ROMAddr[0x13c] & 0x40) {
-	    if(!(DelayTime & 0x01)) {
-	    	Delay = (USHORT)ROMAddr[0x141];
-            } else {
-	    	Delay = (USHORT)ROMAddr[0x142];
-		if(DelayTime & 0x04) Delay = 0x190;
-            }
+	  SiS_ShortDelay(SiS_Pr,Delay);
+
+      } else {							/* 300 series, 301(B) */
+
+	  PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+	  temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
+          if(!(temp & 0x10))  PanelID = 0x12;
+
+          DelayIndex = PanelID >> 4;
+
+	  if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
+              Delay = 3;
+          } else {
+              if(DelayTime >= 2) DelayTime -= 2;
+
+              if(!(DelayTime & 0x01)) {
+       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+              } else {
+       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+              }
+	      if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+                  if(ROMAddr[0x220] & 0x40) {
+                      if(!(DelayTime & 0x01)) {
+	    	          Delay = (USHORT)ROMAddr[0x225];
+                      } else {
+	    	          Delay = (USHORT)ROMAddr[0x226];
+                      }
+                  }
+              }
+          }
+	  SiS_ShortDelay(SiS_Pr,Delay);
+
+      }
+
+#endif  /* SIS300 */
+
+   } else {
+
+      if(HwDeviceExtension->jChipType == SIS_330) return;
+
+#ifdef SIS315H
+
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 310/325 series, LVDS */
+
+          if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+              PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+	      DelayIndex = PanelID >> 4;
+	      if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
+                 Delay = 3;
+              } else {
+                 if(DelayTime >= 2) DelayTime -= 2;
+
+                 if(!(DelayTime & 0x01)) {
+       		     Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
+                 } else {
+       		     Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
+                 }
+	         if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+                    if(ROMAddr[0x13c] & 0x40) {
+                        if(!(DelayTime & 0x01)) {
+	    	           Delay = (USHORT)ROMAddr[0x17e];
+                        } else {
+	    	           Delay = (USHORT)ROMAddr[0x17f];
+                        }
+                    }
+                 }
+              }
+	      SiS_ShortDelay(SiS_Pr,Delay);
 	  }
-	}
-    }
-  }
-  SiS_ShortDelay(Delay);
+
+      } else {							/* 310/325 series, 301(B) */
+
+          PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+	  DelayIndex = PanelID >> 4;
+          if(!(DelayTime & 0x01)) {
+       		Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+          } else {
+       		Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+          }
+	  SiS_DDC2Delay(SiS_Pr, Delay * 4);
+
+      }
+
+#endif /* SIS315H */
+
+   }
+
 }
 
 void
-SiS_LongDelay(USHORT delay)
+SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
 {
   while(delay--) {
-    SiS_GenericDelay(0x19df);   /* 6623 */
+    SiS_GenericDelay(SiS_Pr,0x19df);
   }
 }
 
 void
-SiS_ShortDelay(USHORT delay)
+SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
 {
   while(delay--) {
-      SiS_GenericDelay(0x42);   /* 66 */
+      SiS_GenericDelay(SiS_Pr,0x42);
   }
 }
 
 void
-SiS_GenericDelay(USHORT delay)
+SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
 {
   USHORT temp,flag;
 
@@ -4499,68 +6222,76 @@
 }
 
 BOOLEAN
-SiS_Is301B(USHORT BaseAddr)
+SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr)
 {
   USHORT flag;
 
-  flag = SiS_GetReg1(SiS_Part4Port,0x01);
+  flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);
   if(flag >= 0x0B0) return(1);
   else return(0);
 }
 
 BOOLEAN
-SiS_CRT2IsLCD(USHORT BaseAddr)
+SiS_CRT2IsLCD(SiS_Private *SiS_Pr, USHORT BaseAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT flag;
 
-  flag = SiS_GetReg1(SiS_P3d4,0x30);
+  if(HwDeviceExtension->jChipType == SIS_730) {
+     flag = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
+     if(flag & 0x20) return(1);
+  }
+  flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
   if(flag & 0x20) return(1);
   else return(0);
 }
 
 BOOLEAN
-SiS_IsDualEdge(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
 #ifdef SIS315H
   USHORT flag;
 
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_P3d4,0x38);
-     if(flag & EnableDualEdge)  return(1);    /* TW: Inverted result */
-     else  return(0);
+     if((HwDeviceExtension->jChipType != SIS_650) || (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
+        flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+        if(flag & EnableDualEdge) return(1);
+        else return(0);
+     } else return(0);
   } else
 #endif
      return(0);
 }
 
-/* TW: Inverted result! */
 BOOLEAN
-SiS_IsVAMode(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
 #ifdef SIS315H
   USHORT flag;
 
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_P3d4,0x38);
-     if((flag & EnableDualEdge) && (flag & SetToLCDA))
-        return(1);
-     else if(SiS_VBType & VB_SIS301BLV302BLV) {   /* TW: Inserted from 650/301LV BIOS */
-       if(flag) return(1);   			  /* TW: Inserted from 650/301LV BIOS */
-       else     return(0);   			  /* TW: Inserted from 650/301LV BIOS */
-     } else  return(0);
+     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+     if((flag & EnableDualEdge) && (flag & SetToLCDA))   return(1);
+#if 0 /* Not done in 650/30xLV 1.10.6s, but in 650/301LV */
+     else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+       if(flag) return(1);
+       else     return(0);   			         
+     }
+#endif
+     else
+       return(0);
   } else
 #endif
      return(0);
  }
 
 BOOLEAN
-SiS_WeHaveBacklightCtrl(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
 #ifdef SIS315H
   USHORT flag;
 
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_P3d4,0x79);
+     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79);
      if(flag & 0x10)  return(1);
      else             return(0);
   } else
@@ -4570,13 +6301,13 @@
 
 #if 0
 BOOLEAN
-SiS_Is315E(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_Is315E(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
 #ifdef SIS315H
   USHORT flag;
 
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_P3d4,0x5f);
+     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f);
      if(flag & 0x10)  return(1);
      else      	      return(0);
   } else
@@ -4586,57 +6317,89 @@
 #endif
 
 BOOLEAN
-SiS_IsYPbPr(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_IsNotM650or651(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+#ifdef SIS315H
+  USHORT flag;
+
+  if(HwDeviceExtension->jChipType == SIS_650) {
+     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f);
+     flag &= 0xF0;
+     if((flag == 0xb0) || (flag == 0x90)) return 0;
+     else return 1;
+  } else
+#endif
+    return 1;
+}
+
+BOOLEAN
+SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
 #ifdef SIS315H
   USHORT flag;
 
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_P3d4,0x38);
-     if(flag & 0x08)  return(1);
-     else      	      return(0);
+     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+     if(flag & EnableLVDSHiVision)  return(1);  /* = YPrPb = 0x08 */
+     else      	                    return(0);
   } else
 #endif
      return(0);
 }
 
 BOOLEAN
-SiS_IsTVOrSomething(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+{
+#ifdef SIS315H
+  USHORT flag;
+
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+     if(flag & EnableLVDSScart)     return(1);  /* = Scart = 0x04 */
+     else      	                    return(0);
+  } else
+#endif
+     return(0);
+}
+
+BOOLEAN
+SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
   USHORT flag;
 
 #ifdef SIS315H
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_P3d4,0x30);
-     if(flag & SetCRT2ToTV) return(1);
-     flag = SiS_GetReg1(SiS_P3d4,0x38);
-     if(flag & 0x08)        return(1);
-     else                   return(0);
+     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+     if(flag & SetCRT2ToTV)        return(1);
+     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+     if(flag & EnableLVDSHiVision) return(1);  /* = YPrPb = 0x08 */
+     if(flag & EnableLVDSScart)    return(1);  /* = Scart = 0x04- TW inserted */
+     else                          return(0);
   } else
 #endif
   {
-     flag = SiS_GetReg1(SiS_P3d4,0x30);
+     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
      if(flag & SetCRT2ToTV) return(1);
   }
   return(0);
 }
 
 BOOLEAN
-SiS_IsLCDOrLCDA(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
   USHORT flag;
 
 #ifdef SIS315H
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_P3d4,0x30);
+     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
      if(flag & SetCRT2ToLCD) return(1);
-     flag = SiS_GetReg1(SiS_P3d4,0x38);
+     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
      if(flag & SetToLCDA)    return(1);
      else                    return(0);
   } else
 #endif
   {
-   flag = SiS_GetReg1(SiS_P3d4,0x30);
+   flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
    if(flag & SetCRT2ToLCD)   return(1);
   }
   return(0);
@@ -4644,339 +6407,461 @@
 }
 
 BOOLEAN
-SiS_IsDisableCRT2(USHORT BaseAddr)
+SiS_IsDisableCRT2(SiS_Private *SiS_Pr, USHORT BaseAddr)
 {
   USHORT flag;
 
-  flag = SiS_GetReg1(SiS_P3d4,0x30);
+  flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
   if(flag & 0x20) return(0);
   else            return(1);
 }
 
 BOOLEAN
-SiS_BridgeIsOn(USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT flag;
 
-  if(SiS_IF_DEF_LVDS == 1) {
-     return(0);   					/* TW: Changed from 1 to 0! */
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     return(0);
   } else {
-#if 0   /* TW: Commented for test on bridge-less systems */
-     if(HwDeviceExtension->jChipType >= SIS_315H) {    	/* TW: New (from 630/301B BIOS - not done there) */
-#endif
-        flag = SiS_GetReg1(SiS_Part4Port,0x00);
-        if((flag == 1) || (flag == 2)) return(0);       /* TW: Changed from 1 to 0! */
-        else return(1);                                 /* TW: Changed from 0 to 1! */
-#if 0
-     } else  return(0);					/* TW: New (from 630/301B BIOS - always return 0) */
-#endif
+     flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
+     if((flag == 1) || (flag == 2)) return(0);
+     else return(1);
   }
 }
 
-
 BOOLEAN
-SiS_BridgeIsEnable(USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT flag;
 
-  if(SiS_BridgeIsOn(BaseAddr,HwDeviceExtension) == 0) {
-    flag=SiS_GetReg1(SiS_Part1Port,0x00);
+  if(!(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+    flag = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
     if(HwDeviceExtension->jChipType < SIS_315H) {
-      /* 300 series */
-      if(flag & 0x0a0) return 1;
-      else	       return 0;
+      /* 300 series (630/301B 2.04.5a) */
+      flag &= 0xa0;
+      if((flag == 0x80) || (flag == 0x20)) return 0;
+      else	                           return 1;
     } else {
-      /* 310 series */
-      if(flag & 0x050) return 1;
-      else             return 0;
+      /* 310/325 series (650/30xLV 1.10.6s) */
+      flag &= 0x50;
+      if((flag == 0x40) || (flag == 0x10)) return 0;
+      else                                 return 1;
     }
   }
-  return 0;
+  return 1;
 }
 
 BOOLEAN
-SiS_BridgeInSlave()
+SiS_BridgeInSlave(SiS_Private *SiS_Pr)
 {
   USHORT flag1;
 
-  flag1 = SiS_GetReg1(SiS_P3d4,0x31);
+  flag1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31);
   if(flag1 & (SetInSlaveMode >> 8)) return 1;
   else return 0;
 }
 
-/* TW: New from 650/301LV BIOS */
 void
-SiS_SetHiVision(USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-  SiS_HiVision = 0;
+#ifdef SIS315H
+  USHORT temp;
+#endif
+
+  /* Note: This variable is only used on 30xLV systems.
+     CR38 has a different meaning on LVDS/CH7019 systems.
+   */
+
+  SiS_Pr->SiS_HiVision = 0;
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-     if(SiS_VBType & VB_SIS301BLV302BLV) {
-        if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
-           SiS_HiVision = SiS_GetReg1(SiS_P3d4,0x38);
-	   SiS_HiVision &= 0x38;
-	   SiS_HiVision >>= 3;
-        }
+#ifdef SIS315H
+     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+           temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+	   temp &= 0x38;
+	   SiS_Pr->SiS_HiVision = (temp >> 3);
+	}
      }
+#endif /* SIS315H */
   }
 }
 
-/* TW: Checked against 650/LVDS and 650/301LV BIOS */
 BOOLEAN
-SiS_GetLCDResInfo301(UCHAR *ROMAddr,USHORT SiS_P3d4,USHORT ModeNo,
-               USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
+                  USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT temp,modeflag,resinfo=0;
+  const unsigned char SiS300SeriesLCDRes[] =
+         { 0, 1, 2, 3, 7, 4, 5, 8,
+	   0, 0, 0, 0, 0, 0, 0, 0 };
+
+  SiS_Pr->SiS_LCDResInfo = 0;
+  SiS_Pr->SiS_LCDTypeInfo = 0;
+  SiS_Pr->SiS_LCDInfo = 0;
 
-  SiS_LCDResInfo = 0;
-  SiS_LCDTypeInfo = 0;
-  SiS_LCDInfo = 0;
-
-  if (ModeNo<=0x13) {
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
   } else {
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     if(ModeNo <= 0x13) {
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     } else {
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     }
   }
 
-  if(!(SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))   return 0;
+  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))   return 0;
 
-  if(!(SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return 0;
+  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return 0;
 
-  temp = SiS_GetReg1(SiS_P3d4,0x36);
+  temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
 
-  /*fstn*: Fake CR36 (TypeInfo 2, ResInfo Panel320x480) */
-  if(SiS_IF_DEF_FSTN){
-   	temp = 0x20 | Panel320x480;
-   	SiS_SetReg1(SiS_P3d4,0x36,temp);
+  /* FSTN: Fake CR36 (TypeInfo 2, ResInfo SiS_Panel320x480) */
+  if(SiS_Pr->SiS_IF_DEF_FSTN) {
+   	temp = 0x20 | SiS_Pr->SiS_Panel320x480;
+   	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
   }
 
-  SiS_LCDTypeInfo = temp >> 4;   /* BIOS uses entire CR36 - 1 */
-  SiS_LCDResInfo = temp & 0x0F;
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+  	SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
+  } else {
+        SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
+  }
+  temp &= 0x0f;
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+      /* TW: Translate 300 series LCDRes to 310/325 series for unified usage */
+      temp = SiS300SeriesLCDRes[temp];
+  }
+  SiS_Pr->SiS_LCDResInfo = temp;
 
-  if(SiS_IF_DEF_FSTN){
-       	SiS_LCDResInfo = Panel320x480;
+  if(SiS_Pr->SiS_IF_DEF_FSTN){
+       	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel320x480;
   }
 
-  if(SiS_IF_DEF_LVDS == 0) {
-    	if(SiS_LCDResInfo < PanelMin301) SiS_LCDResInfo = PanelMin301;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+    	if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
+		SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
   } else {
-    	if(SiS_LCDResInfo < PanelMinLVDS) SiS_LCDResInfo = PanelMinLVDS;
+    	if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
+		SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
   }
 
-  if(SiS_LCDResInfo > PanelMax) SiS_LCDResInfo = Panel1024x768;
+  if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
+  	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel1024x768;
 
-  temp=SiS_GetReg1(SiS_P3d4,0x37);
-  if(SiS_IF_DEF_FSTN){
+  temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
+  if(SiS_Pr->SiS_IF_DEF_FSTN){
         /* TW: Fake LVDS bridge for FSTN */
       	temp = 0x04;
-      	SiS_SetReg1(SiS_P3d4,0x37,temp);
-  }
-  SiS_LCDInfo = temp;
-  /* TW: Inserted entire 315-block from 650/LVDS BIOS */
-  if(SiS_IF_DEF_LVDS == 1) {
-     if (HwDeviceExtension->jChipType >= SIS_315H) {
-        temp = SiS_GetReg1(SiS_P3d4,0x39);
-        if(temp & 0x01) {
-	   SiS_LCDInfo &= 0xFFEF;     /* TW: What is this? */
-	   SiS_LCDInfo |= 0x0100;     /* TW: What is this? */
-        }
-     }
+      	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,temp);
   }
+  SiS_Pr->SiS_LCDInfo = temp;
+  
+  if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
 
-#ifdef LINUX_KERNEL
-  printk(KERN_INFO "sisfb: (LCDInfo = 0x%x LCDResInfo = 0x%x LCDTypeInfo = 0x%x)\n",
-                   SiS_LCDInfo, SiS_LCDResInfo, SiS_LCDTypeInfo);
+  /* TW: Inserted entire 315-block from 650/LVDS/30xLV BIOSes */
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+#ifdef SIS315H
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+		 if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
+		     /* Bridge does not scale to 1280x1024 */
+		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+		 }
+	     }
+	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+	         if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
+		     /* TW: Bridge does not scale to 1280x960 */
+		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+		 }
+		 if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
+		     /* TW: Bridge does not scale to 640x400 */
+		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+		 }
+	     }
+	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+	         if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
+		     /* TW: Most panels can't scale to 640x400 */
+		     SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+		 }
+	     }
+	 }
+     }
+     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
+         SiS_Pr->SiS_LCDInfo &= 0xFFEF;    
+	 SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     }
 #endif
-#ifdef LINUX_XF86
-  xf86DrvMsg(0, X_INFO, "(init301: LCDInfo = 0x%x LCDResInfo = 0x%x LCDTypeInfo = 0x%x)\n",
-			SiS_LCDInfo, SiS_LCDResInfo, SiS_LCDTypeInfo);
+  } else {
+#ifdef SIS300
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+        if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+           if(!(ROMAddr[0x235] & 0x02)) {
+	      SiS_Pr->SiS_LCDInfo &= 0xEF;
+	   }
+        }
+     } else {
+        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	   if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
+               SiS_Pr->SiS_LCDInfo &= 0xEF;
+	   }
+	}
+     }
 #endif
-
+  }
+  
   /* TW: With Trumpion, always Expanding */
-  if(SiS_IF_DEF_TRUMPION != 0){
-       SiS_LCDInfo &= (~LCDNonExpanding);
+  if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0){
+       SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
   }
 
-  /* TW: Removed LVDS==1 check here; done foe 301B BIOSes as well */
-  if(modeflag & HalfDCLK){
-        if(SiS_IF_DEF_TRUMPION == 0){
-	    if((!(SiS_LCDInfo & 0x0100)) || (SiS_IF_DEF_LVDS == 0)) {  /* TW: Inserted from 650/LVDS BIOS */
-               if(!(SiS_LCDInfo & LCDNonExpanding)){
-	          if(!((SiS_IF_DEF_LVDS == 1) && (SiS_LCDResInfo == Panel640x480))){  /* TW: Inserted from 650/LVDS BIOS */
-                     if(ModeNo > 0x13) {
-                        if(SiS_LCDResInfo == Panel1024x768){
-                           if(resinfo == 4){                              /* 512x384  */
-                              SiS_SetFlag |= EnableLVDSDDA;
-                           }
-                        } else {
-                           if(SiS_LCDResInfo == Panel800x600){
-                              if(resinfo == 3){                           /* 400x300  */
-                                 SiS_SetFlag |= EnableLVDSDDA;
-                              }
-                           }
-                        }
-                     }
-		   } else {
-		     SiS_SetFlag |= EnableLVDSDDA;
-		   }
-               } else { /* NonExpanding */
-                 SiS_SetFlag |= EnableLVDSDDA;
-               }
-           } else {                          /* TW: Inserted from 650/LVDS BIOS */
-	     SiS_SetFlag |= EnableLVDSDDA;   /* TW: Inserted from 650/LVDS BIOS */
-	   }                                 /* TW: Inserted from 650/LVDS BIOS */
-        } else { /* TRUMPION */
-          SiS_SetFlag |= EnableLVDSDDA;
+  if(!((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
+
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+	   if(ModeNo > 0x13) {
+	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+                 if((resinfo == 7) || (resinfo == 3)) {
+                    SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+		 }
+              }
+           }
         }
+	if(ModeNo == 0x12) {
+	   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+	      SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+	   }
+	}
+     }
+
+     if(modeflag & HalfDCLK) {
+        if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+           if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+	      if(!(((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (HwDeviceExtension->jChipType < SIS_315H)) &&
+	                                      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480))) {
+                 if(ModeNo > 0x13) {
+                    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+                       if(resinfo == 4) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;     /* 512x384  */
+                    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+                       if(resinfo == 3) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;     /* 400x300  */
+                    }
+                 }
+	      } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+           } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+        } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+     }
+
   }
 
-  /* TW: wdr: if (VBInfo & LCD) && (VBInfo & (SetSimuScanMode | SwitchToCRT2)) { */
-  if(SiS_VBInfo & SetInSlaveMode){
-    	if(SiS_VBInfo & SetNotSimuMode){
-      		SiS_SetFlag |= LCDVESATiming;
+  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+    	if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
+      		SiS_Pr->SiS_SetFlag |= LCDVESATiming;
     	}
   } else {
-    	SiS_SetFlag |= LCDVESATiming;
+    	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
   }
 
+#ifdef SIS315H
+  /* TW: 650/30xLV 1.10.6s */
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+    if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS302LV)) {
+      /* Enable 302B/302LV dual link mode */
+      /* (302B is a theory - not in any BIOS */
+      temp = 0x00;
+      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) temp = 0x04;
+      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x04;
+      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) temp = 0x04;
+      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,temp);
+    } else if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,0x00);
+    }
+  }
+#endif
+
+#ifdef LINUX_KERNEL
+#ifdef TWDEBUG
+  printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
+	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
+#endif
+#endif
+#ifdef LINUX_XF86
+  xf86DrvMsgVerb(0, X_PROBED, 3, 
+  	"(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
+	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
+#endif
+
   return 1;
 }
 
 void
-SiS_PresetScratchregister(USHORT SiS_P3d4,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-  /*SiS_SetReg1(SiS_P3d4,0x30,0x21);  */
-  /*SiS_SetReg1(SiS_P3d4,0x31,0x41);  */
-  /*SiS_SetReg1(SiS_P3d4,0x32,0x28);  */
-  /*SiS_SetReg1(SiS_P3d4,0x33,0x22);  */
-  /*SiS_SetReg1(SiS_P3d4,0x35,0x43);  */
-  /*SiS_SetReg1(SiS_P3d4,0x36,0x01);  */
-  /*SiS_SetReg1(SiS_P3d4,0x37,0x00);  */
+  return;
+  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x21);  */
+  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x31,0x41);  */
+  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x32,0x28);  */
+  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x33,0x22);  */
+  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,0x43);  */
+  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,0x01);  */
+  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x00);  */
 }
 
 void
-SiS_LongWait()
+SiS_LongWait(SiS_Private *SiS_Pr)
 {
   USHORT i;
 
-  i=SiS_GetReg1(SiS_P3c4,0x1F);
-  if(!(i&0xC0)) {
+  i = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);
 
+  if(!(i & 0xC0)) {
     for(i=0; i<0xFFFF; i++) {
-       if(!(SiS_GetReg2(SiS_P3da) & 0x08))
+       if(!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08))
          break;
     }
     for(i=0; i<0xFFFF; i++) {
-       if((SiS_GetReg2(SiS_P3da) & 0x08))
+       if((SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08))
          break;
     }
   }
 }
 
 void
-SiS_VBLongWait()
+SiS_VBLongWait(SiS_Private *SiS_Pr)
 {
-  if(!(SiS_VBInfo & SetCRT2ToTV)) {
-    SiS_VBWait();
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+    SiS_VBWait(SiS_Pr);
   } else {
-    SiS_LongWait();
+    SiS_LongWait(SiS_Pr);
   }
   return;
 }
 
 void
-SiS_VBWait(void)
+SiS_VBWait(SiS_Private *SiS_Pr)
 {
   USHORT tempal,temp,i,j;
 
-  temp=0;
-  for(i=0;i<3;i++) {
-    for(j=0;j<100;j++) {
-       tempal=SiS_GetReg2(SiS_P3da);
-       if(temp&0x01) {
-          if((tempal&0x08))  continue;
-          if(!(tempal&0x08)) break;
+  temp = 0;
+  for(i=0; i<3; i++) {
+    for(j=0; j<100; j++) {
+       tempal = SiS_GetReg2(SiS_Pr->SiS_P3da);
+       if(temp & 0x01) {
+          if((tempal & 0x08))  continue;
+          if(!(tempal & 0x08)) break;
        } else {
-          if(!(tempal&0x08)) continue;
-          if((tempal&0x08))  break;
+          if(!(tempal & 0x08)) continue;
+          if((tempal & 0x08))  break;
        }
     }
-    temp=temp^0x01;
+    temp ^= 0x01;
   }
 }
 
 void
-SiS_WaitVBRetrace(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   if(HwDeviceExtension->jChipType < SIS_315H) {
-     if(SiS_VBType & VB_SIS301BLV302BLV) {
-        if(!(SiS_GetReg1(SiS_Part1Port,0x00) & 0x20)) return;
+#ifdef SIS300
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+        if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
      }
-     if(!(SiS_GetReg1(SiS_Part1Port,0x00) & 0x80)) {
-        SiS_WaitRetrace1(HwDeviceExtension);
+     if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
+        SiS_WaitRetrace1(SiS_Pr,HwDeviceExtension);
      } else {
-        SiS_WaitRetrace2(HwDeviceExtension);
+        SiS_WaitRetrace2(SiS_Pr,HwDeviceExtension);
      }
+#endif
   } else {
-     if(!(SiS_GetReg1(SiS_Part1Port,0x00) & 0x40)) {
-        SiS_WaitRetrace1(HwDeviceExtension);
+#ifdef SIS315H
+     if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
+        SiS_WaitRetrace1(SiS_Pr,HwDeviceExtension);
      } else {
-        SiS_WaitRetrace2(HwDeviceExtension);
+        SiS_WaitRetrace2(SiS_Pr,HwDeviceExtension);
      }
+#endif
   }
 }
 
 void
-SiS_WaitRetrace1(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_WaitRetrace1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-  USHORT i,watchdog;
-  
+  USHORT watchdog;
+#ifdef SIS300
+  USHORT i;
+#endif
+
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-     if(SiS_GetReg1(SiS_P3c4,0x1f) & 0xc0) return;
+#ifdef SIS315H
+     if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
      watchdog = 65535;
-     while( (SiS_GetReg2(SiS_P3da) & 0x08) && --watchdog);
+     while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
      watchdog = 65535;
-     while( (!(SiS_GetReg2(SiS_P3da) & 0x08)) && --watchdog);
+     while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
+#endif
   } else {
+#ifdef SIS300
 #if 0  /* TW: Not done in A901 BIOS */
-     if(SiS_VBType & VB_SIS301BLV302BLV) {
-        if(SiS_GetReg1(SiS_P3c4,0x1f) & 0xc0) return;
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+        if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
      }
 #endif
      for(i=0; i<10; i++) {
         watchdog = 65535;
-        while( (SiS_GetReg2(SiS_P3da) & 0x08) && --watchdog);
+        while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
 	if(watchdog) break;
      }
      for(i=0; i<10; i++) {
         watchdog = 65535;
-        while( (!(SiS_GetReg2(SiS_P3da) & 0x08)) && --watchdog);
+        while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
 	if(watchdog) break;
      }
+#endif
   }
 }
 
 void
-SiS_WaitRetrace2(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_WaitRetraceDDC(SiS_Private *SiS_Pr)
+{
+  USHORT watchdog;
+
+  if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
+  watchdog = 65535;
+  while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
+  watchdog = 65535;
+  while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
+}
+
+void
+SiS_WaitRetrace2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-  USHORT i,watchdog,temp;
+  USHORT watchdog;
+#ifdef SIS300
+  USHORT i;
+#endif
 
   if(HwDeviceExtension->jChipType >= SIS_315H) {
+#ifdef SIS315H
      watchdog = 65535;
-     while( (SiS_GetReg1(SiS_Part1Port,0x30) & 0x02) && --watchdog);
+     while( (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x30) & 0x02) && --watchdog);
      watchdog = 65535;
-     while( (!(SiS_GetReg1(SiS_Part1Port,0x30) & 0x02)) && --watchdog);
+     while( (!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x30) & 0x02)) && --watchdog);
+#endif
   } else {
+#ifdef SIS300
      for(i=0; i<10; i++) {
         watchdog = 65535;
-	while( (temp = SiS_GetReg1(SiS_Part1Port,0x25) & 0x02) && --watchdog);
+	while( (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x25) & 0x02) && --watchdog);
 	if(watchdog) break;
      }
      for(i=0; i<10; i++) {
         watchdog = 65535;
-	while( (!(temp = SiS_GetReg1(SiS_Part1Port,0x25) & 0x02)) && --watchdog);
+	while( (!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x25) & 0x02)) && --watchdog);
 	if(watchdog) break;
      }
+#endif
   }
 }
 
@@ -4987,8 +6872,8 @@
 {
   USHORT temp;
 
-  temp=SiS_GetReg1(Port,Index);     /* SiS_Part1Port index 02 */
-  temp=(temp&(DataAND))|DataOR;
+  temp = SiS_GetReg1(Port,Index);    
+  temp = (temp & (DataAND)) | DataOR;
   SiS_SetReg1(Port,Index,temp);
 }
 
@@ -4997,8 +6882,8 @@
 {
   USHORT temp;
 
-  temp=SiS_GetReg1(Port,Index);     /* SiS_Part1Port index 02 */
-  temp=temp&DataAND;
+  temp = SiS_GetReg1(Port,Index);    
+  temp &= DataAND;
   SiS_SetReg1(Port,Index,temp);
 }
 
@@ -5006,47 +6891,90 @@
 {
   USHORT temp;
 
-  temp=SiS_GetReg1(Port,Index);     /* SiS_Part1Port index 02 */
-  temp=temp|DataOR;
+  temp = SiS_GetReg1(Port,Index);    
+  temp |= DataOR;
   SiS_SetReg1(Port,Index,temp);
 }
 
 /* ========================================================= */
 
 /* TW: Set 301 TV Encoder (and some LCD relevant) registers */
-/* TW: Checked against 650/301LV and 630/301B (I+II) */
 void
-SiS_SetGroup2(USHORT BaseAddr,UCHAR *ROMAddr, USHORT ModeNo,
-                   USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr, USHORT ModeNo,
+              USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+	      PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-  USHORT i,j,tempax,tempbx,tempcx,temp,temp3;
-  USHORT push1,push2,temp1;
-  UCHAR *PhasePoint;
-  UCHAR *TimingPoint;
-  SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
-  USHORT  modeflag,resinfo,crt2crtc,resindex,CRT2Index;
-  ULONG longtemp,tempeax,tempebx,temp2,tempecx;
-  USHORT  SiS_RY1COE=0,SiS_RY2COE=0,SiS_RY3COE=0,SiS_RY4COE=0;
-  UCHAR atable[] = {
-           0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
-	   0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
+  USHORT      i, j, tempax, tempbx, tempcx, temp, temp1;
+  USHORT      push1, push2;
+  const       UCHAR *PhasePoint;
+  const       UCHAR *TimingPoint;
+#ifdef SIS315H   
+  const       SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
+  USHORT      resindex, CRT2Index;
+#endif  
+  USHORT      modeflag, resinfo, crt2crtc;
+  ULONG       longtemp, tempeax, tempebx, temp2, tempecx;
+  const UCHAR atable[] = {
+                 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
+	         0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
   };
 
-  /* TW: Inserted from 650/301LV BIOS */
-  if(SiS_VBInfo & SetCRT2ToLCDA) return;
+#ifdef SIS315H   
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+     /* TW: 650/30xLV 1.10.6s: (Is at end of SetGroup2!) */
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03);
+	   temp = 1;
+	   if(ModeNo <= 0x13) temp = 3;
+	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
+	}
+     }
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+           if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
+           }
+         }
+       }
+     }
+     return;
+  }
+#endif  
 
   if(ModeNo<=0x13) {
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
-    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-    	crt2crtc = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
+    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+    	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   } else {
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
-    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-    	crt2crtc = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    	crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   }
 
-  tempcx = SiS_VBInfo;
+  tempcx = SiS_Pr->SiS_VBInfo;
   tempax = (tempcx & 0x00FF) << 8;
   tempbx = (tempcx & 0x00FF) | ((tempcx & 0x00FF) << 8);
   tempbx &= 0x0410;
@@ -5054,486 +6982,517 @@
   temp >>= 1;
   temp |= (((tempbx & 0xFF00) >> 8) << 1);
   temp |= ((tempbx & 0x00FF) >> 3);
-  temp = temp ^ 0x0C;
+  temp ^= 0x0C;
 
-  PhasePoint = SiS_PALPhase;
-#ifdef oldHV
-  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {          /* PALPhase */
-    temp = temp ^ 0x01;
-    if(SiS_VBInfo & SetInSlaveMode) {
-      TimingPoint = SiS_HiTVSt2Timing;
-      if(SiS_SetFlag & TVSimuMode) {
-        if(modeflag & Charx8Dot) TimingPoint = SiS_HiTVSt1Timing;
-        else TimingPoint = SiS_HiTVTextTiming;
-      }
-    } else TimingPoint = SiS_HiTVExtTiming;
-  } else {
-#endif
-    if(SiS_VBInfo & SetPALTV){
-      if( (SiS_VBType & VB_SIS301BLV302BLV) &&    /* TW: @@@ 650+301LV BIOS only tests 301B, 302B */
-          ( (!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode) ) )
-         PhasePoint = SiS_PALPhase2;
-      else
-         PhasePoint = SiS_PALPhase;
+  /* TW: From 1.10.7w (no vb check there; don't care - this only disables SVIDEO and CVBS signal) */
+  if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+  	temp |= 0x0c;
+  }
+
+  PhasePoint  = SiS_Pr->SiS_PALPhase;
+  TimingPoint = SiS_Pr->SiS_PALTiming;
+  
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {          
+  
+    temp ^= 0x01;
+    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+      TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
+      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+        if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
+        else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
+      }
+    } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
+    
+    if(SiS_Pr->SiS_HiVision & 0x03) temp &= 0xfe;
+    
+  } else {
+  
+    if(SiS_Pr->SiS_VBInfo & SetPALTV){
+
+      TimingPoint = SiS_Pr->SiS_PALTiming;
+      PhasePoint  = SiS_Pr->SiS_PALPhase;
+
+      if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+	    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+         PhasePoint = SiS_Pr->SiS_PALPhase2;
+      }
 
-         TimingPoint = SiS_PALTiming;
     } else {
+
         temp |= 0x10;
-        if( (SiS_VBType & VB_SIS301BLV302BLV) &&  /* TW: @@@ 650+301LV BIOS only tests 301B, 302B */
-	    ( (!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode) ) )
-        	PhasePoint = SiS_NTSCPhase2;
-        else
-        	PhasePoint = SiS_NTSCPhase;
-      
-        TimingPoint = SiS_NTSCTiming;
+	TimingPoint = SiS_Pr->SiS_NTSCTiming;
+	PhasePoint  = SiS_Pr->SiS_NTSCPhase;
+
+        if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+	    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+	      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+        	PhasePoint = SiS_Pr->SiS_NTSCPhase2;
+        }
+
     }
-#ifdef oldHV
+    
   }
-#endif
-  SiS_SetReg1(SiS_Part2Port,0x00,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,temp);
 
-#ifdef SIS300
-  if((HwDeviceExtension->jChipType==SIS_630)||
-     (HwDeviceExtension->jChipType==SIS_730)) {
-     	if(SiS_VBInfo & SetCRT2ToTV) {
-             if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
-                  temp1 = SiS_GetReg1(SiS_P3d4,0x35);
-                  if(temp1 & 0x40)
-                     	PhasePoint = SiS_PALMPhase;
-			if( (SiS_VBType & VB_SIS301BLV302BLV) &&  /* TW: From 650/301LV BIOS (see note above) */
-			    ( (!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode) ) )
-		           PhasePoint = SiS_PALMPhase2;
-                  if(temp1 & 0x80)
-                     	PhasePoint = SiS_PALNPhase;
-			if( (SiS_VBType & VB_SIS301BLV302BLV) &&  /* TW: From 650/301LV BIOS (see note above) */
-			    ( (!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode) ) )
-		           PhasePoint = SiS_PALNPhase2;
-             }
-        }
+  temp = 0;
+  if((HwDeviceExtension->jChipType == SIS_630)||
+     (HwDeviceExtension->jChipType == SIS_730)) {
+     temp = 0x35;
+  }
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     temp = 0x38;
+  }
+  if(temp) {
+    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+          temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,temp);
+          if(temp1 & EnablePALM) {	/* 0x40 */
+              	PhasePoint = SiS_Pr->SiS_PALMPhase;
+		if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+		    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+		      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+	           PhasePoint = SiS_Pr->SiS_PALMPhase2;
+		}
+	  }
+          if(temp1 & EnablePALN) {	/* 0x80 */
+               	PhasePoint = SiS_Pr->SiS_PALNPhase;
+		if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+		    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+		      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+	           PhasePoint = SiS_Pr->SiS_PALNPhase2;
+		}
+	  }
+      }
+    }
   }
-#endif
 
 #ifdef SIS315H
+  /* TW: 650/301LV BIOS */
   if(HwDeviceExtension->jChipType >= SIS_315H) {
-           if(SiS_VBInfo & SetCRT2ToTV) {
-              if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
-                  temp1 = SiS_GetReg1(SiS_P3d4,0x38);
-                  if(temp1 & 0x40) {
-                     PhasePoint = SiS_PALMPhase;
-		     if( (SiS_VBType & VB_SIS301BLV302BLV) &&  /* TW: @@@ From 650/301LV BIOS (see above) */
-		         ( (!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode) ) )
-		        PhasePoint = SiS_PALMPhase2;           /* TW: From 650/301LV BIOS */
-		  }
-                  if(temp1 & 0x80) {
-                     PhasePoint = SiS_PALNPhase;
-		     if( (SiS_VBType & VB_SIS301BLV302BLV) && /* TW: @@@ From 650/301LV BIOS (see above) */
-		         ( (!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode) ) )
-		        PhasePoint = SiS_PALNPhase2;          /* TW: From 650/301LV BIOS */
-		  }
-              }
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {  
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+           if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+              if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+	         PhasePoint = SiS_Pr->SiS_SpecialPhase;
+	      }
            }
+        }
+     }
   }
 #endif
 
-  for(i=0x31, j=0; i<=0x34; i++, j++){
-     SiS_SetReg1(SiS_Part2Port,i,PhasePoint[j]);
-  }
-
-  /* TW: Inserted from 650/301LV BIOS */
-  if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) {
-     if(SiS_VBInfo & SetCRT2ToTV) {
-        if(!(SiS_VBInfo & SetPALTV)) {
-           if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
-               SiS_SetReg1(SiS_Part2Port,0x31,0x1e);
-	       SiS_SetReg1(SiS_Part2Port,0x32,0x8c);
-	       SiS_SetReg1(SiS_Part2Port,0x33,0x5c);
-	       SiS_SetReg1(SiS_Part2Port,0x34,0x7a);
-	   }
-        }
-     }
+  for(i=0x31, j=0; i<=0x34; i++, j++) {
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
   }
 
-  for(i=0x01, j=0; i<=0x2D; i++, j++){
-     SiS_SetReg1(SiS_Part2Port,i,TimingPoint[j]);
+  for(i=0x01, j=0; i<=0x2D; i++, j++) {
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
   }
-  for(i=0x39; i<=0x45; i++, j++){
-     SiS_SetReg1(SiS_Part2Port,i,TimingPoint[j]);
+  for(i=0x39; i<=0x45; i++, j++) {
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
   }
-  if(SiS_VBInfo & SetCRT2ToTV) {
+
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
     if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if (!(SiS_ModeType & 0x07))
-        SiS_SetRegAND(SiS_Part2Port,0x3A,0x1F);
+      if(!(SiS_Pr->SiS_ModeType & 0x07))
+        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
     } else {
-      SiS_SetRegAND(SiS_Part2Port,0x3A,0x1F);
+      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
     }
   }
 
-  SiS_SetRegOR(SiS_Part2Port,0x0A,SiS_NewFlickerMode);
+  SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
 
-#if 0  /* TW: No BIOS does this */
-     SiS_SetReg1(SiS_Part2Port,0x35,0x00); /*301b*/
-     SiS_SetReg1(SiS_Part2Port,0x36,0x00);
-     SiS_SetReg1(SiS_Part2Port,0x37,0x00);
-     SiS_SetReg1(SiS_Part2Port,0x38,SiS_RY1COE);
-     SiS_SetReg1(SiS_Part2Port,0x48,SiS_RY2COE);
-     SiS_SetReg1(SiS_Part2Port,0x49,SiS_RY3COE);
-     SiS_SetReg1(SiS_Part2Port,0x4a,SiS_RY4COE);
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
 
-     /*add to change 630+301b filter*/
-     resindex=SiS_GetResInfo(ROMAddr,ModeNo,ModeIdIndex);
-     if(ModeNo<=0x13)
-        xres = SiS_StResInfo[resindex].HTotal;
-     else
-        xres = SiS_ModeResInfo[resindex].HTotal;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+      if(SiS_Pr->SiS_HiVision == 3) tempax = 950;
+      else tempax = 440;
+  } else {
+    if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520;
+    else tempax = 440;
+  }
 
-     if(xres == 640) {  SiS_RY1COE=0xFF; SiS_RY2COE=0x03; SiS_RY3COE=0x02; SiS_RY4COE=0xF6;
-                        SiS_RY5COE=0xFC; SiS_RY6COE=0x27; SiS_RY7COE=0x46;}
-     if(xres == 800) {  SiS_RY1COE=0x01; SiS_RY2COE=0x01; SiS_RY3COE=0xFC; SiS_RY4COE=0xF8;
-                        SiS_RY5COE=0x08; SiS_RY6COE=0x26; SiS_RY7COE=0x38;}
-     if(xres == 1024){  SiS_RY1COE=0xFF; SiS_RY2COE=0xFF; SiS_RY3COE=0xFC; SiS_RY4COE=0x00;
-                        SiS_RY5COE=0x0F; SiS_RY6COE=0x22; SiS_RY7COE=0x28;}
-     if(xres == 720) {  SiS_RY1COE=0x01; SiS_RY2COE=0x02; SiS_RY3COE=0xFE; SiS_RY4COE=0xF7;
-                        SiS_RY5COE=0x03; SiS_RY6COE=0x27; SiS_RY7COE=0x3c;}
-     SiS_SetReg1(SiS_Part2Port,0x35,SiS_RY1COE); /*301b*/
-     SiS_SetReg1(SiS_Part2Port,0x36,SiS_RY2COE);
-     SiS_SetReg1(SiS_Part2Port,0x37,SiS_RY3COE);
-     SiS_SetReg1(SiS_Part2Port,0x38,SiS_RY4COE);
-     SiS_SetReg1(SiS_Part2Port,0x48,SiS_RY5COE);
-     SiS_SetReg1(SiS_Part2Port,0x49,SiS_RY6COE);
-     SiS_SetReg1(SiS_Part2Port,0x4a,SiS_RY7COE);
-     /*end add*/
-#endif
-
-  /* TW: From 650/301LV and 630/301B BIOS: */
-  SiS_SetReg1(SiS_Part2Port,0x35,SiS_RY1COE);
-  SiS_SetReg1(SiS_Part2Port,0x36,SiS_RY2COE);
-  SiS_SetReg1(SiS_Part2Port,0x37,SiS_RY3COE);
-  SiS_SetReg1(SiS_Part2Port,0x38,SiS_RY4COE);
+  if( ( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_HiVision == 3) ) && (SiS_Pr->SiS_VDE <= tempax) ) ||
+      ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (SiS_Pr->SiS_HiVision != 3) &&
+        ( (SiS_Pr->SiS_VGAHDE == 1024) || ((SiS_Pr->SiS_VGAHDE != 1024) && (SiS_Pr->SiS_VDE <= tempax)) ) ) ) {
+
+     tempax -= SiS_Pr->SiS_VDE;
+     tempax >>= 2;
+     tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
+
+     temp = (tempax & 0xFF00) >> 8;
+     temp += (USHORT)TimingPoint[0];
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
+
+     temp = (tempax & 0xFF00) >> 8;
+     temp += (USHORT)TimingPoint[1];
+     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
+
+     if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
+        (SiS_Pr->SiS_HiVision != 3) &&
+        (SiS_Pr->SiS_VGAHDE >= 1024) ) {
+        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x19);
+           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x52);
+        } else {
+           if(HwDeviceExtension->jChipType >= SIS_315H) {
+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x17);
+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1d);
+	   } else {
+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b);
+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11);
+	   }
+        }
+     }
 
-#ifdef oldHV
-  if(SiS_VBInfo & SetCRT2ToHiVisionTV) tempax = 950;
-  else {
-#endif
-    if(SiS_VBInfo & SetPALTV) tempax = 520;
-    else tempax = 440;
-#ifdef oldHV
   }
-#endif
 
-  if(SiS_VDE <= tempax) {
-    tempax -= SiS_VDE;
-    tempax >>= 2;
-    tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
-    push1 = tempax;
-    temp = (tempax & 0xFF00) >> 8;
-    temp += (USHORT)TimingPoint[0];
-    SiS_SetReg1(SiS_Part2Port,0x01,temp);
+  tempcx = SiS_Pr->SiS_HT;
 
-    tempax = push1;
-    temp = (tempax & 0xFF00) >> 8;
-    temp += TimingPoint[1];
-    SiS_SetReg1(SiS_Part2Port,0x02,temp);
+  /* TW: 650/30xLV 1.10.6s */
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
+      	   tempcx >>= 1;
+      }
   }
 
-  if( (SiS_VBType & VB_SIS301BLV302BLV) &&
-      (SiS_VBInfo & SetCRT2ToTV) &&
-      (SiS_VGAHDE >= 1024) &&
-      (SiS_HiVision != 3) ) {
-      if(SiS_VBInfo & SetPALTV) {
-         SiS_SetReg1(SiS_Part2Port,0x01,0x19);
-         SiS_SetReg1(SiS_Part2Port,0x02,0x52);
-      } else {
-         if(HwDeviceExtension->jChipType >= SIS_315H) {
-            SiS_SetReg1(SiS_Part2Port,0x01,0x17);
-            SiS_SetReg1(SiS_Part2Port,0x02,0x1d);
-	 } else {
-            SiS_SetReg1(SiS_Part2Port,0x01,0x0b);
-            SiS_SetReg1(SiS_Part2Port,0x02,0x11);
-	 }
-      } 
-    }
-    
-  tempcx = SiS_HT - 1;
-  if(SiS_VBType & VB_SIS301BLV302BLV) {
+  tempcx--;
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
         tempcx--;
   }
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Part2Port,0x1B,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1B,temp);
   temp = (tempcx & 0xFF00) >> 8;
-  SiS_SetRegANDOR(SiS_Part2Port,0x1D,0xF0,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,temp);
+
+  tempcx++;
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+        tempcx++;
+  }
+  tempcx >>= 1;
+
+  push1 = tempcx;
 
-  tempcx = SiS_HT >> 1;
-  push1 = tempcx;                           /* push cx */
   tempcx += 7;
-#ifdef oldHV
-  if(SiS_VBInfo & SetCRT2ToHiVisionTV)  tempcx -= 4;   /* TW: @@@ not done in 301LV/630+301B BIOS */
-#endif
+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+     (SiS_Pr->SiS_HiVision == 3)) {
+       tempcx -= 4;
+  }
   temp = (tempcx & 0x00FF) << 4;
-  SiS_SetRegANDOR(SiS_Part2Port,0x22,0x0F,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,temp);
 
   tempbx = TimingPoint[j] | ((TimingPoint[j+1]) << 8);
   tempbx += tempcx;
+
   push2 = tempbx;
+
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Part2Port,0x24,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,temp);
   temp = ((tempbx & 0xFF00) >> 8) << 4;
-  SiS_SetRegANDOR(SiS_Part2Port,0x25,0x0F,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,temp);
 
   tempbx = push2;
 
   tempbx += 8;
-#ifdef oldHV
-  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {	/* TW: @@@ not done in 301LV/630+301B BIOS */
-    tempbx -= 4;				/* TW: @@@ not done in 301LV/630+301B BIOS */
-    tempcx = tempbx;				/* TW: @@@ not done in 301LV/630+301B BIOS */
-  }						/* TW: @@@ not done in 301LV/630+301B BIOS */
-#endif
+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+     (SiS_Pr->SiS_HiVision == 3)) {
+    tempbx -= 4;
+    tempcx = tempbx;
+  }
   temp = (tempbx & 0x00FF) << 4;
-  SiS_SetRegANDOR(SiS_Part2Port,0x29,0x0F,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,temp);
 
   j += 2;
   tempcx += ((TimingPoint[j] | ((TimingPoint[j+1]) << 8)));
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Part2Port,0x27,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,temp);
   temp = ((tempcx & 0xFF00) >> 8) << 4;
-  SiS_SetRegANDOR(SiS_Part2Port,0x28,0x0F,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,temp);
 
   tempcx += 8;
-#ifdef oldHV
-  if(SiS_VBInfo & SetCRT2ToHiVisionTV)  tempcx -= 4; /* TW: @@@ not done in 301LV BIOS */
-#endif
-  temp = (tempcx & 0xFF) << 4;
-  SiS_SetRegANDOR(SiS_Part2Port,0x2A,0x0F,temp);
+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+     (SiS_Pr->SiS_HiVision == 3)) {
+     tempcx -= 4; 
+  }
+  temp = (tempcx & 0x00FF) << 4;
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,temp);
 
   tempcx = push1;
+
   j += 2;
   tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
   temp = (tempcx & 0x00FF) << 4;
-  SiS_SetRegANDOR(SiS_Part2Port,0x2D,0x0F,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,temp);
 
   tempcx -= 11;
-  if(!(SiS_VBInfo & SetCRT2ToTV)){
-    tempax = SiS_GetVGAHT2() - 1;
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+    tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
     tempcx = tempax;
   }
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Part2Port,0x2E,temp);	  
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2E,temp);
 
-  tempbx = SiS_VDE;
-  if(SiS_VGAVDE == 360) tempbx = 746;
-  if(SiS_VGAVDE == 375) tempbx = 746;
-  if(SiS_VGAVDE == 405) tempbx = 853;
+  tempbx = SiS_Pr->SiS_VDE;
+  if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
+  if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
+  if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
   if(HwDeviceExtension->jChipType < SIS_315H) {
-  	if(SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
+  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
   } else {
-	if((SiS_VBInfo & SetCRT2ToTV) && (!(SiS_HiVision & 0x03))) {
+	if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
 	   tempbx >>= 1;
-	   if(SiS_SetFlag & TVSimuMode) {
+	   if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
 	      if(ModeNo <= 0x13) {
 	         if(crt2crtc == 1) {
 	            tempbx++;
                  }
 	      }
 	   } else {
-              if(SiS_VBInfo & SetInSlaveMode) {
+              if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
 	         if(crt2crtc == 4)   /* TW: BIOS calls GetRatePtrCRT2 here - does not make sense */
-                    if(SiS_ModeType <= 3) tempbx++;
+                    if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
 	      }
 	   }
         }
   }
   tempbx -= 2;
   temp = tempbx & 0x00FF;
-#ifdef oldHV
-  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
-    if(SiS_VBInfo & SetInSlaveMode) {
+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+     (SiS_Pr->SiS_HiVision == 3)) {
+    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
       if(ModeNo == 0x2f) temp++;
     }
   }
-#endif
-  SiS_SetReg1(SiS_Part2Port,0x2F,temp);
+  /* TW: From 1.10.7w - doesn't make sense */
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {   /* SetFlag?? */
+	       if(ModeNo == 0x03) temp++;
+	   }
+	}
+     }
+  }
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2F,temp);
 
-  temp = (tempcx & 0xFF00) >> 8;
-  temp |= (((tempbx & 0xFF00) >> 8) << 6);
-#ifdef oldHV
-  if(!(SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-#endif
-    if(!(SiS_VBInfo & SetCRT2ToSCART)) {		/* TW: New from 630/301B (II) BIOS */
-       temp |= 0x10;
-       if(!(SiS_VBInfo & SetCRT2ToSVIDEO))  temp |= 0x20;
-    }
-#ifdef oldHV
+  tempax = (tempcx & 0xFF00) | (tempax & 0x00FF);
+  tempbx = ((tempbx & 0xFF00) << 6) | (tempbx & 0x00FF);
+  tempax |= (tempbx & 0xFF00);
+  if(HwDeviceExtension->jChipType < SIS_315H) {
+     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) {		/* TW: New from 630/301B (II) BIOS */
+           tempax |= 0x1000;
+           if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO))  tempax |= 0x2000;
+        }
+     }
+  } else {
+     /* TODO Check this with other BIOSes */
+     if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) && 
+        (SiS_Pr->SiS_HiVision == 3)) {
+	tempax |= 0x1000;
+        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO))  tempax |= 0x2000;
+     }
   }
-#endif
-  SiS_SetReg1(SiS_Part2Port,0x30,temp);
+  temp = (tempax & 0xFF00) >> 8;
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,temp);
 
-  if(SiS_VBType & VB_SIS301BLV302BLV) {      /* tv gatingno */
-    tempbx = SiS_VDE;
-    if((SiS_VBInfo & SetCRT2ToTV) && (!(SiS_HiVision & 0x03))) {
+  /* TW: 650/30xLV 1.10.6s */
+  if(HwDeviceExtension->jChipType > SIS_315H) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ) {
+            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
+        }
+     }
+  }
+  
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+     if(SiS_Pr->SiS_HiVision != 3) {
+	for(i=0, j=0; i<=0x2d; i++, j++) {
+	    SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS_HiVisionTable[SiS_Pr->SiS_HiVision][j]);
+	}
+	for(i=0x39; i<=0x45; i++, j++) {
+	    SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS_HiVisionTable[SiS_Pr->SiS_HiVision][j]);
+	}
+     }
+  }
+
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {     
+    tempbx = SiS_Pr->SiS_VDE;
+    if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
          tempbx >>= 1;
     }
-    temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
-    temp |= 0x18;                                    /* TW: Inserted from 650/301/301LV BIOS */
-    SiS_SetReg1(SiS_Part2Port,0x46,temp);
-    temp = (tempbx - 3) & 0x00FF;
-    SiS_SetReg1(SiS_Part2Port,0x47,temp);
-    if(SiS_HiVision & 0x03) {
-        if(SiS_HiVision & 0x01) temp = 0x30;
-	else temp = 0x50;
-	SiS_SetReg1(SiS_Part2Port,0x4d,temp);
+    tempbx -= 3;
+    tempbx &= 0x03ff;
+    temp = ((tempbx & 0xFF00) >> 8) << 5;
+    temp |= 0x18;
+    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp);
+    temp = tempbx & 0x00FF;
+    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp);	/* tv gatingno */
+    if(HwDeviceExtension->jChipType >= SIS_315H) {	/* TW: 650/30xLV 1.10.6s */
+       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+          tempax = 0;
+          if(SiS_Pr->SiS_HiVision & 0x03) {
+	     tempax = 0x3000;
+	     if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x5000;
+	  }
+	  temp = (tempax & 0xFF00) >> 8;
+          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp);
+       }
     }
   }
 
   tempbx &= 0x00FF;
-  if(!(modeflag & HalfDCLK)){
-    tempcx = SiS_VGAHDE;
-    if(tempcx >= SiS_HDE){
+  if(!(modeflag & HalfDCLK)) {
+    tempcx = SiS_Pr->SiS_VGAHDE;
+    if(tempcx >= SiS_Pr->SiS_HDE) {
       tempbx |= 0x2000;
       tempax &= 0x00FF;
     }
   }
 
   tempcx = 0x0101;
-  if( (SiS_VBInfo & SetCRT2ToTV) && (!(SiS_HiVision & 0x03)) ) {  /*301b- TW: BIOS BUG! */
-    if(SiS_VGAHDE >= 1024) {
-      if(!(modeflag & HalfDCLK)) {   	/* TW: "if" inserted from 650/301LV and 630/301B BIOS */
-        tempcx = 0x1920;
-        if(SiS_VGAHDE >= 1280) {
-          tempcx = 0x1420;
-          tempbx &= 0xDFFF;
+/*if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) {  */ /*301b- TW: BIOS BUG? */
+  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
+    if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+      if(SiS_Pr->SiS_VGAHDE >= 1024) {
+        if((!(modeflag & HalfDCLK)) || (HwDeviceExtension->jChipType < SIS_315H)) {   /* TW: This check not in 630/301B */
+          tempcx = 0x1920;
+          if(SiS_Pr->SiS_VGAHDE >= 1280) {
+            tempcx = 0x1420;
+            tempbx &= 0xDFFF;
+          }
         }
       }
     }
   }
 
-  if(!(tempbx & 0x2000)){
-
-    if(modeflag & HalfDCLK){
-      tempcx = (tempcx & 0xFF00) | (((tempcx & 0x00FF) << 1) & 0xff);
+  if(!(tempbx & 0x2000)) {
+    if(modeflag & HalfDCLK) {
+         tempcx = (tempcx & 0xFF00) | (((tempcx & 0x00FF) << 1) & 0xff);
     }
     push1 = tempbx;
-    tempeax = SiS_VGAHDE;
+    tempeax = SiS_Pr->SiS_VGAHDE;
     tempebx = (tempcx & 0xFF00) >> 8;
     longtemp = tempeax * tempebx;
     tempecx = tempcx & 0x00FF;
     longtemp /= tempecx;
     longtemp <<= 0x0d;
-    if(SiS_VBType & VB_SIS301BLV302BLV) {
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
      	longtemp <<= 3;
     }
-    tempecx = SiS_HDE;
+    tempecx = SiS_Pr->SiS_HDE;
     temp2 = longtemp % tempecx;
     tempeax = longtemp / tempecx;
     if(temp2 != 0) tempeax++;
     tempax = (USHORT)tempeax;
     tempbx = push1;
-    if(SiS_VBType & VB_SIS301BLV302BLV) {   /* TW: Done anyway in BIOS, but does not matter */
-     	tempcx = ((tempax & 0xFF00) >> 5) >> 8;
-    }
+    tempcx = (tempcx & 0xff00) | (((tempax & 0xFF00) >> 8) >> 5);
     tempbx |= (tempax & 0x1F00);
     tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
   }
 
   temp = (tempax & 0xFF00) >> 8;
-  SiS_SetReg1(SiS_Part2Port,0x44,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x44,temp);
   temp = (tempbx & 0xFF00) >> 8;
-  SiS_SetRegANDOR(SiS_Part2Port,0x45,0xC0,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,temp);
 
-  if(SiS_VBType & VB_SIS301BLV302BLV) {
-       if(tempbx & 0x2000)
-    		tempcx=0x00;
-       temp = tempcx;
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+       temp = tempcx & 0x00FF;
+       if(tempbx & 0x2000) temp = 0;
        temp |= 0x18;
-       SiS_SetRegANDOR(SiS_Part2Port,0x46,0xE0,temp);
-       if(SiS_VBInfo & SetPALTV) {
-             tempbx = 0x0382;    /* TW: BIOS; Was 0x0364; */
-             tempcx = 0x007e;    /* TW: BIOS; Was 0x009c; */
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
+       if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+             tempbx = 0x0382;  
+             tempcx = 0x007e;  
        } else {
-             tempbx = 0x0369;    /* TW: BIOS; Was 0x0346; */
-             tempcx = 0x0061;    /* TW: BIOS; Was 0x0078; */
+             tempbx = 0x0369;  
+             tempcx = 0x0061;  
        }
        temp = (tempbx & 0x00FF) ;
-       SiS_SetReg1(SiS_Part2Port,0x4B,temp);
+       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
        temp = (tempcx & 0x00FF) ;
-       SiS_SetReg1(SiS_Part2Port,0x4C,temp);
-       tempbx &= 0x0300;
+       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
+       tempbx &= 0x03FF;
        temp = (tempcx & 0xFF00) >> 8;
        temp = (temp & 0x0003) << 2;
        temp |= (tempbx >> 8);
-       SiS_SetRegOR(SiS_Part2Port,0x4D,temp);   /* TW: 650/LV - was SetReg1() (not 630/301B) */
+       if(HwDeviceExtension->jChipType < SIS_315H) {
+          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
+       } else {
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
+       }
 
-       temp = SiS_GetReg1(SiS_Part2Port,0x43);
-       SiS_SetReg1(SiS_Part2Port,0x43,(USHORT)(temp - 3));
+       temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43);
+       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
   }
 
-#ifdef SIS300
-  if((HwDeviceExtension->jChipType==SIS_630)||
-     (HwDeviceExtension->jChipType==SIS_730)) {
-          if(SiS_VBInfo & SetCRT2ToTV) {
-             if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
-                  if(SiS_GetReg1(SiS_P3d4,0x35) & 0x40) {
-                           SiS_SetRegAND(SiS_Part2Port,0x00,0xEF);
-                           temp3=SiS_GetReg1(SiS_Part2Port,0x01);
-                           SiS_SetReg1(SiS_Part2Port,0x01,temp3-1);
-                  }
-             }
-          }
-  }
-#endif
-
-#ifdef SIS315H
-  if (HwDeviceExtension->jChipType >= SIS_315H) {
-            if(SiS_VBInfo & SetCRT2ToTV) {
-               if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
-                    if(SiS_GetReg1(SiS_P3d4,0x38) & 0x40) {
-                             SiS_SetRegAND(SiS_Part2Port,0x00,0xEF);
-                             temp3=SiS_GetReg1(SiS_Part2Port,0x01);
-                             SiS_SetReg1(SiS_Part2Port,0x01,temp3-1);
-                    }
+  temp = 0;
+  if((HwDeviceExtension->jChipType == SIS_630) ||
+     (HwDeviceExtension->jChipType == SIS_730)) {
+     temp = 0x35;
+  } else if(HwDeviceExtension->jChipType >= SIS_315H) {
+     temp = 0x38;
+  }
+  if(temp) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+               if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM) {  /* 0x40 */
+                     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
+                     temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
+                     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
                }
-            }
+          }
+      }
   }
-  /*end add*/
-#endif
 
-#ifdef oldHV
-  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
-    if(!(SiS_VBInfo & SetInSlaveMode)) {
-      SiS_SetReg1(SiS_Part2Port,0x0B,0x00);
+  if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+      (!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) ) {
+    if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
     }
   }
-#endif
 
   if(HwDeviceExtension->jChipType < SIS_315H) {
-     if(SiS_VBInfo & SetCRT2ToTV)  return;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     	SiS_Set300Part2Regs(SiS_Pr, HwDeviceExtension, ModeIdIndex,
+			    RefreshRateTableIndex, BaseAddr, ModeNo);
+	return;
+     }
   } else {
-     if(SiS_VBInfo & SetCRT2ToTV) {
-       if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) {
-         if(SiS_VBInfo & SetCRT2ToTV) {
-           if(!(SiS_VBInfo & SetPALTV)) {
+     /* TW: !!! The following is a duplicate, done for LCDA as well (see above) */
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    
+         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+           if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
              if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
-               SiS_SetReg1(SiS_Part2Port,0x1c,0xa7);
-	       SiS_SetReg1(SiS_Part2Port,0x1d,0x07);
-	       SiS_SetReg1(SiS_Part2Port,0x1e,0xf2);
-	       SiS_SetReg1(SiS_Part2Port,0x1f,0x6e);
-	       SiS_SetReg1(SiS_Part2Port,0x20,0x17);
-	       SiS_SetReg1(SiS_Part2Port,0x21,0x8b);
-	       SiS_SetReg1(SiS_Part2Port,0x22,0x73);
-	       SiS_SetReg1(SiS_Part2Port,0x23,0x53);
-	       SiS_SetReg1(SiS_Part2Port,0x24,0x13);
-	       SiS_SetReg1(SiS_Part2Port,0x25,0x40);
-	       SiS_SetReg1(SiS_Part2Port,0x26,0x34);
-	       SiS_SetReg1(SiS_Part2Port,0x27,0xf4);
-	       SiS_SetReg1(SiS_Part2Port,0x28,0x63);
-	       SiS_SetReg1(SiS_Part2Port,0x29,0xbb);
-	       SiS_SetReg1(SiS_Part2Port,0x2a,0xcc);
-	       SiS_SetReg1(SiS_Part2Port,0x2b,0x7a);
-	       SiS_SetReg1(SiS_Part2Port,0x2c,0x58);
-	       SiS_SetReg1(SiS_Part2Port,0x2d,0xe4);
-	       SiS_SetReg1(SiS_Part2Port,0x2e,0x73);
-	       SiS_SetReg1(SiS_Part2Port,0x2f,0xda);
-	       SiS_SetReg1(SiS_Part2Port,0x30,0x13);
-	       SiS_SetReg1(SiS_Part2Port,0x43,0x72);
+               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
+	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
 	     }
            }
          }
@@ -5542,152 +7501,227 @@
      }
   }
 
-  /* TW: From here: LCD Part2 group */
+  /* TW: From here: Part2 LCD setup */
 
-  tempbx = SiS_HDE - 1;         /* RHACTE=HDE-1 */
+  tempbx = SiS_Pr->SiS_HDE;
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+      /* TW: 650/30xLV 1.10.6s */
+      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
+  }
+  tempbx--;			         	/* RHACTE=HDE-1 */
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Part2Port,0x2C,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2C,temp);
   temp = (tempbx & 0xFF00) >> 8;
   temp <<= 4;
-  SiS_SetRegANDOR(SiS_Part2Port,0x2B,0x0F,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp);
 
   temp = 0x01;
-  if(SiS_LCDResInfo == Panel1280x1024) {
-    if(SiS_ModeType == ModeEGA) {
-      if(SiS_VGAHDE >= 1024) {
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+    if(SiS_Pr->SiS_ModeType == ModeEGA) {
+      if(SiS_Pr->SiS_VGAHDE >= 1024) {
         temp = 0x02;
 	if(HwDeviceExtension->jChipType >= SIS_315H) {
-           if (SiS_SetFlag & LCDVESATiming) {
+           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
              temp = 0x01;
 	   }
 	}
       }
     }
   }
-  SiS_SetReg1(SiS_Part2Port,0x0B,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,temp);
 
-  tempbx = SiS_VDE;         /* RTVACTEO=(VDE-1)&0xFF */
+  tempbx = SiS_Pr->SiS_VDE;         		/* RTVACTEO=(VDE-1)&0xFF */
   push1 = tempbx;
+
   tempbx--;
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Part2Port,0x03,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x03,temp);
   temp = ((tempbx & 0xFF00) >> 8) & 0x07;
-  SiS_SetRegANDOR(SiS_Part2Port,0x0C,0xF8,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,temp);
 
-  tempcx = SiS_VT;
+  tempcx = SiS_Pr->SiS_VT;
   push2 = tempcx;
+
   tempcx--;
-  temp = tempcx & 0x00FF;   /* RVTVT=VT-1 */
-  SiS_SetReg1(SiS_Part2Port,0x19,temp);
+  temp = tempcx & 0x00FF;  			 /* RVTVT=VT-1 */
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x19,temp);
 
   temp = (tempcx & 0xFF00) >> 8;
   temp <<= 5;
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-    if(SiS_VBType & VB_SIS301BLV302BLV) temp |= 0x10;
+  
+  /* Enable dithering; newer versions only do this for 32bpp mode */
+  if((HwDeviceExtension->jChipType == SIS_300) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+    if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x10;
+  } else if(HwDeviceExtension->jChipType < SIS_315H) {
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp |= 0x10;
     else {
-#if 0
-      if(SiS_LCDInfo & LCDRGB18Bit)   /* TW: 630/301B (II) BIOS does not check this!!! */
-#endif
-      if(SiS_LCDInfo & LCDSync)       /* TW: 630/301 BIOS checks this */
+      if(SiS_Pr->SiS_LCDInfo & LCDSync)       /* TW: 630/301 BIOS checks this */
          temp |= 0x10;
     }
-  } else temp |= 0x10;
+  } else {
+      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+         /* TW: 650/30xLV 1.10.6s */
+         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+            if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {  /* 32bpp mode? */
+      	       temp |= 0x10;
+	    }
+         }
+      } else {
+         temp |= 0x10;
+      }
+  }
 
   /* 630/301 does not do all this */
-  if((SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo & SetCRT2ToLCD)) {
-      tempbx = (tempbx & 0xFF00) | (SiS_LCDInfo & 0x0FF);
-      if(tempbx & LCDSync) {
-        tempbx &= (0xFF00 | LCDSyncBit);
-        tempbx = (tempbx & 0xFF00) | ((tempbx & 0x00FF) >> LCDSyncShift);
-        temp |= (tempbx & 0x00FF);
-      }
+  if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+     if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+        /* TW: 650/30xLV 1.10.6s */
+        temp |= (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37) >> 6);
+	temp |= 0x08;   					/* From 1.10.7w */
+	if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04; 	/* From 1.10.7w */
+     } else {
+        tempbx = (tempbx & 0xFF00) | (SiS_Pr->SiS_LCDInfo & 0x0FF);
+        if(tempbx & LCDSync) {
+           tempbx &= 0xFFE0;
+           tempbx = (tempbx & 0xFF00) | ((tempbx & 0x00FF) >> 6);
+           temp |= (tempbx & 0x00FF);
+        }
+     }
   }
-  SiS_SetReg1(SiS_Part2Port,0x1A,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1A,temp);
 
-  SiS_SetRegAND(SiS_Part2Port,0x09,0xF0);
-  SiS_SetRegAND(SiS_Part2Port,0x0A,0xF0);
+  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
+  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
 
-  SiS_SetRegAND(SiS_Part2Port,0x17,0xFB);
-  SiS_SetRegAND(SiS_Part2Port,0x18,0xDF);
+  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
+  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {   /* 310 series */
+  /* 1280x960, 1280x1024 and 1600x1200 data invalid/missing in tables, use old calculation */
+  if((HwDeviceExtension->jChipType >= SIS_315H)             && 
+     (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)                &&  
+     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) &&
+     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) &&
+     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960)) {
+     
+#ifdef SIS315H 							/* ------------- 310/325/330 series ------------ */
 
-      /* TW: Inserted this entire section from 650/301LV BIOS */
+      /* TW: Inserted this entire section from 650/301LV(x) BIOS */
+      
+      /* Using this on the 301B with an auto-expanding 1024 panel (CR37=1) results
+       * in a black bar in modes < 1024; if the panel is non-expanding, the bridge
+       * scales all modes to 1024. All modes in both variants (exp/non-exp) work.
+       */
 
-      SiS_GetCRT2Part2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+      SiS_GetCRT2Part2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                          &CRT2Index,&resindex);
 
       switch(CRT2Index) {
-        case 0: CRT2Part2Ptr = SiS_CRT2Part2_1024x768_1;  break;  /* "Normal" */
-        case 1: CRT2Part2Ptr = SiS_CRT2Part2_1280x1024_1; break;
-        case 2: CRT2Part2Ptr = SiS_CRT2Part2_1024x768_2;  break;  /* Non-Expanding */
-        case 3: CRT2Part2Ptr = SiS_CRT2Part2_1280x1024_2; break;
-        case 4: CRT2Part2Ptr = SiS_CRT2Part2_1024x768_3;  break;  /* VESA Timing */
-        case 5: CRT2Part2Ptr = SiS_CRT2Part2_1280x1024_3; break;
+        case Panel_1024x768      : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;  break;  /* "Normal" */
+        case Panel_1280x1024     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_1; break;
+	case Panel_1400x1050     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_1; break;
+	case Panel_1600x1200     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_1; break;
+        case Panel_1024x768  + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;  break;  /* Non-Expanding */
+        case Panel_1280x1024 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_2; break;
+	case Panel_1400x1050 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_2; break;
+	case Panel_1600x1200 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_2; break;
+        case Panel_1024x768  + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;  break;  /* VESA Timing */
+        case Panel_1280x1024 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_3; break;
+	case Panel_1400x1050 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_3; break;
+	case Panel_1600x1200 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_3; break;
+	default:                   CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;  break;
       }
 
-      SiS_SetRegANDOR(SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
-      SiS_SetRegANDOR(SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
       for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
-        SiS_SetReg1(SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
       }
       for(j = 0x1c; j <= 0x1d; i++, j++ ) {
-        SiS_SetReg1(SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
       }
       for(j = 0x1f; j <= 0x21; i++, j++ ) {
-        SiS_SetReg1(SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
       }
-      SiS_SetReg1(SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
-      SiS_SetRegANDOR(SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
+      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
 
-      if(!(SiS_SetFlag & LCDVESATiming)) {
-        if(SiS_VGAVDE == 0x20d) {
+      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+        if(SiS_Pr->SiS_VGAVDE == 525) {
 	  temp = 0xc3;
-	  if(SiS_ModeType <= ModeVGA) {
+	  if(SiS_Pr->SiS_ModeType <= ModeVGA) {
 	     temp++;
-	     if(SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
+	     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
 	  }
-	  SiS_SetReg1(SiS_Part2Port,0x2f,temp);
-	  SiS_SetReg1(SiS_Part2Port,0x30,0xb3);
+	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xb3);
 	}
-	if(SiS_VGAVDE == 0x1a4) {
+	if(SiS_Pr->SiS_VGAVDE == 420) {
 	  temp = 0x4d;
-	  if(SiS_ModeType <= ModeVGA) {
+	  if(SiS_Pr->SiS_ModeType <= ModeVGA) {
 	     temp++;
-	     if(SiS_VBType & VB_SIS301BLV302BLV) temp++;
+	     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
 	  }
-	  SiS_SetReg1(SiS_Part2Port,0x2f,temp);
+	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+	}
+     }
+
+     /* TW: 650/30xLV 1.10.6s: */
+     /* !!! This is a duplicate, done for LCDA as well - see above */
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03);   /* Not done in 1.10.7w */
+	   temp = 1;
+	   if(ModeNo <= 0x13) temp = 3;
+	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
 	}
-     } /* 2f5d */
+     }
+#endif
 
-  } else {   /* 300 series */
+  } else {   /* ------ 300 series and other bridges, other LCD resolutions ------ */
 
+      /* Using this on the 301B with an auto-expanding 1024 panel (CR37=1) makes
+       * the panel scale at modes < 1024 (no black bars); if the panel is non-expanding, 
+       * the bridge scales all modes to 1024.
+       * !!! Malfunction at 640x480 and 640x400 when panel is auto-expanding - black screen !!!
+       */
+  
     tempcx++;
+    
+    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx =  768;
+    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1024;
+    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1200;
+    else if(SiS_Pr->SiS_VDE != 1024) 				  tempbx =  960;
+    else            						  tempbx = 1024;
+    
+#if 0  /* old */
     tempbx = 768;
-    if(SiS_LCDResInfo != Panel1024x768) {
+    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
       tempbx = 1024;
-      if(SiS_LCDResInfo != Panel1280x1024) {
+      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
          tempbx = 1200;
-         if(SiS_LCDResInfo != Panel1600x1200) {
-            if(tempbx != SiS_VDE) {
+         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+            if(tempbx != SiS_Pr->SiS_VDE) {
                tempbx = 960;
             }
          }
       }
     }
-    if(SiS_LCDInfo & LCDNonExpanding) {
-      tempbx = SiS_VDE - 1;
+#endif
+    
+    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+      tempbx = SiS_Pr->SiS_VDE - 1;
       tempcx--;
     }
+    
     tempax = 1;
-    if(!(SiS_LCDInfo & LCDNonExpanding)) {
-      if(tempbx != SiS_VDE){
+    if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+      if(tempbx != SiS_Pr->SiS_VDE) {
         tempax = tempbx;
-        if(tempax < SiS_VDE) {
+/*	if(SiS_Pr->SiS_VGAVDE == 525) tempax += 60;   in 650/301B BIOS */
+        if(tempax < SiS_Pr->SiS_VDE) {
           tempax = 0;
           tempcx = 0;
         } else {
-          tempax -= SiS_VDE;
+          tempax -= SiS_Pr->SiS_VDE;
         }
         tempax >>= 1;
       }
@@ -5698,15 +7732,19 @@
       tempcx -= tempax; /* lcdvdes */
       tempbx -= tempax; /* lcdvdee */
     }
+    
+#ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO, "lcdvds 0x%x lcdvde 0x%x\n", tempcx, tempbx);
+#endif    
 
-    temp = tempcx & 0x00FF;   /* RVEQ1EQ=lcdvdes */
-    SiS_SetReg1(SiS_Part2Port,0x05,temp);
-    temp = tempbx & 0x00FF;   /* RVEQ2EQ=lcdvdee */
-    SiS_SetReg1(SiS_Part2Port,0x06,temp);
+    temp = tempcx & 0x00FF;   				/* RVEQ1EQ=lcdvdes */
+    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,temp);
+    temp = tempbx & 0x00FF;   				/* RVEQ2EQ=lcdvdee */
+    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,temp);
 
-    temp = ((tempbx & 0xFF00) >> 8 ) << 3;
+    temp = ((tempbx & 0xFF00) >> 8) << 3;
     temp |= ((tempcx & 0xFF00) >> 8);
-    SiS_SetReg1(SiS_Part2Port,0x02,temp);
+    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
 
     tempbx = push2;
     tempax = push1;
@@ -5715,343 +7753,438 @@
     tempcx >>= 4;
     tempbx += tempax;
     tempbx >>= 1;
-    if(SiS_LCDInfo & LCDNonExpanding)  tempbx -= 10;
+    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx -= 10;
+    
+#ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
+#endif
 
-    temp = tempbx & 0x00FF;   		/* RTVACTEE=lcdvrs */
-    SiS_SetReg1(SiS_Part2Port,0x04,temp);
+    temp = tempbx & 0x00FF;   				/* RTVACTEE=lcdvrs */
+    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
 
     temp = ((tempbx & 0xFF00) >> 8) << 4;
     tempbx += (tempcx + 1);
     temp |= (tempbx & 0x000F);
-    SiS_SetReg1(SiS_Part2Port,0x01,temp);
+    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
 
     /* TW: Code from 630/301B (I+II) BIOS */
 
     if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
             (HwDeviceExtension->jChipType == SIS_730) ) &&
           (HwDeviceExtension->jChipRevision > 2) )  &&
-        (SiS_LCDResInfo == Panel1024x768) &&
-        (!(SiS_SetFlag & LCDVESATiming))  &&
-        (!(SiS_LCDInfo & LCDNonExpanding)) ) {
+        (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
+        (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
+        (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
             if(ModeNo == 0x13) {
-              SiS_SetReg1(SiS_Part2Port,0x04,0xB9);
-              SiS_SetReg1(SiS_Part2Port,0x05,0xCC);
-              SiS_SetReg1(SiS_Part2Port,0x06,0xA6);
+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
+              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
             } else {
               if((crt2crtc & 0x3F) == 4) {
-                SiS_SetReg1(SiS_Part2Port,0x01,0x2B);
-                SiS_SetReg1(SiS_Part2Port,0x02,0x13);
-                SiS_SetReg1(SiS_Part2Port,0x04,0xE5);
-                SiS_SetReg1(SiS_Part2Port,0x05,0x08);
-                SiS_SetReg1(SiS_Part2Port,0x06,0xE2);
+                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x2B);
+                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x13);
+                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xE5);
+                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0x08);
+                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xE2);
               }
             }
     }
 
-    /* TW: Inserted missing code from 630/301B BIOS: (II: 3258) */
+    /* TW: Inserted missing code from 630/301B BIOS;
+     *     Strangely, this is done in all 650 BIOSes as
+     *     well (although LCDTypeInfo is not used there
+     *     in the same way as on 300 series)
+     */
 
-    if(SiS_LCDTypeInfo == 0x0c) {
+    if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
          crt2crtc &= 0x1f;
          tempcx = 0;
-         if(!(SiS_VBInfo & SetNotSimuMode)) {
-           if (SiS_VBInfo & SetInSlaveMode) {
+         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+           if (SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
               tempcx += 7;
            }
          }
          tempcx += crt2crtc;
          if (crt2crtc >= 4) {
-           SiS_SetReg1(SiS_Part2Port,0x06,0xff);
+           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
          }
 
-         if(!(SiS_VBInfo & SetNotSimuMode)) {
-           if (SiS_VBInfo & SetInSlaveMode) {
-             if (crt2crtc == 4) {
-                SiS_SetReg1(SiS_Part2Port,0x01,0x28);
+         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+             if(crt2crtc == 4) {
+                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
              }
            }
          }
-         SiS_SetReg1(SiS_Part2Port,0x02,0x18);
-         SiS_SetReg1(SiS_Part2Port,0x04,atable[tempcx]);
+         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
+         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
     }
 
-    tempcx = (SiS_HT - SiS_HDE) >> 2;    	/* (HT-HDE)>>2     */
-    tempbx = SiS_HDE + 7;            		/* lcdhdee         */
-    if(SiS_VBType & VB_SIS301BLV302BLV) {
+    tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2;     /* (HT-HDE)>>2     */
+    tempbx = SiS_Pr->SiS_HDE + 7;            		  /* lcdhdee         */
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
          tempbx += 2;
     }
     push1 = tempbx;
-    temp = tempbx & 0x00FF;    			/* RHEQPLE=lcdhdee */
-    SiS_SetReg1(SiS_Part2Port,0x23,temp);
+#ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO, "lcdhde 0x%x\n", tempbx);
+#endif    
+    temp = tempbx & 0x00FF;    			          /* RHEQPLE=lcdhdee */
+    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,temp);
     temp = (tempbx & 0xFF00) >> 8;
-    SiS_SetRegANDOR(SiS_Part2Port,0x25,0xF0,temp);
+    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp);
 
     temp = 7;
-    if(SiS_VBType & VB_SIS301BLV302BLV) {
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
          temp += 2;
     }
-    SiS_SetReg1(SiS_Part2Port,0x1F,temp);  	/* RHBLKE=lcdhdes */
-
-    SiS_SetRegAND(SiS_Part2Port,0x20,0x0F);
+    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp);  	  /* RHBLKE=lcdhdes[7:0] */
+    SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x20,0x0F);	  /* lcdhdes [11:8] */
 
     tempbx += tempcx;
     push2 = tempbx;
-    temp = tempbx & 0xFF;            		/* RHBURSTS=lcdhrs */
-    if(SiS_LCDResInfo == Panel1280x1024) {
-      if(SiS_LCDInfo & LCDNonExpanding) {
-        if(SiS_HDE == 1280)  temp = 0x47;
-      }
+#ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
+#endif
+    temp = tempbx & 0x00FF;            		          /* RHBURSTS=lcdhrs */
+    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 
+          if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
+       }
     }
-    SiS_SetReg1(SiS_Part2Port,0x1C,temp);
+    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1C,temp);
     temp = ((tempbx & 0xFF00) >> 8) << 4;
-    SiS_SetRegANDOR(SiS_Part2Port,0x1D,0x0F,temp);
+    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
 
     tempbx = push2;
     tempcx <<= 1;
     tempbx += tempcx;
-    temp = tempbx & 0x00FF;            		/* RHSYEXP2S=lcdhre */
-    SiS_SetReg1(SiS_Part2Port,0x21,temp);
-
-    if(!(SiS_SetFlag & LCDVESATiming)) {
-      if(SiS_VGAVDE == 525) {
-/*      if(SiS_VBType & VB_SIS301BLV302BLV)  */ /* TW: 630/301B (I+II) */
-        if(SiS_ModeType <= ModeVGA)
+#ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
+#endif    
+    temp = tempbx & 0x00FF;            		          /* RHSYEXP2S=lcdhre */
+    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,temp);
+
+    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+      if(SiS_Pr->SiS_VGAVDE == 525) {
+        if(SiS_Pr->SiS_ModeType <= ModeVGA)
     	   temp=0xC6;
         else
-       	   temp=0xC3;   /* 650: c4 */
-        SiS_SetReg1(SiS_Part2Port,0x2f,temp);
-        SiS_SetReg1(SiS_Part2Port,0x30,0xB3);
-      } else if(SiS_VGAVDE==420) {
-/*      if(SiS_VBType & VB_SIS301BLV302BLV)  */ /* TW: 630/301B (I+II) */
-        if(SiS_ModeType <= ModeVGA)
+       	   temp=0xC3;
+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
+      } else if(SiS_Pr->SiS_VGAVDE == 420) {
+        if(SiS_Pr->SiS_ModeType <= ModeVGA)
 	   temp=0x4F;
         else
-       	   temp=0x4D;   /* 650: 4e */
-        SiS_SetReg1(SiS_Part2Port,0x2f,temp);
+       	   temp=0x4D;   
+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
       }
     }
+    SiS_Set300Part2Regs(SiS_Pr, HwDeviceExtension, ModeIdIndex,
+                        RefreshRateTableIndex, BaseAddr, ModeNo);
 
   } /* HwDeviceExtension */
 }
 
 USHORT
-SiS_GetVGAHT2()
+SiS_GetVGAHT2(SiS_Private *SiS_Pr)
 {
   ULONG tempax,tempbx;
 
-  tempbx = ((SiS_VGAVT - SiS_VGAVDE) * SiS_RVBHCMAX) & 0xFFFF;
-  tempax = (SiS_VT - SiS_VDE) * SiS_RVBHCFACT;
-  tempax = (tempax * SiS_HT) / tempbx;
+  tempbx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX) & 0xFFFF;
+  tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
+  tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
   return((USHORT) tempax);
 }
 
+/* TW: New from 300/301LV BIOS 1.16.51 for ECS A907. Seems highly preliminary. */
+void
+SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+    			USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+			USHORT BaseAddr, USHORT ModeNo)
+{
+  USHORT crt2crtc, resindex;
+  int    i,j;
+  const  SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
+
+  if(HwDeviceExtension->jChipType != SIS_300) return;
+  if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+
+  if(ModeNo<=0x13) {
+    	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+    	crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
+
+  resindex = crt2crtc & 0x3F;
+  if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
+  else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
+
+  /* TW: The BIOS code (1.16.51) is obviously a fragment! */
+  if(ModeNo > 0x13) {
+     CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
+     resindex = 4;
+  }
+
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
+  for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+  }
+  for(j = 0x1c; j <= 0x1d; i++, j++ ) {
+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+  }
+  for(j = 0x1f; j <= 0x21; i++, j++ ) {
+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+  }
+  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
+}
+
 /* TW: Set 301 Macrovision(tm) registers */
-/* TW: Double-Checked against 650/301LV and 630/301B BIOS */
 void
-SiS_SetGroup3(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
               USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
+  USHORT temp;
   USHORT i;
-  UCHAR  *tempdi;
+  const UCHAR  *tempdi;
   USHORT modeflag;
 
-  if(SiS_VBInfo & SetCRT2ToLCDA) return;   /* TW: Inserted from BIOS */
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
 
   if(ModeNo<=0x13)
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   else
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-  SiS_SetReg1(SiS_Part3Port,0x00,0x00);
+  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x00,0x00);
 
-  if(SiS_VBInfo & SetPALTV) {
-    SiS_SetReg1(SiS_Part3Port,0x13,0xFA);
-    SiS_SetReg1(SiS_Part3Port,0x14,0xC8);
+  if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+    SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
+    SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
   } else {
     if(HwDeviceExtension->jChipType >= SIS_315H) {
-      SiS_SetReg1(SiS_Part3Port,0x13,0xF5);
-      SiS_SetReg1(SiS_Part3Port,0x14,0xB7);
+      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5);
+      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7);
     } else {
-      SiS_SetReg1(SiS_Part3Port,0x13,0xF6);
-      SiS_SetReg1(SiS_Part3Port,0x14,0xBf);
+      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6);
+      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf);
     }
   }
 
-#ifdef SIS300
-  if((HwDeviceExtension->jChipType==SIS_630)||
-     (HwDeviceExtension->jChipType==SIS_730)) {
-           if(SiS_VBInfo & SetCRT2ToTV) {
-              if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
-                  if(SiS_GetReg1(SiS_P3d4,0x35) & 0x40){
-                          SiS_SetReg1(SiS_Part3Port,0x13,0xFA);
-                          SiS_SetReg1(SiS_Part3Port,0x14,0xC8);
-                          SiS_SetReg1(SiS_Part3Port,0x3D,0xA8);
-                  }
+  temp = 0;
+  if((HwDeviceExtension->jChipType == SIS_630)||
+     (HwDeviceExtension->jChipType == SIS_730)) {
+     temp = 0x35;
+  } else if(HwDeviceExtension->jChipType >= SIS_315H) {
+     temp = 0x38;
+  }
+  if(temp) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+              if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM){  /* 0x40 */
+                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
+                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
+                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
               }
           }
+      }
   }
-#endif
-
-#ifdef SIS315H
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-         if(SiS_VBInfo & SetCRT2ToTV) {
-             if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
-                   if(SiS_GetReg1(SiS_P3d4,0x38) & 0x40){
-                          SiS_SetReg1(SiS_Part3Port,0x13,0xFA);
-                          SiS_SetReg1(SiS_Part3Port,0x14,0xC8);
-                          SiS_SetReg1(SiS_Part3Port,0x3D,0xA8);
-                   }
-             }
-         }
-  }
-#endif
 
-  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
-    tempdi = SiS_HiTVGroup3Data;
-    if(SiS_SetFlag & TVSimuMode) {
-      tempdi = SiS_HiTVGroup3Simu;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+    tempdi = SiS_Pr->SiS_HiTVGroup3Data;
+    if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+      tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
       if(!(modeflag & Charx8Dot)) {
-        tempdi = SiS_HiTVGroup3Text;
+        tempdi = SiS_Pr->SiS_HiTVGroup3Text;
       }
     }
+    if(SiS_Pr->SiS_HiVision & 0x03) {
+       tempdi = SiS_HiTVGroup3_1;
+       if(SiS_Pr->SiS_HiVision & 0x02) tempdi = SiS_HiTVGroup3_2;
+    }
     for(i=0; i<=0x3E; i++){
-       SiS_SetReg1(SiS_Part3Port,i,tempdi[i]);
+       SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
     }
   }
+
   return;
 }
 
 /* TW: Set 301 VGA2 registers */
-/* TW: Double-Checked against 650/301LV and 630/301B BIOS */
 void
-SiS_SetGroup4(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
               USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
 	      PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
-  USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,push1;
+  USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,resinfo;
   ULONG tempebx,tempeax,templong;
 
-  if(ModeNo<=0x13)
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  else
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-  /* TW: From 650/301LV BIOS (done above as well, but does not matter) */
-  if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) {
-      if(SiS_VBInfo & SetCRT2ToLCDA)
-          SiS_SetReg1(SiS_Part4Port,0x24,0x0e);
+  if(ModeNo<=0x13) {
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else {
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
 
-  /* TW: From 650/301LV BIOS */
-  if(SiS_VBInfo & SetCRT2ToLCDA) return;
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+      /* TW: From 650/302LV 1.10.6s (not for 300/301LV - no LCDA on this combination) */
+     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+           SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
+        }
+     }
+  }
 
-  temp = SiS_RVBHCFACT;
-  SiS_SetReg1(SiS_Part4Port,0x13,temp);
+  if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
+      }
+  }
 
-  tempbx = SiS_RVBHCMAX;
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	   /* TW: From 650/301LV (any, incl. 1.10.6s, 1.10.7w) */
+  	   /* TW: This is a duplicate; done at the end, too */
+	   if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
+		SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+	   }
+	   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+	   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+	   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+	}
+   	return;
+     }
+  }
+
+  temp = SiS_Pr->SiS_RVBHCFACT;
+  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x13,temp);
+
+  tempbx = SiS_Pr->SiS_RVBHCMAX;
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Part4Port,0x14,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x14,temp);
 
   temp2 = (((tempbx & 0xFF00) >> 8) << 7) & 0x00ff;
 
-  tempcx = SiS_VGAHT - 1;
+  tempcx = SiS_Pr->SiS_VGAHT - 1;
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Part4Port,0x16,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x16,temp);
 
   temp = (((tempcx & 0xFF00) >> 8) << 3) & 0x00ff;
   temp2 |= temp;
 
-  tempcx = SiS_VGAVT - 1;
-  if(!(SiS_VBInfo & SetCRT2ToTV))  tempcx -= 5;
+  tempcx = SiS_Pr->SiS_VGAVT - 1;
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempcx -= 5;
 
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Part4Port,0x17,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x17,temp);
 
   temp = temp2 | ((tempcx & 0xFF00) >> 8);
-  SiS_SetReg1(SiS_Part4Port,0x15,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x15,temp);
 
-  tempcx = SiS_VBInfo;
-  tempbx = SiS_VGAHDE;
+  tempbx = SiS_Pr->SiS_VGAHDE;
   if(modeflag & HalfDCLK)  tempbx >>= 1;
 
   /* TW: New for 650/301LV and 630/301B */
   temp = 0xA0;
-  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
-       temp = 0xA0;
-       if(tempbx != 1024) {
-           temp = 0xC0;
-           if(tempbx != 1280) temp = 0;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+       temp = 0;
+       if(tempbx > 800) {
+          temp = 0xA0;
+          if(tempbx != 1024) {
+             temp = 0xC0;
+             if(tempbx != 1280) temp = 0;
+	  }
        }
-  } else if(SiS_VBInfo & SetCRT2ToTV) {
+  } else
+    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
       if(tempbx <= 800) {
          temp = 0x80;
-	 if(SiS_VBInfo & SetCRT2ToLCD){
+	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
             temp = 0;
             if(tempbx > 800) temp = 0x60;
          }
       }
   } else {
       temp = 0x80;
-      if(SiS_VBInfo & SetCRT2ToLCD){
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
             temp = 0;
             if(tempbx > 800) temp = 0x60;
       }
   }
-  if(SiS_HiVision & 0x03) {
+  if(SiS_Pr->SiS_HiVision & 0x03) {
         temp = 0;
-	if(SiS_VGAHDE == 1024) temp = 0x20;
+	if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
   }
-  SiS_SetRegANDOR(SiS_Part4Port,0x0E,0x10,temp);
+  if(HwDeviceExtension->jChipType >= SIS_315H) {
+  	if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0;
+  }
+
+  if(SiS_Pr->SiS_VBType & VB_SIS301) {
+     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
+        temp |= 0x0A;
+  }
+
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
 
-  tempebx = SiS_VDE;
-  if(SiS_VBInfo & SetCRT2ToHiVisionTV) {
+  tempebx = SiS_Pr->SiS_VDE;
+
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
      if(!(temp & 0xE0)) tempebx >>=1;
   }
 
-  tempcx = SiS_RVBHRS;
+  tempcx = SiS_Pr->SiS_RVBHRS;
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Part4Port,0x18,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x18,temp);
 
-  tempeax = SiS_VGAVDE;
+  tempeax = SiS_Pr->SiS_VGAVDE;
   tempcx |= 0x4000;
   if(tempeax <= tempebx){
-    tempcx = ((tempcx & 0xFF00) ^ 0x4000) | (tempcx & 0x00ff);
+    tempcx ^= 0x4000;
   } else {
     tempeax -= tempebx;
   }
 
-  push1 = tempcx;
-
   templong = (tempeax * 256 * 1024) % tempebx;
   tempeax = (tempeax * 256 * 1024) / tempebx;
   tempebx = tempeax;
   if(templong != 0) tempebx++;
 
-  tempcx = push1;
-
   temp = (USHORT)(tempebx & 0x000000FF);
-  SiS_SetReg1(SiS_Part4Port,0x1B,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1B,temp);
   temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
-  SiS_SetReg1(SiS_Part4Port,0x1A,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1A,temp);
 
   tempbx = (USHORT)(tempebx >> 16);
   temp = tempbx & 0x00FF;
   temp <<= 4;
   temp |= ((tempcx & 0xFF00) >> 8);
-  SiS_SetReg1(SiS_Part4Port,0x19,temp);
+  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x19,temp);
+
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 
-  if(SiS_VBType & VB_SIS301BLV302BLV) {
-         SiS_SetReg1(SiS_Part4Port,0x1C,0x28);
-	 tempbx = 0;   			/* TW: From 630/301B and 650/301LV BIOS */
-         tempax = SiS_VGAHDE;
+         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1C,0x28);
+	 tempbx = 0;
+         tempax = SiS_Pr->SiS_VGAHDE;
          if(modeflag & HalfDCLK) tempax >>= 1;
-         if((SiS_VBInfo & SetCRT2ToLCD) || (SiS_HiVision & 0x03)) {
-             if(tempax > 800) tempax -= 800;
+         if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || (SiS_Pr->SiS_HiVision & 0x03)) {
+	     if(HwDeviceExtension->jChipType >= SIS_315H) {
+	         if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1;
+		 else if(tempax > 800) tempax -= 800;
+	     } else {
+                 if(tempax > 800) tempax -= 800;
+             }
          }
 
-         if((SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) &&
-	                                 (!(SiS_HiVision & 0x03))) {
+/*       if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetPALTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {  */
+ 	 if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
            if(tempax > 800) {
-	      tempbx = 8;  		/* TW: From 630/301B and 650/301LV BIOS */
+	      tempbx = 8;
               if(tempax == 1024)
 	        tempax *= 25;
               else
@@ -6066,197 +8199,244 @@
 	 tempax--;
          temp = (tempax & 0xFF00) >> 8;
          temp &= 0x03;
-	 SiS_SetReg1(SiS_Part4Port,0x1D,tempax & 0x00FF);
+	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {		/* From 1.10.7w */
+	 	if(ModeNo > 0x13) {			/* From 1.10.7w */
+			if(resinfo == 8) tempax = 0x1f;	/* From 1.10.7w */
+		}					/* From 1.10.7w */
+	 }						/* From 1.10.7w */
+	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
 	 temp <<= 4;
 	 temp |= tempbx;
-	 SiS_SetReg1(SiS_Part4Port,0x1E,temp);
+	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1E,temp);
 
-         temp = 0x0036;
-         if((SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV)) &&
-	                               (!(SiS_HiVision & 0x03))) {  /* TW: From 650/301LV BIOS */
+	 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	    if(IS_SIS650740) {
+	        temp = 0x0026;  /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
+	    } else {
+	        temp = 0x0036;
+	    }
+	 } else {
+	     temp = 0x0036;
+	 }
+         if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
+	                               (!(SiS_Pr->SiS_HiVision & 0x03))) {
 		temp |= 0x01;
-	        if(SiS_VBInfo & SetInSlaveMode) {                   /* TW: From 650/301LV BIOS */
-	          if(!(SiS_SetFlag & TVSimuMode))                   /* TW: From 650/301LV BIOS */
-  	                  temp &= 0xFE;                             /* TW: From 650/301LV BIOS */
+	        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+	          if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
+  	                  temp &= 0xFE;
 		}
          }
-         SiS_SetRegANDOR(SiS_Part4Port,0x1F,0xC0,temp);
-         tempbx = (SiS_HT >> 1) - 2;
+         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
+
+	 tempbx = SiS_Pr->SiS_HT;
+	 if(HwDeviceExtension->jChipType >= SIS_315H) {
+	 	if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
+	 }
+         tempbx >>= 1;
+	 tempbx -= 2;
          temp = ((tempbx & 0x0700) >> 8) << 3;
-         SiS_SetRegANDOR(SiS_Part4Port,0x21,0xC0,temp);
+         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
          temp = tempbx & 0x00FF;
-         SiS_SetReg1(SiS_Part4Port,0x22,temp);
-         if( (SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) &&
-	                        (SiS_VBInfo & SetCRT2ToLCD) ) {
-             SiS_SetReg1(SiS_Part4Port,0x24,0x0e);
+         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x22,temp);
+	 
+         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+               SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
+	    }
+	 }
+
+	 if(HwDeviceExtension->jChipType >= SIS_315H) {
+	     /* TW: 650/LV BIOS does this for all bridge types - assumingly wrong */
+	     /* 315, 330, 650+301B BIOS don't do this at all */
+             /* TW: This is a duplicate; done for LCDA as well (see above) */
+	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
+		   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+	        }
+	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+	     }
+         } else if(HwDeviceExtension->jChipType == SIS_300) {
+	     /* TW: 300/301LV BIOS does this for all bridge types - assumingly wrong */
+	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+	     }
 	 }
-  }
 
-  SiS_SetCRT2VCLK(BaseAddr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
+  }  /* 301B */
+
+  SiS_SetCRT2VCLK(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
+                  RefreshRateTableIndex,HwDeviceExtension);
 }
 
-/* TW: Double-Checked against 650/301LV and 630/301B BIOS */
+
 void
-SiS_SetCRT2VCLK(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                  USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT vclkindex;
-  USHORT tempah,temp1;
+  USHORT tempah;
 
-  vclkindex = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+  vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                               HwDeviceExtension);
 
-  if(SiS_VBType & VB_SIS301BLV302BLV) {
-   	tempah = SiS_VBVCLKData[vclkindex].Part4_A;
-   	SiS_SetReg1(SiS_Part4Port,0x0A,tempah);
-   	tempah = SiS_VBVCLKData[vclkindex].Part4_B;
-   	SiS_SetReg1(SiS_Part4Port,0x0B,tempah);
-	/* TW: New from 650/301LV BIOS */
-	if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) {
-           if(SiS_VBInfo & SetCRT2ToTV) {
-	      if(!(SiS_VBInfo & SetPALTV)) {
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
+     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
+     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
+     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
+     if(HwDeviceExtension->jChipType >= SIS_315H) {
+	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
                  if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
-		    SiS_SetReg1(SiS_Part4Port,0x0a,0x57);
-		    SiS_SetReg1(SiS_Part4Port,0x0b,0x46);
-		    SiS_SetReg1(SiS_Part4Port,0x1f,0xf6);
+		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0a,0x57);
+		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0b,0x46);
+		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
                  }
               }
            }
 	}
-  } else {
-   	SiS_SetReg1(SiS_Part4Port,0x0A,0x01);
-   	tempah = SiS_VBVCLKData[vclkindex].Part4_B;
-   	SiS_SetReg1(SiS_Part4Port,0x0B,tempah);
-   	tempah = SiS_VBVCLKData[vclkindex].Part4_A;
-   	SiS_SetReg1(SiS_Part4Port,0x0A,tempah);
+     }
+  } else {	
+     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,0x01);
+     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
+     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
+     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
+     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
   }
-  SiS_SetReg1(SiS_Part4Port,0x12,0x00);
+  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x12,0x00);
   tempah = 0x08;
-  if(SiS_VBInfo & SetCRT2ToRAMDAC) {
-    	tempah |= 0x020;
-  }
-  temp1 = SiS_GetReg1(SiS_Part4Port,0x12);
-  tempah |= temp1;
-  SiS_SetReg1(SiS_Part4Port,0x12,tempah);
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) tempah |= 0x20;
+  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,tempah);
 }
 
-/* TW: Double-checked against 650/LVDS (1.10.07), 630/301B/LVDS/LVDS+CH, 650/301LV BIOS */
 USHORT
-SiS_GetVCLK2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-        USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT tempbx;
+  const USHORT LCDXlat0VCLK[4]    = {VCLK40, VCLK40, VCLK40, VCLK40};
+  const USHORT LVDSXlat1VCLK[4]   = {VCLK40, VCLK40, VCLK40, VCLK40};
 #ifdef SIS300
-  USHORT LCDXlat1VCLK300[4] = {VCLK65,   VCLK65,   VCLK65,   VCLK65};
-  USHORT LCDXlat2VCLK300[4] = {VCLK108_2,VCLK108_2,VCLK108_2,VCLK108_2};
-  USHORT LVDSXlat2VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
-  USHORT LVDSXlat3VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
+  const USHORT LCDXlat1VCLK300[4] = {VCLK65,   VCLK65,   VCLK65,   VCLK65};
+  const USHORT LCDXlat2VCLK300[4] = {VCLK108_2,VCLK108_2,VCLK108_2,VCLK108_2};
+  const USHORT LVDSXlat2VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
+  const USHORT LVDSXlat3VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
 #endif
 #ifdef SIS315H
-  USHORT LCDXlat1VCLK310[4] = {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
-  USHORT LCDXlat2VCLK310[4] = {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
-  USHORT LVDSXlat2VCLK310[4]= {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
-  USHORT LVDSXlat3VCLK310[4]= {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
-  			   /* {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2}; -  650/LVDS 1.10.07 */
+  const USHORT LCDXlat1VCLK310[4] = {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
+  const USHORT LCDXlat2VCLK310[4] = {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
+  const USHORT LVDSXlat2VCLK310[4]= {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
+  const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
 #endif
-  USHORT LCDXlat0VCLK[4]    = {VCLK40, VCLK40, VCLK40, VCLK40};
-  USHORT LVDSXlat1VCLK[4]   = {VCLK40, VCLK40, VCLK40, VCLK40};
   USHORT CRT2Index,VCLKIndex=0;
   USHORT modeflag,resinfo;
-  UCHAR *CHTVVCLKPtr=NULL;
-  USHORT *LCDXlatVCLK1 = NULL;
-  USHORT *LCDXlatVCLK2 = NULL;
-  USHORT *LVDSXlatVCLK2 = NULL;
-  USHORT *LVDSXlatVCLK3 = NULL;
+  const UCHAR *CHTVVCLKPtr=NULL;
+  const USHORT *LCDXlatVCLK1 = NULL;
+  const USHORT *LCDXlatVCLK2 = NULL;
+  const USHORT *LVDSXlatVCLK2 = NULL;
+  const USHORT *LVDSXlatVCLK3 = NULL;
 
-#ifdef SIS315H
   if(HwDeviceExtension->jChipType >= SIS_315H) {
+#ifdef SIS315H
 		LCDXlatVCLK1 = LCDXlat1VCLK310;
 		LCDXlatVCLK2 = LCDXlat2VCLK310;
 		LVDSXlatVCLK2 = LVDSXlat2VCLK310;
 		LVDSXlatVCLK3 = LVDSXlat3VCLK310;
-  } else {
 #endif
+  } else {
 #ifdef SIS300
 		LCDXlatVCLK1 = LCDXlat1VCLK300;
 		LCDXlatVCLK2 = LCDXlat2VCLK300;
 		LVDSXlatVCLK2 = LVDSXlat2VCLK300;
 		LVDSXlatVCLK3 = LVDSXlat3VCLK300;
 #endif
-#ifdef SIS315H
   }
-#endif
 
-  if(ModeNo<=0x13) {
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	resinfo = SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-    	CRT2Index = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  if(ModeNo <= 0x13) {
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+    	CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   } else {
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	resinfo = SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-    	CRT2Index = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+    	CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   }
 
-  if(SiS_IF_DEF_LVDS==0) {    /* 301 */
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {    /* 30x/B/LV */
 
-     if (SiS_SetFlag & ProgrammingCRT2) {
+     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
 
         CRT2Index >>= 6;
-        if(SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)){      /*  LCD */
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)){      /*  LCD */
             if(HwDeviceExtension->jChipType < SIS_315H) {
-	       /* TW: Inserted from 630/301B BIOS */
-	       if(SiS_LCDResInfo == Panel800x600)
+	       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)
 	    		VCLKIndex = LCDXlat0VCLK[CRT2Index];
-	       else if(SiS_LCDResInfo == Panel1024x768)
+	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
+	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
+	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
+	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
+	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)
 	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
 	       else
 	    		VCLKIndex = LCDXlatVCLK2[CRT2Index];
 	    } else {
-               /* TW: 650/301LV BIOS does not check expanding, 315 does  */
+               /* TW: 330, 650/301LV BIOS does not check expanding, 315 does  */
 	       if( (HwDeviceExtension->jChipType > SIS_315PRO) ||
-	           (!(SiS_LCDInfo & LCDNonExpanding)) ) {
-      	          if(SiS_LCDResInfo == Panel1024x768){
+	           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
+      	          if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+		     VCLKIndex = 0x19;
+		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+		     VCLKIndex = 0x19;
+		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+		     VCLKIndex = 0x21;
+		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
 		     VCLKIndex = LCDXlatVCLK1[CRT2Index];
-                   } else if(SiS_LCDResInfo == Panel1280x960) {
-		     VCLKIndex = 0x45;
+                  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+		     VCLKIndex = 0x45;  /* TW: in VBVCLK table */
 		     if(resinfo == 0x09) VCLKIndex++;
-	           } else {
+	          } else {
 		     VCLKIndex = LCDXlatVCLK2[CRT2Index];
-      	           }
+      	          }
 	       } else {
-                   VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_P3ca+0x02));  /*  Port 3cch */
+                   VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));  /*  Port 3cch */
          	   VCLKIndex = ((VCLKIndex >> 2) & 0x03);
         	   if(ModeNo > 0x13) {
-          		VCLKIndex = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+          		VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
         	   }
-		   if(ModeNo <= 0x13) {  /* TW: Inserted from 315 BIOS */
-		      if(SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
+		   if(ModeNo <= 0x13) {  /* TW: 315 BIOS */
+		      if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
 		   }
 		   if(VCLKIndex == 0) VCLKIndex = 0x41;
 		   if(VCLKIndex == 1) VCLKIndex = 0x43;
 		   if(VCLKIndex == 4) VCLKIndex = 0x44;
 	       }
 	    }
-        } else if(SiS_VBInfo & SetCRT2ToTV) {                 /*  TV */
-        	if((SiS_IF_DEF_HiVision == 1) && (SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-          		if(SiS_SetFlag & RPLLDIV2XO)      VCLKIndex = HiTVVCLKDIV2;
-     			else                              VCLKIndex = HiTVVCLK;
-          		if(SiS_SetFlag & TVSimuMode) {
-            			if(modeflag & Charx8Dot)  VCLKIndex = HiTVSimuVCLK;
-            			else 			  VCLKIndex = HiTVTextVCLK;
+        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 /*  TV */
+        	if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) && 
+		    (!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) ) {
+          		if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO)  VCLKIndex = HiTVVCLKDIV2;
+     			else                                  VCLKIndex = HiTVVCLK;
+          		if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+            			if(modeflag & Charx8Dot)      VCLKIndex = HiTVSimuVCLK;
+            			else 			      VCLKIndex = HiTVTextVCLK;
           		}
         	} else {
-       			if(SiS_SetFlag & RPLLDIV2XO)      VCLKIndex = TVVCLKDIV2;
-            		else         		          VCLKIndex = TVVCLK;
+       			if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO)  VCLKIndex = TVVCLKDIV2;
+            		else         		              VCLKIndex = TVVCLK;
           	}
 		if(HwDeviceExtension->jChipType >= SIS_315H) {
               		VCLKIndex += 25;
   		}
         } else {         					/* RAMDAC2 */
-        	VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_P3ca+0x02));
+        	VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
         	VCLKIndex = ((VCLKIndex >> 2) & 0x03);
         	if(ModeNo > 0x13) {
-          		VCLKIndex = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; 
+          		VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
 			if(HwDeviceExtension->jChipType < SIS_315H) {
           			VCLKIndex &= 0x3f;
 				if( (HwDeviceExtension->jChipType == SIS_630) &&
@@ -6269,13 +8449,14 @@
 
     } else {   /* If not programming CRT2 */
 
-        VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_P3ca+0x02));
+        VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
         VCLKIndex = ((VCLKIndex >> 2) & 0x03);
         if(ModeNo > 0x13) {
-             VCLKIndex = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+             VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
 	     if(HwDeviceExtension->jChipType < SIS_315H) {
                 VCLKIndex &= 0x3f;
-		if(HwDeviceExtension->jChipType != SIS_630) {
+		if( (HwDeviceExtension->jChipType != SIS_630) &&
+		    (HwDeviceExtension->jChipType != SIS_300) ) {
 		   if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
 		}
 	     }
@@ -6286,492 +8467,306 @@
 
     	VCLKIndex = CRT2Index;
 
-	if(SiS_SetFlag & ProgrammingCRT2) {  /* programming CRT2 */
+	if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {  /* programming CRT2 */
 
-	   if( (SiS_IF_DEF_CH70xx != 0) && (SiS_VBInfo & SetCRT2ToTV) ) {
+	   if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
 
 		VCLKIndex &= 0x1f;
         	tempbx = 0;
-        	if(SiS_VBInfo & SetPALTV) tempbx += 2;
-        	if(SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+		if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+        	if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+			tempbx += 2;
+			if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
+			if(SiS_Pr->SiS_CHPALM) {
+				tempbx = 4;
+				if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+			} else if(SiS_Pr->SiS_CHPALN) {
+				tempbx = 6;
+				if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+			}
+		}
        		switch(tempbx) {
-          	   case 0: CHTVVCLKPtr = SiS_CHTVVCLKUNTSC;  break;
-         	   case 1: CHTVVCLKPtr = SiS_CHTVVCLKONTSC;  break;
-                   case 2: CHTVVCLKPtr = SiS_CHTVVCLKUPAL;   break;
-                   case 3: CHTVVCLKPtr = SiS_CHTVVCLKOPAL;   break;
+          	   case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
+         	   case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
+                   case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
+                   case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
+		   case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
+         	   case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
+                   case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
+                   case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
+		   case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
+		   default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
         	}
         	VCLKIndex = CHTVVCLKPtr[VCLKIndex];
 
-	   } else if(SiS_VBInfo & SetCRT2ToLCD) {
+	   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
 
 	        VCLKIndex >>= 6;
-     		if((SiS_LCDResInfo==Panel800x600) || (SiS_LCDResInfo==Panel320x480))
+     		if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
+		   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480))
      			VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
-     		else if(SiS_LCDResInfo==Panel1024x768)
+     		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
      			VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
-     		else 	VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
+		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
+                        VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
+		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)
+                        VCLKIndex = LVDSXlatVCLK2[VCLKIndex];			
+     		else    VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
 
 	   } else {
 
-	        VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_P3ca+0x02));
+	        VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
                 VCLKIndex = ((VCLKIndex >> 2) & 0x03);
                 if(ModeNo > 0x13) {
-                     VCLKIndex = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+                     VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+		     if(HwDeviceExtension->jChipType < SIS_315H) {
+    		        VCLKIndex &= 0x3F;
+                     }
 		     if( (HwDeviceExtension->jChipType == SIS_630) &&
                          (HwDeviceExtension->jChipRevision >= 0x30) ) {
 		         	if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
 		     }
 	        }
-
 	   }
 
 	} else {  /* if not programming CRT2 */
 
-	   VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_P3ca+0x02));
+	   VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
            VCLKIndex = ((VCLKIndex >> 2) & 0x03);
            if(ModeNo > 0x13) {
-              VCLKIndex = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+              VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
               if(HwDeviceExtension->jChipType < SIS_315H) {
-	         if(HwDeviceExtension->jChipType != SIS_630) {
+	         VCLKIndex &= 0x3F;
+	         if( (HwDeviceExtension->jChipType != SIS_630) &&
+		     (HwDeviceExtension->jChipType != SIS_300) ) {
 		        if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
 	         }
+#if 0		 
+		 if(HwDeviceExtension->jChipType == SIS_730) {
+		    if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
+		    if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */ 
+		 }
+#endif		 
 	      }
 	   }
 
 	}
 
   }
-
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-    	VCLKIndex &= 0x3F;
-  }
+#ifdef TWDEBUG
+  xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
+#endif
   return (VCLKIndex);
 }
 
 /* TW: Set 301 Palette address port registers */
 /* TW: Checked against 650/301LV BIOS */
 void
-SiS_SetGroup5(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-              USHORT ModeIdIndex)
+SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
+              UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
 {
 
-  if((SiS_VBType & VB_SIS301BLV302BLV) && (SiS_VBInfo & SetCRT2ToLCDA))
-      return;
-
-  if(SiS_ModeType == ModeVGA){
-    if(!(SiS_VBInfo & (SetInSlaveMode|LoadDACFlag))){
-      SiS_EnableCRT2();
-      SiS_LoadDAC2(ROMAddr,SiS_Part5Port,ModeNo,ModeIdIndex);
-    }
-  }
-  return;
-}
-
-/* TW: Checked against 650/301LV BIOS */
-void
-SiS_LoadDAC2(UCHAR *ROMAddr,USHORT SiS_Part5Port,
-             USHORT ModeNo,USHORT ModeIdIndex)
-{
-   USHORT data,data2;
-   USHORT time,i,j,k;
-   USHORT m,n,o;
-   USHORT si,di,bx,dl;
-   USHORT al,ah,dh;
-   USHORT *table=0;
-   USHORT Pindex,Pdata,modeflag;
-
-/* if(SiS_SetFlag & SetDispDevSwitchFlag) return;  - TW: Not needed */
-
-   if(ModeNo <= 0x13)
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
-   else
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
-
-#if 0
-   if(!(ds:489 & 0x08)) {
-#endif
-
-	Pindex = SiS_Part5Port;
-	Pdata = SiS_Part5Port + 1;
-	data = modeflag & DACInfoFlag;
-	time = 64;
-	if(data == 0x00) table = SiS_MDA_DAC;
-	if(data == 0x08) table = SiS_CGA_DAC;
-	if(data == 0x10) table = SiS_EGA_DAC;
-	if(data == 0x18) {
-	   time = 256;
-	   table = SiS_VGA_DAC;
-	}
-
-	if(time == 256) j = 16;
-	else j = time;
-
-	SiS_SetReg3(Pindex,0x00);
-
-	for(i=0; i<j; i++) {
-	   data = table[i];
-	   for(k=0; k<3; k++) {
-		data2 = 0;
-		if(data & 0x01) data2 = 0x2A;
-		if(data & 0x02) data2 += 0x15;
-		data2 <<= 2;   			/* TW: New from 650/301LV BIOS */
-		SiS_SetReg3(Pdata,data2);
-		data >>= 2;
-	   }
-	}
-
-	if(time == 256) {
-	   for(i=16;i<32;i++) {
-		data = table[i];
-		data <<= 2;   			/* TW: New from 650/301LV BIOS */
-		for(k=0; k<3; k++) SiS_SetReg3(Pdata,data);
-	   }
-           si = 32;
-           for(m=0; m<9; m++) {
-             di = si;
-             bx = si + 0x04;
-             dl = 0;
-             for(n=0; n<3; n++) {
-                for(o=0; o<5; o++) {
-                  dh = table[si];
-                  ah = table[di];
-                  al = table[bx];
-                  si++;
-                  SiS_WriteDAC2(Pdata,dl,ah,al,dh);
-                }         /* for 5 */
-                si = si - 2;
-                for(o=0; o<3; o++) {
-                  dh = table[bx];
-                  ah = table[di];
-                  al = table[si];
-                  si--;
-                  SiS_WriteDAC2(Pdata,dl,ah,al,dh);
-                }         /* for 3 */
-                dl++;
-             }            /* for 3 */
-             si = si + 5;
-           }               /* for 9 */
-        }
-#if 0
-    } /* ds:489 & 0x08 */
-#endif
-}
-
-/* TW: Checked against 650/301LV BIOS */
-void
-SiS_WriteDAC2(USHORT Pdata, USHORT dl, USHORT ah, USHORT al, USHORT dh)
-{
-  USHORT temp;
-  USHORT bh,bl;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
 
-  bh = ah;
-  bl = al;
-  if(dl != 0) {
-    temp = bh;
-    bh = dh;
-    dh = temp;
-    if(dl == 1) {
-       temp = bl;
-       bl = dh;
-       dh = temp;
-    } else {
-       temp = bl;
-       bl = bh;
-       bh = temp;
-    }
+  if(SiS_Pr->SiS_ModeType == ModeVGA){
+     if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))){
+        SiS_EnableCRT2(SiS_Pr);
+        SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
+     }
   }
-  dh <<= 2;   				/* TW: New from 650/301LV BIOS */
-  bh <<= 2;   				/* TW: New from 650/301LV BIOS */
-  bl <<= 2;   				/* TW: New from 650/301LV BIOS */
-  SiS_SetReg3(Pdata,(USHORT)dh);
-  SiS_SetReg3(Pdata,(USHORT)bh);
-  SiS_SetReg3(Pdata,(USHORT)bl);
 }
 
-/* TW: Checked against 650/LVDS and 630/301B BIOS */
 void
-SiS_ModCRT1CRTC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT temp,tempah,i,modeflag,j;
   USHORT ResInfo,DisplayType;
-  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
+  const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
 
   if(ModeNo <= 0x13) {
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   } else {
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
-  temp = SiS_GetLVDSCRT1Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+  temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                             &ResInfo,&DisplayType);
 
   if(temp == 0) return;
 
-  /* TW: Inserted from 630/LVDS BIOS */
   if(HwDeviceExtension->jChipType < SIS_315H) {
-     if(SiS_SetFlag & CRT2IsVGA) return;
+     if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
   }
 
   switch(DisplayType) {
-    case 0 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;           break;
-    case 1 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;          break;
-    case 2 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;         break;
-    case 3 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;         break;
-    case 4 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;        break;
-    case 5 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;       break;
-    case 6 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;           break;
-    case 7 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;          break;
-    case 8 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;         break;
-    case 9 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;         break;
-    case 10: LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;        break;
-    case 11: LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;       break;
-    case 12: LVDSCRT1Ptr = SiS_LVDSCRT1XXXxXXX_1;           break;
-    case 13: LVDSCRT1Ptr = SiS_LVDSCRT1XXXxXXX_1_H;         break;
-    case 14: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_1;         break;
-    case 15: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_1_H;       break;
-    case 16: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_2;         break;
-    case 17: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_2_H;       break;
-    case 18: LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;               break;
-    case 19: LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;               break;
-    case 20: LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;                break;
-    case 21: LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;                break;
-    case 22: LVDSCRT1Ptr = SiS_LVDSCRT1320x480_1;           break; /* FSTN */
-    case 23: LVDSCRT1Ptr = SiS_LVDSCRT11024x600_1;          break;
-    case 24: LVDSCRT1Ptr = SiS_LVDSCRT11024x600_1_H;        break;
-    case 25: LVDSCRT1Ptr = SiS_LVDSCRT11024x600_2;          break;
-    case 26: LVDSCRT1Ptr = SiS_LVDSCRT11024x600_2_H;        break;
-    case 27: LVDSCRT1Ptr = SiS_LVDSCRT11152x768_1;          break;
-    case 28: LVDSCRT1Ptr = SiS_LVDSCRT11152x768_1_H;        break;
-    case 29: LVDSCRT1Ptr = SiS_LVDSCRT11152x768_2;          break;
-    case 30: LVDSCRT1Ptr = SiS_LVDSCRT11152x768_2_H;        break;
+    case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1;           break;
+    case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
+    case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1;         break;
+    case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H;         break;
+    case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H;        break;
+    case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H;       break;
+    case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2;           break;
+    case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2;          break;
+    case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2;         break;
+    case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H;         break;
+    case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H;        break;
+    case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H;       break;
+    case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1;           break;
+    case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H;         break;
+    case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1;         break;
+    case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H;       break;
+    case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2;         break;
+    case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H;       break;
+    case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
+    case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
+    case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
+    case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
+    case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1;           break; /* FSTN */
+    case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
+    case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
+    case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
+    case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
+    case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1;          break;
+    case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H;        break;
+    case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2;          break;
+    case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H;        break;
+    case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1;         break;
+    case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H;       break;
+    case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2;         break;
+    case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H;       break;
+    case 40: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1;          break;
+    case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H;        break;
+    case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2;          break;
+    case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H;        break;
+    case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
+    default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
   }
 
-  SiS_SetRegAND(SiS_P3d4,0x11,0x7f);                        /*unlock cr0-7  */
+  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                        /*unlock cr0-7  */
 
   tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
-  SiS_SetReg1(SiS_P3d4,0x00,tempah);
+  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
 
   for(i=0x02,j=1;i<=0x05;i++,j++){
     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_P3d4,i,tempah);
+    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x06,j=5;i<=0x07;i++,j++){
     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_P3d4,i,tempah);
+    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x10,j=7;i<=0x11;i++,j++){
     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_P3d4,i,tempah);
+    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x15,j=9;i<=0x16;i++,j++){
     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_P3d4,i,tempah);
+    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x0A,j=11;i<=0x0C;i++,j++){
     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_P3c4,i,tempah);
+    SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
   }
 
   tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
   tempah &= 0xE0;
-  SiS_SetRegANDOR(SiS_P3c4,0x0E,0x1f,tempah);     	/* TW: Modfied (650/LVDS); Was SetReg(tempah) */
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);     
 
   tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
   tempah &= 0x01;
   tempah <<= 5;
-  if(modeflag & DoubleScanMode){
-    	tempah |= 0x080;
-  }
-  SiS_SetRegANDOR(SiS_P3d4,0x09,~0x020,tempah);
+  if(modeflag & DoubleScanMode)  tempah |= 0x080;
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
 
-  /* TW: Inserted from 650/LVDS BIOS */
-  if(SiS_VBInfo & SetCRT2ToTV) {
+  /* TW: 650/LVDS BIOS - doesn't make sense */
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
      if(modeflag & HalfDCLK)
-        SiS_SetRegAND(SiS_P3d4,0x11,0x7f);
+        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
   }
-
-  return;
 }
 
-#if 0 /* TW: Unused */
-/*301b*/
-void
-SiS_CHACRT1CRTC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                USHORT RefreshRateTableIndex)
-{
-  USHORT temp,tempah,i,modeflag,j;
-  USHORT ResInfo,DisplayType;
-  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
-
-  if(ModeNo<=0x13) {
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
-  } else {
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
-  }
-
-  temp=SiS_GetLVDSCRT1Ptr(ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                       &ResInfo,&DisplayType);
-  if(temp==0){
-    return;
-  }
-
-  switch(DisplayType) {
-    case 0 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1;           break;
-    case 1 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1;          break;
-    case 2 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1;         break;
-    case 3 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_1_H;         break;
-    case 4 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_1_H;        break;
-    case 5 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_1_H;       break;
-    case 6 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2;           break;
-    case 7 : LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2;          break;
-    case 8 : LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2;         break;
-    case 9 : LVDSCRT1Ptr = SiS_LVDSCRT1800x600_2_H;         break;
-    case 10: LVDSCRT1Ptr = SiS_LVDSCRT11024x768_2_H;        break;
-    case 11: LVDSCRT1Ptr = SiS_LVDSCRT11280x1024_2_H;       break;
-    case 12: LVDSCRT1Ptr = SiS_LVDSCRT1XXXxXXX_1;           break;
-    case 13: LVDSCRT1Ptr = SiS_LVDSCRT1XXXxXXX_1_H;         break;
-    case 14: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_1;         break;
-    case 15: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_1_H;       break;
-    case 16: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_2;         break;
-    case 17: LVDSCRT1Ptr = SiS_LVDSCRT11400x1050_2_H;       break;
-    case 18: LVDSCRT1Ptr = SiS_CHTVCRT1UNTSC;               break;
-    case 19: LVDSCRT1Ptr = SiS_CHTVCRT1ONTSC;               break;
-    case 20: LVDSCRT1Ptr = SiS_CHTVCRT1UPAL;                break;
-    case 21: LVDSCRT1Ptr = SiS_CHTVCRT1OPAL;                break;
-    case 22: LVDSCRT1Ptr = SiS_LVDSCRT1320x480_1;           break; /* FSTN */
-  }
-
-  tempah=(UCHAR)SiS_GetReg1(SiS_P3d4,0x11);                        /*unlock cr0-7  */
-  tempah=tempah&0x7F;
-  SiS_SetReg1(SiS_P3d4,0x11,tempah);
-  tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
-  SiS_SetReg1(SiS_P3d4,0x0,tempah);
-  for(i=0x02,j=1;i<=0x05;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_P3d4,i,tempah);
-  }
-  for(i=0x06,j=5;i<=0x07;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_P3d4,i,tempah);
-  }
-  for(i=0x10,j=7;i<=0x11;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_P3d4,i,tempah);
-  }
-  for(i=0x15,j=9;i<=0x16;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_P3d4,i,tempah);
-  }
-
-  for(i=0x0A,j=11;i<=0x0C;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_P3c4,i,tempah);
-  }
-
-  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
-  tempah=tempah&0x0E0;
-  SiS_SetReg1(SiS_P3c4,0x0E,tempah);
-
-  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
-  tempah=tempah&0x01;
-  tempah=tempah<<5;
-  if(modeflag&DoubleScanMode){
-    	tempah=tempah|0x080;
-  }
-  SiS_SetRegANDOR(SiS_P3d4,0x09,~0x020,tempah);
-  return;
-}
-/*add for LCDA*/
-#endif
-
 BOOLEAN
-SiS_GetLCDACRT1Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
-		   USHORT *DisplayType)
- {
-  USHORT tempbx=0,modeflag=0;
-  USHORT CRT2CRTC=0;
-
-  if(ModeNo<=0x13) {
-  	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  	CRT2CRTC = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  } else {
-  	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-  	CRT2CRTC = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-  }
-
-  tempbx = SiS_LCDResInfo - PanelMinLVDS;
-
-  if(SiS_LCDInfo & LCDNonExpanding) tempbx += 6;
-
-  if(modeflag & HalfDCLK) tempbx += 3;
-
-  *ResInfo = CRT2CRTC & 0x3F;
-  *DisplayType = tempbx;
-
-  return 1;
-}
-
-/* TW: Checked against 650/LVDS BIOS: modified for new panel resolutions */
-BOOLEAN
-SiS_GetLVDSCRT1Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
 		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
 		   USHORT *DisplayType)
  {
   USHORT tempbx,modeflag=0;
   USHORT Flag,CRT2CRTC;
 
-  if(!(SiS_VBInfo & SetCRT2ToLCDA)) {                    /* TW: Inserted from 650/LVDS BIOS */
-      if(!(SiS_VBInfo & SetInSlaveMode)) return 0;
-  }							 /* TW: Inserted from 650/LVDS BIOS */
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return 0;
+     }
+  } else {
+     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return 0;
+  }
 
   if(ModeNo <= 0x13) {
-    	modeflag = SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	CRT2CRTC = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+    	CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   } else {
-    	modeflag = SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	CRT2CRTC = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   }
 
   Flag = 1;
   tempbx = 0;
-  if(SiS_IF_DEF_CH70xx != 0) {
-    if(!(SiS_VBInfo & SetCRT2ToLCD)) {
-      Flag = 0;
-      tempbx = 18;
-      if(SiS_VBInfo & SetPALTV) tempbx += 2;
-      if(SiS_VBInfo & SetCHTVOverScan) tempbx++;
-    }
+  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+        Flag = 0;
+        tempbx = 18;
+        if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
+        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+      	   tempbx += 2;
+	   if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
+	   if(SiS_Pr->SiS_CHPALM) {
+	      tempbx = 18;  /* PALM uses NTSC data */
+	      if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
+	   } else if(SiS_Pr->SiS_CHPALN) {
+	      tempbx = 20;  /* PALN uses PAL data  */
+	      if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
+	   }
+        }
+     }
   }
   if(Flag) {
-    tempbx = SiS_LCDResInfo;
-    tempbx -= PanelMinLVDS;
-    if(SiS_LCDResInfo <= Panel1280x1024) {
-       if(SiS_LCDInfo & LCDNonExpanding) tempbx += 6;
-       if(modeflag & HalfDCLK) tempbx += 3;
-    } else {
-       if(SiS_LCDResInfo == Panel1400x1050) {
+     tempbx = SiS_Pr->SiS_LCDResInfo;
+     tempbx -= SiS_Pr->SiS_PanelMinLVDS;
+     if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
+        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 6;
+        if(modeflag & HalfDCLK) tempbx += 3;
+     } else {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
            tempbx = 14;
-	   if(SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
-	   if(modeflag & HalfDCLK) tempbx++;
-       } else if(SiS_LCDInfo & 0x0100) {
-           tempbx = 12;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
 	   if(modeflag & HalfDCLK) tempbx++;
-       } else if(SiS_LCDResInfo == Panel1024x600) {
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
            tempbx = 23;
-	   if(SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
 	   if(modeflag & HalfDCLK) tempbx++;
-       } else if(SiS_LCDResInfo == Panel1152x768) {
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
            tempbx = 27;
-	   if(SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
 	   if(modeflag & HalfDCLK) tempbx++;
-       }
-    }
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+           tempbx = 36;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
+	   if(modeflag & HalfDCLK) tempbx++;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+           tempbx = 40;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
+	   if(modeflag & HalfDCLK) tempbx++;
+        }
+     }
+     if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+        tempbx = 12;
+	if(modeflag & HalfDCLK) tempbx++;
+     }
   }
-  if(SiS_IF_DEF_FSTN){
-     if(SiS_LCDResInfo==Panel320x480){
-       tempbx=22;
+  if(SiS_Pr->SiS_IF_DEF_FSTN){
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
+        tempbx = 22;
      }
   }
   *ResInfo = CRT2CRTC & 0x3F;
@@ -6779,79 +8774,72 @@
   return 1;
 }
 
-/* TW: Checked against 650/LVDS (1.10a, 1.10.07), 630/301B (I/II) and 630/LVDS BIOS */
 void
-SiS_SetCRT2ECLK(UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
            USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
   USHORT tempah,tempal,pushax;
   USHORT vclkindex=0;
-
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-     if(SiS_VBType & VB_SIS301BLV302BLV) {
-        if(!(SiS_VBInfo & SetCRT2ToLCD)) return;
-     }
-  }
-
-  if((SiS_LCDResInfo == Panel640x480) || (SiS_IF_DEF_TRUMPION == 1)) {
-	SiS_SetFlag &= (~ProgrammingCRT2);
-        tempal = SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+    
+  if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) {
+	SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+        tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
     	tempal &= 0x3F;
 	if(tempal == 2) RefreshRateTableIndex--;
-	vclkindex = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,
+	vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
                                RefreshRateTableIndex,HwDeviceExtension);
-	SiS_SetFlag |= ProgrammingCRT2;
+	SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
   } else {
-        vclkindex = SiS_GetVCLK2Ptr(ROMAddr,ModeNo,ModeIdIndex,
+        vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
                                RefreshRateTableIndex,HwDeviceExtension);
   }
-
+  
   tempal = 0x02B;
-  if(!(SiS_VBInfo & SetCRT2ToLCDA)) {
-     if(!(SiS_VBInfo & SetInSlaveMode)) {
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
     	tempal += 3;
      }
   }
-  SiS_SetReg1(SiS_P3c4,0x05,0x86);
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
   pushax = tempal;
-  SiS_SetReg1(SiS_P3c4,0x31,0x20);
-  tempah = SiS_VCLKData[vclkindex].SR2B;
-  SiS_SetReg1(SiS_P3c4,tempal,tempah);
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
+  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
   tempal++;
-  tempah = SiS_VCLKData[vclkindex].SR2C;
-  SiS_SetReg1(SiS_P3c4,tempal,tempah);
-  SiS_SetReg1(SiS_P3c4,0x31,0x10);
+  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
   tempal = pushax;
-  tempah = SiS_VCLKData[vclkindex].SR2B;
-  SiS_SetReg1(SiS_P3c4,tempal,tempah);
+  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
   tempal++;
-  tempah = SiS_VCLKData[vclkindex].SR2C;
-  SiS_SetReg1(SiS_P3c4,tempal,tempah);
-  SiS_SetReg1(SiS_P3c4,0x31,0x00);
+  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
   tempal = pushax;
-  tempah = SiS_VCLKData[vclkindex].SR2B;
-  SiS_SetReg1(SiS_P3c4,tempal,tempah);
+  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
   tempal++;
-  tempah = SiS_VCLKData[vclkindex].SR2C;
-  SiS_SetReg1(SiS_P3c4,tempal,tempah);
+  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
   return;
 }
 
 #if 0  /* TW: Not used */
 void
-SiS_SetDefCRT2ExtRegs(USHORT BaseAddr)
+SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_Pr, USHORT BaseAddr)
 {
   USHORT  temp;
 
-  if(SiS_IF_DEF_LVDS==0) {
-    SiS_SetReg1(SiS_Part1Port,0x02,0x40);
-    SiS_SetReg1(SiS_Part4Port,0x10,0x80);
-    temp=(UCHAR)SiS_GetReg1(SiS_P3c4,0x16);
+  if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
+    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,0x40);
+    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x10,0x80);
+    temp=(UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
     temp &= 0xC3;
-    SiS_SetReg1(SiS_P3d4,0x35,temp);
+    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,temp);
   } else {
-    SiS_SetReg1(SiS_P3d4,0x32,0x02);
-    SiS_SetReg1(SiS_Part1Port,0x02,0x00);
+    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x32,0x02);
+    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,0x00);
   }
 }
 #endif
@@ -6860,66 +8848,84 @@
 
 /* Set-up the Chrontel Registers */
 void
-SiS_SetCHTVReg(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                USHORT RefreshRateTableIndex)
 {
-  USHORT temp,tempbx,tempcl;
-  USHORT TVType,resindex;
-  SiS_CHTVRegDataStruct *CHTVRegData=NULL;
+  USHORT temp, tempbx, tempcl;
+  USHORT TVType, resindex;
+  const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
 
-  if(ModeNo<=0x13)
-    	tempcl = SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  if(ModeNo <= 0x13)
+    	tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   else
-    	tempcl = SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+    	tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 
   TVType = 0;
-  if(SiS_VBInfo & SetPALTV) TVType += 2;
-  if(SiS_VBInfo & SetCHTVOverScan) TVType += 1;
+  if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1;
+  if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+  	TVType += 2;
+	if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
+	if(SiS_Pr->SiS_CHPALM) {
+		TVType = 4;
+		if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1;
+	} else if(SiS_Pr->SiS_CHPALN) {
+		TVType = 6;
+		if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1;
+	}
+  }
   switch(TVType) {
-    	case 0: CHTVRegData = SiS_CHTVReg_UNTSC; break;
-    	case 1: CHTVRegData = SiS_CHTVReg_ONTSC; break;
-    	case 2: CHTVRegData = SiS_CHTVReg_UPAL;  break;
-    	case 3: CHTVRegData = SiS_CHTVReg_OPAL;  break;
+    	case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
+    	case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
+    	case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
+    	case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
+	case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
+    	case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
+    	case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
+    	case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
+	case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
+	default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
   }
   resindex = tempcl & 0x3F;
 
-  if(SiS_IF_DEF_CH70xx == 1) {
+  if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
 
-     /* Chrontel 7005 */
+#ifdef SIS300
+  
+     /* Chrontel 7005 - I assume that it does not come with a 310/325 series chip */
 
      /* TW: We don't support modes >800x600 */
      if (resindex > 5) return;
 
-     if(SiS_VBInfo & SetPALTV) {
-    	SiS_SetCH700x(0x4304);  /* TW: 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
-    	SiS_SetCH700x(0x6909);	/* TW: Black level for PAL (105)*/
+     if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+    	SiS_SetCH700x(SiS_Pr,0x4304);   /* TW: 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
+    	SiS_SetCH700x(SiS_Pr,0x6909);	/* TW: Black level for PAL (105)*/
      } else {
-    	SiS_SetCH700x(0x0304);  /* TW: upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
-    	SiS_SetCH700x(0x7109);	/* TW: Black level for NTSC (113)*/
+    	SiS_SetCH700x(SiS_Pr,0x0304);   /* TW: upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
+    	SiS_SetCH700x(SiS_Pr,0x7109);	/* TW: Black level for NTSC (113)*/
      }
 
      temp = CHTVRegData[resindex].Reg[0];
      tempbx=((temp&0x00FF)<<8)|0x00;	/* TW: Mode register */
-     SiS_SetCH700x(tempbx);
+     SiS_SetCH700x(SiS_Pr,tempbx);
      temp = CHTVRegData[resindex].Reg[1];
      tempbx=((temp&0x00FF)<<8)|0x07;	/* TW: Start active video register */
-     SiS_SetCH700x(tempbx);
+     SiS_SetCH700x(SiS_Pr,tempbx);
      temp = CHTVRegData[resindex].Reg[2];
      tempbx=((temp&0x00FF)<<8)|0x08;	/* TW: Position overflow register */
-     SiS_SetCH700x(tempbx);
+     SiS_SetCH700x(SiS_Pr,tempbx);
      temp = CHTVRegData[resindex].Reg[3];
      tempbx=((temp&0x00FF)<<8)|0x0A;	/* TW: Horiz Position register */
-     SiS_SetCH700x(tempbx);
+     SiS_SetCH700x(SiS_Pr,tempbx);
      temp = CHTVRegData[resindex].Reg[4];
      tempbx=((temp&0x00FF)<<8)|0x0B;	/* TW: Vertical Position register */
-     SiS_SetCH700x(tempbx);
+     SiS_SetCH700x(SiS_Pr,tempbx);
 
      /* TW: Set minimum flicker filter for Luma channel (SR1-0=00),
                 minimum text enhancement (S3-2=10),
    	        maximum flicker filter for Chroma channel (S5-4=10)
 	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
       */
-     SiS_SetCH700x(0x2801);
+     SiS_SetCH700x(SiS_Pr,0x2801);
 
      /* TW: Set video bandwidth
             High bandwith Luma composite video filter(S0=1)
@@ -6928,475 +8934,673 @@
 	    high bandwidth Chroma Filter (S5-4=11)
 	    =00110001=0x31
      */
-     SiS_SetCH700x(0xb103);       /* old: 3103 */
+     SiS_SetCH700x(SiS_Pr,0xb103);       /* old: 3103 */
 
      /* TW: Register 0x3D does not exist in non-macrovision register map
             (Maybe this is a macrovision register?)
       */
-     /* SiS_SetCH70xx(0x003D); */
+     /* SiS_SetCH70xx(SiS_Pr,0x003D); */
 
      /* TW: Register 0x10 only contains 1 writable bit (S0) for sensing,
             all other bits a read-only. Macrovision?
       */
-     SiS_SetCH70xxANDOR(0x0010,0x1F);
+     SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
 
      /* TW: Register 0x11 only contains 3 writable bits (S0-S2) for
-            contrast enhancement (set to 010 -> gain 2 Yout = 9/8*(Yin-57) )
+            contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
       */
-     SiS_SetCH70xxANDOR(0x0211,0xF8);
+     SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
 
      /* TW: Clear DSEN
       */
-     SiS_SetCH70xxANDOR(0x001C,0xEF);
+     SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
 
-     if(!(SiS_VBInfo&SetPALTV)) {		/* ---- NTSC ---- */
-       tempcl=tempcl&0x3F;
-       if(SiS_VBInfo&SetCHTVOverScan) {
-         if(tempcl==0x04) {   			/* 640x480 overscan: Mode 16 */
-      	   SiS_SetCH70xxANDOR(0x0020,0xEF);   	/* loop filter off */
-           SiS_SetCH70xxANDOR(0x0121,0xFE);       /* ACIV on, no need to set FSCI */
+     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {		/* ---- NTSC ---- */
+       if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) {
+         if(resindex == 0x04) {   			/* 640x480 overscan: Mode 16 */
+      	   SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);   	/* loop filter off */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on, no need to set FSCI */
          } else {
-           if(tempcl==0x05) {    			/* 800x600 overscan: Mode 23 */
-             SiS_SetCH70xxANDOR(0x0118,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
-             SiS_SetCH70xxANDOR(0x0C19,0xF0);
-             SiS_SetCH70xxANDOR(0x001A,0xF0);
-             SiS_SetCH70xxANDOR(0x001B,0xF0);
-             SiS_SetCH70xxANDOR(0x001C,0xF0);
-             SiS_SetCH70xxANDOR(0x001D,0xF0);
-             SiS_SetCH70xxANDOR(0x001E,0xF0);
-             SiS_SetCH70xxANDOR(0x001F,0xF0);
-             SiS_SetCH70xxANDOR(0x1020,0xEF);     /* Loop filter on for mode 23 */
-             SiS_SetCH70xxANDOR(0x0021,0xFE);     /* ACIV off, need to set FSCI */
+           if(resindex == 0x05) {    			/* 800x600 overscan: Mode 23 */
+             SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
+             SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
+             SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
+             SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
+             SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
+             SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
+             SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
+             SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
+             SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF);     /* Loop filter on for mode 23 */
+             SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);     /* ACIV off, need to set FSCI */
            }
          }
        } else {
-         if(tempcl==0x04) {     			/* ----- 640x480 underscan; Mode 17 */
-           SiS_SetCH70xxANDOR(0x0020,0xEF); 	/* loop filter off */
-           SiS_SetCH70xxANDOR(0x0121,0xFE);
+         if(resindex == 0x04) {     			 /* ----- 640x480 underscan; Mode 17 */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	 /* loop filter off */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
          } else {
-           if(tempcl==0x05) {   			/* ----- 800x600 underscan: Mode 24 */
-             SiS_SetCH70xxANDOR(0x0118,0xF0);   /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
-             SiS_SetCH70xxANDOR(0x0919,0xF0);	/* FSCI for mode 24 is 428,554,851 */
-             SiS_SetCH70xxANDOR(0x081A,0xF0);
-             SiS_SetCH70xxANDOR(0x0b1B,0xF0);
-             SiS_SetCH70xxANDOR(0x031C,0xF0);
-             SiS_SetCH70xxANDOR(0x0a1D,0xF0);
-             SiS_SetCH70xxANDOR(0x061E,0xF0);
-             SiS_SetCH70xxANDOR(0x031F,0xF0);
-             SiS_SetCH70xxANDOR(0x0020,0xEF);   /* loop filter off for mode 24 */
-             SiS_SetCH70xxANDOR(0x0021,0xFE);	/* ACIV off, need to set FSCI */
+           if(resindex == 0x05) {   			 /* ----- 800x600 underscan: Mode 24 */
+             SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);     /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
+             SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0);	 /* FSCI for mode 24 is 428,554,851 */
+             SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0);
+             SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
+             SiS_SetCH70xxANDOR(SiS_Pr,0x031C,0xF0);
+             SiS_SetCH70xxANDOR(SiS_Pr,0x0a1D,0xF0);
+             SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
+             SiS_SetCH70xxANDOR(SiS_Pr,0x031F,0xF0);
+             SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);     /* loop filter off for mode 24 */
+             SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);	 /* ACIV off, need to set FSCI */
            }
          }
        }
      } else {				/* ---- PAL ---- */
            /* TW: We don't play around with FSCI in PAL mode */
-         if (tempcl==0x04) {
-           SiS_SetCH70xxANDOR(0x0020,0xEF); 	/* loop filter off */
-           SiS_SetCH70xxANDOR(0x0121,0xFE);     /* ACIV on */
+         if (resindex == 0x04) {
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	/* loop filter off */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
          } else {
-           SiS_SetCH70xxANDOR(0x0020,0xEF); 	/* loop filter off */
-           SiS_SetCH70xxANDOR(0x0121,0xFE);     /* ACIV on */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	/* loop filter off */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
          }
      }
+     
+#endif  /* 300 */
 
   } else {
 
-     /* Chrontel 7019 */
+     /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
+
+#ifdef SIS315H
 
      /* TW: We don't support modes >1024x768 */
      if (resindex > 6) return;
 
      temp = CHTVRegData[resindex].Reg[0];
      tempbx=((temp & 0x00FF) <<8 ) | 0x00;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[1];
      tempbx=((temp & 0x00FF) <<8 ) | 0x01;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[2];
      tempbx=((temp & 0x00FF) <<8 ) | 0x02;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[3];
      tempbx=((temp & 0x00FF) <<8 ) | 0x04;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[4];
      tempbx=((temp & 0x00FF) <<8 ) | 0x03;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[5];
      tempbx=((temp & 0x00FF) <<8 ) | 0x05;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[6];
      tempbx=((temp & 0x00FF) <<8 ) | 0x06;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[7];
      tempbx=((temp & 0x00FF) <<8 ) | 0x07;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[8];
      tempbx=((temp & 0x00FF) <<8 ) | 0x08;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[9];
      tempbx=((temp & 0x00FF) <<8 ) | 0x15;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[10];
      tempbx=((temp & 0x00FF) <<8 ) | 0x1f;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[11];
      tempbx=((temp & 0x00FF) <<8 ) | 0x0c;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[12];
      tempbx=((temp & 0x00FF) <<8 ) | 0x0d;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[13];
      tempbx=((temp & 0x00FF) <<8 ) | 0x0e;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[14];
      tempbx=((temp & 0x00FF) <<8 ) | 0x0f;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
 
      temp = CHTVRegData[resindex].Reg[15];
      tempbx=((temp & 0x00FF) <<8 ) | 0x10;
-     SiS_SetCH701x(tempbx);
+     SiS_SetCH701x(SiS_Pr,tempbx);
+     
+#endif	/* 315 */
 
-#if 0  /* TW: Not done in BIOS 1.10.07 */
-     SiS_SetCH701x(0x3848);
-     SiS_DDC2Delay(SiS_I2CDELAYSHORT * 2);
-     SiS_SetCH701x(0x1848);
-#endif
   }
 }
 
+/* TW: Chrontel 701x functions ================================= */
+
 void
-SiS_SetCHTVForLCD(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr)
 {
+#ifndef NEWCH701x
+  USHORT temp;
+#endif  
+
+  /* TW: Enable Chrontel 7019 LCD panel backlight */
+  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+#ifdef NEWCH701x
+        SiS_SetCH701x(SiS_Pr,0x6566);
+#else  
+        temp = SiS_GetCH701x(SiS_Pr,0x66);
+        temp |= 0x20;
+	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+#endif	
+  }
+}
+
+void
+SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
+{
+  USHORT temp;
+
+  /* TW: Disable Chrontel 7019 LCD panel backlight */
+  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+        temp = SiS_GetCH701x(SiS_Pr,0x66);
+        temp &= 0xDF;
+	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+  }
+}
+
+#ifdef SIS315H  /* -------- 310/325 series only --------- */
+
+void
+SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+{
+#ifdef NEWCH701x  
+  UCHAR regtable[]  = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
+                        0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
+  UCHAR table1024[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+                        0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 }; 
+  UCHAR table1280[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+   			0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 }; 			
+  UCHAR table1400[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,         
+                        0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 }; 
+  UCHAR table1600[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+  			0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
+#else
   UCHAR regtable[]  = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
                         0x72, 0x73, 0x74, 0x76, 0x78, 0x7d };
-  UCHAR table28b4[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
-                        0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
-  UCHAR table28c0[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
-                        0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
+  UCHAR table1024[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+                        0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 }; 
+  UCHAR table1280[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+   			0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 }; 			
+  UCHAR table1400[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,   
+                        0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 }; 
+  UCHAR table1600[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+  			0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
+#endif			
   UCHAR *tableptr = NULL;
   USHORT tempbh;
   int i;
 
-  if(SiS_LCDResInfo == Panel1400x1050) {
-      tableptr = table28c0;
-  } else {
-      tableptr = table28b4;
-  }
-  tempbh = SiS_GetCH701x(0x74);
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+     tableptr = table1024;
+  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+     tableptr = table1280;
+  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+     tableptr = table1400;
+  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+     tableptr = table1600;
+  } else return;
+
+  tempbh = SiS_GetCH701x(SiS_Pr,0x74);
   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
-     tempbh = SiS_GetCH701x(0x73);
+     tempbh = SiS_GetCH701x(SiS_Pr,0x73);
      if(tempbh == 0xc8) {
-        if(SiS_LCDResInfo != Panel1400x1050) return;
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) return;
      } else if(tempbh == 0xdb) {
-        if(SiS_LCDResInfo == Panel1400x1050) return;
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) return;
+	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
+     } else if(tempbh == 0xde) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
      }
   }
+#ifdef NEWCH701x     /* New from 740/LVDS: */    
+  for(i=0; i<0x0d; i++) {	
+#else
   for(i=0; i<0x0c; i++) {
-     SiS_SetCH701x((tableptr[i] << 8) | regtable[i]);
+#endif  
+     SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
   }
-  SiS_Chrontel19f2();
-  tempbh = SiS_GetCH701x(0x1e);			/* TW: NEW in BIOS 1.10.07 */
-  tempbh |= 0xc0;				/* TW: NEW in BIOS 1.10.07 */
-  SiS_SetCH701x((tempbh << 8) | 0x1e);		/* TW: NEW in BIOS 1.10.07 */
+  SiS_ChrontelPowerSequencing(SiS_Pr);
+  tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
+  tempbh |= 0xc0;
+  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
+  
+#ifdef NEWCH701x     /* 740/LVDS: */
+  tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
+  tempbh &= 0xfb;
+  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
+  SiS_SetReg1(SiS_Pr->SiS_Part1Port, 0x2d, 0x03);
+  tempbh = SiS_GetCH701x(SiS_Pr,0x64);
+  tempbh |= 0x40;
+  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
+  tempbh = SiS_GetCH701x(SiS_Pr,0x03);
+  tempbh &= 0x3f;
+  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
+#endif  /* End 740/LVDS */
 }
 
-/* TW: Chrontel 701x functions ================================= */
-
 void
-SiS_Chrontel19f2(void)
+SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr)
 {
   UCHAR regtable[]  = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
-  UCHAR table19e8[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
-  UCHAR table19ed[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+#ifdef NEWCH701x  
+  UCHAR table1024[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
+  UCHAR table1400[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
+#else
+  UCHAR table1024[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+  UCHAR table1400[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+#endif  
   UCHAR *tableptr = NULL;
   int i;
 
-  if(SiS_LCDResInfo == Panel1400x1050) {
-      tableptr = table19ed;
-  } else {
-      tableptr = table19e8;
-  }
-
+  /* Set up Power up/down timing */
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+     tableptr = table1024;
+  } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+	    (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
+     tableptr = table1400;
+  } else return;
+  
   for(i=0; i<5; i++) {
-     SiS_SetCH701x((tableptr[i] << 8) | regtable[i]);
-  }
-}
-
-void
-SiS_Chrontel701xOn()
-{
-  USHORT temp;
-
-  if(SiS_IF_DEF_CH70xx == 2) {
-        temp = SiS_GetCH701x(0x66);
-        temp |= 0x20;
-	SiS_SetCH701x((temp << 8) | 0x66);
+     SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
   }
 }
 
 void
-SiS_Chrontel701xOn2(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
 {
   USHORT temp;
 
-  if(SiS_IF_DEF_CH70xx == 2) {
-     if(SiS_IsYPbPr(HwDeviceExtension, BaseAddr)) {
-        temp = SiS_GetCH701x(0x01);
+  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+#ifdef NEWCH701x
+     temp = SiS_GetCH701x(SiS_Pr,0x1c);
+     temp |= 0x04;
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+#endif 
+     if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+        temp = SiS_GetCH701x(SiS_Pr,0x01);
 	temp &= 0x3f;
-	temp |= 0x80;
-	SiS_SetCH701x((temp << 8) | 0x01);
+	temp |= 0x80;	/* TW: Enable YPrPb (HDTV) */
+	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
+     }
+     if(SiS_IsChScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+        temp = SiS_GetCH701x(SiS_Pr,0x01);
+	temp &= 0x3f;
+	temp |= 0xc0;	/* TW: Enable SCART + CVBS */
+	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
      }
-     SiS_SetCH701x(0x2049);
-     temp = SiS_GetCH701x(0x49);
-     if(SiS_IsYPbPr(HwDeviceExtension, BaseAddr)) {
-        temp = SiS_GetCH701x(0x73);
+#ifdef NEWCH701x
+     SiS_ChrontelDoSomething5(SiS_Pr);
+     SiS_SetCH701x(SiS_Pr,0x2049);   			/* TW: Enable TV path */
+#else      
+     SiS_SetCH701x(SiS_Pr,0x2049);   			/* TW: Enable TV path */
+     temp = SiS_GetCH701x(SiS_Pr,0x49);
+     if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+        temp = SiS_GetCH701x(SiS_Pr,0x73);
 	temp |= 0x60;
-	SiS_SetCH701x((temp << 8) | 0x73);
+	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
      }
-     /* TW: New from BIOS 1.10.07: */
-     temp = SiS_GetCH701x(0x47);
+     temp = SiS_GetCH701x(SiS_Pr,0x47);
      temp &= 0x7f;
-     SiS_SetCH701x((temp << 8) | 0x47);
-     SiS_LongDelay(2);
-     temp = SiS_GetCH701x(0x47);
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+     SiS_LongDelay(SiS_Pr,2);
+     temp = SiS_GetCH701x(SiS_Pr,0x47);
      temp |= 0x80;
-     SiS_SetCH701x((temp << 8) | 0x47);
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+#endif     
   }
 }
 
 void
-SiS_Chrontel701xOff()
+SiS_Chrontel701xOff(SiS_Private *SiS_Pr)
 {
   USHORT temp;
 
-  if(SiS_IF_DEF_CH70xx == 2) {
-        temp = SiS_GetCH701x(0x66);
-        temp &= 0xDF;
-	SiS_SetCH701x((temp << 8) | 0x66);
+  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+        SiS_LongDelay(SiS_Pr,2);
+	/* TW: Complete power down of LVDS */
+	temp = SiS_GetCH701x(SiS_Pr,0x76);
+	temp &= 0xfc;
+	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+	SiS_SetCH701x(SiS_Pr,0x0066);
   }
 }
 
+#ifdef NEWCH701x
 void
-SiS_Chrontel701xOff2()
+SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr)
 {
-  USHORT temp;
-
-  if(SiS_IF_DEF_CH70xx == 2) {
-        SiS_LongDelay(2);
-	temp = SiS_GetCH701x(0x76);
-	temp &= 0xfc;
-	SiS_SetCH701x((temp << 8) | 0x76);
-	SiS_SetCH701x(0x0066);
-  }
+     unsigned char temp, temp1;
+     
+     temp1 = SiS_GetCH701x(SiS_Pr,0x49);
+     SiS_SetCH701x(SiS_Pr,0x3e49);
+     temp = SiS_GetCH701x(SiS_Pr,0x47);
+     temp &= 0x7f;
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+     SiS_LongDelay(SiS_Pr,3);
+     temp = SiS_GetCH701x(SiS_Pr,0x47);
+     temp |= 0x80;
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+     SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
 }
+#endif
 
 void
-SiS_ChrontelFlip0x48()
+SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
-     SiS_SetCH701x(0x1048);
-     SiS_LongDelay(1);
-     SiS_SetCH701x(0x1848);
+#ifdef NEWCH701x
+     USHORT temp;
+     
+     /* 740/LVDS: */
+     temp = SiS_GetCH701x(SiS_Pr,0x4a);
+     temp &= 0x01;
+     if(!(temp)) {
+     
+        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	   temp = SiS_GetCH701x(SiS_Pr,0x49);
+	   SiS_SetCH701x(SiS_Pr,0x3e49);
+	}
+	/* TW: Reset Chrontel 7019 datapath */
+        SiS_SetCH701x(SiS_Pr,0x1048);
+        SiS_LongDelay(SiS_Pr,1);
+        SiS_SetCH701x(SiS_Pr,0x1848);
+	
+	if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	   SiS_ChrontelDoSomething5(SiS_Pr);
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
+	}    
+     } else {
+     
+        temp = SiS_GetCH701x(SiS_Pr,0x5c);
+	temp &= 0xef;
+	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+	temp = SiS_GetCH701x(SiS_Pr,0x5c);
+	temp |= 0x10;
+	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+	temp = SiS_GetCH701x(SiS_Pr,0x5c);
+	temp &= 0xef;
+	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+	temp = SiS_GetCH701x(SiS_Pr,0x61);
+	if(!temp) {
+	   SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
+	}
+     }
+#else /* pre 740/LVDS code */     
+     /* TW: Reset Chrontel 7019 datapath */
+     SiS_SetCH701x(SiS_Pr,0x1048);
+     SiS_LongDelay(SiS_Pr,1);
+     SiS_SetCH701x(SiS_Pr,0x1848);
+#endif     
 }
 
 void
-SiS_ChrontelDoSomething4(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
+#ifdef NEWCH701x
+     if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+        SiS_ChrontelDoSomething5(SiS_Pr);
+     }
+#else
      USHORT temp;
 
-     SiS_SetCH701x(0xaf76);
-     temp = SiS_GetCH701x(0x49);
+     SiS_SetCH701x(SiS_Pr,0xaf76);  /* Power up LVDS block */
+     temp = SiS_GetCH701x(SiS_Pr,0x49);
      temp &= 1;
-     if(temp != 1) {
-	temp = SiS_GetCH701x(0x47);
+     if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
+	temp = SiS_GetCH701x(SiS_Pr,0x47);
 	temp &= 0x70;
-	SiS_SetCH701x((temp << 8) | 0x47);
-	SiS_LongDelay(3);
-	temp = SiS_GetCH701x(0x47);
+	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* enable VSYNC */
+	SiS_LongDelay(SiS_Pr,3);
+	temp = SiS_GetCH701x(SiS_Pr,0x47);
 	temp |= 0x80;
-	SiS_SetCH701x((temp << 8) | 0x47);
+	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* disable VSYNC */
      }
+#endif     
 }
 
 void
-SiS_ChrontelDoSomething3(USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension,
                          USHORT BaseAddr)
 {
-     USHORT temp,temp1;
+#ifdef NEWCH701x
+     USHORT temp;
+     
+     temp = SiS_GetCH701x(SiS_Pr,0x61);
+     if(temp < 1) {
+          temp++;
+	  SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+     }
+     SiS_SetCH701x(SiS_Pr,0x4566);
+     SiS_SetCH701x(SiS_Pr,0xaf76);
+     SiS_LongDelay(SiS_Pr,1);
+     SiS_GenericDelay(SiS_Pr,0x16ff);
 
+#else
+     USHORT temp,temp1;
+     
      temp1 = 0;
-     temp = SiS_GetCH701x(0x61);
+     temp = SiS_GetCH701x(SiS_Pr,0x61);
      if(temp < 2) {
           temp++;
-	  SiS_SetCH701x((temp << 8) | 0x61);
+	  SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
 	  temp1 = 1;
      }
-     SiS_SetCH701x(0xac76);
-     temp = SiS_GetCH701x(0x66);
+     SiS_SetCH701x(SiS_Pr,0xac76);
+     temp = SiS_GetCH701x(SiS_Pr,0x66);
      temp |= 0x5f;
-     SiS_SetCH701x((temp << 8) | 0x66);
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
      if(ModeNo > 0x13) {
-         if(SiS_WeHaveBacklightCtrl(HwDeviceExtension, BaseAddr)) {
-	    SiS_GenericDelay(0x3ff);
+         if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	    SiS_GenericDelay(SiS_Pr,0x3ff);
 	 } else {
-	    SiS_GenericDelay(0x2ff);
+	    SiS_GenericDelay(SiS_Pr,0x2ff);
 	 }
      } else {
          if(!temp1)
-	    SiS_GenericDelay(0x2ff);
+	    SiS_GenericDelay(SiS_Pr,0x2ff);
      }
-     temp = SiS_GetCH701x(0x76);
+     temp = SiS_GetCH701x(SiS_Pr,0x76);
      temp |= 0x03;
-     SiS_SetCH701x((temp << 8) | 0x76);
-     temp = SiS_GetCH701x(0x66);
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+     temp = SiS_GetCH701x(SiS_Pr,0x66);
      temp &= 0x7f;
-     SiS_SetCH701x((temp << 8) | 0x66);
-     SiS_LongDelay(1);
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+     SiS_LongDelay(SiS_Pr,1);
+#endif     
 }
 
 void
-SiS_ChrontelDoSomething2(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
 {
      USHORT temp,tempcl,tempch;
 
-     SiS_LongDelay(1);
+     SiS_LongDelay(SiS_Pr, 1);
      tempcl = 3;
      tempch = 0;
 
      do {
-       temp = SiS_GetCH701x(0x66);
+       temp = SiS_GetCH701x(SiS_Pr,0x66);
        temp &= 0x04;
        if(temp == 0x04) break;
+       
+#ifdef NEWCH701x
+       SiS_SetCH701x(SiS_Pr,0xac76);    /* 740/LVDS */
+#endif       
 
-       SiS_SetCHTVForLCD(HwDeviceExtension, BaseAddr);
+       SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
 
        if(tempcl == 0) {
            if(tempch == 3) break;
-	   SiS_ChrontelFlip0x48();
+	   SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr);
 	   tempcl = 3;
 	   tempch++;
        }
        tempcl--;
-       temp = SiS_GetCH701x(0x76);
+       temp = SiS_GetCH701x(SiS_Pr,0x76);
        temp &= 0xfb;
-       SiS_SetCH701x((temp << 8) | 0x76);
-       SiS_LongDelay(2);
-       temp = SiS_GetCH701x(0x76);
+       SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+       SiS_LongDelay(SiS_Pr,2);
+       temp = SiS_GetCH701x(SiS_Pr,0x76);
        temp |= 0x04;
-       SiS_SetCH701x((temp << 8) | 0x76);
-       SiS_SetCH701x(0x6078);
-       SiS_LongDelay(2);
+       SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+#ifdef NEWCH701x
+       SiS_SetCH701x(SiS_Pr,0xe078);
+#else       
+       SiS_SetCH701x(SiS_Pr,0x6078);
+#endif       
+       SiS_LongDelay(SiS_Pr,2);
     } while(0);
 
-    SiS_SetCH701x(0x0077);
+    SiS_SetCH701x(SiS_Pr,0x0077);
 }
 
 void
-SiS_ChrontelDoSomething1(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
                          USHORT BaseAddr)
 {
      USHORT temp;
 
-     temp = SiS_GetCH701x(0x03);
-     temp |= 0x80;
-     temp &= 0xbf;
-     SiS_SetCH701x((temp << 8) | 0x03);
-
-     SiS_ChrontelFlip0x48();
+     temp = SiS_GetCH701x(SiS_Pr,0x03);
+     temp |= 0x80;	/* Set datapath 1 to TV   */
+     temp &= 0xbf;	/* Set datapath 2 to LVDS */
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
+     
+#ifdef NEWCH701x   /* 740/LVDS: */
 
-     SiS_ChrontelDoSomething2(HwDeviceExtension, BaseAddr);
+     temp = SiS_GetCH701x(SiS_Pr,0x1c);
+     temp &= 0xfb;
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+     
+     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
      
-     temp = SiS_GetReg1(SiS_P3d4,0x34);
-     SiS_ChrontelDoSomething3(temp, HwDeviceExtension, BaseAddr);
+     temp = SiS_GetCH701x(SiS_Pr,0x64);
+     temp |= 0x40;
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
+     
+     temp = SiS_GetCH701x(SiS_Pr,0x03);
+     temp &= 0x3f;	
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
+     
+     temp = SiS_GetCH701x(SiS_Pr,0x66);
+     if(temp != 0x45) {
+        SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr);
+        SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
+	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
+        SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
+     }     
+
+#else  /* pre-740/LVDS: */     
+
+     SiS_ChrontelResetDB(SiS_Pr);
 
-     SiS_SetCH701x(0xaf76);
+     SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
+
+     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
+     SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
+
+     SiS_SetCH701x(SiS_Pr,0xaf76);
+     
+#endif  /* End of pre-740/LVDS */
 }
 
+#endif  /* 310/325 series --------------------------------- */
+
 /* TW: End of Chrontel 701x functions ==================================== */
 
 /* TW: Generic Read/write routines for Chrontel ========================== */
 
-/* The Chrontel seems to be connected to the 630/730 via
- * the 630/730's DDC port (which is used as a I2C port here).
+/* TW: The Chrontel is connected to the 630/730 via
+ * the 630/730's DDC/I2C port.
  *
- * On 630(S)T chipset, the port changed from 0x11 to 0x0a
+ * On 630(S)T chipset, the index changed from 0x11 to 0x0a,
+ * possibly for working around the DDC problems
  */
 
 void
-SiS_SetCH70xx(USHORT tempbx)
+SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
 {
-   if (SiS_IF_DEF_CH70xx == 1)
-      SiS_SetCH700x(tempbx);
+   if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+      SiS_SetCH700x(SiS_Pr,tempbx);
    else
-      SiS_SetCH701x(tempbx);
+      SiS_SetCH701x(SiS_Pr,tempbx);
 }
 
 /* TW: Write to Chrontel 700x */
 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
 void
-SiS_SetCH700x(USHORT tempbx)
+SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
 {
   USHORT tempah,temp,i;
 
-  if(!(SiS_ChrontelInit)) {
-     SiS_DDC_Index = 0x11;		   /* TW: Bit 0 = SC;  Bit 1 = SD */
-     SiS_DDC_Data  = 0x02;                 /* Bitmask in IndexReg for Data */
-     SiS_DDC_Clk   = 0x01;                 /* Bitmask in IndexReg for Clk */
-     SiS_DDC_DataShift = 0x00;
-     SiS_DDC_DeviceAddr = 0xEA;  	   /* TW: DAB (Device Address Byte) */
+  if(!(SiS_Pr->SiS_ChrontelInit)) {
+     SiS_Pr->SiS_DDC_Index = 0x11;		   /* TW: Bit 0 = SC;  Bit 1 = SD */
+     SiS_Pr->SiS_DDC_Data  = 0x02;                 /* Bitmask in IndexReg for Data */
+     SiS_Pr->SiS_DDC_Clk   = 0x01;                 /* Bitmask in IndexReg for Clk */
+     SiS_Pr->SiS_DDC_DataShift = 0x00;
+     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	   /* TW: DAB (Device Address Byte) */
   }
 
   for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
-    SiS_SetSwitchDDC2();
-    if (SiS_SetStart()) continue;	/* TW: Set start condition */
-    tempah=SiS_DDC_DeviceAddr;
-    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write DAB (S0=0=write) */
-    if(temp) continue;			/* TW:    (ERROR: no ack) */
-    tempah=tempbx&0x00FF;
-    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write RAB */
-    if(temp) continue;			/* TW:    (ERROR: no ack) */
-    tempah=(tempbx&0xFF00)>>8;
-    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write data */
-    if(temp) continue;			/* TW:    (ERROR: no ack) */
-    if (SiS_SetStop()) continue;	/* TW: Set stop condition */
-    SiS_ChrontelInit = 1;
+    /* SiS_SetSwitchDDC2(SiS_Pr); */
+    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
+    tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
+    if(temp) continue;				/* TW:    (ERROR: no ack) */
+    tempah = tempbx & 0x00FF;			/* TW: Write RAB */
+    tempah |= 0x80;                             /* TW: (set bit 7, see datasheet) */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+    if(temp) continue;				/* TW:    (ERROR: no ack) */
+    tempah = (tempbx & 0xFF00) >> 8;
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
+    if(temp) continue;				/* TW:    (ERROR: no ack) */
+    if(SiS_SetStop(SiS_Pr)) continue;		/* TW: Set stop condition */
+    SiS_Pr->SiS_ChrontelInit = 1;
     return;
   }
 
-  if(!(SiS_ChrontelInit)) {
-     SiS_DDC_Index = 0x0a;			/* TW: Bit 0 = SC;  Bit 1 = SD */
-     SiS_DDC_Data  = 0x80;                 /* Bitmask in IndexReg for Data */
-     SiS_DDC_Clk   = 0x40;                 /* Bitmask in IndexReg for Clk */
-     SiS_DDC_DataShift = 0x00;
-     SiS_DDC_DeviceAddr = 0xEA;  		/* TW: DAB (Device Address Byte) */
+  /* TW: For 630ST */
+  if(!(SiS_Pr->SiS_ChrontelInit)) {
+     SiS_Pr->SiS_DDC_Index = 0x0a;		/* TW: Bit 7 = SC;  Bit 6 = SD */
+     SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
+     SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
+     SiS_Pr->SiS_DDC_DataShift = 0x00;
+     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
 
      for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
-       SiS_SetSwitchDDC2();
-       if (SiS_SetStart()) continue;		/* TW: Set start condition */
-       tempah=SiS_DDC_DeviceAddr;
-       temp=SiS_WriteDDC2Data(tempah);		/* TW: Write DAB (S0=0=write) */
+       /* SiS_SetSwitchDDC2(SiS_Pr); */
+       if (SiS_SetStart(SiS_Pr)) continue;	/* TW: Set start condition */
+       tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
        if(temp) continue;			/* TW:    (ERROR: no ack) */
-       tempah=tempbx&0x00FF;
-       temp=SiS_WriteDDC2Data(tempah);		/* TW: Write RAB */
+       tempah = tempbx & 0x00FF;		/* TW: Write RAB */
+       tempah |= 0x80;                          /* TW: (set bit 7, see datasheet) */
+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
        if(temp) continue;			/* TW:    (ERROR: no ack) */
-       tempah=(tempbx&0xFF00)>>8;
-       temp=SiS_WriteDDC2Data(tempah);		/* TW: Write data */
+       tempah = (tempbx & 0xFF00) >> 8;
+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
        if(temp) continue;			/* TW:    (ERROR: no ack) */
-       if (SiS_SetStop()) continue;		/* TW: Set stop condition */
-       SiS_ChrontelInit = 1;
+       if(SiS_SetStop(SiS_Pr)) continue;	/* TW: Set stop condition */
+       SiS_Pr->SiS_ChrontelInit = 1;
        return;
     }
   }
@@ -7405,31 +9609,28 @@
 /* TW: Write to Chrontel 701x */
 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
 void
-SiS_SetCH701x(USHORT tempbx)
+SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
 {
   USHORT tempah,temp,i;
 
-  /* TW: Toggle to DDC port */
-  SiS_SetRegOR(SiS_P3c4,0x38,0x20);
-
-  SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
-  SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
-  SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
-  SiS_DDC_DataShift = 0x00;
-  SiS_DDC_DeviceAddr = 0xEA;  		/* TW: DAB (Device Address Byte) */
+  SiS_Pr->SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
+  SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
+  SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
+  SiS_Pr->SiS_DDC_DataShift = 0x00;
+  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* TW: DAB (Device Address Byte) */
 
   for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
-    if (SiS_SetStart()) continue;	/* TW: Set start condition */
-    tempah=SiS_DDC_DeviceAddr;
-    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write DAB (S0=0=write) */
-    if(temp) continue;			/* TW:    (ERROR: no ack) */
-    tempah=tempbx&0x00FF;
-    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write RAB */
-    if(temp) continue;			/* TW:    (ERROR: no ack) */
-    tempah=(tempbx&0xFF00)>>8;
-    temp=SiS_WriteDDC2Data(tempah);	/* TW: Write data */
-    if(temp) continue;			/* TW:    (ERROR: no ack) */
-    if (SiS_SetStop()) continue;	/* TW: Set stop condition */
+    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
+    tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
+    if(temp) continue;				/* TW:    (ERROR: no ack) */
+    tempah = tempbx & 0x00FF;
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write RAB */
+    if(temp) continue;				/* TW:    (ERROR: no ack) */
+    tempah = (tempbx & 0xFF00) >> 8;
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
+    if(temp) continue;				/* TW:    (ERROR: no ack) */
+    if(SiS_SetStop(SiS_Pr)) continue;		/* TW: Set stop condition */
     return;
   }
 }
@@ -7437,73 +9638,74 @@
 /* TW: Read from Chrontel 70xx */
 /* Parameter is [Register no (S7-S0)] */
 USHORT
-SiS_GetCH70xx(USHORT tempbx)
+SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
 {
-   if (SiS_IF_DEF_CH70xx == 1)
-      return(SiS_GetCH700x(tempbx));
+   if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+      return(SiS_GetCH700x(SiS_Pr,tempbx));
    else
-      return(SiS_GetCH701x(tempbx));
+      return(SiS_GetCH701x(SiS_Pr,tempbx));
 }
 
 /* TW: Read from Chrontel 700x */
 /* Parameter is [Register no (S7-S0)] */
 USHORT
-SiS_GetCH700x(USHORT tempbx)
+SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
 {
   USHORT tempah,temp,i;
 
-  if(!(SiS_ChrontelInit)) {
-     SiS_DDC_Index = 0x11;		/* TW: Bit 0 = SC;  Bit 1 = SD */
-     SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
-     SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
-     SiS_DDC_DataShift = 0x00;
-     SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
+  if(!(SiS_Pr->SiS_ChrontelInit)) {
+     SiS_Pr->SiS_DDC_Index = 0x11;		/* TW: Bit 0 = SC;  Bit 1 = SD */
+     SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
+     SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
+     SiS_Pr->SiS_DDC_DataShift = 0x00;
+     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
   }
 
-  SiS_DDC_ReadAddr = tempbx;
+  SiS_Pr->SiS_DDC_ReadAddr = tempbx;
 
   for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
-    SiS_SetSwitchDDC2();
-    if(SiS_SetStart()) continue;	/* TW: Set start condition */
-    tempah = SiS_DDC_DeviceAddr;
-    temp = SiS_WriteDDC2Data(tempah);	/* TW: Write DAB (S0=0=write) */
-    if(temp) continue;			/* TW:        (ERROR: no ack) */
-    tempah = SiS_DDC_ReadAddr;		/* TW: Write RAB */
-    temp = SiS_WriteDDC2Data(tempah);
-    if(temp) continue;			/* TW:        (ERROR: no ack) */
-    if (SiS_SetStart()) continue;	/* TW: Re-start */
-    tempah = SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
-    temp = SiS_WriteDDC2Data(tempah);	/* TW: DAB (S0=1=read) */
-    if(temp) continue;			/* TW:        (ERROR: no ack) */
-    tempah = SiS_ReadDDC2Data(tempah);	/* TW: Read byte */
-    if (SiS_SetStop()) continue;	/* TW: Stop condition */
-    SiS_ChrontelInit = 1;
+    /* SiS_SetSwitchDDC2(SiS_Pr); */
+    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
+    tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
+    if(temp) continue;				/* TW:        (ERROR: no ack) */
+    tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* TW: Write RAB | 0x80 */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+    if(temp) continue;				/* TW:        (ERROR: no ack) */
+    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
+    tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: DAB (S0=1=read) */
+    if(temp) continue;				/* TW:        (ERROR: no ack) */
+    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
+    if (SiS_SetStop(SiS_Pr)) continue;		/* TW: Stop condition */
+    SiS_Pr->SiS_ChrontelInit = 1;
     return(tempah);
   }
 
-  if(!SiS_ChrontelInit) {
-     SiS_DDC_Index = 0x0a;		/* TW: Bit 0 = SC;  Bit 1 = SD */
-     SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
-     SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
-     SiS_DDC_DataShift = 0x00;
-     SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
+  /* TW: For 630ST */
+  if(!SiS_Pr->SiS_ChrontelInit) {
+     SiS_Pr->SiS_DDC_Index = 0x0a;		/* TW: Bit 0 = SC;  Bit 1 = SD */
+     SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
+     SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
+     SiS_Pr->SiS_DDC_DataShift = 0x00;
+     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
 
      for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
-       SiS_SetSwitchDDC2();
-       if(SiS_SetStart()) continue;		/* TW: Set start condition */
-       tempah = SiS_DDC_DeviceAddr;
-       temp = SiS_WriteDDC2Data(tempah);	/* TW: Write DAB (S0=0=write) */
-       if(temp) continue;			/* TW:        (ERROR: no ack) */
-       tempah = SiS_DDC_ReadAddr;		/* TW: Write RAB */
-       temp = SiS_WriteDDC2Data(tempah);
-       if(temp) continue;			/* TW:        (ERROR: no ack) */
-       if (SiS_SetStart()) continue;		/* TW: Re-start */
-       tempah = SiS_DDC_DeviceAddr | 0x01; 	/* DAB | 0x01 = Read */
-       temp = SiS_WriteDDC2Data(tempah);	/* TW: DAB (S0=1=read) */
-       if(temp) continue;			/* TW:        (ERROR: no ack) */
-       tempah = SiS_ReadDDC2Data(tempah);	/* TW: Read byte */
-       if (SiS_SetStop()) continue;		/* TW: Stop condition */
-       SiS_ChrontelInit = 1;
+       /* SiS_SetSwitchDDC2(SiS_Pr); */
+       if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
+       tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* TW: Write DAB (S0=0=write) */
+       if(temp) continue;				/* TW:        (ERROR: no ack) */
+       tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* TW: Write RAB | 0x80 */
+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+       if(temp) continue;				/* TW:        (ERROR: no ack) */
+       if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
+       tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; 	/* DAB | 0x01 = Read */
+       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* TW: DAB (S0=1=read) */
+       if(temp) continue;				/* TW:        (ERROR: no ack) */
+       tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
+       if (SiS_SetStop(SiS_Pr)) continue;		/* TW: Stop condition */
+       SiS_Pr->SiS_ChrontelInit = 1;
        return(tempah);
      }
   }
@@ -7513,232 +9715,1203 @@
 /* TW: Read from Chrontel 701x */
 /* Parameter is [Register no (S7-S0)] */
 USHORT
-SiS_GetCH701x(USHORT tempbx)
+SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
 {
   USHORT tempah,temp,i;
 
-  /* TW: Toggle to DDC port */
-  SiS_SetRegOR(SiS_P3c4,0x38,0x20);
-
-  SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
-  SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
-  SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
-  SiS_DDC_DataShift = 0x00;
-  SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
-  SiS_DDC_ReadAddr = tempbx;
+  SiS_Pr->SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
+  SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
+  SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
+  SiS_Pr->SiS_DDC_DataShift = 0x00;
+  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
+  SiS_Pr->SiS_DDC_ReadAddr = tempbx;
 
    for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
-    if(SiS_SetStart()) continue;	/* TW: Set start condition */
-    tempah = SiS_DDC_DeviceAddr;
-    temp = SiS_WriteDDC2Data(tempah);	/* TW: Write DAB (S0=0=write) */
-    if(temp) continue;			/* TW:        (ERROR: no ack) */
-    tempah = SiS_DDC_ReadAddr;		/* TW: Write RAB */
-    temp = SiS_WriteDDC2Data(tempah);
-    if(temp) continue;			/* TW:        (ERROR: no ack) */
-    if (SiS_SetStart()) continue;	/* TW: Re-start */
-    tempah = SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
-    temp = SiS_WriteDDC2Data(tempah);	/* TW: DAB (S0=1=read) */
-    if(temp) continue;			/* TW:        (ERROR: no ack) */
-    tempah = SiS_ReadDDC2Data(tempah);	/* TW: Read byte */
-    SiS_SetStop();			/* TW: Stop condition */
+    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
+    tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
+    if(temp) continue;				/* TW:        (ERROR: no ack) */
+    tempah = SiS_Pr->SiS_DDC_ReadAddr;		/* TW: Write RAB */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+    if(temp) continue;				/* TW:        (ERROR: no ack) */
+    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
+    tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
+    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: DAB (S0=1=read) */
+    if(temp) continue;				/* TW:        (ERROR: no ack) */
+    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
+    SiS_SetStop(SiS_Pr);			/* TW: Stop condition */
     return(tempah);
    }
   return 0xFFFF;
 }
 
+#ifdef LINUX_XF86
+/* TW: Our own DDC functions */
+USHORT
+SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype,
+		BOOLEAN checkcr32)
+{
+     unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
+     unsigned char flag, cr32;
+     USHORT        temp = 0, myadaptnum = adaptnum;
+
+     if(adaptnum != 0) {
+        if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0xFFFF;
+	if((pSiS->VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
+     }	
+     
+     /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
+     
+     SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
+
+     SiS_Pr->SiS_DDC_SecAddr = 0;
+     SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
+     SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
+     SiS_Pr->SiS_DDC_Index = 0x11;
+     flag = 0xff;
+
+     cr32 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x32);
+  
+     if(pSiS->VBFlags & VB_SISBRIDGE) {
+	if(myadaptnum == 0) {
+	   if(!(cr32 & 0x20)) {
+	      myadaptnum = 2;
+	      if(!(cr32 & 0x10)) {
+	         myadaptnum = 1;
+		 if(!(cr32 & 0x08)) {
+		    myadaptnum = 0;
+		 }
+	      }
+	   }
+        }
+     }
+
+     if(pSiS->VGAEngine == SIS_300_VGA) {		/* 300 series */
+	
+        if(myadaptnum != 0) {
+	   flag = 0;
+	   if(pSiS->VBFlags & VB_SISBRIDGE) {
+	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
+              SiS_Pr->SiS_DDC_Index = 0x0f;
+	   }
+        }
+
+	if(!(pSiS->VBFlags & VB_301)) {
+	   if((cr32 & 0x80) && (checkcr32)) {
+              if(myadaptnum >= 1) {
+	         if(!(cr32 & 0x08)) {
+	             myadaptnum = 1;
+		     if(!(cr32 & 0x10)) return 0xFFFF;
+                 }
+	      }
+	   }
+	}
+
+	temp = 4 - (myadaptnum * 2);
+	if(flag) temp = 0;
+
+     } else {						/* 310/325/330 series */
+
+     	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
+	
+	if(pSiS->VBFlags & VB_SISBRIDGE) {
+	   if(myadaptnum == 2) {
+	      myadaptnum = 1;
+           }
+	}
+
+        if(myadaptnum == 1) {
+     	   flag = 0;
+	   if(pSiS->VBFlags & VB_SISBRIDGE) {
+	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
+              SiS_Pr->SiS_DDC_Index = 0x0f;
+	   }
+        }
+
+        if((cr32 & 0x80) && (checkcr32)) {
+           if(myadaptnum >= 1) {
+	      if(!(cr32 & 0x08)) {
+	         myadaptnum = 1;
+		 if(!(cr32 & 0x10)) return 0xFFFF;
+	      }
+	   }
+        }
+
+        temp = myadaptnum;
+        if(myadaptnum == 1) {
+           temp = 0;
+	   if(pSiS->VBFlags & VB_LVDS) flag = 0xff;
+        }
+
+	if(flag) temp = 0;
+    }
+    
+    SiS_Pr->SiS_DDC_Data = 0x02 << temp;
+    SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
+
+#ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
+    		SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
+#endif	 
+    
+    return 0;
+}
+
+USHORT
+SiS_WriteDABDDC(SiS_Private *SiS_Pr)
+{
+   if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
+   if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
+#ifdef TWDEBUG
+        xf86DrvMsg(0, X_INFO, "WriteDAB 1 failed\n");
+#endif	 
+  	return 0xFFFF;
+   }
+   if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
+#ifdef TWDEBUG
+        xf86DrvMsg(0, X_INFO, "WriteDAB 2 failed\n");
+#endif	 
+   	return 0xFFFF;
+   }
+   return(0);
+}
+
+USHORT
+SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
+{
+   if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
+   if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
+#ifdef TWDEBUG
+        xf86DrvMsg(0, X_INFO, "PrepareReadDDC 1 failed\n");
+#endif	 
+   	return 0xFFFF;
+   }
+   return(0);
+}
+
+USHORT
+SiS_PrepareDDC(SiS_Private *SiS_Pr)
+{
+   if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
+   if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
+   return(0);
+}
+
+void
+SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
+{
+   SiS_SetSCLKLow(SiS_Pr);
+   if(yesno) {
+      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index,
+                      ~SiS_Pr->SiS_DDC_Data, SiS_Pr->SiS_DDC_Data);
+   } else {
+      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index,
+                      ~SiS_Pr->SiS_DDC_Data, 0);
+   }
+   SiS_SetSCLKHigh(SiS_Pr);
+}
+
+USHORT
+SiS_DoProbeDDC(SiS_Private *SiS_Pr)
+{
+    unsigned char mask, value;
+    USHORT  temp, ret=0;
+    BOOLEAN failed = FALSE;
+
+    SiS_SetSwitchDDC2(SiS_Pr);
+    if(SiS_PrepareDDC(SiS_Pr)) {
+         SiS_SetStop(SiS_Pr);
+#ifdef TWDEBUG
+	 xf86DrvMsg(0, X_INFO, "DoProbeDDC 1 failed at PrepareDDC\n");
+#endif	 
+         return(0xFFFF);
+    }
+    mask = 0xf0;
+    value = 0x20;
+    if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
+       temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+       SiS_SendACK(SiS_Pr, 0);
+       if(temp == 0) {
+           mask = 0xff;
+	   value = 0xff;
+       } else {
+           failed = TRUE;
+	   ret = 0xFFFF;
+       }
+    }
+    if(failed == FALSE) {
+       temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+       SiS_SendACK(SiS_Pr, 1);
+       temp &= mask;
+       if(temp == value) ret = 0;
+       else {
+          ret = 0xFFFF;
+          if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
+             if(temp == 0x30) ret = 0;
+          }
+       }
+    }
+    SiS_SetStop(SiS_Pr);
+    return(ret);
+}
+
+USHORT
+SiS_ProbeDDC(SiS_Private *SiS_Pr)
+{
+   USHORT flag;
+
+   flag = 0x180;
+   SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+   if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
+   SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
+   if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
+   SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
+   if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
+   if(!(flag & 0x1a)) flag = 0;
+   return(flag);
+}
+
+USHORT
+SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer)
+{
+   USHORT flag, length, i;
+   unsigned char chksum,gotcha;
+
+   if(DDCdatatype > 4) return 0xFFFF;  
+
+   flag = 0;
+   SiS_SetSwitchDDC2(SiS_Pr);
+   if(!(SiS_PrepareDDC(SiS_Pr))) {
+      length = 127;
+      if(DDCdatatype != 1) length = 255;
+      chksum = 0;
+      gotcha = 0;
+      for(i=0; i<length; i++) {
+         buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+	 chksum += buffer[i];
+	 gotcha |= buffer[i];
+	 SiS_SendACK(SiS_Pr, 0);
+      }
+      buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+      chksum += buffer[i];
+      SiS_SendACK(SiS_Pr, 1);
+      if(gotcha) flag = (USHORT)chksum;
+      else flag = 0xFFFF;
+   } else {
+      flag = 0xFFFF;
+   }
+   SiS_SetStop(SiS_Pr);
+   return(flag);
+}
+
+USHORT
+SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer)
+{
+   USHORT i=0, flag=0;
+
+   length--;
+   
+   SiS_SetSwitchDDC2(SiS_Pr);
+   if(!(SiS_PrepareDDC(SiS_Pr))) {
+      for(i=0; i<length; i++) {
+         buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+         SiS_SendACK(SiS_Pr, 0);
+      }
+      buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
+      SiS_SendACK(SiS_Pr, 1);
+   } else flag = 0xFFFF;
+   
+   SiS_SetStop(SiS_Pr);
+   return(0);
+}
+
+/* TW: Our private DDC function
+
+   It complies somewhat with the corresponding VESA function
+   in arguments and return values.
+
+   Since this is probably called before the mode is changed,
+   we use our pre-detected pSiS-values instead of SiS_Pr as
+   regards chipset and video bridge type.
+
+   Arguments:
+       adaptnum: 0=CRT1, 1=LCD, 2=VGA2
+                 CRT2 DDC is only supported on SiS301, 301B (non-DH version), 302B.
+       DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
+       buffer: ptr to 256 data bytes which will be filled with read data.
+
+   Returns 0xFFFF if error, otherwise
+       if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
+       if DDCdatatype = 0:  Returns supported DDC modes
+
+ */
+USHORT
+SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
+              USHORT DDCdatatype, unsigned char *buffer)
+{
+   if(adaptnum > 2) return 0xFFFF;
+   if(DDCdatatype > 4) return 0xFFFF;
+   if((!(pSiS->VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
+   if(SiS_InitDDCRegs(SiS_Pr, pSiS, adaptnum, DDCdatatype, TRUE) == 0xFFFF) return 0xFFFF;
+   if(DDCdatatype == 0) {
+       return(SiS_ProbeDDC(SiS_Pr));
+   } else {
+       return(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer));
+   }
+}
+
+/* Sense the LCD parameters (CR36, CR37) via DDC */
+/* SiS30x(B) only */
+USHORT
+SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
+{
+   USHORT DDCdatatype, paneltype, flag, xres, yres;
+   USHORT index, myindex, lumsize, numcodes;
+   unsigned char cr37=0, seekcode;
+   BOOLEAN checkexpand = FALSE;
+   int retry, i;
+   unsigned char buffer[256];
+   
+   if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0;
+   if(pSiS->VBFlags & VB_30xBDH) return 0;
+  
+   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 1, 0, FALSE) == 0xFFFF) return 0;
+   
+   SiS_Pr->SiS_DDC_SecAddr = 0x00;
+   
+   /* Probe supported DA's */
+   flag = SiS_ProbeDDC(SiS_Pr);
+#ifdef TWDEBUG   
+   xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
+   	"CRT2 DDC capabilities 0x%x\n", flag);
+#endif	
+   if(flag & 0x10) {
+      SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;	/* EDID V2 (FP) */
+      DDCdatatype = 4;
+   } else if(flag & 0x08) {
+      SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;	/* EDID V2 (P&D-D Monitor) */
+      DDCdatatype = 3;
+   } else if(flag & 0x02) {
+      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;	/* EDID V1 */
+      DDCdatatype = 1;
+   } else return 0;				/* no DDC support (or no device attached) */
+   
+   /* Read the entire EDID */
+   retry = 2;
+   do {
+      if(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer)) {
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
+	 	"CRT2: DDC read failed (attempt %d), %s\n", 
+		(3-retry), (retry == 1) ? "giving up" : "retrying");
+	 retry--;
+	 if(retry == 0) return 0xFFFF;
+      } else break;
+   } while(1);
+   
+#ifdef TWDEBUG   
+   for(i=0; i<256; i+=16) {
+       xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
+       	"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+	buffer[i],    buffer[i+1], buffer[i+2], buffer[i+3],
+	buffer[i+4],  buffer[i+5], buffer[i+6], buffer[i+7],
+	buffer[i+8],  buffer[i+9], buffer[i+10], buffer[i+11],
+	buffer[i+12], buffer[i+13], buffer[i+14], buffer[i+15]);
+   }
+#endif   
+   
+   /* Analyze EDID and retrieve LCD panel information */
+   paneltype = 0;
+   switch(DDCdatatype) {
+   case 1:							/* Analyze EDID V1 */
+      /* Catch a few clear cases: */
+      if(!(buffer[0x14] & 0x80)) {
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, 
+	        "CRT2: Attached display expects analog input (0x%02x)\n",
+		buffer[0x14]);
+      	 return 0;
+      }
+      
+      if((buffer[0x18] & 0x18) != 0x08) {
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, 
+	 	"CRT2: Attached display is not of RGB but of %s type (0x%02x)\n", 
+		((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
+		  ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" : 
+		     "undefined"),
+		buffer[0x18]);
+	 return 0;
+      }
+      
+      /* Now analyze the first Detailed Timing Block and hope
+       * that the preferred timing mode is stored there.
+       */	
+      xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
+      yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
+      checkexpand = FALSE;
+      switch(xres) {
+         case 800:
+	     if(yres == 600) {
+	     	paneltype = Panel310_800x600;
+	     	checkexpand = TRUE;
+	     }
+	     break;
+         case 1024:
+	     if(yres == 768) {
+	     	paneltype = Panel310_1024x768;
+	     	checkexpand = FALSE;    /* expand causes error at 640x480, should otherwise be TRUE; */
+	     }
+	     break;
+	 case 1280:
+	     if(yres == 960) {
+	        if(pSiS->VGAEngine == SIS_300_VGA) {
+		   paneltype = Panel300_1280x960;
+		} else {
+		   paneltype = Panel310_1280x960; 
+		}
+	     } else if(yres == 1024) {
+	     	paneltype = Panel310_1280x1024;  
+		checkexpand = TRUE;
+	     } else if(pSiS->VGAEngine == SIS_315_VGA) {
+	        if(yres == 768) {
+	       	   paneltype = Panel310_1280x768; 	/* Panel size 1280x768 not supported yet */
+		   checkexpand = TRUE;	
+	        }	
+	     }
+	     break;
+	 case 1400:
+	     if(pSiS->VGAEngine == SIS_315_VGA) {
+	        if(yres == 1050) {
+	           paneltype = Panel310_1400x1050;
+		   checkexpand = TRUE; 
+	        } 
+	     }
+      	     break;
+	 case 1600:
+	     if(pSiS->VGAEngine == SIS_315_VGA) {
+	        if(yres == 1200) {
+	           paneltype = Panel310_1600x1200;
+		   checkexpand = TRUE;
+	        } 
+	     }
+      	     break;
+      }
+
+      if(buffer[0x18] & 0x02) {
+         /* If the preferred timing mode is stored in the first
+	  * detailed timing block, we now can extract the sync
+	  * polarisation information as well. This only works
+	  * if the Flags indicate a digital separate output.
+	  */
+	  if((buffer[0x47] & 0x18) == 0x18) {
+	     cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
+	  } else {
+	     /* What now? There is no digital separate output timing... */
+	     xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
+	     	"CRT2: Unable to retrieve Sync polarity information\n");
+	  }
+	  
+      } else {
+         /* If the preferred timing mode is *not* stored in the first
+	  * detailed timing block, we need to guess the resolution
+	  * from the supported Established Timings and assume the
+	  * default sync polarity
+	  */
+	 paneltype = 0;
+	 if(buffer[0x24] & 0x01) { 	
+	 	paneltype = Panel310_1280x1024;
+		checkexpand = TRUE;
+		cr37 |= 0x20;
+	 } else if(buffer[0x24] & 0x0e) {
+	 	paneltype = Panel310_1024x768;
+		cr37 |= 0xe0;
+		checkexpand = FALSE;		/* Bug at 640x480 */
+	 } else if(buffer[0x23] & 0x01) {
+	 	paneltype = Panel310_800x600;
+		cr37 |= 0xe0;
+		checkexpand = TRUE;
+         }
+      }
+      
+      if(checkexpand) {
+         /* If any of the Established low-res modes is supported, the 
+	  * panel can scale automatically. For 800x600 panels, we only 
+	  * check the even lower ones.
+	  */
+	 if(paneltype == Panel310_800x600) {
+	    if(buffer[0x23] & 0xfc) cr37 |= 0x10;
+	 } else {
+            if(buffer[0x23])	    cr37 |= 0x10;
+	 }
+      }
+       
+      break;
+      
+   case 3:							/* Analyze EDID V2 */
+   case 4:
+      index = 0;
+      if((buffer[0x41] & 0x0f) == 0x03) {
+         index = 0x42 + 3;
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	 	"CRT2: Display supports TMDS input on primary interface\n");
+      } else if((buffer[0x41] & 0xf0) == 0x30) {
+         index = 0x46 + 3;
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	 	"CRT2: Display supports TMDS input on secondary interface\n");
+      } else {
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	 	"CRT2: Display does not support TMDS video interface (0x%02x)\n", 
+		buffer[0x41]);
+	 return 0;
+      }
+   
+      xres = buffer[0x76] | (buffer[0x77] << 8);
+      yres = buffer[0x78] | (buffer[0x79] << 8);
+      switch(xres) {
+         case 800:
+	     if(yres == 600) {
+	     	paneltype = Panel310_800x600;
+	     	checkexpand = TRUE;
+	     }
+	     break;
+         case 1024:
+	     if(yres == 768) {
+	     	paneltype = Panel310_1024x768;
+	     	checkexpand = FALSE;			/* Bug at 640x480; we do the scaling ourselves */
+	     }
+	     break;
+	 case 1280:
+	     if(yres == 960) {
+	        if(pSiS->VGAEngine == SIS_315_VGA) {
+	     	   paneltype = Panel310_1280x960;
+		} else {
+		   paneltype = Panel300_1280x960;
+		}
+	     } else if(yres == 1024) {
+	     	paneltype = Panel310_1280x1024;  
+		checkexpand = TRUE;
+	     } else if(pSiS->VGAEngine == SIS_315_VGA) {
+	        if(yres == 768) {
+	       	   paneltype = Panel310_1280x768; 	/* Panel size 1280x768 not supported yet */
+		   checkexpand = TRUE;
+	        }
+	     } 
+	     break;
+	 case 1400:
+	     if(pSiS->VGAEngine == SIS_315_VGA) {
+	        if(yres == 1050) {
+	           paneltype = Panel310_1400x1050;
+		   checkexpand = TRUE;
+	        } 
+	     }
+      	     break;
+	 case 1600:
+	     if(pSiS->VGAEngine == SIS_315_VGA) {
+	        if(yres == 1200) {
+	           paneltype = Panel310_1600x1200;
+		   checkexpand = TRUE;
+	        } 
+	     }
+      	     break;
+      }
+                 
+      /* Determine if RGB18 or RGB24 */
+      if(index) {
+         if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
+	    cr37 |= 0x01;
+	 }
+      }
+      
+      if(checkexpand) {
+         /* TODO - for now, we let the panel scale */
+	 cr37 |= 0x10;
+      }
+     
+      /* Now seek 4-Byte Timing codes and extract sync pol info */
+      index = 0x80;
+      if(buffer[0x7e] & 0x20) {			    /* skip Luminance Table (if provided) */
+         lumsize = buffer[0x80] & 0x1f;
+	 if(buffer[0x80] & 0x80) lumsize *= 3;
+	 lumsize++;
+	 index += lumsize;
+      }
+      index += (((buffer[0x7e] & 0x1c) >> 2) * 8);   /* skip Frequency Ranges */
+      index += ((buffer[0x7e] & 0x03) * 27);         /* skip Detailed Range Limits */
+      numcodes = (buffer[0x7f] & 0xf8) >> 3;
+      if(numcodes) {
+         myindex = index;
+ 	 seekcode = (xres - 256) / 16;
+     	 for(i=0; i<numcodes; i++) {
+	    if(buffer[myindex] == seekcode) break;
+	    myindex += 4;
+	 }
+	 if(buffer[myindex] == seekcode) {
+	    cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
+	 } else {
+	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
+	    	"CRT2: Unable to retrieve Sync polarity information\n");    
+	 }
+      } else {
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
+	    	"CRT2: Unable to retrieve Sync polarity information\n");
+      }
+
+      break;
+     
+   }
+   
+   /* 1280x960 panels are always RGB24, unable to scale and use
+    * high active sync polarity
+    */
+   if(pSiS->VGAEngine == SIS_315_VGA) {
+      if(paneltype == Panel310_1280x960) cr37 &= 0x0e; 
+   } else {
+      if(paneltype == Panel300_1280x960) cr37 &= 0x0e; 
+   }
+   
+   if(paneltype) {
+       cr37 &= 0xf1;
+       cr37 |= 0x02;    /* SiS301 */
+       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x36,0xf0,paneltype);
+       SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,cr37);
+       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
+#ifdef TWDEBUG       
+       xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3, 
+       	"CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
+#endif	
+   }
+   return 0;
+}
+   
+USHORT
+SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS)
+{
+   USHORT DDCdatatype,flag;
+   BOOLEAN foundcrt = FALSE;
+   int retry;
+   unsigned char buffer[256];
+
+   if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0;
+/* if(pSiS->VBFlags & VB_30xBDH) return 0;  */
+   
+   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 2, 0, FALSE) == 0xFFFF) return 0;
+   
+   SiS_Pr->SiS_DDC_SecAddr = 0x00;
+   
+   /* Probe supported DA's */
+   flag = SiS_ProbeDDC(SiS_Pr);
+   if(flag & 0x10) {
+      SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;	/* EDID V2 (FP) */
+      DDCdatatype = 4;
+   } else if(flag & 0x08) {
+      SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;	/* EDID V2 (P&D-D Monitor) */
+      DDCdatatype = 3;
+   } else if(flag & 0x02) {
+      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;	/* EDID V1 */
+      DDCdatatype = 1;
+   } else {
+   	xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
+		"Do DDC answer\n");
+   	return 0;				/* no DDC support (or no device attached) */
+   }
+   
+   /* Read the entire EDID */
+   retry = 2;
+   do {
+      if(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer)) {
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
+	 	"CRT2: DDC read failed (attempt %d), %s\n", 
+		(3-retry), (retry == 1) ? "giving up" : "retrying");
+	 retry--;
+	 if(retry == 0) return 0xFFFF;
+      } else break;
+   } while(1);
+   
+   /* Analyze EDID. We don't have many chances to 
+    * distinguish a flat panel from a CRT...
+    */
+   switch(DDCdatatype) {
+   case 1:
+      if(buffer[0x14] & 0x80) {			/* Display uses digital input */
+          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	  	"CRT2: Attached display expects digital input\n");
+      	  return 0;  	
+      }
+      foundcrt = TRUE;
+      break;
+   case 3:
+   case 4:
+      if( ((buffer[0x41] & 0x0f) != 0x01) &&  	/* Display does not support analog input */
+          ((buffer[0x41] & 0x0f) != 0x02) &&
+	  ((buffer[0x41] & 0xf0) != 0x10) &&
+	  ((buffer[0x41] & 0xf0) != 0x20) ) {
+	  xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	     	"CRT2: Attached display does not support analog input (0x%02x)\n",
+		buffer[0x41]);
+	  return 0;
+      }
+      foundcrt = TRUE;
+      break;	  
+   }
+   
+   if(foundcrt) {
+       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
+   }
+   return(0);
+}
+
+#if 0
+   /* ----- */
+USHORT
+SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
+{
+   USHORT DDCdatatype, paneltype, flag;
+   unsigned char cr36=0, cr37=0;
+   unsigned char tempal, tempah, tempbl, tempbh;
+   USHORT tempax, tempbx, tempcx, push1, push2, push3;
+   unsigned char addresstable[] = { 0x00, 0x22, 0x30, 0x40 };
+   int i;
+   unsigned char buffer[256];
+   
+   if(pSiS->VGAEngine != SIS_315_VGA) return 0xFFFF;
+   if(!(pSiS->VBFlags & (VB_301B|VB_302B))) return 0xFFFF;
+   
+   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 1, 0, FALSE) == 0xFFFF) return 0xFFFF;   
+   
+   flag = SiS_ProbeDDC(SiS_Pr);
+   if(flag & 0x02) {
+      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;	/* EDID V1 */
+      DDCdatatype = 1;
+      SiS_Pr->SiS_DDC_SecAddr = 0x3a;
+   } else if(flag & 0x08) {
+      SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;	/* EDID V2 (P&D-D Monitor) */
+      DDCdatatype = 3;
+      SiS_Pr->SiS_DDC_SecAddr = 0x76;
+   } else if(flag & 0x10) {
+      SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;	/* EDID V2 (FP) */
+      DDCdatatype = 4;
+      SiS_Pr->SiS_DDC_SecAddr = 0x76;
+   } else return 0xFFFF;
+   
+   
+   SiS_ReadLCDDDC(SiS_Pr, 4, buffer);
+   tempbl = buffer[0];  /* 3a - 76 */
+   tempbh = buffer[1];  /* 3b - 77 */
+   
+   if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
+   
+      /* Read and analyze EDID V1 (res) */
+   
+      tempah = 0x02;				/* 1024x768 by default */
+      tempbl &= 0xf0;
+      if(tempbl != 0x40) {			
+         tempah = 0x03;				/* 1280x1024 by default */
+	 if(tempbl == 0x50) {
+	    if(!tempbh) {
+	       tempbh = buffer[3] & 0xf0;
+	       if(tempbh == 0x30) {
+	           SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+      		   SiS_Pr->SiS_DDC_SecAddr = 0x23;
+		   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+		   tempbl = buffer[0];  /* 0x23 */
+		   tempbh = buffer[1];  /* 0x24 */
+		   if(tempbl) cr37 |= 0x10;
+		   tempah = 0x0a;		/* 1280x768 */
+	       }
+	       if(tempbh == 0x40) {
+	           SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+      		   SiS_Pr->SiS_DDC_SecAddr = 0x23;
+		   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+		   tempbl = buffer[0];  /* 0x23 */
+		   tempbh = buffer[1];  /* 0x24 */
+		   if(tempbl) cr37 |= 0x10;
+		   tempah = 0x03;		/* 1280x1024 */
+	       }
+	       tempbh = 0x00;
+	    }
+	 }
+	 if(tempbh == 0x00) goto cr36ready;
+	 tempah = 0x07;				/* 1280x960 */
+	 if(tempbh == 0xc0) goto cr36ready;
+      }
+      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+      SiS_Pr->SiS_DDC_SecAddr = 0x18;		/* feature support */
+      SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+      tempbl = buffer[0];
+      tempbh = buffer[1];
+      if(tempbl & 0x02) goto cr36ready;
+      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
+      SiS_Pr->SiS_DDC_SecAddr = 0x23;		/* Established Timings */
+      SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+      tempbl = buffer[0];
+      tempbh = buffer[1];
+      tempah = 0x03;
+      if(!(tempbh & 0x01)) tempah = 0x02;
+      if(!tempbl) cr37 |= 0x10;
+      
+  } else {
+  
+      /* Read and analyze EDID V2 (res) */
+      
+      tempah = 0x02;
+      tempbx = tempbl | (tempbh << 8);
+      if(tempbx != 1024) tempah = 0x03;
+      
+  }     
+
+cr36ready:
+  cr36 = tempah;      
+  
+  if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
+  
+     /* Read and analyze EDID V1 (pol) */
+  
+     SiS_Pr->SiS_DDC_SecAddr = 0x47;
+     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+     tempah = buffer[0];
+     tempah &= 0x06;
+     tempah ^= 0x06;
+     tempah <<= 5;
+     tempah |= 0x20;
+     cr37 &= 0x1f;
+     cr37 |= tempah;
+     if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
+     
+  } else {
+  
+     /* Read and analyze EDID V2 (depth, pol) */
+  
+     push1 = tempah;
+     SiS_Pr->SiS_DDC_SecAddr = 0x45;
+     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+     tempah = 0x01;
+     if((buffer[0] != 0x20) && (buffer[0] != 0x34)) {   /* RGB18 or 24? */
+        tempah = 0x00;
+     }
+     cr37 &= 0xfe;
+     cr37 |= tempah;
+     
+     SiS_Pr->SiS_DDC_SecAddr = 0x7e;
+     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+     tempax = (USHORT)(buffer[0] | (buffer[1] << 8));
+     push2 = tempax;
+     tempax &= 0x0003;
+     tempax *= 0x1b;
+     push3 = tempax;
+     tempax = (USHORT)buffer[0];
+     tempax &= 0x001c;
+     tempax >>= 2;
+     tempax *= 8;
+     tempbx = push3;
+     tempbx += tempax;
+     if(buffer[0] & 0x20) {		/* Luminance table provided? */
+        SiS_Pr->SiS_DDC_SecAddr = 0x80;
+	SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+	tempax = buffer[0] | (buffer[1] << 8);
+	tempax &= 0x1f;
+	if(buffer[0] & 0x70) tempax <<= 1;
+	tempax++;	
+	tempbx += tempax;        	/* yes -> skip it */
+     }
+     tempcx = push2;
+     tempax = push1 << 8;
+     tempbx = (tempbx & 0xff00) | (((tempbx & 0x00ff) + 0x80) & 0x00ff);
+     if(tempcx & 0xf800) {
+        tempal = addresstable[((tempax & 0xff00) >> 8)];
+	tempcx &= 0xf8ff;
+	tempcx >>= 11;
+	for(i=0; i<tempcx; i++) {
+	   SiS_Pr->SiS_DDC_SecAddr = (tempbx & 0x00ff);
+	   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
+	   tempbx += 0x04;
+	   if(buffer[0] == tempal) break;
+	}
+	tempah = buffer[1];
+	tempah &= 0x0c;
+	tempah ^= 0x0c;
+	tempah <<= 4;
+	tempah |= 0x20;
+        cr37 &= 0x1f;
+        cr37 |= tempah;
+	if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
+     }
+  }
+  xf86DrvMsg(0, X_INFO, "DDC: cr36 = 0x%02x, cr37 = 0x%02x\n", cr36, cr37);
+  return 0;
+}
+#endif
+
+/* TW: Generic I2C functions (compliant to i2c library) */
+
+#if 0
+USHORT
+SiS_I2C_GetByte(SiS_Private *SiS_Pr)
+{
+   return(SiS_ReadDDC2Data(SiS_Pr,0));
+}
+
+Bool
+SiS_I2C_PutByte(SiS_Private *SiS_Pr, USHORT data)
+{
+   if(SiS_WriteDDC2Data(SiS_Pr,data)) return FALSE;
+   return TRUE;
+}
+
+Bool
+SiS_I2C_Address(SiS_Private *SiS_Pr, USHORT addr)
+{
+   if(SiS_SetStart(SiS_Pr)) return FALSE;
+   if(SiS_WriteDDC2Data(SiS_Pr,addr)) return FALSE;
+   return TRUE;
+}
+
 void
-SiS_SetCH70xxANDOR(USHORT tempax,USHORT tempbh)
+SiS_I2C_Stop(SiS_Private *SiS_Pr)
+{
+   SiS_SetStop(SiS_Pr);
+}
+#endif
+
+#endif
+
+void
+SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
 {
   USHORT tempal,tempah,tempbl;
 
   tempal = tempax & 0x00FF;
   tempah =(tempax >> 8) & 0x00FF;
-  tempbl = SiS_GetCH70xx(tempal);
+  tempbl = SiS_GetCH70xx(SiS_Pr,tempal);
   tempbl = (((tempbl & tempbh) | tempah) << 8 | tempal);
-  SiS_SetCH70xx(tempbl);
+  SiS_SetCH70xx(SiS_Pr,tempbl);
 }
 
 /* TW: Generic I2C functions for Chrontel --------- */
 
-/* I2C functions CHECKED FOR TV BUG */
 void
-SiS_SetSwitchDDC2(void)
+SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
 {
-  SiS_SetSCLKHigh();
-  SiS_DDC2Delay(SiS_I2CDELAY);
-
-  SiS_SetSCLKLow();
-  SiS_DDC2Delay(SiS_I2CDELAY);
+  SiS_SetSCLKHigh(SiS_Pr);
+  /* SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAY); */
+  SiS_WaitRetraceDDC(SiS_Pr);
+
+  SiS_SetSCLKLow(SiS_Pr);
+  /* SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAY); */
+  SiS_WaitRetraceDDC(SiS_Pr);
 }
 
 /* TW: Set I2C start condition */
 /* TW: This is done by a SD high-to-low transition while SC is high */
 USHORT
-SiS_SetStart(void)
+SiS_SetStart(SiS_Private *SiS_Pr)
 {
-  if (SiS_SetSCLKLow()) return 0xFFFF;			                   /* TW: (SC->low)  */
-  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,SiS_DDC_Data);  /* TW: SD->high */
-  if (SiS_SetSCLKHigh()) return 0xFFFF;			                   /* TW: SC->high */
-  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,0x00);          /* TW: SD->low = start condition */
-  if (SiS_SetSCLKHigh()) return 0xFFFF;			                   /* TW: (SC->low) */
+  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low)  */
+  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);             /* TW: SD->high */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: SC->high */
+  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+                  ~SiS_Pr->SiS_DDC_Data,0x00);                             /* TW: SD->low = start condition */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low) */
   return 0;
 }
 
 /* TW: Set I2C stop condition */
 /* TW: This is done by a SD low-to-high transition while SC is high */
 USHORT
-SiS_SetStop(void)
+SiS_SetStop(SiS_Private *SiS_Pr)
 {
-  if (SiS_SetSCLKLow()) return 0xFFFF;			                   /* TW: (SC->low) */
-  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,0x00);          /* TW: SD->low   */
-  if (SiS_SetSCLKHigh()) return 0xFFFF;			                   /* TW: SC->high  */
-  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,SiS_DDC_Data);  /* TW: SD->high = stop condition */
-  if (SiS_SetSCLKHigh()) return 0xFFFF;			                   /* TW: (SC->high) */
+  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low) */
+  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+                  ~SiS_Pr->SiS_DDC_Data,0x00);          		   /* TW: SD->low   */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: SC->high  */
+  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);  	   /* TW: SD->high = stop condition */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->high) */
   return 0;
 }
 
 /* TW: Write 8 bits of data */
 USHORT
-SiS_WriteDDC2Data(USHORT tempax)
+SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
 {
   USHORT i,flag,temp;
 
   flag=0x80;
   for(i=0;i<8;i++) {
-    SiS_SetSCLKLow();					                      /* TW: SC->low */
+    SiS_SetSCLKLow(SiS_Pr);				                      /* TW: SC->low */
     if(tempax & flag) {
-      SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,SiS_DDC_Data); /* TW: Write bit (1) to SD */
+      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+                      ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);            /* TW: Write bit (1) to SD */
     } else {
-      SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,0x00);         /* TW: Write bit (0) to SD */
+      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+                      ~SiS_Pr->SiS_DDC_Data,0x00);                            /* TW: Write bit (0) to SD */
     }
-    SiS_SetSCLKHigh();					                      /* TW: SC->high */
+    SiS_SetSCLKHigh(SiS_Pr);				                      /* TW: SC->high */
     flag >>= 1;
   }
-  temp=SiS_CheckACK();					                      /* TW: Check acknowledge */
+  temp = SiS_CheckACK(SiS_Pr);				                      /* TW: Check acknowledge */
   return(temp);
 }
 
 USHORT
-SiS_ReadDDC2Data(USHORT tempax)
+SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
 {
   USHORT i,temp,getdata;
 
   getdata=0;
   for(i=0; i<8; i++) {
     getdata <<= 1;
-    SiS_SetSCLKLow();
-    SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,SiS_DDC_Data);
-    SiS_SetSCLKHigh();
-    temp = SiS_GetReg1(SiS_DDC_Port,SiS_DDC_Index);
-    if(temp & SiS_DDC_Data) getdata |= 0x01;
+    SiS_SetSCLKLow(SiS_Pr);
+    SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+                    ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);
+    SiS_SetSCLKHigh(SiS_Pr);
+    temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
+    if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
   }
   return(getdata);
 }
 
 USHORT
-SiS_SetSCLKLow(void)
+SiS_SetSCLKLow(SiS_Private *SiS_Pr)
 {
-  USHORT temp, watchdog=50000;
-
-  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Clk,0x00);      /* SetSCLKLow()  */
-  do {
-    temp = SiS_GetReg1(SiS_DDC_Port,SiS_DDC_Index);
-  } while((temp & SiS_DDC_Clk) && --watchdog);
-  if (!watchdog) return 0xFFFF;
-  SiS_DDC2Delay(SiS_I2CDELAYSHORT);
+  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+                  ~SiS_Pr->SiS_DDC_Clk,0x00);      		/* SetSCLKLow()  */
+  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
   return 0;
 }
 
 USHORT
-SiS_SetSCLKHigh(void)
+SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
 {
-  USHORT temp,watchdog=50000;
+  USHORT temp,watchdog=1000;
 
-  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Clk,SiS_DDC_Clk);      /* SetSCLKHigh()  */
+  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+                  ~SiS_Pr->SiS_DDC_Clk,SiS_Pr->SiS_DDC_Clk);  	/* SetSCLKHigh()  */
   do {
-    temp = SiS_GetReg1(SiS_DDC_Port,SiS_DDC_Index);
-  } while((!(temp & SiS_DDC_Clk)) && --watchdog);
-  if (!watchdog) return 0xFFFF;
-  SiS_DDC2Delay(SiS_I2CDELAYSHORT);
+    temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
+  } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
+  if (!watchdog) {
+#ifdef TWDEBUG
+        xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
+#endif	   
+  	return 0xFFFF;
+  }
+  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
   return 0;
 }
 
 void
-SiS_DDC2Delay(USHORT delaytime)
+SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
 {
   USHORT i;
 
   for(i=0; i<delaytime; i++) {
-    SiS_GetReg1(SiS_P3c4,0x05);
+    SiS_GetReg1(SiS_Pr->SiS_P3c4,0x05);
   }
 }
 
 /* TW: Check I2C acknowledge */
 /* Returns 0 if ack ok, non-0 if ack not ok */
 USHORT
-SiS_CheckACK(void)
+SiS_CheckACK(SiS_Private *SiS_Pr)
 {
   USHORT tempah;
 
-  SiS_SetSCLKLow();					                   /* TW: (SC->low) */
-  SiS_SetRegANDOR(SiS_DDC_Port,SiS_DDC_Index,~SiS_DDC_Data,SiS_DDC_Data);  /* TW: (SD->high) */
-  SiS_SetSCLKHigh();					                   /* TW: SC->high = clock impulse for ack */
-  tempah = SiS_GetReg1(SiS_DDC_Port,SiS_DDC_Index);	                   /* TW: Read SD */
-  SiS_SetSCLKLow();					                   /* TW: SC->low = end of clock impulse */
-  if(tempah & SiS_DDC_Data) return(1);			                   /* TW: Ack OK if bit = 0 */
+  SiS_SetSCLKLow(SiS_Pr);				           /* TW: (SC->low) */
+  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
+                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);     /* TW: (SD->high) */
+  SiS_SetSCLKHigh(SiS_Pr);				           /* TW: SC->high = clock impulse for ack */
+  tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* TW: Read SD */
+  SiS_SetSCLKLow(SiS_Pr);				           /* TW: SC->low = end of clock impulse */
+  if(tempah & SiS_Pr->SiS_DDC_Data) return(1);			   /* TW: Ack OK if bit = 0 */
   else return(0);
 }
 
 /* TW: End of I2C functions ----------------------- */
 
 
-/* =============== SiS 310 O.E.M. ================= */
+/* =============== SiS 310/325/330 O.E.M. ================= */
 
 #ifdef SIS315H
 
-/*
----------------------------------------------------------
-   LCDResInfo 1 : 800x600          TW: Table wrong for LVDS!
-              2 : 1024x768
-              3 : 1280x1024
-              4 : 1280x960         TW: 1400x1050
-              5 : 640x480          TW: 1600x1200
-              6 : 1600x1200
-              7 : 1920x1440
-   VESA
-   non-VESA
-   non-Expanding
----------------------------------------------------------
-*/
-USHORT
-GetLCDPtrIndex (void)
+static USHORT
+GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr)
 {
-   USHORT index;
+  USHORT romptr;
 
-   if(SiS_IF_DEF_LVDS == 1) {   /* TW: Inserted entire if statement */
+  if(HwDeviceExtension->jChipType < SIS_330) {
+     romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);  
+     if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
+        romptr = ROMAddr[0x12a] | (ROMAddr[0x12b] << 8);
+  } else {
+     romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);  
+     if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
+        romptr = ROMAddr[0x1aa] | (ROMAddr[0x1ab] << 8);
+  }
+  return(romptr);
+}
 
-     index = SiS_LCDResInfo & 0x0F;
-     if(SiS_LCDResInfo == Panel1400x1050)  index -= 5;
-     if(SiS_LCDResInfo == Panel1600x1200)  index -= 6;
-     index--;
-     index *= 3;
-     if(SiS_LCDInfo & LCDNonExpanding) index += 2;
-     else if(!(SiS_SetFlag & LCDVESATiming)) index++;
+static USHORT
+GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr)
+{
+  USHORT romptr;
 
-   } else {
+  if(HwDeviceExtension->jChipType < SIS_330) {
+     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);  
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+        romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
+  } else {
+     romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);  
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+        romptr = ROMAddr[0x1a2] | (ROMAddr[0x1a3] << 8);
+  }
+  return(romptr);
+}
 
-     index = (SiS_LCDResInfo & 0x0F) - 1;
-     index *= 3;
-     if (SiS_LCDInfo & LCDNonExpanding)
-        index += 2;
-     else if (!(SiS_SetFlag & LCDVESATiming))
-         index++;
+static USHORT
+GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr)
+{
+  USHORT romptr;
 
-   }
+  if(HwDeviceExtension->jChipType < SIS_330) {
+     romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8);
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+        romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8);
+  } else {
+     romptr = ROMAddr[0x194] | (ROMAddr[0x195] << 8);
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
+        romptr = ROMAddr[0x19a] | (ROMAddr[0x19b] << 8);
+  }
+  return(romptr);
+}
+
+static USHORT
+GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr)
+{
+  USHORT index;
+  
+  index = SiS_Pr->SiS_LCDResInfo & 0x0F;
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)      index -= 5;
+  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) index -= 6;
+  index--;
+  index *= 3;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
+  else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
 
   return index;
- }
+}
 
+static USHORT
+GetLCDPtrIndex(SiS_Private *SiS_Pr)
+{
+  USHORT index;
+
+  index = SiS_Pr->SiS_LCDResInfo & 0x0F;
+  index--;
+  index *= 3;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
+  else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
+
+  return index;
+}
 
 /*
 ---------------------------------------------------------
@@ -7751,282 +10924,599 @@
                        5 : HiVision Standard TVSimuMode
 ---------------------------------------------------------
 */
-USHORT
-GetTVPtrIndex(void)
+static USHORT
+GetTVPtrIndex(SiS_Private *SiS_Pr)
 {
   USHORT index;
 
   index = 0;
-  if (SiS_VBInfo & SetPALTV)
-    index++;
-  if (SiS_VBInfo & SetCRT2ToHiVisionTV)  /* Hivision TV use PAL */
-    index++;
+  if(SiS_Pr->SiS_VBInfo & SetPALTV) index++;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) index++;  /* Hivision TV use PAL */
 
   index <<= 1;
 
-  if((SiS_VBInfo & SetInSlaveMode) && (SiS_SetFlag & TVSimuMode))
+  if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (SiS_Pr->SiS_SetFlag & TVSimuMode))
     index++;
 
   return index;
 }
 
-/* TW: Checked against 650/LVDS (1.10.07) and 650/301LV BIOS (including data) */
-void
-SetDelayComp(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-             UCHAR *ROMAddr,USHORT ModeNo)
+static void
+SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+             UCHAR *ROMAddr, USHORT ModeNo)
 {
-  USHORT Part1Port;
-  USHORT delay,index;
+  USHORT delay,index,myindex,temp,romptr=0;
+  
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* VGA */
+     
+     if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+        romptr = GetRAMDACromptr(SiS_Pr, HwDeviceExtension, ROMAddr);
+	if(!romptr) return;
+	delay = ROMAddr[romptr];
+     } else {
+        delay = 0x04;
+        if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+	   if(IS_SIS650) {
+	      delay = 0x0a;
+	   } else if(IS_SIS740) {
+	      delay = 0x00;
+	   } else if(HwDeviceExtension->jChipType < SIS_330) {
+	      delay = 0x0c;
+	   } else {
+	      delay = 0x0c;
+	   }
+	}
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
+           delay = 0x00;
+     }
+  
+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {		/* LCD */
+  
+     index = GetLCDPtrIndexBIOS(SiS_Pr);
+     myindex = GetLCDPtrIndex(SiS_Pr);
+     
+     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { 	/* 650+30xLV */
+       if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+          if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+#if 0	     /* Always use the second pointer on 650; some BIOSes */
+             /* still carry old 301 data at the first location    */  
+	     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8); 
+	     if(SiS_Pr->SiS_VBType & VB_SIS302LV) 
+#endif		
+	        romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
+	     if(!romptr) return;
+	     delay = ROMAddr[(romptr + index)];
+	  } else {
+             delay = SiS310_LCDDelayCompensation_650301B[myindex];   
+#if 0	     
+	     if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+	        delay = SiS310_LCDDelayCompensation_650301B[myindex];
+#endif		
+	  }
+       } else {
+          delay = SiS310_LCDDelayCompensation_651301LV[myindex];     
+	  if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+	     delay = SiS310_LCDDelayCompensation_651302LV[myindex];  
+       }
+     } else {
+        if((ROMAddr) && SiS_Pr->SiS_UseROM && 				/* 315, 330, 740, 650+301B */
+	   (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) { 
+           romptr = GetLCDromptr(SiS_Pr, HwDeviceExtension, ROMAddr);
+	   if(!romptr) return;
+	   delay = ROMAddr[(romptr + index)];
+        } else {
+           delay = SiS310_LCDDelayCompensation_301[myindex];
+           if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+#if 0 	      /* This data is (like the one in the BIOS) wrong. */	   
+	      if(IS_SIS650740) {  /* V */
+	         delay = SiS310_LCDDelayCompensation_650301B[myindex];
+	      } else {
+#endif	      
+                 delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
+#if 0		 
+	      }
+#endif	      
+	   }
+           if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+	      if(IS_SIS650) {
+                 delay = SiS310_LCDDelayCompensation_LVDS650[myindex];
+	      } else {
+	         delay = SiS310_LCDDelayCompensation_LVDS740[myindex];
+	      }
+	   }
+        }
+     }
+     
+  } else {							/* TV */
+  
+     index = GetTVPtrIndex(SiS_Pr);
+     
+     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+       if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+          if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+#if 0	     /* Always use the second pointer on 650; some BIOSes */
+             /* still carry old 301 data at the first location    */  	  
+             romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8);
+	     if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+#endif	     
+	        romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8);
+	     if(!romptr) return;
+	     delay = ROMAddr[romptr + index];
+	  } else {
+	     delay = SiS310_TVDelayCompensation_301B[index];     
+#if 0	     
+	     if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+	        delay = SiS310_TVDelayCompensation_301B[index];  
+#endif		
+	  }
+       } else {
+          delay = SiS310_TVDelayCompensation_651301LV[index];       
+	  if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+	      delay = SiS310_TVDelayCompensation_651302LV[index];   
+       }
+     } else {
+       if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+          romptr = GetTVromptr(SiS_Pr, HwDeviceExtension, ROMAddr);
+	  if(!romptr) return;
+	  delay = ROMAddr[romptr + index];
+       } else {
+	    delay = SiS310_TVDelayCompensation_301[index];
+            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	       if(IS_SIS740) 
+	          delay = SiS310_TVDelayCompensation_740301B[index];
+	       else 
+                  delay = SiS310_TVDelayCompensation_301B[index];
+	    }
+            if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
+               delay = SiS310_TVDelayCompensation_LVDS[index];
+       }
+     }
+    
+  }
 
-  if (SiS_VBInfo & SetCRT2ToRAMDAC) {
-     delay = SiS310_CRT2DelayCompensation1;
-     if (SiS_VBType & (VB_SIS301B | VB_SIS302B))
-       delay = SiS310_CRT2DelayCompensation2;
-     if(SiS_IF_DEF_LVDS == 1)
-       delay = SiS310_CRT2DelayCompensation3;
-  } else if (SiS_VBInfo & SetCRT2ToLCD) {
-       index = GetLCDPtrIndex();
-       delay = SiS310_LCDDelayCompensation1[index];
-       if (SiS_VBType & (VB_SIS301B|VB_SIS302B|VB_SIS301LV))
-         delay = SiS310_LCDDelayCompensation2[index];
-       if(SiS_IF_DEF_LVDS == 1)
-         delay = SiS310_LCDDelayCompensation3[index];
-  } else {
-       index = GetTVPtrIndex();
-       delay = SiS310_TVDelayCompensation1[index];
-       if (SiS_VBType & (VB_SIS301B | VB_SIS302B))
-         delay = SiS310_TVDelayCompensation2[index];
-       if(SiS_IF_DEF_LVDS == 1)
-         delay = SiS310_TVDelayCompensation3[index];
-  }
-  Part1Port=BaseAddr+SIS_CRT2_PORT_04;
-  if(SiS_IF_DEF_LVDS == 1) {
-    if(SiS_VBInfo & SetCRT2ToTV) {
-       SiS_SetRegANDOR(Part1Port,0x2D,0xF0,delay);
-    } else {
-       delay <<= 4;
-       SiS_SetRegANDOR(Part1Port,0x2D,0x0F,delay);
-    }
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
+     } else {
+        if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
+           delay <<= 4;
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
+        } else {
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
+        }
+     }
   } else {
-     SiS_SetRegANDOR(Part1Port,0x2D,0xF0,delay);  /* index 2D D[3:0] */
+     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+        temp = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
+        if(temp == 8) {
+	   delay &= 0x0f;
+	   delay |= 0xb0;
+        } else if(temp == 6) {
+           delay &= 0x0f;
+	   delay |= 0xc0;
+        }
+        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay);  /* index 2D D[3:0] */
+     } else {
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
+     }
   }
 }
 
-/* TW: Checked against 650/301LV BIOS (including data) */
-void
-SetAntiFlicker(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+static void
+SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
                UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-  USHORT Part2Port;
-  USHORT index,temp;
+  USHORT index,temp,romptr=0;
 
-  Part2Port=BaseAddr+SIS_CRT2_PORT_10;
+  temp = GetTVPtrIndex(SiS_Pr);
+  temp >>= 1;  	  /* 0: NTSC, 1: PAL, 2: HiTV */
 
-  temp = GetTVPtrIndex();
-  temp >>= 1;  	  /* 0: NTSC, 1 :PAL, 2:HiTV */
-
-  if (ModeNo<=0x13)
-    index = SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
+  if(ModeNo<=0x13)
+     index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
   else
-    index = SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
+     index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
 
-  temp = SiS310_TVAntiFlick1[temp][index];
-  temp  <<= 4;
+  if(ROMAddr && SiS_Pr->SiS_UseROM) {
+     romptr = ROMAddr[0x112] | (ROMAddr[0x113] << 8);
+     if(HwDeviceExtension->jChipType == SIS_330) {
+        romptr = ROMAddr[0x192] | (ROMAddr[0x193] << 8);
+     }
+  }
 
-  SiS_SetRegANDOR(Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
+  if(romptr) {
+     temp <<= 1;
+     temp = ROMAddr[romptr + temp + index];
+  } else {
+     temp = SiS310_TVAntiFlick1[temp][index];
+  }
+  temp <<= 4;
+
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
 }
 
-/* TW: Checked against 650/301LV BIOS (including data) */
-void
-SetEdgeEnhance(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+static void
+SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
                UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-  USHORT Part2Port;
-  USHORT index,temp;
-
-  Part2Port = BaseAddr + SIS_CRT2_PORT_10;
+  USHORT index,temp,romptr=0;
 
-  temp = GetTVPtrIndex();
-  temp >>= 1;              	/* 0: NTSC, 1 :PAL, 2:HiTV */
+  temp = GetTVPtrIndex(SiS_Pr);
+  temp >>= 1;              	/* 0: NTSC, 1: PAL, 2: HiTV */
 
-  if (ModeNo<=0x13)
-    index = SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
+  if(ModeNo<=0x13)
+     index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
   else
-    index = SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
+     index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
+
+  if(ROMAddr && SiS_Pr->SiS_UseROM) {
+     romptr = ROMAddr[0x124] | (ROMAddr[0x125] << 8);
+     if(HwDeviceExtension->jChipType == SIS_330) {
+        romptr = ROMAddr[0x1a4] | (ROMAddr[0x1a5] << 8);
+     }
+  }
 
-  temp = SiS310_TVEdge1[temp][index];
+  if(romptr) {
+     temp <<= 1;
+     temp = ROMAddr[romptr + temp + index];
+  } else {
+     temp = SiS310_TVEdge1[temp][index];
+  }
   temp <<= 5;
-  SiS_SetRegANDOR(Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
 }
 
-/* TW: Checked against 650/301LV BIOS */
-void
-SetYFilter(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+static void
+SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
            UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-  USHORT Part2Port;
-  USHORT index,temp,i,j;
-  UCHAR  OutputSelect=*pSiS_OutputSelect;
+  USHORT index, temp, i, j;
+  UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
 
-  Part2Port = BaseAddr + SIS_CRT2_PORT_10;
-
-  temp = GetTVPtrIndex();
-  temp >>= 1;  			/* 0: NTSC, 1 :PAL, 2:HiTV */
+  temp = GetTVPtrIndex(SiS_Pr);
+  temp >>= 1;  			/* 0: NTSC, 1: PAL, 2: HiTV */
 
   if (ModeNo<=0x13) {
-    index =  SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
+    index =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
   } else {
-    index =  SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
+    index =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
   }
 
-  if (SiS_VBInfo&SetCRT2ToHiVisionTV)  /* Hivision TV uses PAL */
-    temp = 0;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)  temp = 1;  /* Hivision TV uses PAL */
 
-  if(SiS_VBType & VB_SIS301BLV302BLV) {
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
     for(i=0x35, j=0; i<=0x38; i++, j++) {
-       SiS_SetReg1(Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
+       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
     }
     for(i=0x48; i<=0x4A; i++, j++) {
-       SiS_SetReg1(Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
+       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
     }
   } else {
     for(i=0x35, j=0; i<=0x38; i++, j++){
-       SiS_SetReg1(Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
+       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
     }
   }
 
+  if(ROMAddr && SiS_Pr->SiS_UseROM) {
+  	OutputSelect = ROMAddr[0xf3];
+	if(HwDeviceExtension->jChipType == SIS_330) {
+	    OutputSelect = ROMAddr[0x11b];
+	}
+  }
   if(OutputSelect & EnablePALMN) {
-      if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
-         temp = SiS_GetReg1(SiS_P3d4,0x38);
-         temp &= (EnablePALMN | EnablePALN);
-         if(temp == EnablePALMN) {
-              if(SiS_VBType & VB_SIS301BLV302BLV) {
-                 for(i=0x35, j=0; i<=0x38; i++, j++){
-                      SiS_SetReg1(Part2Port,i,SiS310_PALMFilter2[index][j]);
+      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+         temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+         temp &= (EnablePALM | EnablePALN);
+         if(temp == EnablePALM) {
+              if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+                 for(i=0x35, j=0; i<=0x38; i++, j++) {
+                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]);
                  }
                  for(i=0x48; i<=0x4A; i++, j++) {
-                       SiS_SetReg1(Part2Port,i,SiS310_PALMFilter2[index][j]);
+                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]);
                  }
               } else {
                  for(i=0x35, j=0; i<=0x38; i++, j++) {
-                       SiS_SetReg1(Part2Port,i,SiS310_PALMFilter[index][j]);
+                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter[index][j]);
                  }
               }
          }
          if(temp == EnablePALN) {
-              if(SiS_VBType & VB_SIS301BLV302BLV) {
+              if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
                  for(i=0x35, j=0; i<=0x38; i++, j++) {
-                      SiS_SetReg1(Part2Port,i,SiS310_PALNFilter2[index][j]);
+                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]);
                  }
                  for(i=0x48, j=0; i<=0x4A; i++, j++) {
-                       SiS_SetReg1(Part2Port,i,SiS310_PALNFilter2[index][j]);
+                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]);
                  }
              } else {
-                 for(i=0x35, j=0; i<=0x38; i++, j++)
-                       SiS_SetReg1(Part2Port,i,SiS310_PALNFilter[index][j]);
+                 for(i=0x35, j=0; i<=0x38; i++, j++) {
+                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter[index][j]);
+		 }
              }
          }
       }
   }
 }
 
-/* TW: Checked against 650/301LV BIOS (including data) */
-void
-SetPhaseIncr(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-             UCHAR *ROMAddr,USHORT ModeNo)
+static void
+SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+             UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-  USHORT Part2Port;
-  USHORT index,temp,temp1,i,j;
+  USHORT index,temp,temp1,i,j,resinfo,romptr=0;
 
-  if(!(SiS_VBInfo & SetCRT2ToTV)) return;
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
 
-  temp1 = SiS_GetReg1(SiS_P3d4,0x38);        /* if PALM/N not set */
-  temp1 &=  (EnablePALMN | EnablePALN);
+  temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);        /* if PALM/N not set */
+  temp1 &=  (EnablePALM | EnablePALN);
   if(temp1) return;
 
-  Part2Port=BaseAddr + SIS_CRT2_PORT_10;
+  if (ModeNo<=0x13) {
+    resinfo =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else {
+    resinfo =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
 
-  temp = GetTVPtrIndex();
-  /* 0: NTSC Graphics, 1: NTSC Text,    2:PAL Graphics,
-   * 3: PAL Text,      4: HiTV Graphics 5:HiTV Text
+  temp = GetTVPtrIndex(SiS_Pr);
+  /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,
+   * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text
    */
-  index = temp % 2;
-  temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
-
-  for(j=0, i=0x31; i<=0x34; i++, j++) {
-     if(!(SiS_VBType & VB_SIS301BLV302BLV))
-	  SiS_SetReg1(Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
-     else if((!(SiS_VBInfo & SetInSlaveMode)) || (SiS_SetFlag & TVSimuMode))
-          SiS_SetReg1(Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
-     else
-          SiS_SetReg1(Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
+  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+     romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
+     if(HwDeviceExtension->jChipType == SIS_330) {
+        romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
+     }
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+        romptr = ROMAddr[0x11c] | (ROMAddr[0x11d] << 8);
+	if(HwDeviceExtension->jChipType == SIS_330) {
+	   romptr = ROMAddr[0x19c] | (ROMAddr[0x19d] << 8);
+	}
+	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_SetFlag & TVSimuMode))) {
+	   romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
+	   if(HwDeviceExtension->jChipType == SIS_330) {
+              romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
+           }
+	}
+     }
   }
-  if(SiS_VBType & (VB_SIS301LV | VB_SIS302LV)) {
-     if(!(SiS_VBInfo & SetPALTV)) {
-        if((ModeNo == 0x38) || (ModeNo == 0x4a)) {
-	    SiS_SetReg1(SiS_Part2Port,0x31,0x1e);
-	    SiS_SetReg1(SiS_Part2Port,0x32,0x8c);
-	    SiS_SetReg1(SiS_Part2Port,0x33,0x5c);
-	    SiS_SetReg1(SiS_Part2Port,0x34,0x7a);
+  if(romptr) {
+     romptr += (temp << 2);
+     for(j=0, i=0x31; i<=0x34; i++, j++) {
+        SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
+     }
+  } else {
+     index = temp % 2;
+     temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
+     for(j=0, i=0x31; i<=0x34; i++, j++) {
+        if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
+	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
+        else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_SetFlag & TVSimuMode))
+           SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
+        else
+           SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
+     }
+  }
+
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* TW: 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
+     if((!(SiS_Pr->SiS_VBInfo & SetPALTV)) && (ModeNo > 0x13)) {
+        if(resinfo == 6) {
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
+	} else if (resinfo == 7) {
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
+	} else if (resinfo == 8) {
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x1e);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0x8b);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xfb);
+	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7b);
 	}
      }
   }
 }
 
 void
-SiS_OEM310Setting(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
                   UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-   SetDelayComp(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
-   /* TW: The TV funtions are not for LVDS */
-   if( (SiS_IF_DEF_LVDS == 0) && (SiS_VBInfo & SetCRT2ToTV) ) {
-       SetAntiFlicker(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-       SetPhaseIncr(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
-       SetYFilter(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-       if(!(SiS_VBType & VB_SIS301BLV302BLV)) {
-          SetEdgeEnhance(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+   SetDelayComp(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+   /* TW: The TV functions are not for LVDS */
+   if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
+       SetAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       SetPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       SetYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+          SetEdgeEnhance(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
        }
    }
 }
 
+/* FinalizeLCD
+ * This finalizes some Part1 registers for the very panel used.
+ * If we have a backup if these registers, we use it; otherwise
+ * we set the register according to most BIOSes. However, this
+ * function looks quite different in every BIOS, so you better
+ * pray that we have a backup...
+ */
+void
+SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+{
+  USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
+  USHORT resinfo,modeflag;
+
+  if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
+
+  if(ModeNo <= 0x13) {
+	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+	modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else {
+    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+	modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
+
+  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
+	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+     }
+     tempch = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+     tempch &= 0xf0;
+     tempch >>= 4;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1f,0x76);
+	}
+	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {	
+	   if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
+	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
+	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
+	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
+	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
+	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
+	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
+	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
+	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
+	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
+	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
+	   } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {	/* From 1.10.8w */
+	       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,0x90);
+	       if(ModeNo <= 0x13) {
+	          SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x11);
+		  if((resinfo == 0) && (resinfo == 2)) return;
+		  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x18);
+		  if((resinfo == 1) && (resinfo == 3)) return;
+	       }
+	       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);
+	       if((ModeNo > 0x13) && (resinfo == 8)) {
+	          SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
+#if 0	       
+	          tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
+		  tempbx--;
+		  temp = tempbx & 0xff;
+		  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,temp);
+		  temp = (tempbx >> 8) & 0x03;
+		  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
+#endif		  
+	       }
+	   } else {
+	       if(ModeNo <= 0x13) {
+	          if(ModeNo <= 1) {
+		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x70);
+		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0xff);
+		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x48);
+		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x12);
+		  }
+		  if(!(modeflag & HalfDCLK)) {
+		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,0x20);
+		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,0x1a);
+		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,0x28);
+		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,0x00);
+		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x4c);
+		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0xdc);
+		     if(ModeNo == 0x12) {
+			 switch(tempch) {
+			 case 0:
+			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x95);
+			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0xdc);
+			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1a,0x10);
+			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x95);
+			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,0x48);
+			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x12);
+			    break;
+			 case 2:
+			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x95);
+			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x48);
+			    break;
+			 case 3:
+			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x95);
+			    break;
+			 }
+		     }
+		  }
+	       }
+	   }
+	}
+     } else {
+        tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
+	tempcl &= 0x0f;
+	tempbh &= 0x70;
+	tempbh >>= 4;
+	tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
+	tempbx = (tempbh << 8) | tempbl;
+	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+	   if((resinfo == 8) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
+	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+	      	tempbx = 770;
+	      } else {
+	        if(tempbx > 770) tempbx = 770;
+		if(SiS_Pr->SiS_VGAVDE < 600) {
+		   tempax = 768 - SiS_Pr->SiS_VGAVDE;
+		   tempax >>= 4;  				/* From 1.10.7w; 1.10.6s: 3;  */
+		   if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* From 1.10.7w; 1.10.6s: < 480; >>=1; */
+		   tempbx -= tempax;
+		}
+	      }
+	   } else return;
+	}
+#if 0
+	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+	}
+#endif
+	temp = tempbx & 0xff;
+	SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
+	temp = (tempbx & 0xff00) >> 8;
+	temp <<= 4;
+	temp |= tempcl;
+	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
+     }
+  }
+}
+
+#if 0
 /* TW: New and checked from 650/301LV BIOS */
+/* This might clash with newer "FinalizeLCD()" function */
 void
-SiS_OEMLCD(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
                   UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
    USHORT tempbx,tempah,tempbl,tempbh,tempcl;
 
-   if(SiS_IF_DEF_LVDS == 1) return;
+   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
 
-   if(SiS_VBInfo & SetCRT2ToLCDA) {
-      SiS_UnLockCRT2(HwDeviceExtension,BaseAddr);
-      tempbh = SiS_GetReg1(SiS_Part1Port,0x1a);
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+      SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+      tempbh = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x1a);
       tempbh &= 0x38;
       tempbh >>= 3;
-      tempbl = SiS_GetReg1(SiS_Part1Port,0x18);
+      tempbl = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
       tempbx = (tempbh << 8) | tempbl;
-      if(SiS_LCDTypeInfo == 1)  tempbx -= 0x12;
-      SiS_SetReg1(SiS_Part1Port,0x18,tempbx & 0x00ff);
+      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempbx -= 0x12;
+      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,tempbx & 0x00ff);
       tempah = (tempbx & 0xff00) >> 8;
       tempah &= 0x07;
       tempah <<= 3;
-      SiS_SetRegANDOR(SiS_Part1Port,0x1a,0xc7,tempah);
-      tempah = SiS_GetReg1(SiS_Part1Port,0x19);
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0xc7,tempah);
+      tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x19);
       tempah &= 0x0f;
-      if(SiS_LCDTypeInfo == 1)  tempah -= 2;
+      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah -= 2;
       tempah &= 0x0f;
-      SiS_SetRegANDOR(SiS_Part1Port,0x19,0xF0,tempah);
-      tempah = SiS_GetReg1(SiS_Part1Port,0x14);
-      if(SiS_LCDTypeInfo == 1)  tempah++;
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,tempah);
+      tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x14);
+      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah++;
       tempah -= 8;
-      SiS_SetReg1(SiS_Part1Port,0x14,tempah);
-   } else if(SiS_VBInfo & SetCRT2ToLCD) {
-      tempcl = tempbh = SiS_GetReg1(SiS_Part2Port,0x01);
+      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,tempah);
+   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+      tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
       tempbh &= 0x70;
       tempbh >>= 4;
-      tempbl = SiS_GetReg1(SiS_Part2Port,0x04);
+      tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
       tempbx = (tempbh << 8) | tempbl;
-      if(SiS_LCDTypeInfo == 1)  {
+      if(SiS_Pr->SiS_LCDTypeInfo == 1)  {
            tempbx -= 0x1e;
 	   tempcl &= 0x0f;
 	   tempcl -= 4;
@@ -8034,22 +11524,24 @@
       }
       tempbl = tempbx & 0x00ff;
       tempbh = (tempbx >> 8) & 0x00ff;
-      SiS_SetReg1(SiS_Part2Port,0x04,tempbl);
+      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,tempbl);
       tempbh <<= 4;
       tempbh |= tempcl;
-      SiS_SetRegANDOR(SiS_Part2Port,0x01,0x80,tempbh);
+      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,tempbh);
    }
 }
 #endif
 
+#endif
+
 
 /*  =================  SiS 300 O.E.M. ================== */
 
 #ifdef SIS300
 
 #if 0   /* Not used */
-USHORT
-GetRevisionID(PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static USHORT
+GetRevisionID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
 {
    ULONG temp1;
 #ifndef LINUX_XF86
@@ -8075,225 +11567,357 @@
 }
 #endif
 
-/* TW: Checked against 630/301B BIOS (incl data) */
-USHORT
-GetOEMLCDPtr(PSIS_HW_DEVICE_INFO HwDeviceExtension, int Flag)
+static USHORT
+GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr, int Flag)
 {
-  USHORT tempbx=0;
-  UCHAR customtable[] = {
+  USHORT tempbx=0,romptr=0;
+  UCHAR customtable300[] = {
+  	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+  };
+  UCHAR customtable630[] = {
   	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
   };
 
-  if(Flag) {
-      if(customtable[SiS_LCDTypeInfo] == 0xFF) return 0xFFFF;
-  }
-  if(SiS_IF_DEF_LVDS == 0) {
-        tempbx = SiS_LCDTypeInfo << 2;
-	if(SiS_VBInfo & SetInSlaveMode) tempbx += 2;
-	if(SiS_LCDInfo & LCDNonExpanding) tempbx++;
+  if(HwDeviceExtension->jChipType == SIS_300) {
+
+    tempbx = SiS_Pr->SiS_LCDResInfo - 2;
+    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
+    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
+    }
+    if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+       if(ROMAddr[0x235] & 0x80) {
+          tempbx = SiS_Pr->SiS_LCDTypeInfo;
+          if(Flag) {
+	    romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
+	    if(romptr) {
+	        tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
+	    } else {
+	        tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
+	    }
+            if(tempbx == 0xFF) return 0xFFFF;
+          }
+	  tempbx <<= 1;
+	  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
+       }
+    }
+
   } else {
-  	tempbx = SiS_LCDTypeInfo;
-	if(SiS_LCDInfo & LCDNonExpanding) tempbx += 16;
+
+    if(Flag) {
+      if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+         romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
+	 if(romptr) {
+	    tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
+	 } else {
+	    tempbx = 0xff;
+	 }
+      } else {
+         tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
+      }
+      if(tempbx == 0xFF) return 0xFFFF;
+      tempbx <<= 2;
+      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
+      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
+      return tempbx;
+    }
+    tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
+    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
+    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
   }
   return tempbx;
 }
 
-/* TW: Checked against 630/301B and 630/LVDS BIOS (incl data) */
-void
-SetOEMLCDDelay(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+static void
+SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
                UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-  USHORT Part1Port;
-  USHORT index,temp;
+  USHORT index,temp,romptr=0;
 
-  /* TW: The Panel Compensation Delay should be set according to tables
-   *     here. Unfortunately, the different BIOS versions don't case about
-   *     a uniform way using eg. ROM byte 0x220, but use different
-   *     hard coded delays (0x04, 0x20, 0x18) in SetGroup1(). So we can't
-   *     rely on the other OEM bits in 0x237, 0x238 here either.
-   */
-#if 0
-  if(ROMAddr) {
+  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x237] & 0x01)) return;
      if(!(ROMAddr[0x237] & 0x02)) return;
+     romptr = ROMAddr[0x24b] | (ROMAddr[0x24c] << 8);
   }
-#endif
-  /* TW: We just check if a non-standard delay has been set; if not,
-   * we use our tables. Otherwise don't do anything here.
+
+  /* TW: The Panel Compensation Delay should be set according to tables
+   *     here. Unfortunately, various BIOS versions don't case about
+   *     a uniform way using eg. ROM byte 0x220, but use different
+   *     hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
+   *     Thus we don't set this if the user select a custom pdc or if
+   *     we otherwise detected a valid pdc.
    */
-  if(ROMAddr) {
-     if(ROMAddr[0x220] & 0x80) return;
-  }
-  /* TW: We don't need to set this if the user select a custom pdc */
   if(HwDeviceExtension->pdc) return;
 
-  Part1Port = BaseAddr + SIS_CRT2_PORT_04;
+  temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 0);
 
-  temp = GetOEMLCDPtr(HwDeviceExtension, 0);
+  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
 
-  index = SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
-
-  if (SiS_IF_DEF_LVDS == 0) {
-    	temp = SiS300_OEMLCDDelay2[temp][index];
+  if(HwDeviceExtension->jChipType != SIS_300) {
+	if(romptr) {
+	   romptr += (temp * 2);
+	   romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+	   romptr += index;
+	   temp = ROMAddr[romptr];
+	} else {
+	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+    	      temp = SiS300_OEMLCDDelay2[temp][index];
+	   } else {
+              temp = SiS300_OEMLCDDelay3[temp][index];
+           }
+	}
   } else {
-        temp = SiS300_OEMLCDDelay3[temp][index];
+      if((ROMAddr) && SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
+	  if(romptr) {
+	     romptr += (temp * 2);
+	     romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+	     romptr += index;
+	     temp = ROMAddr[romptr];
+	  } else {
+	     temp = SiS300_OEMLCDDelay5[temp][index];
+	  }
+      } else {
+          if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+	     romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
+	     if(romptr) {
+	        romptr += (temp * 2);
+	        romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+	        romptr += index;
+	        temp = ROMAddr[romptr];
+	     } else {
+	        temp = SiS300_OEMLCDDelay4[temp][index];
+	     }
+	  } else {
+	     temp = SiS300_OEMLCDDelay4[temp][index];
+	  }
+      }
   }
   temp &= 0x3c;
-  SiS_SetRegANDOR(Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
 }
 
-/* TW: Checked against 630/301B and 630/LVDS BIOS */
-USHORT
-GetOEMTVPtr(void)
+static void
+SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+#if 0  /* TW: Unfinished; VData table missing */
+  USHORT index,temp;
+
+  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+     if(!(ROMAddr[0x237] & 0x01)) return;
+     if(!(ROMAddr[0x237] & 0x04)) return;
+     /* No rom pointer in BIOS header! */
+  }
+
+  temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 1);
+  if(temp = 0xFFFF) return;
+
+  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
+  for(i=0x14, j=0; i<=0x17; i++, j++) {
+      SiS_SetReg1(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
+  }
+  SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
+
+  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
+  SiS_SetReg1(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
+  SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
+  SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
+  for(i=0x1b, j=3; i<=0x1d; i++, j++) {
+      SiS_SetReg1(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
+  }
+#endif
+}
+
+static USHORT
+GetOEMTVPtr(SiS_Private *SiS_Pr)
 {
   USHORT index;
 
   index = 0;
-  if(!(SiS_VBInfo & SetInSlaveMode)) index += 4;
-  if(SiS_IF_DEF_LVDS == 0) {
-     if(SiS_VBInfo & SetCRT2ToSCART) index += 2;
-     else if (SiS_VBInfo & SetCRT2ToHiVisionTV) index += 3;
-     else if(SiS_VBInfo & SetPALTV)  index += 1;
+  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
+     else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) index += 3;
+     else if(SiS_Pr->SiS_VBInfo & SetPALTV)   index += 1;
   } else {
-     if(SiS_VBInfo & SetCHTVOverScan) index += 2;
-     if(SiS_VBInfo & SetPALTV)  index += 1;
+     if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) index += 2;
+     if(SiS_Pr->SiS_VBInfo & SetPALTV)        index += 1;
   }
   return index;
 }
 
-/* TW: Checked against 630/301B and 630/LVDS BIOS (incl data) */
-void
-SetOEMTVDelay(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+static void
+SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-  USHORT Part1Port;
-  USHORT index,temp;
+  USHORT index,temp,romptr=0;
 
-#if 0
-  if(ROMAddr) {
+  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x238] & 0x01)) return;
      if(!(ROMAddr[0x238] & 0x02)) return;
+     romptr = ROMAddr[0x241] | (ROMAddr[0x242] << 8);
   }
-#endif
 
-  Part1Port = BaseAddr + SIS_CRT2_PORT_04;
+  temp = GetOEMTVPtr(SiS_Pr);
 
-  temp = GetOEMTVPtr();
+  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
 
-  index = SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
-
-  if(SiS_IF_DEF_LVDS == 0) {
-     temp = SiS300_OEMTVDelay301[temp][index];
+  if(romptr) {
+     romptr += (temp * 2);
+     romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+     romptr += index;
+     temp = ROMAddr[romptr];
   } else {
-     temp = SiS300_OEMTVDelayLVDS[temp][index];
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+        temp = SiS300_OEMTVDelay301[temp][index];
+     } else {
+        temp = SiS300_OEMTVDelayLVDS[temp][index];
+     }
   }
   temp &= 0x3c;
-  SiS_SetRegANDOR(Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
 }
 
-/* TW: Checked against 630/301B BIOS (incl data) */
-void
-SetOEMAntiFlicker(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+static void
+SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
                   USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
 		  USHORT ModeIdIndex)
 {
-  USHORT Part2Port;
-  USHORT index,temp;
+  USHORT index,temp,romptr=0;
 
-  Part2Port = BaseAddr + SIS_CRT2_PORT_10;
+  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+     if(!(ROMAddr[0x238] & 0x01)) return;
+     if(!(ROMAddr[0x238] & 0x04)) return;
+     romptr = ROMAddr[0x243] | (ROMAddr[0x244] << 8);
+  }
 
-  temp = GetOEMTVPtr();
+  temp = GetOEMTVPtr(SiS_Pr);
 
-  index = SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
+  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
 
-  temp = SiS300_OEMTVFlicker[temp][index];
+  if(romptr) {
+     romptr += (temp * 2);
+     romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+     romptr += index;
+     temp = ROMAddr[romptr];
+  } else {
+     temp = SiS300_OEMTVFlicker[temp][index];
+  }
   temp &= 0x70;
-  SiS_SetRegANDOR(Part2Port,0x0A,0x8F,temp);  /* index 0A D[6:4] */
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);  /* index 0A D[6:4] */
 }
 
-/* TW: Checked against 630/301B BIOS (incl data) */
-void
-SetOEMPhaseIncr(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+static void
+SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
                 UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-  USHORT Part2Port;
-  USHORT index,i,j,temp;
+  USHORT index,i,j,temp,romptr=0;
 
-  if(SiS_VBInfo & SetCRT2ToHiVisionTV) return;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) return;
 
-  Part2Port = BaseAddr + SIS_CRT2_PORT_10;
+  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+     if(!(ROMAddr[0x238] & 0x01)) return;
+     if(!(ROMAddr[0x238] & 0x08)) return;
+     romptr = ROMAddr[0x245] | (ROMAddr[0x246] << 8);
+  }
 
-  temp = GetOEMTVPtr();
+  temp = GetOEMTVPtr(SiS_Pr);
 
-  index = SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
+  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
 
-  if(SiS_VBType & VB_SIS301BLV302BLV) {
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
        for(i=0x31, j=0; i<=0x34; i++, j++) {
-          SiS_SetReg1(Part2Port,i,SiS300_Phase2[temp][index][j]);
+          SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
        }
   } else {
-       for(i=0x31, j=0; i<=0x34; i++, j++) {
-          SiS_SetReg1(Part2Port,i,SiS300_Phase1[temp][index][j]);
+       if(romptr) {
+          romptr += (temp * 2);
+	  romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+	  romptr += (index * 4);
+          for(i=0x31, j=0; i<=0x34; i++, j++) {
+	     SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
+	  }
+       } else {
+          for(i=0x31, j=0; i<=0x34; i++, j++) {
+             SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
+	  }
        }
   }
 }
 
-/* TW: Checked against 630/301B BIOS (incl data) */
-void
-SetOEMYFilter(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+static void
+SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
 {
-  USHORT Part2Port;
-  USHORT index,temp,temp1,i,j;
+  USHORT index,temp,temp1,i,j,romptr=0;
 
-  if(SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVisionTV)) return;
+  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVisionTV)) return;
 
-  Part2Port = BaseAddr + SIS_CRT2_PORT_10;
+  if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+     if(!(ROMAddr[0x238] & 0x01)) return;
+     if(!(ROMAddr[0x238] & 0x10)) return;
+     romptr = ROMAddr[0x247] | (ROMAddr[0x248] << 8);
+  }
 
-  temp = GetOEMTVPtr();
+  temp = GetOEMTVPtr(SiS_Pr);
 
-  index = SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
+  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
 
-  if(SiS_GetReg1(SiS_P3d4,0x31) & 0x01) {
-       temp1 = SiS_GetReg1(SiS_P3d4,0x35);
-       if(temp1 & (EnablePALMN | EnablePALN)) {
-          temp = 16;
-	  if(temp1 & EnablePALN) temp = 18;
+  if(HwDeviceExtension->jChipType > SIS_300) {
+     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+       temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+       if(temp1 & (EnablePALM | EnablePALN)) {
+          temp = 8;
+	  if(!(temp1 & EnablePALM)) temp = 9;
        }
+     }
   }
-  if(SiS_VBType & VB_SIS301BLV302BLV) {
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
       for(i=0x35, j=0; i<=0x38; i++, j++) {
-       	SiS_SetReg1(Part2Port,i,SiS300_Filter2[temp][index][j]);
+       	SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
       }
       for(i=0x48; i<=0x4A; i++, j++) {
-     	SiS_SetReg1(Part2Port,i,SiS300_Filter2[temp][index][j]);
+     	SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
       }
   } else {
-      for(i=0x35, j=0; i<=0x38; i++, j++) {
-       	SiS_SetReg1(Part2Port,i,SiS300_Filter1[temp][index][j]);
+      if(romptr) {
+         romptr += (temp * 2);
+	 romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+	 romptr += (index * 4);
+	 for(i=0x35, j=0; i<=0x38; i++, j++) {
+       	    SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
+         }
+      } else {
+         for(i=0x35, j=0; i<=0x38; i++, j++) {
+       	    SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
+         }
       }
   }
 }
 
 void
-SiS_OEM300Setting(PSIS_HW_DEVICE_INFO HwDeviceExtension,
+SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
 		  USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo)
 {
   USHORT ModeIdIndex;
 
-  ModeIdIndex = SiS_SearchVBModeID(ROMAddr,&ModeNo);
+  ModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
   if(!(ModeIdIndex)) return;
 
-  if (SiS_VBInfo & SetCRT2ToLCD) {
-       SetOEMLCDDelay(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+       SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+            SetOEMLCDData(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       }
   }
-  if (SiS_VBInfo & SetCRT2ToTV) {
-       SetOEMTVDelay(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-       if(SiS_IF_DEF_LVDS==0) {
-       		SetOEMAntiFlicker(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-    		SetOEMPhaseIncr(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-       		SetOEMYFilter(HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+       SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+       		SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+    		SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       		SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
        }
   }
 }
diff -Nru a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
--- a/drivers/video/sis/init301.h	Thu Jul 11 10:30:30 2002
+++ b/drivers/video/sis/init301.h	Fri Mar  7 11:19:01 2003
@@ -24,9 +24,15 @@
 #endif
 
 #ifdef LINUX_KERNEL
+#include <linux/config.h>
+#include <linux/version.h>
 #include <asm/io.h>
 #include <linux/types.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 #include <linux/sisfb.h>
+#else
+#include <video/sisfb.h>
+#endif
 #endif
 
 #ifdef WIN2000
@@ -41,274 +47,315 @@
 #include "sisv.h"
 #endif
 
-USHORT   SiS_SetFlag;
-USHORT   SiS_RVBHCFACT,SiS_RVBHCMAX,SiS_RVBHRS;
-USHORT   SiS_VGAVT,SiS_VGAHT;
-USHORT   SiS_VT,SiS_HT;
-USHORT   SiS_VGAVDE,SiS_VGAHDE;
-USHORT   SiS_VDE,SiS_HDE;
-USHORT   SiS_NewFlickerMode,SiS_RY1COE,SiS_RY2COE,SiS_RY3COE,SiS_RY4COE;
-USHORT   SiS_LCDHDES,SiS_LCDVDES;
-USHORT   SiS_DDC_Port, SiS_DDC_Index,SiS_DDC_Data, SiS_DDC_Clk;
-USHORT   SiS_DDC_DataShift, SiS_DDC_DeviceAddr, SiS_DDC_Flag;
-USHORT   SiS_DDC_ReadAddr, SiS_DDC_Buffer;
-
-USHORT   Panel800x600,   Panel1024x768,  Panel1280x1024, Panel1600x1200;
-USHORT   Panel1280x960,  Panel1400x1050, Panel320x480,   Panel1152x768;
-USHORT   Panel1280x768,  Panel1024x600,  Panel640x480,   Panel1152x864;
-USHORT   PanelMax, PanelMinLVDS, PanelMin301;
-
-USHORT   SiS_ChrontelInit;
-
-extern   USHORT   SiS_CRT1Mode;
-extern   USHORT   SiS_P3c4,SiS_P3d4;
-extern   USHORT   SiS_P3ca;
-extern   USHORT   SiS_P3c9;
-extern   USHORT   SiS_P3da;
-extern   USHORT   SiS_Part1Port,SiS_Part2Port;
-extern   USHORT   SiS_Part3Port,SiS_Part4Port,SiS_Part5Port;
-extern   USHORT   SiS_MDA_DAC[];
-extern   USHORT   SiS_CGA_DAC[];
-extern   USHORT   SiS_EGA_DAC[];
-extern   USHORT   SiS_VGA_DAC[];
-extern   USHORT   SiS_ModeType;
-extern   USHORT   SiS_SelectCRT2Rate;
-extern   USHORT   SiS_IF_DEF_LVDS;
-extern   USHORT   SiS_IF_DEF_TRUMPION;
-extern   USHORT   SiS_IF_DEF_CH70xx;
-extern   USHORT   SiS_Backup70xx;
-extern   USHORT   SiS_IF_DEF_HiVision;
-extern   USHORT   SiS_IF_DEF_DSTN;   /*add for dstn*/
-extern   USHORT   SiS_IF_DEF_FSTN;   /*add for fstn*/
-extern   USHORT   SiS_VBInfo;
-extern   USHORT   SiS_VBType;
-extern   USHORT   SiS_VBExtInfo;
-extern   USHORT   SiS_LCDResInfo;
-extern   USHORT   SiS_LCDTypeInfo;
-extern   USHORT   SiS_LCDInfo;
-extern   USHORT   SiS_HiVision;
-
-extern   BOOLEAN  SiS_SearchVBModeID(UCHAR *RomAddr, USHORT *);
-
-BOOLEAN  SiS_Is301B(USHORT BaseAddr);
-BOOLEAN  SiS_IsDisableCRT2(USHORT BaseAddr);
-BOOLEAN  SiS_IsVAMode(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-BOOLEAN  SiS_IsDualEdge(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-BOOLEAN  SiS_CRT2IsLCD(USHORT BaseAddr);
-
-void     SiS_SetDefCRT2ExtRegs(USHORT BaseAddr);
-USHORT   SiS_GetRatePtrCRT2(UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
-BOOLEAN  SiS_AdjustCRT2Rate(UCHAR *ROMAddr,USHORT ModeNo,USHORT MODEIdIndex,USHORT RefreshRateTableIndex,USHORT *i);
-void     SiS_SaveCRT2Info(USHORT ModeNo);
-void     SiS_GetCRT2Data(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-                         PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_GetCRT2DataLVDS(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_GetCRT2PtrA(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-                         USHORT *CRT2Index,USHORT *ResIndex);
-void     SiS_GetCRT2Part2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		             USHORT RefreshRateTableIndex,USHORT *CRT2Index,
-		             USHORT *ResIndex);
-void     SiS_GetCRT2Data301(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-                            PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT   SiS_GetResInfo(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void     SiS_GetCRT2ResInfo(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_GetRAMDAC2DATA(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-                            PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_GetCRT2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-		        USHORT *CRT2Index,USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetCRT2ModeRegs(USHORT BaseAddr,USHORT ModeNo,USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO );
-void     SiS_SetHiVision(USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#if 0
+extern   const USHORT   SiS_MDA_DAC[];
+extern   const USHORT   SiS_CGA_DAC[];
+extern   const USHORT   SiS_EGA_DAC[];
+extern   const USHORT   SiS_VGA_DAC[];
+#endif
+
+extern   BOOLEAN  SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *RomAddr, USHORT *);
 
-void     SiS_GetLVDSDesData(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+BOOLEAN  SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr);
+BOOLEAN  SiS_IsNotM650or651(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_IsDisableCRT2(SiS_Private *SiS_Pr, USHORT BaseAddr);
+BOOLEAN  SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_CRT2IsLCD(SiS_Private *SiS_Pr, USHORT BaseAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_Pr, USHORT BaseAddr);
+USHORT   SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+                            PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN  SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT MODEIdIndex,
+                            USHORT RefreshRateTableIndex,USHORT *i,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo);
+void     SiS_GetCRT2Data(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                             USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#ifdef SIS315H			     
+void     SiS_GetCRT2PtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                         USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex);
+#endif
+void     SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		             USHORT RefreshRateTableIndex,USHORT *CRT2Index, USHORT *ResIndex);
+void     SiS_GetCRT2Data301(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                            USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT   SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetCRT2Offset(USHORT Part1Port,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+void     SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                            USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                        USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
+			PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT BaseAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                             PSIS_HW_DEVICE_INFO );
+void     SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_GetLVDSDesData(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+			    USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT2Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                            USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT   SiS_GetOffset(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-                       PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT   SiS_GetColorDepth(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-USHORT   SiS_GetMCLK(UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT   SiS_CalcDelayVB(void);
-USHORT   SiS_GetVCLK2Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+USHORT   SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                       USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT   SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
+USHORT   SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+USHORT   SiS_CalcDelayVB(SiS_Private *SiS_Pr);
+USHORT   SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
                          USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetCRT2Sync(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex,
-                         PSIS_HW_DEVICE_INFO HwDeviceExtension);
 void     SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR);
 void     SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR);
 void     SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND);
-USHORT   SiS_GetVGAHT2(void);
-void     SiS_SetGroup2(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+USHORT   SiS_GetVGAHT2(SiS_Private *SiS_Pr);
+void     SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+    	 		     USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+			     USHORT BaseAddr, USHORT ModeNo);
+void     SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                        USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetGroup3(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+void     SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                        PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetGroup4(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+void     SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                        USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetGroup5(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void     SiS_SetCRT2VCLK(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_EnableCRT2(void);
-void     SiS_LoadDAC2(UCHAR *ROMAddr,USHORT Part5Port,USHORT ModeNo,USHORT ModeIdIndex);
-void     SiS_WriteDAC2(USHORT Pdata,USHORT dl, USHORT ah, USHORT al, USHORT dh);
-void     SiS_GetVBInfo301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                          PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN  SiS_GetLCDResInfo(UCHAR *ROMAddr,USHORT P3d4,USHORT ModeNo,USHORT ModeIdIndex);
-BOOLEAN  SiS_BridgeIsOn(USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
-BOOLEAN  SiS_BridgeIsEnable(USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
-BOOLEAN  SiS_BridgeInSlave(void);
-void     SiS_PresetScratchregister(USHORT SiS_P3d4,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetTVSystem(VOID);
-void     SiS_LongWait(VOID);
-USHORT   SiS_GetQueueConfig(VOID);
-void     SiS_VBLongWait(VOID);
-USHORT   SiS_GetVCLKLen(UCHAR *ROMAddr);
-void     SiS_WaitVBRetrace(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_WaitRetrace1(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_WaitRetrace2(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetCRT2ECLK(UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+void     SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+                       USHORT ModeIdIndex);
+void     SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                          PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_GetLVDSDesPtr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-                           USHORT *PanelIndex,USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_GetLVDSDesPtrA(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-                            USHORT *PanelIndex,USHORT *ResIndex);
-void     SiS_SetTPData(VOID);
-void     SiS_ModCRT1CRTC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-			 PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN  SiS_GetLVDSCRT1Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-		       USHORT *ResInfo,USHORT *DisplayType);
-void     SiS_SetCHTVReg(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
-void     SiS_GetCHTVRegPtr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
-void     SiS_SetCH700x(USHORT tempax);
-USHORT   SiS_GetCH700x(USHORT tempax);
-void     SiS_SetCH701x(USHORT tempax);
-USHORT   SiS_GetCH701x(USHORT tempax);
-void     SiS_SetCH70xx(USHORT tempax);
-USHORT   SiS_GetCH70xx(USHORT tempax);
-void     SiS_SetCH70xxANDOR(USHORT tempax,USHORT tempbh);
-void     SiS_SetSwitchDDC2(void);
-USHORT   SiS_SetStart(void);
-USHORT   SiS_SetStop(void);
-void     SiS_DDC2Delay(USHORT delaytime);
-USHORT   SiS_SetSCLKLow(void);
-USHORT   SiS_SetSCLKHigh(void);
-USHORT   SiS_ReadDDC2Data(USHORT tempax);
-USHORT   SiS_WriteDDC2Data(USHORT tempax);
-USHORT   SiS_CheckACK(void);
+void     SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_EnableCRT2(SiS_Private *SiS_Pr);
+void     SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                       PSIS_HW_DEVICE_INFO HwDeviceExtension, int checkcrt2mode);
+BOOLEAN  SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
+BOOLEAN  SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
+BOOLEAN  SiS_BridgeInSlave(SiS_Private *SiS_Pr);
+void     SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetTVSystem(SiS_Private *SiS_Pr);
+void     SiS_LongWait(SiS_Private *SiS_Pr);
+USHORT   SiS_GetQueueConfig(SiS_Private *SiS_Pr);
+void     SiS_VBLongWait(SiS_Private *SiS_Pr);
+USHORT   SiS_GetVCLKLen(SiS_Private *SiS_Pr, UCHAR *ROMAddr);
+void     SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_WaitRetrace1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_WaitRetrace2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_WaitRetraceDDC(SiS_Private *SiS_Pr);
+void     SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
+                         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                           USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex,
+			   PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#ifdef SIS315H			   
+void     SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                            USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex);
+#endif			    
+void     SiS_SetTPData(SiS_Private *SiS_Pr);
+void     SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo);
+void     SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                        USHORT RefreshRateTableIndex);
+void     SiS_GetCHTVRegPtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                           USHORT RefreshRateTableIndex);
+void     SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT   SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
+void     SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT   SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
+void     SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT   SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
+#ifdef LINUX_XF86
+USHORT   SiS_I2C_GetByte(SiS_Private *SiS_Pr);
+Bool     SiS_I2C_PutByte(SiS_Private *SiS_Pr, USHORT data);
+Bool     SiS_I2C_Address(SiS_Private *SiS_Pr, USHORT addr);
+void     SiS_I2C_Stop(SiS_Private *SiS_Pr);
+#endif
+void     SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
+void     SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
+USHORT   SiS_SetStart(SiS_Private *SiS_Pr);
+USHORT   SiS_SetStop(SiS_Private *SiS_Pr);
+void     SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
+USHORT   SiS_SetSCLKLow(SiS_Private *SiS_Pr);
+USHORT   SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
+USHORT   SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT   SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT   SiS_CheckACK(SiS_Private *SiS_Pr);
+USHORT   SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer);
+#ifdef LINUX_XF86
+USHORT   SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+USHORT   SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+#endif
 #ifdef SIS315H
-void     SiS_OEM310Setting(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+void     SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
                            UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void     SiS_OEMLCD(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+void     SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
                     UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
 #endif
 #ifdef SIS300
-void     SiS_OEM300Setting(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
+void     SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
                            UCHAR *ROMAddr,USHORT ModeNo);
 #endif
-USHORT   GetRevisionID(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN  SiS_LowModeStuff(USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN  SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
 
-BOOLEAN  SiS_GetLCDResInfo301(UCHAR *ROMAddr,USHORT SiS_P3d4, USHORT ModeNo, USHORT ModeIdIndex,
-                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
-/* void    SiS_CHACRT1CRTC(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+BOOLEAN  SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex,
+                           PSIS_HW_DEVICE_INFO HwDeviceExtension);
+/* void    SiS_CHACRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                         USHORT RefreshRateTableIndex); */
-BOOLEAN  SiS_GetLCDACRT1Ptr(UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
-		   USHORT *DisplayType);
-/* 310 series OEM */
-USHORT 	GetLCDPtrIndex (void);
-USHORT  GetTVPtrIndex(void);
-void    SetDelayComp(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-             	     UCHAR *ROMAddr,USHORT ModeNo);
-void    SetAntiFlicker(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-               	       UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void    SetEdgeEnhance (PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-                        UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void    SetYFilter(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-           	   UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void	SetPhaseIncr(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-             	     UCHAR *ROMAddr,USHORT ModeNo);
-/* 300 series OEM */
-USHORT 	GetOEMLCDPtr(PSIS_HW_DEVICE_INFO HwDeviceExtension, int Flag);
-USHORT 	GetOEMTVPtr(void);
-void	SetOEMTVDelay(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-              	      UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void	SetOEMLCDDelay(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-               	       UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void	SetOEMAntiFlicker(PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                          USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void  	SetOEMPhaseIncr(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-                        UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void	SetOEMYFilter(PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-              	      UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-
-extern   void     SiS_SetReg1(USHORT, USHORT, USHORT);
-extern   void     SiS_SetReg3(USHORT, USHORT);
-extern   UCHAR    SiS_GetReg1(USHORT, USHORT);
-extern   UCHAR    SiS_GetReg2(USHORT);
-extern   BOOLEAN  SiS_SearchModeID(UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
-extern   BOOLEAN  SiS_GetRatePtr(ULONG, USHORT);
-extern   void     SiS_SetReg4(USHORT, ULONG);
-extern   ULONG    SiS_GetReg3(USHORT);
-extern   void     SiS_DisplayOff(void);
-extern   void     SiS_DisplayOn(void);
-extern   UCHAR    SiS_GetModePtr(UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
-#ifdef SIS315H
-extern   UCHAR    SiS_Get310DRAMType(UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-#endif
 
-BOOLEAN  SiS_SetCRT2Group301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
+BOOLEAN  SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
                              PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetGroup1(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+void     SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                        PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
-void     SiS_SetGroup1_LVDS(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+void     SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                            PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
+#ifdef SIS315H			    
+void     SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                             PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
-void     SiS_SetGroup1_LCDA(USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                            PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);/*301b*/
-void     SiS_SetGroup1_301(USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+#endif			    
+void     SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
                            PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
 #ifdef SIS300
-void     SiS_SetCRT2FIFO_300(UCHAR *ROMAddr,USHORT ModeNo,
+void     SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
                              PSIS_HW_DEVICE_INFO HwDeviceExtension);
 #endif
 #ifdef SIS315H
-void     SiS_SetCRT2FIFO_310(UCHAR *ROMAddr,USHORT ModeNo,
+void     SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
                              PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_CRT2AutoThreshold(USHORT  BaseAddr);
+void     SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr, USHORT  BaseAddr);
+#endif
+BOOLEAN  SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+void     SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+void     SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT  BaseAddr);
+void     SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
+void     SiS_SetPanelDelay(SiS_Private *SiS_Pr, UCHAR* ROMAddr,PSIS_HW_DEVICE_INFO,USHORT DelayTime);
+void     SiS_SetPanelDelayLoop(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                               USHORT DelayTime, USHORT DelayLoop);
+void     SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay);
+void     SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay);
+void     SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay);
+void     SiS_VBWait(SiS_Private *SiS_Pr);
+
+void     SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+void     SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+void     SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr);
+void     SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
+#ifdef SIS315H
+void     SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+                            USHORT BaseAddr);
+void     SiS_Chrontel701xOff(SiS_Private *SiS_Pr);
+void     SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void     SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void     SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void     SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void     SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+void     SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr);
+void     SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+#ifdef NEWCH701x
+void     SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr);
 #endif
-BOOLEAN  SiS_GetLCDDDCInfo(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_UnLockCRT2(PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
-void     SiS_LockCRT2(PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
-void     SiS_DisableBridge(PSIS_HW_DEVICE_INFO,USHORT  BaseAddr);
-void     SiS_EnableBridge(PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
-void     SiS_SetPanelDelay(UCHAR* ROMAddr,PSIS_HW_DEVICE_INFO,USHORT DelayTime);
-void     SiS_ShortDelay(USHORT delay);
-void     SiS_LongDelay(USHORT delay);
-void     SiS_GenericDelay(USHORT delay);
-void     SiS_VBWait(void);
-
-/* TW: New functions (with temporary names) */
-void     SiS_Chrontel701xOn(void);
-void     SiS_Chrontel701xOn2(PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                           USHORT BaseAddr);
-void     SiS_Chrontel701xOff(void);
-void     SiS_Chrontel701xOff2(void);
-void     SiS_ChrontelFlip0x48(void);
-void     SiS_ChrontelDoSomething4(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-void     SiS_ChrontelDoSomething3(USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-void     SiS_ChrontelDoSomething2(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-void     SiS_ChrontelDoSomething1(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-BOOLEAN  SiS_WeHaveBacklightCtrl(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+#endif /* 315 */
 #if 0
-BOOLEAN  SiS_IsSomethingCR5F(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_IsSomethingCR5F(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+#endif
+BOOLEAN  SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
+BOOLEAN  SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN  SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+BOOLEAN  SiS_IsSR13_CR30(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+
+extern   void     SiS_SetReg1(USHORT, USHORT, USHORT);
+extern   void     SiS_SetReg3(USHORT, USHORT);
+extern   UCHAR    SiS_GetReg1(USHORT, USHORT);
+extern   UCHAR    SiS_GetReg2(USHORT);
+extern   BOOLEAN  SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
+extern   BOOLEAN  SiS_GetRatePtr(SiS_Private *SiS_Pr, ULONG, USHORT);
+extern   void     SiS_SetReg4(USHORT, ULONG);
+extern   ULONG    SiS_GetReg3(USHORT);
+extern   void     SiS_SetReg5(USHORT, USHORT);
+extern   USHORT   SiS_GetReg4(USHORT);
+extern   void     SiS_DisplayOff(SiS_Private *SiS_Pr);
+extern   void     SiS_DisplayOn(SiS_Private *SiS_Pr);
+extern   UCHAR    SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
+extern   BOOLEAN  SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+		                     USHORT RefreshRateTableIndex,USHORT *ResInfo,USHORT *DisplayType);
+extern   BOOLEAN  SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+                                     USHORT RefreshRateTableIndex,USHORT *ResInfo,USHORT *DisplayType);
+extern   void     SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO, UCHAR *ROMAddr,USHORT ModeNo,
+                              USHORT ModeIdIndex);
+#ifdef SIS315H
+extern   UCHAR    SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#endif
+
+#ifdef LINUX_XF86
+/* DDC functions */
+USHORT   SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
+USHORT   SiS_WriteDABDDC(SiS_Private *SiS_Pr);
+USHORT   SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
+USHORT   SiS_PrepareDDC(SiS_Private *SiS_Pr);
+void     SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
+USHORT   SiS_DoProbeDDC(SiS_Private *SiS_Pr);
+USHORT   SiS_ProbeDDC(SiS_Private *SiS_Pr);
+USHORT   SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer);
+USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
+                       USHORT DDCdatatype, unsigned char *buffer);
 #endif
-BOOLEAN  SiS_IsYPbPr(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-BOOLEAN  SiS_IsTVOrSomething(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-BOOLEAN  SiS_IsLCDOrLCDA(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-void     SiS_SetCHTVForLCD(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-void     SiS_Chrontel19f2(void);
-BOOLEAN  SiS_CR36BIOSWord23b(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN  SiS_CR36BIOSWord23d(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN  SiS_IsSR13_CR30(PSIS_HW_DEVICE_INFO HwDeviceExtension);
 
-/* TW end */
+const UCHAR SiS_HiVisionTable[3][64] = {
+  { 
+    0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
+    0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
+    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
+    0x0c, 0x50, 0x00, 0x97, 0x00, 0xd4, 0x4a, 0x17,
+    0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02,
+    0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40,
+    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x53,
+    0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
+  },
+  { 
+    0x1d, 0x1d, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c,
+    0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a,
+    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
+    0x0c, 0x50, 0xb2, 0x2e, 0x16, 0xb5, 0xf4, 0x03,
+    0x7d, 0x11, 0x7d, 0xea, 0x30, 0x36, 0x18, 0x96,
+    0x21, 0x0a, 0x58, 0xee, 0x42, 0x92, 0x0f, 0x40,
+    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x04, 0xf3,
+    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
+  },
+  { 
+    0x13, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c, 
+    0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a, 
+    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f, 
+    0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x2b, 0x13, 
+    0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0, 
+    0x4b, 0x4b, 0x6f, 0x2f, 0x63, 0x92, 0x0f, 0x40, 
+    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x2a, 
+    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00 
+  }
+};
+
+const UCHAR SiS_HiTVGroup3_1[] = {
+    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
+    0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
+    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
+    0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
+    0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
+    0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
+    0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
+    0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
+};
+
+const UCHAR SiS_HiTVGroup3_2[] = {
+    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
+    0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
+    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
+    0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
+    0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
+    0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
+    0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
+    0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
+};
 
 #endif
diff -Nru a/drivers/video/sis/initdef.h b/drivers/video/sis/initdef.h
--- a/drivers/video/sis/initdef.h	Thu Jul 11 10:30:30 2002
+++ b/drivers/video/sis/initdef.h	Wed Mar  5 09:22:35 2003
@@ -15,8 +15,19 @@
 #define VB_SIS302B        	0x0004
 #define VB_SIS301LV     	0x0008
 #define VB_SIS302LV     	0x0010
+#define VB_SIS30xLV		VB_SIS301LV
+#define VB_SIS30xNEW		VB_SIS302LV
 #define VB_NoLCD        	0x8000
 #define VB_SIS301BLV302BLV      (VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)
+#define VB_SIS301B302B          (VB_SIS301B|VB_SIS302B)
+#define VB_SIS301LV302LV        (VB_SIS301LV|VB_SIS302LV)
+
+#define IS_SIS650740            ((HwDeviceExtension->jChipType >= SIS_650) && (HwDeviceExtension->jChipType < SIS_330))
+
+#define IS_SIS650		(HwDeviceExtension->jChipType == SIS_650)
+#define IS_SIS740		(HwDeviceExtension->jChipType == SIS_740)
+#define IS_SIS330		(HwDeviceExtension->jChipType == SIS_330)
+#define IS_SIS550		(HwDeviceExtension->jChipType == SIS_550)
 
 #define CRT1Len                 17
 #define LVDSCRT1Len             15
@@ -35,9 +46,9 @@
 #define ModeInfoFlag            0x07
 #define IsTextMode              0x07
 
-#define DACInfoFlag             0x18
-#define MemoryInfoFlag          0x1E0
-#define MemorySizeShift         0x05
+#define DACInfoFlag             0x0018
+#define MemoryInfoFlag          0x01E0
+#define MemorySizeShift         5
 
 /* modeflag */
 #define Charx8Dot               0x0200
@@ -57,8 +68,9 @@
 #define NoSupportHiVisionTV     0x0060
 #define NoSupportLCD            0x0058
 #define SupportCHTV 		0x0800
-#define SupportTV1024           0x0800  /*301b*/            
+#define SupportTV1024           0x0800            
 #define InterlaceMode           0x0080
+#define SupportHiVisionTV2      0x1000
 #define SyncPP                  0x0000
 #define SyncPN                  0x4000
 #define SyncNP                  0x8000
@@ -72,13 +84,13 @@
 /* VBInfo */
 #define SetSimuScanMode         0x0001   /* CR 30 */
 #define SwitchToCRT2            0x0002
-#define SetCRT2ToTV             0x009C
 #define SetCRT2ToAVIDEO         0x0004
 #define SetCRT2ToSVIDEO         0x0008
 #define SetCRT2ToSCART          0x0010
 #define SetCRT2ToLCD            0x0020
 #define SetCRT2ToRAMDAC         0x0040
 #define SetCRT2ToHiVisionTV     0x0080
+#define SetCRT2ToTV             0x009C   /* alias */
 #define SetNTSCTV               0x0000   /* CR 31 */
 #define SetPALTV                0x0100
 #define SetInSlaveMode          0x0200
@@ -92,6 +104,7 @@
 #define DriverMode              0x4000
 #define HotKeySwitch            0x8000  /* TW: ? */
 #define SetCRT2ToLCDA           0x8000
+
 #define PanelRGB18Bit           0x0100
 #define PanelRGB24Bit           0x0000
 
@@ -126,12 +139,12 @@
 	    010   LVDS
 	    011   LVDS + Chrontel 7019
 	  All other combinations reserved
-   [4]    LVDS: Expanding(0)/Non-expanding(1) LCD display
-          30x:  SiS30x(0)/LCD monitor(1) scaling display
+   [4]    LVDS: 0: Panel Link expands / 1: Panel Link does not expand
+          30x:  0: Bridge scales      / 1: Bridge does not scale = Panel scales (if possible)
    [5]    LCD polarity select
           0: VESA DMT Standard
 	  1: EDID 2.x defined
-   [6]    LCD honrizontal polarity select
+   [6]    LCD horizontal polarity select
           0: High active
 	  1: Low active
    [7]    LCD vertical polarity select
@@ -139,12 +152,37 @@
 	  1: Low active
 */
 
-#define EnableDualEdge 		0x01   /* CR38 (310/325 series) */
-/* #define PAL_NTSC             0x01      (only on 315PRO) */
-#define SetToLCDA		0x02   /* TW: LCD channel A (302 only) */
-#define SetYPbPr                0x10   /* TW: ? */
-#define EnablePALMN             0x40
-#define EnablePALN              0x80
+/* CR37: LCDInfo */
+#define LCDRGB18Bit           0x0001
+#define LCDNonExpanding       0x0010
+#define DontExpandLCD	      LCDNonExpanding
+#define LCDNonExpandingShift       4
+#define DontExpandLCDShift    LCDNonExpandingShift
+#define LCDSync               0x0020
+#define LCDPass11             0x0100 
+#define LCDSyncBit            0x00e0
+#define LCDSyncShift               6
+
+/* CR38 (310/325 series) */
+#define EnableDualEdge 		0x01   
+#define SetToLCDA		0x02   /* LCD channel A (302B/LV and 650+LVDS only) */
+#define EnableSiSHiVision       0x04   /* HiVision (HDTV) on SiS bridge */
+#define EnableLVDSScart         0x04   /* Scart on Ch7019 (unofficial definition - TW) */
+#define EnableLVDSHiVision      0x08   /* YPbPr color format (480i HDTV); only on 650/Ch7019 systems */
+#define SiSHiVision1            0x10   /* See SetHiVision() */
+#define SiSHiVision2            0x20
+#define EnablePALM              0x40   /* 1 = Set PALM */
+#define EnablePALN              0x80   /* 1 = Set PALN */
+
+#define SetSCARTOutput          0x01
+#define BoardTVType             0x02
+
+#define EnablePALMN             0x40   /* Romflag: 1 = Allow PALM/PALN */
+
+/* CR39 (650) */
+#define LCDPass1_1		0x01   /* LVDS only; set by driver to pass 1:1 data to LVDS output  */
+#define Enable302LV_DualLink    0x04   /* 30xNEW (302LV) only; set by mode switching function */
+
 
 /* CR79 (310/325 series only)
    [3-0] Notify driver
@@ -155,16 +193,15 @@
 	 0101 Set Contrast event
 	 0110 Set Mute event
 	 0111 Set Volume Up/Down event
-   [4]   Enable Backlight Control by BIOS/driver (set by driver)
+   [4]   Enable Backlight Control by BIOS/driver 
+         (set by driver; set means that the BIOS should
+	 not touch the backlight registers because eg.
+	 the driver already switched off the backlight)
    [5]   PAL/NTSC (set by BIOS)
-   [6]   Expansion On/Off (set by BIOS)
+   [6]   Expansion On/Off (set by BIOS; copied to CR32[4])
    [7]   TV UnderScan/OverScan (set by BIOS)
 */
 
-
-#define SetSCARTOutput          0x01
-#define BoardTVType             0x02
-
 /* SetFlag */
 #define ProgrammingCRT2         0x01
 #define TVSimuMode              0x02
@@ -173,8 +210,7 @@
 #define EnableLVDSDDA           0x10
 #define SetDispDevSwitchFlag    0x20
 #define CheckWinDos             0x40
-#define SetJDOSMode             0x80
-#define CRT2IsVGA	        0x80  /* TW: Not sure about this name... */
+#define SetDOSMode              0x80
 
 /* LCDResInfo */
 #define Panel300_800x600        0x01	/* CR36 */
@@ -184,7 +220,6 @@
 #define Panel300_640x480        0x05
 #define Panel300_1024x600       0x06
 #define Panel300_1152x768       0x07
-/* #define Panel300_1600x1200      0x06  OLD */
 #define Panel300_320x480        0x08 	/* fstn - TW: This is fake, can be any */
 
 #define Panel310_800x600        0x01
@@ -194,35 +229,40 @@
 #define Panel310_1024x600       0x05
 #define Panel310_1152x864       0x06
 #define Panel310_1280x960       0x07
-#define Panel310_1152x768       0x08
+#define Panel310_1152x768       0x08	/* LVDS only */
 #define Panel310_1400x1050      0x09
-#define Panel310_1280x768       0x0a
+#define Panel310_1280x768       0x0a    /* LVDS only */
 #define Panel310_1600x1200      0x0b
-#define Panel310_320x480        0x0c           /* fstn - TW: This is fake, can be any */
+#define Panel310_320x480        0x0c    /* fstn - TW: This is fake, can be any */
+
+#define Panel_800x600           0x01	/* Unified values */
+#define Panel_1024x768          0x02
+#define Panel_1280x1024         0x03
+#define Panel_640x480           0x04
+#define Panel_1024x600          0x05
+#define Panel_1152x864          0x06
+#define Panel_1280x960          0x07
+#define Panel_1152x768          0x08	/* LVDS only */
+#define Panel_1400x1050         0x09
+#define Panel_1280x768          0x0a    /* LVDS only */
+#define Panel_1600x1200         0x0b
+#define Panel_320x480           0x0c    /* fstn - TW: This is fake, can be any */
 
 #define ExtChipType             0x0e
 #define ExtChip301              0x02
 #define ExtChipLVDS             0x04
 #define ExtChipTrumpion         0x06
 #define ExtChipCH7005           0x08
-#define ExtChipMitacTV          0x0a            /* TW: Incorrect, 0x0a = Chrontel 7005 only */
+#define ExtChipMitacTV          0x0a    /* TW: Incorrect, 0x0a = Chrontel 7005 only */
 
-#define IsM650                  0x80   		/* TW: CR5F */
-
-/* LCDInfo */
-#define LCDRGB18Bit             0x01
-#define LCDNonExpandingShift    0x04
-#define LCDNonExpanding         0x10
-#define LCDSync                 0x20
-/* TW: What is.. */        /*  0x100   */
-#define LCDSyncBit              0xe0
-#define LCDSyncShift            6
+#define IsM650                  0x80   	/* TW: CR5F */
 
 #define LCDDataLen              8
 #define HiTVDataLen             12
 #define TVDataLen               16
 #define SetPALTV                0x0100
 #define HalfDCLK                0x1000  /* modeflag */
+
 #define NTSCHT                  1716
 #define NTSC2HT                 1920
 #define NTSCVT                  525
diff -Nru a/drivers/video/sis/oem300.h b/drivers/video/sis/oem300.h
--- a/drivers/video/sis/oem300.h	Thu Jul 11 10:30:30 2002
+++ b/drivers/video/sis/oem300.h	Wed Mar  5 09:22:35 2003
@@ -1,7 +1,7 @@
 
 /* OEM Data for 300 series */
 
-UCHAR SiS300_OEMTVDelay301[8][4] =
+const UCHAR SiS300_OEMTVDelay301[8][4] =
 {
 	{0x08,0x08,0x08,0x08},
 	{0x08,0x08,0x08,0x08},
@@ -13,7 +13,7 @@
 	{0x20,0x20,0x20,0x20}
 };
 
-UCHAR SiS300_OEMTVDelayLVDS[8][4] =
+const UCHAR SiS300_OEMTVDelayLVDS[8][4] =
 {
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -25,7 +25,7 @@
 	{0x20,0x20,0x20,0x20}
 };
 
-UCHAR SiS300_OEMTVFlicker[8][4] =
+const UCHAR SiS300_OEMTVFlicker[8][4] =
 {
 	{0x00,0x00,0x00,0x00},
 	{0x00,0x00,0x00,0x00},
@@ -38,7 +38,7 @@
 };
 
 #if 0   /* TW: Not used */
-UCHAR SiS300_OEMLCDDelay1[12][4]={
+const UCHAR SiS300_OEMLCDDelay1[12][4]={
 	{0x2c,0x2c,0x2c,0x2c},
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -55,7 +55,7 @@
 #endif
 
 /* TW: From 630/301B BIOS */
-UCHAR SiS300_OEMLCDDelay2[64][4] =		 /* for 301/301b/302b/301LV/302LV */
+const UCHAR SiS300_OEMLCDDelay2[64][4] =		 /* for 301/301b/302b/301LV/302LV */
 {
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -123,9 +123,99 @@
 	{0x20,0x20,0x20,0x20}
 };
 
+/* TW: From 300/301LV BIOS */
+const UCHAR SiS300_OEMLCDDelay4[12][4] =
+{
+	{0x2c,0x2c,0x2c,0x2c},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x2c,0x2c,0x2c,0x2c},
+	{0x2c,0x2c,0x2c,0x2c},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x24,0x24,0x24,0x24},
+	{0x24,0x24,0x24,0x24},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x24,0x24,0x24,0x24}
+};
+
+/* TW: From 300/301LV BIOS */
+const UCHAR SiS300_OEMLCDDelay5[32][4] =
+{
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+};
+
 /* TW: Added for LVDS */
-UCHAR SiS300_OEMLCDDelay3[32][4] = {	/* For LVDS */
-	{0x20,0x20,0x20,0x20},  /* --- Expanding panels */
+const UCHAR SiS300_OEMLCDDelay3[64][4] = {	/* For LVDS */
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
+	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -137,11 +227,8 @@
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
-	{0x04,0x04,0x04,0x04},		/* Clevo 2202 (PanelType 12); Mitac needs 0x20! */
 	{0x20,0x20,0x20,0x20},
-	{0x20,0x20,0x20,0x20},  	/* Uniwill N241S2 (PanelType 14)*/
 	{0x20,0x20,0x20,0x20},
-	{0x20,0x20,0x20,0x20},  /* ---- NonExpanding panels */
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
@@ -153,13 +240,12 @@
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
-	{0x04,0x04,0x04,0x04},          /* Gericom 2200C (PanelType 28) */
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20},
 	{0x20,0x20,0x20,0x20}
 };
 
-UCHAR SiS300_Phase1[8][6][4] =
+const UCHAR SiS300_Phase1[8][6][4] =
 {
     {
 	{0x21,0xed,0x00,0x08},
@@ -228,7 +314,7 @@
 };
 
 
-UCHAR SiS300_Phase2[8][6][4] =
+const UCHAR SiS300_Phase2[8][6][4] =
 {
     {
         {0x21,0xed,0x00,0x08},
@@ -296,7 +382,7 @@
     }
 };
 
-UCHAR SiS300_Filter1[10][17][4] =
+const UCHAR SiS300_Filter1[10][16][4] =
 {
     {
 	{0x00,0xf4,0x10,0x38},
@@ -314,8 +400,7 @@
 	{0xeb,0x04,0x25,0x18},
 	{0xeb,0x04,0x25,0x18},
 	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xff,0xff,0xff,0xff}
+	{0xeb,0x04,0x25,0x18}
     },
     {
 	{0x00,0xf4,0x10,0x38},
@@ -333,8 +418,7 @@
 	{0xf1,0xf7,0x1f,0x32},
 	{0xf1,0xf7,0x1f,0x32},
 	{0xf1,0xf7,0x1f,0x32},
-	{0xf1,0xf7,0x1f,0x32},
-	{0xff,0xff,0xff,0xff}
+	{0xf1,0xf7,0x1f,0x32}
     },
     {
 	{0x00,0xf4,0x10,0x38},
@@ -352,8 +436,7 @@
 	{0xf1,0xf7,0x1f,0x32},
 	{0xf1,0xf7,0x1f,0x32},
 	{0xf1,0xf7,0x1f,0x32},
-	{0xf1,0xf7,0x1f,0x32},
-	{0xff,0xff,0xff,0xff}
+	{0xf1,0xf7,0x1f,0x32}
     },
     {
 	{0x00,0xf4,0x10,0x38},
@@ -371,8 +454,7 @@
 	{0xf1,0xf7,0x1f,0x32},
 	{0xf1,0xf7,0x1f,0x32},
 	{0xf1,0xf7,0x1f,0x32},
-	{0xf1,0xf7,0x1f,0x32},
-	{0xff,0xff,0xff,0xff}
+	{0xf1,0xf7,0x1f,0x32}
     },
     {
 	{0x00,0xf4,0x10,0x38},
@@ -390,8 +472,7 @@
 	{0xeb,0x04,0x25,0x18},
 	{0xeb,0x04,0x25,0x18},
 	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xff,0xff,0xff,0xff}
+	{0xeb,0x04,0x25,0x18}
     },
     {
 	{0x00,0xf4,0x10,0x38},
@@ -409,8 +490,7 @@
 	{0xf1,0xf7,0x1f,0x32},
 	{0xf1,0xf7,0x1f,0x32},
 	{0xf1,0xf7,0x1f,0x32},
-	{0xf1,0xf7,0x1f,0x32},
-	{0xff,0xff,0xff,0xff}
+	{0xf1,0xf7,0x1f,0x32}
     },
     {
 	{0x00,0xf4,0x10,0x38},
@@ -428,8 +508,7 @@
 	{0xf1,0xf7,0x1f,0x32},
 	{0xf1,0xf7,0x1f,0x32},
 	{0xf1,0xf7,0x1f,0x32},
-	{0xf1,0xf7,0x1f,0x32},
-	{0xff,0xff,0xff,0xff}
+	{0xf1,0xf7,0x1f,0x32}
     },
     {
 	{0x00,0xf4,0x10,0x38},
@@ -447,8 +526,7 @@
 	{0xf1,0xf7,0x1f,0x32},
 	{0xf1,0xf7,0x1f,0x32},
 	{0xf1,0xf7,0x1f,0x32},
-	{0xf1,0xf7,0x1f,0x32},
-	{0xff,0xff,0xff,0xff}
+	{0xf1,0xf7,0x1f,0x32}
     },
     {
 	{0x00,0xf4,0x10,0x38},
@@ -466,8 +544,7 @@
 	{0xeb,0x04,0x25,0x18},
 	{0xeb,0x04,0x25,0x18},
 	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xff,0xff,0xff,0xff}
+	{0xeb,0x04,0x25,0x18}
     },
     {
 	{0x00,0xf4,0x10,0x38},
@@ -485,12 +562,11 @@
 	{0xeb,0x04,0x25,0x18},
 	{0xeb,0x04,0x25,0x18},
 	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xff,0xff,0xff,0xff}
+	{0xeb,0x04,0x25,0x18}
     },
 };
 
-UCHAR SiS300_Filter2[10][9][7] =
+const UCHAR SiS300_Filter2[10][9][7] =
 {
     {
 	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
@@ -604,3 +680,325 @@
     }
 };
 
+const UCHAR SiS300_LCDHData[24][11][5] = {
+    {
+        {0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x65,0xef,0x83,0x5c,0x00},
+	{0x65,0xef,0x83,0x5c,0x00},
+	{0x8a,0x14,0x00,0x80,0x00},
+	{0x8a,0x14,0x00,0x80,0x00}
+    },
+    {
+        {0x4e,0x18,0x90,0x38,0x00},
+	{0x4e,0x18,0x90,0x38,0x00},
+	{0x8e,0x18,0x28,0x78,0x00},
+	{0x8e,0x18,0x28,0x78,0x00},
+	{0x8e,0x18,0x28,0x78,0x00},
+	{0x4e,0x18,0x90,0x38,0x00},
+	{0x4e,0x18,0x90,0x38,0x00},
+	{0x67,0x11,0x9a,0x56,0x00},
+        {0x67,0x11,0x9a,0x56,0x00},
+	{0x8a,0x14,0x00,0x80,0x00},
+	{0x8a,0x14,0x00,0x80,0x00}
+    },
+    {
+        {0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x65,0xef,0x83,0x5c,0x00},
+	{0x65,0xef,0x83,0x5c,0x00},
+	{0x8a,0x14,0x00,0x80,0x00},
+	{0x8a,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x4e,0x18,0x90,0x38,0x00},
+	{0x4e,0x18,0x90,0x38,0x00},
+	{0x8e,0x18,0x28,0x78,0x00},
+	{0x8e,0x18,0x28,0x78,0x00},
+	{0x8e,0x18,0x28,0x78,0x00},
+	{0x4e,0x18,0x90,0x38,0x00},
+	{0x4e,0x18,0x90,0x38,0x00},
+	{0x67,0x11,0x9a,0x56,0x00},
+	{0x67,0x11,0x9a,0x56,0x00},
+	{0x8a,0x14,0x00,0x80,0x00},
+	{0x8a,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x67,0x91,0x84,0x5e,0x00},
+	{0x65,0xef,0x83,0x5c,0x00},
+	{0x65,0xef,0x83,0x5c,0x00},
+	{0x8a,0x14,0x00,0x80,0x00},
+	{0x8a,0x14,0x00,0x80,0x00}
+    },
+    {
+        {0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+    	{0x67,0x91,0x84,0x5E,0x00},
+    	{0x67,0x91,0x84,0x5E,0x00},
+    	{0x67,0x91,0x84,0x5E,0x00},
+    	{0x67,0x91,0x84,0x5E,0x00},
+    	{0x65,0xEF,0x83,0x5C,0x00},
+    	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x67,0x91,0x84,0x5E,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x65,0xEF,0x83,0x5C,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    },
+    {
+    	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x8E,0x18,0x28,0x78,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x4E,0x18,0x90,0x38,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x67,0x11,0x9A,0x56,0x00},
+	{0x8A,0x14,0x00,0x80,0x00},
+	{0x8A,0x14,0x00,0x80,0x00}
+    }
+};
+
+#if 0
+const UCHAR SiS300_LCDVData[24][11][6] = {
+    {
+        {
+    },
+};
+#endif
diff -Nru a/drivers/video/sis/oem310.h b/drivers/video/sis/oem310.h
--- a/drivers/video/sis/oem310.h	Thu Jul 11 10:30:30 2002
+++ b/drivers/video/sis/oem310.h	Fri Mar  7 11:19:01 2003
@@ -1,93 +1,198 @@
 
-/* OEM Data for 300 series */
+/* OEM Data for 310/325/330 series */
 
-UCHAR SiS310_CRT2DelayCompensation1 = 0x04; /* 301A */
+const UCHAR SiS310_LCDDelayCompensation_301[] =	    	/* 301 */
+{
+		 0x00,0x00,0x00,    /*   800x600 */
+		 0x0b,0x0b,0x0b,    /*  1024x768 */
+		 0x08,0x08,0x08,    /* 1280x1024 */
+		 0x00,0x00,0x00,    /*   640x480 (unknown) */
+		 0x00,0x00,0x00,    /*  1024x600 (unknown) */
+		 0x00,0x00,0x00,    /*  1152x864 (unknown) */
+		 0x08,0x08,0x08,    /*  1280x960 (guessed) */
+		 0x00,0x00,0x00,    /*  1152x768 (unknown) */
+		 0x08,0x08,0x08,    /* 1400x1050 */
+		 0x08,0x08,0x08,    /*  1280x768  (guessed) */
+		 0x00,0x00,0x00,    /* 1600x1200 */
+		 0x00,0x00,0x00,    /*   320x480 (unknown) */
+		 0x00,0x00,0x00,
+		 0x00,0x00,0x00,
+		 0x00,0x00,0x00
+};
+
+/* This is contained in 650+301B BIOSes, but it is wrong - so we don't use it */
+UCHAR SiS310_LCDDelayCompensation_650301B[] =	   	/* 30xB,LV */
+{
+		 0x01,0x01,0x01,    /*   800x600 */
+		 0x01,0x01,0x01,    /*  1024x768 */
+		 0x01,0x01,0x01,    /* 1280x1024 */
+                 0x01,0x01,0x01,    /*   640x480 (unknown) */
+		 0x01,0x01,0x01,    /*  1024x600 (unknown) */
+		 0x01,0x01,0x01,    /*  1152x864 (unknown) */
+		 0x01,0x01,0x01,    /*  1280x960 (guessed) */
+		 0x01,0x01,0x01,    /*  1152x768 (unknown) */
+		 0x01,0x01,0x01,    /* 1400x1050 */
+		 0x01,0x01,0x01,    /*  1280x768  (guessed) */
+		 0x01,0x01,0x01,    /* 1600x1200 */
+		 0x02,0x02,0x02,
+		 0x02,0x02,0x02,
+		 0x02,0x02,0x02,
+		 0x02,0x02,0x02
+};
+
+/* This data is correct, so we use it instead of the table above */
+UCHAR SiS310_LCDDelayCompensation_3xx301B[] =	   	/* 30xB,LV */
+{
+		 0x01,0x01,0x01,    /*   800x600 */
+		 0x0C,0x0C,0x0C,    /*  1024x768 */
+		 0x0C,0x0C,0x0C,    /* 1280x1024 */
+                 0x08,0x08,0x08,    /*   640x480 */
+		 0x0C,0x0C,0x0C,    /*  1024x600 (guessed) */
+		 0x0C,0x0C,0x0C,    /*  1152x864 (guessed) */
+		 0x0C,0x0C,0x0C,    /*  1280x960 (guessed) */
+		 0x0C,0x0C,0x0C,    /*  1152x768 (guessed) */
+		 0x0C,0x0C,0x0C,    /* 1400x1050 (guessed) */
+		 0x0C,0x0C,0x0C,    /*  1280x768 (guessed) */
+		 0x0C,0x0C,0x0C,    /* 1600x1200 (guessed) */
+		 0x02,0x02,0x02,
+		 0x02,0x02,0x02,
+		 0x02,0x02,0x02,
+		 0x02,0x02,0x02
+};
+
+const UCHAR SiS310_LCDDelayCompensation_LVDS650[] =   	/* LVDS */
+{
+                 0x00,0x00,0x00,    /*   800x600 */
+		 0x00,0x00,0x00,    /*  1024x768 */
+		 0x00,0x00,0x00,    /* 1280x1024 */
+		 0x00,0x00,0x00,    /*   640x480 (unknown) */
+		 0x00,0x00,0x00,    /*  1024x600 (unknown) */
+		 0x00,0x00,0x00,    /*  1152x864 (unknown) */
+		 0x00,0x00,0x00,    /*  1280x960 (guessed) */
+		 0x00,0x00,0x00,    /*  1152x768 (unknown) */
+		 0x00,0x00,0x00,    /* 1400x1050 */
+		 0x00,0x00,0x00,    /*  1280x768  (guessed) */
+		 0x00,0x00,0x00,    /* 1600x1200 */
+		 0x00,0x00,0x00,
+		 0x00,0x00,0x00,
+		 0x00,0x00,0x00,
+		 0x00,0x00,0x00
+};
 
-UCHAR SiS310_LCDDelayCompensation1[] =
+const UCHAR SiS310_LCDDelayCompensation_LVDS740[] =   	/* LVDS */
 {
+                 0x03,0x03,0x03,    /*   800x600 */
+		 0x03,0x03,0x03,    /*  1024x768 */
+		 0x03,0x03,0x03,    /* 1280x1024 */
+		 0x03,0x03,0x03,    /*   640x480 (unknown) */
+		 0x03,0x03,0x03,    /*  1024x600 (unknown) */
+		 0x03,0x03,0x03,    /*  1152x864 (unknown) */
+		 0x03,0x03,0x03,    /*  1280x960 (guessed) */
+		 0x03,0x03,0x03,    /*  1152x768 (unknown) */
+		 0x03,0x03,0x03,    /* 1400x1050 */
+		 0x03,0x03,0x03,    /*  1280x768  (guessed) */
+		 0x03,0x03,0x03,    /* 1600x1200 */
 		 0x00,0x00,0x00,
-		 0x0b,0x0b,0x0b,
-		 0x08,0x08,0x08,
-		 0x08,0x08,0x08,
 		 0x00,0x00,0x00,
 		 0x00,0x00,0x00,
 		 0x00,0x00,0x00
 };
 
-UCHAR SiS310_TVDelayCompensation1[] =
+const UCHAR SiS310_LCDDelayCompensation_651301LV[] =	  /* M650/651 301LV */
 {
-		  0x02,0x02,    /* NTSC Enhanced, Standard */
-                  0x02,0x02,    /* PAL */
-		  0x08,0x0b     /* HiVision */
+                 0x33,0x33,0x33,    /*   800x600 (guessed) */
+		 0x33,0x33,0x33,    /*  1024x768 */
+		 0x33,0x33,0x33,    /* 1280x1024 */
+		 0x33,0x33,0x33,    /*   640x480 (unknown) */
+		 0x33,0x33,0x33,    /*  1024x600 (unknown) */
+		 0x33,0x33,0x33,    /*  1152x864 (unknown) */
+		 0x33,0x33,0x33,    /*  1280x960 (guessed) */
+		 0x33,0x33,0x33,    /*  1152x768 (unknown) */
+		 0x33,0x33,0x33,    /* 1400x1050 */
+		 0x33,0x33,0x33,    /*  1280x768  (guessed) */
+		 0x33,0x33,0x33,    /* 1600x1200 */
+		 0x33,0x33,0x33,
+		 0x33,0x33,0x33,
+		 0x33,0x33,0x33,
+		 0x33,0x33,0x33
 };
 
-UCHAR SiS310_CRT2DelayCompensation2 = 0x00;   /* TW: From 650/301LV BIOS; was 0x0C; */      /* 301B */
+const UCHAR SiS310_LCDDelayCompensation_651302LV[] =	   /* M650/651 302LV */
+{
+                 0x33,0x33,0x33,    /*   800x600 (guessed) */
+		 0x33,0x33,0x33,    /*  1024x768 */
+		 0x33,0x33,0x33,    /* 1280x1024 */
+		 0x33,0x33,0x33,    /*   640x480 (unknown) */
+		 0x33,0x33,0x33,    /*  1024x600 (unknown) */
+		 0x33,0x33,0x33,    /*  1152x864 (unknown) */
+		 0x33,0x33,0x33,    /*  1280x960 (guessed) */
+		 0x33,0x33,0x33,    /*  1152x768 (unknown) */
+		 0x33,0x33,0x33,    /* 1400x1050 */
+		 0x33,0x33,0x33,    /*  1280x768  (guessed) */
+		 0x33,0x33,0x33,    /* 1600x1200 */
+		 0x33,0x33,0x33,
+		 0x33,0x33,0x33,
+		 0x33,0x33,0x33,
+		 0x33,0x33,0x33
+};
 
-UCHAR SiS310_LCDDelayCompensation2[] =
+const UCHAR SiS310_TVDelayCompensation_301[] = 		/* 301 */
 {
-		  0x01,0x01,0x01,   /* TW: From 650/301LV BIOS */
-		  0x01,0x01,0x01,
-		  0x01,0x01,0x01,
-		  0x01,0x01,0x01,
-		  0x01,0x01,0x01,
-		  0x01,0x01,0x01,
-		  0x01,0x01,0x01
-#if 0
-		  0x00,0x00,0x00,   /* 800x600 VESA, non-VESA, non-expanding */
-		  0x0C,0x0C,0x0C,   /* 1024x768 */
-		  0x0C,0x0C,0x0C,   /* 1280x1024 */
-		  0x08,0x08,0x08,   /* 1280x960 */
-		  0x00,0x00,0x00,   /* 640x480 */
-		  0x00,0x00,0x00,   /* 1600x1200 */
-		  0x00,0x00,0x00    /* 1920x1440 */
-#endif
+		 0x02,0x02,    /* NTSC Enhanced, Standard */
+                 0x02,0x02,    /* PAL */
+		 0x08,0x0b     /* HiVision */
 };
 
-UCHAR SiS310_TVDelayCompensation2[] =
+const UCHAR SiS310_TVDelayCompensation_301B[] =		/* 30xB, 30xLV */
 {
-		  0x05,0x05,        /* TW: From 650/301LV BIOS */
-		  0x05,0x05,
-		  0x05,0x05
-#if 0
-		  0x03,0x03,        /* NTSC Enhanced, Standard */
-                  0x03,0x03,        /* PAL */
-		  0x08,0x0b         /* HiVision */
-#endif
+		 0x03,0x03,
+		 0x03,0x03,
+		 0x03,0x03
 };
 
-UCHAR SiS310_CRT2DelayCompensation3 = 0x00;   /* LVDS */
+const UCHAR SiS310_TVDelayCompensation_740301B[] =	/* 740 + 30xB (30xLV?) */
+{
+		 0x05,0x05,
+		 0x05,0x05,
+		 0x05,0x05
+};
 
-UCHAR SiS310_LCDDelayCompensation3[] =
+const UCHAR SiS310_TVDelayCompensation_LVDS[] =		/* LVDS */
 {
-                   0x00,0x00,0x00,  /* 800x600 */
-		   0x00,0x00,0x00,  /* 1024x768 */
-		   0x00,0x00,0x00,  /* 1280x1024 */
-		   0x00,0x00,0x00,  /* 1400x1050 */
-		   0x00,0x00,0x00   /* 1600x1200 */
+		 0x0a,0x0a,
+		 0x0a,0x0a,
+		 0x0a,0x0a
 };
 
-UCHAR SiS310_TVDelayCompensation3[] =
+const UCHAR SiS310_TVDelayCompensation_651301LV[] =	/* M650, 651, 301LV */
 {
-		   0x0a,0x0a,
-		   0x0a,0x0a,
-		   0x0a,0x0a
+		 0x33,0x33,
+		 0x33,0x33,
+		 0x33,0x33
 };
 
-UCHAR SiS310_TVAntiFlick1[3][2] =
+const UCHAR SiS310_TVDelayCompensation_651302LV[] =	/* M650, 651, 302LV */
+{
+		 0x33,0x33,
+		 0x33,0x33,
+		 0x33,0x33
+};
+
+const UCHAR SiS310_TVAntiFlick1[3][2] =
 {
             {0x4,0x0},
 	    {0x4,0x8},
 	    {0x0,0x0}
 };
 
-UCHAR SiS310_TVEdge1[3][2] =
+const UCHAR SiS310_TVEdge1[3][2] =
 {
             {0x0,0x4},
 	    {0x0,0x4},
 	    {0x0,0x0}
 };
 
-UCHAR SiS310_TVYFilter1[3][8][4] =
+const UCHAR SiS310_TVYFilter1[3][8][4] =
 {
  {
 	{0x00,0xf4,0x10,0x38},
@@ -121,7 +226,7 @@
  }
 };
 
-UCHAR SiS310_TVYFilter2[3][9][7] =
+const UCHAR SiS310_TVYFilter2[3][9][7] =
 {
  {
 	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
@@ -135,7 +240,7 @@
 	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
  },
  {
-	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
+	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},   
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
 	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
@@ -157,7 +262,7 @@
  }
 };
 
-UCHAR SiS310_PALMFilter[17][4] =
+const UCHAR SiS310_PALMFilter[16][4] =
 {
 	{0x00,0xf4,0x10,0x38},
 	{0x00,0xf4,0x10,0x38},
@@ -174,11 +279,10 @@
 	{0xeb,0x04,0x25,0x18},
 	{0xeb,0x04,0x25,0x18},
 	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xff,0xff,0xff,0xff}
+	{0xeb,0x04,0x25,0x18}
 };
 
-UCHAR SiS310_PALNFilter[17][4] =
+const UCHAR SiS310_PALNFilter[16][4] =
 {
 	{0x00,0xf4,0x10,0x38},
 	{0x00,0xf4,0x10,0x38},
@@ -195,12 +299,11 @@
 	{0xeb,0x04,0x25,0x18},
 	{0xeb,0x04,0x25,0x18},
 	{0xeb,0x04,0x25,0x18},
-	{0xeb,0x04,0x25,0x18},
-	{0xff,0xff,0xff,0xff}
+	{0xeb,0x04,0x25,0x18}
 };
 
 
-UCHAR SiS310_PALMFilter2[9][7] =
+const UCHAR SiS310_PALMFilter2[9][7] =
 {
 	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
@@ -213,7 +316,7 @@
 	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
 };
 
-UCHAR SiS310_PALNFilter2[9][7] =
+const UCHAR SiS310_PALNFilter2[9][7] =
 {
 	{0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46},
 	{0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C},
@@ -226,7 +329,7 @@
 	{0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28}
 };
 
-UCHAR SiS310_TVPhaseIncr1[3][2][4]=
+const UCHAR SiS310_TVPhaseIncr1[3][2][4] =
 {
  {
 	{0x21,0xed,0xba,0x08},
@@ -242,15 +345,15 @@
  }
 };
 
-UCHAR SiS310_TVPhaseIncr2[3][2][4]=
+const UCHAR SiS310_TVPhaseIncr2[3][2][4] =
 {
  {
-	{0x21,0xF1,0x37,0x56},
-	{0x21,0xF1,0x37,0x56}
+	{0x21,0xf0,0x7b,0xd6},   /* 1.10.7w;  1.10.6s: {0x1e,0x8b,0xda,0xa7},   old: {0x21,0xF1,0x37,0x56} */
+	{0x21,0xf0,0x7b,0xd6}    /* 1.10.7w;  1.10.6s: {0x1e,0x8b,0xda,0xa7}    old: {0x21,0xF1,0x37,0x56} */
  },
  {
-	{0x2a,0x09,0x86,0xe9},
-	{0x2a,0x09,0x86,0xe9}
+	{0x2a,0x0a,0x41,0xe9},   /* 1.10.7w, 1.10.6s. old: {0x2a,0x09,0x86,0xe9}, */
+	{0x2a,0x0a,0x41,0xe9}    /* 1.10.7w, 1.10.6s. old: {0x2a,0x09,0x86,0xe9}  */
  },
  {
 	{0x2a,0x05,0xd3,0x00},
diff -Nru a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
--- a/drivers/video/sis/osdef.h	Thu Jul 11 10:30:30 2002
+++ b/drivers/video/sis/osdef.h	Wed Mar  5 09:22:35 2003
@@ -7,6 +7,7 @@
 /**********************************************************************/
 #ifdef LINUX_KERNEL
 	#include <linux/config.h>
+	#include <linux/version.h>
 	#ifdef CONFIG_FB_SIS_300
  		#define SIS300
 	#endif
@@ -14,6 +15,12 @@
 	#ifdef CONFIG_FB_SIS_315
 		#define SIS315H
 	#endif
+	#if 1
+		#define SISFBACCEL	/* Include 2D acceleration */
+	#endif
+	#if 1
+		#define SISFB_PAN	/* Include Y-Panning code */
+	#endif
 #else
 /*	#define SIS300*/
 	#define SIS315H
@@ -122,6 +129,10 @@
 #define InPortLong(p)    inl((CARD16)(p))
 #endif
 
+/**********************************************************************/
+/*  LINUX KERNEL                                                      */
+/**********************************************************************/
+
 #ifdef LINUX_KERNEL
 #define OutPortByte(p,v) outb((u8)(v),(u16)(p))
 #define OutPortWord(p,v) outw((u16)(v),(u16)(p))
@@ -146,7 +157,7 @@
 
 
 /**********************************************************************/
-/*  WIN CE                                                          */
+/*  WIN CE                                                            */
 /**********************************************************************/
 
 #ifdef WINCE_HEADER
diff -Nru a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/sis/sis.h	Wed Mar  5 09:22:36 2003
@@ -0,0 +1,10 @@
+#ifndef _SIS_H
+#define _SIS_H
+
+#if 1
+#define TWDEBUG(x)
+#else
+#define TWDEBUG(x) printk(KERN_INFO x "\n");
+#endif
+
+#endif
diff -Nru a/drivers/video/sis/sis_accel.c b/drivers/video/sis/sis_accel.c
--- a/drivers/video/sis/sis_accel.c	Wed Oct 16 10:46:00 2002
+++ b/drivers/video/sis/sis_accel.c	Fri Mar  7 11:19:01 2003
@@ -37,13 +37,21 @@
 #include <linux/agp_backend.h>
 
 #include <linux/types.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 #include <linux/sisfb.h>
+#else
+#include <video/sisfb.h>
+#endif
 
 #include <asm/io.h>
+
+#ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
+#endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 #include <video/fbcon.h>
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)
 #include <video/fbcon-cfb8.h>
 #include <video/fbcon-cfb16.h>
 #include <video/fbcon-cfb24.h>
@@ -54,9 +62,11 @@
 #include "vgatypes.h"
 #include "vstruct.h"
 #include "sis_accel.h"
+#include "sis.h"
 
 extern struct     video_info ivideo;
 extern VGA_ENGINE sisvga_engine;
+extern int sisfb_accel;
 
 static const int sisALUConv[] =
 {
@@ -228,15 +238,38 @@
                                 int width, int height)
 {
 	long srcbase, dstbase;
+	int mymin, mymax;
 
 	srcbase = dstbase = 0;
-	if (src_y >= 2048) {
-		srcbase = ivideo.video_linelength * src_y;
-		src_y = 0;
-	}
-	if (dst_y >= 2048) {
-		dstbase = ivideo.video_linelength * dst_y;
-		dst_y = 0;
+	mymin = min(src_y, dst_y);
+	mymax = max(src_y, dst_y);
+	
+	/* Although the chip knows the direction to use
+	 * if the source and destination areas overlap, 
+	 * that logic fails if we fiddle with the bitmap
+	 * addresses. Therefore, we check if the source
+	 * and destination blitting areas overlap and 
+	 * adapt the bitmap addresses synchronously 
+	 * if the coordinates exceed the valid range.
+	 * The the areas do not overlap, we do our 
+	 * normal check.
+	 */
+	if((mymax - mymin) < height) { 
+	   if((src_y >= 2048) || (dst_y >= 2048)) {	      
+	      srcbase = ivideo.video_linelength * mymin;
+	      dstbase = ivideo.video_linelength * mymin;
+	      src_y -= mymin;
+	      dst_y -= mymin;
+	   }
+	} else {
+	   if(src_y >= 2048) {
+	      srcbase = ivideo.video_linelength * src_y;
+	      src_y = 0;
+	   }
+	   if(dst_y >= 2048) {
+	      dstbase = ivideo.video_linelength * dst_y;
+	      dst_y = 0;
+	   }
 	}
 
 	SiS310SetupSRCBase(srcbase);
@@ -286,25 +319,62 @@
     return(0);
 }
 
+void sisfb_syncaccel(void)
+{
+    if(sisvga_engine == SIS_300_VGA) {
+    	SiS300Sync();
+    } else {
+    	SiS310Sync();
+    }
+}
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)  /* --- KERNEL 2.5.34 and later --- */
 
-void fbcon_sis_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+int fbcon_sis_sync(struct fb_info *info)
+{
+   if(!sisfb_accel) return 0;
+   CRITFLAGS
+   if(sisvga_engine == SIS_300_VGA) {
+      SiS300Sync();
+   } else {
+      SiS310Sync();
+   }
+   CRITEND
+   return 0;
+}
+
+void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
+   int col=0;
    CRITFLAGS
 
+   TWDEBUG("Inside sis_fillrect");
    if(!rect->width || !rect->height)
    	return;
 
+   if(!sisfb_accel) {
+	cfb_fillrect(info, rect);
+	return;
+   }
+   
+   switch(info->var.bits_per_pixel) {
+		case 8: col = rect->color;
+			break;
+		case 16: col = ((u32 *)(info->pseudo_palette))[rect->color];
+			 break;
+		case 32: col = ((u32 *)(info->pseudo_palette))[rect->color];
+			 break;
+	}	
+
    if(sisvga_engine == SIS_300_VGA) {
 	   CRITBEGIN
-	   SiS300SetupForSolidFill(rect->color, myrops[rect->rop], 0);
+	   SiS300SetupForSolidFill(col, myrops[rect->rop], 0);
 	   SiS300SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
 	   CRITEND
 	   SiS300Sync();
    } else {
 	   CRITBEGIN
-	   SiS310SetupForSolidFill(rect->color, myrops[rect->rop], 0);
+	   SiS310SetupForSolidFill(col, myrops[rect->rop], 0);
 	   SiS310SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
 	   CRITEND
 	   SiS310Sync();
@@ -312,11 +382,17 @@
 
 }
 
-void fbcon_sis_copyarea(struct fb_info *info, struct fb_copyarea *area)
+void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
    int xdir, ydir;
    CRITFLAGS
 
+   TWDEBUG("Inside sis_copyarea");
+   if(!sisfb_accel) {
+   	cfb_copyarea(info, area);
+	return;
+   }
+
    if(!area->width || !area->height)
    	return;
 
@@ -350,6 +426,27 @@
         int xdir, ydir;
 	CRITFLAGS
 
+	if(!ivideo.accel) {
+	    switch(ivideo.video_bpp) {
+	    case 8:
+#ifdef FBCON_HAS_CFB8
+	       fbcon_cfb8_bmove(p, srcy, srcx, dsty, dstx, height, width);
+#endif
+	       break;
+	    case 16:
+#ifdef FBCON_HAS_CFB16
+	       fbcon_cfb16_bmove(p, srcy, srcx, dsty, dstx, height, width);
+#endif
+	       break;
+	    case 32:
+#ifdef FBCON_HAS_CFB32
+	       fbcon_cfb32_bmove(p, srcy, srcx, dsty, dstx, height, width);
+#endif
+	       break;
+            }
+	    return;
+	}
+
 	srcx *= fontwidth(p);
 	srcy *= fontheight(p);
 	dstx *= fontwidth(p);
@@ -357,7 +454,6 @@
 	width *= fontwidth(p);
 	height *= fontheight(p);
 
-
 	if(srcx < dstx) xdir = 0;
 	else            xdir = 1;
 	if(srcy < dsty) ydir = 0;
@@ -375,6 +471,10 @@
 	   SiS310SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
 	   CRITEND
 	   SiS310Sync();
+#if 0	   
+	   printk(KERN_INFO "sis_bmove sx %d sy %d dx %d dy %d w %d h %d\n",
+		srcx, srcy, dstx, dsty, width, height);
+#endif		
 	}
 }
 
@@ -409,6 +509,13 @@
 {
 	u32 bgx;
 
+	if(!ivideo.accel) {
+#ifdef FBCON_HAS_CFB8
+	    fbcon_cfb8_clear(conp, p, srcy, srcx, height, width);
+#endif
+	    return;
+	}
+
 	bgx = attr_bgcol_ec(p, conp);
 	fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
 }
@@ -417,6 +524,12 @@
 			int srcy, int srcx, int height, int width)
 {
 	u32 bgx;
+	if(!ivideo.accel) {
+#ifdef FBCON_HAS_CFB16
+	    fbcon_cfb16_clear(conp, p, srcy, srcx, height, width);
+#endif
+	    return;
+	}
 
 	bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
 	fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
@@ -427,6 +540,13 @@
 {
 	u32 bgx;
 
+	if(!ivideo.accel) {
+#ifdef FBCON_HAS_CFB32
+	    fbcon_cfb32_clear(conp, p, srcy, srcx, height, width);
+#endif
+	    return;
+	}
+
 	bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
 	fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
 }
@@ -434,6 +554,22 @@
 void fbcon_sis_revc(struct display *p, int srcx, int srcy)
 {
 	CRITFLAGS
+
+	if(!ivideo.accel) {
+	    switch(ivideo.video_bpp) {
+	    case 16:
+#ifdef FBCON_HAS_CFB16
+	       fbcon_cfb16_revc(p, srcx, srcy);
+#endif
+	       break;
+	    case 32:
+#ifdef FBCON_HAS_CFB32
+	       fbcon_cfb32_revc(p, srcx, srcy);
+#endif
+	       break;
+            }
+	    return;
+	}
 
 	srcx *= fontwidth(p);
 	srcy *= fontheight(p);
diff -Nru a/drivers/video/sis/sis_accel.h b/drivers/video/sis/sis_accel.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/sis/sis_accel.h	Fri Mar  7 11:19:01 2003
@@ -0,0 +1,509 @@
+/*
+ * SiS 300/630/730/540/315/550/650/740 frame buffer driver
+ * for Linux kernels 2.4.x and 2.5.x
+ *
+ * 2D acceleration part
+ *
+ * Based on the X driver's sis300_accel.h which is
+ *     Copyright Xavier Ducoin <x.ducoin@lectra.com>
+ *     Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ * and sis310_accel.h which is
+ *     Copyright 2002 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Author:   Thomas Winischhofer <thomas@winischhofer.net>:
+ *			(see http://www.winischhofer.net/
+ *			for more information and updates)
+ */
+
+#ifndef _SISFB_ACCEL_H
+#define _SISFB_ACCEL_H
+
+/* Guard accelerator accesses with spin_lock_irqsave? Works well without. */
+#undef SISFB_USE_SPINLOCKS
+
+#ifdef SISFB_USE_SPINLOCKS
+#include <linux/spinlock.h>
+#define CRITBEGIN  spin_lock_irqsave(&ivideo.lockaccel), critflags);
+#define CRITEND	   spin_unlock_irqrestore(&ivideo.lockaccel), critflags);
+#define CRITFLAGS  unsigned long critflags;
+#else
+#define CRITBEGIN
+#define CRITEND
+#define CRITFLAGS
+#endif
+
+/* Definitions for the SIS engine communication. */
+
+#define PATREGSIZE      384  /* Pattern register size. 384 bytes @ 0x8300 */
+#define BR(x)   (0x8200 | (x) << 2)
+#define PBR(x)  (0x8300 | (x) << 2)
+
+/* SiS300 engine commands */
+#define BITBLT                  0x00000000  /* Blit */
+#define COLOREXP                0x00000001  /* Color expand */
+#define ENCOLOREXP              0x00000002  /* Enhanced color expand */
+#define MULTIPLE_SCANLINE       0x00000003  /* ? */
+#define LINE                    0x00000004  /* Draw line */
+#define TRAPAZOID_FILL          0x00000005  /* Fill trapezoid */
+#define TRANSPARENT_BITBLT      0x00000006  /* Transparent Blit */
+
+/* Additional engine commands for 310/325 */
+#define ALPHA_BLEND		0x00000007  /* Alpha blend ? */
+#define A3D_FUNCTION		0x00000008  /* 3D command ? */
+#define	CLEAR_Z_BUFFER		0x00000009  /* ? */
+#define GRADIENT_FILL		0x0000000A  /* Gradient fill */
+#define STRETCH_BITBLT		0x0000000B  /* Stretched Blit */
+
+/* source select */
+#define SRCVIDEO                0x00000000  /* source is video RAM */
+#define SRCSYSTEM               0x00000010  /* source is system memory */
+#define SRCCPUBLITBUF           SRCSYSTEM   /* source is CPU-driven BitBuffer (for color expand) */
+#define SRCAGP                  0x00000020  /* source is AGP memory (?) */
+
+/* Pattern flags */
+#define PATFG                   0x00000000  /* foreground color */
+#define PATPATREG               0x00000040  /* pattern in pattern buffer (0x8300) */
+#define PATMONO                 0x00000080  /* mono pattern */
+
+/* blitting direction (300 series only) */
+#define X_INC                   0x00010000
+#define X_DEC                   0x00000000
+#define Y_INC                   0x00020000
+#define Y_DEC                   0x00000000
+
+/* Clipping flags */
+#define NOCLIP                  0x00000000
+#define NOMERGECLIP             0x04000000
+#define CLIPENABLE              0x00040000
+#define CLIPWITHOUTMERGE        0x04040000
+
+/* Transparency */
+#define OPAQUE                  0x00000000
+#define TRANSPARENT             0x00100000
+
+/* ? */
+#define DSTAGP                  0x02000000
+#define DSTVIDEO                0x02000000
+
+/* Line */
+#define LINE_STYLE              0x00800000
+#define NO_RESET_COUNTER        0x00400000
+#define NO_LAST_PIXEL           0x00200000
+
+/* Subfunctions for Color/Enhanced Color Expansion (310/325 only) */
+#define COLOR_TO_MONO		0x00100000
+#define AA_TEXT			0x00200000
+
+/* Some general registers for 310/325 series */
+#define SRC_ADDR		0x8200
+#define SRC_PITCH		0x8204
+#define AGP_BASE		0x8206 /* color-depth dependent value */
+#define SRC_Y			0x8208
+#define SRC_X			0x820A
+#define DST_Y			0x820C
+#define DST_X			0x820E
+#define DST_ADDR		0x8210
+#define DST_PITCH		0x8214
+#define DST_HEIGHT		0x8216
+#define RECT_WIDTH		0x8218
+#define RECT_HEIGHT		0x821A
+#define PAT_FGCOLOR		0x821C
+#define PAT_BGCOLOR		0x8220
+#define SRC_FGCOLOR		0x8224
+#define SRC_BGCOLOR		0x8228
+#define MONO_MASK		0x822C
+#define LEFT_CLIP		0x8234
+#define TOP_CLIP		0x8236
+#define RIGHT_CLIP		0x8238
+#define BOTTOM_CLIP		0x823A
+#define COMMAND_READY		0x823C
+#define FIRE_TRIGGER      	0x8240
+
+#define PATTERN_REG		0x8300  /* 384 bytes pattern buffer */
+
+/* Line registers */
+#define LINE_X0			SRC_Y
+#define LINE_X1			DST_Y
+#define LINE_Y0			SRC_X
+#define LINE_Y1			DST_X
+#define LINE_COUNT		RECT_WIDTH
+#define LINE_STYLE_PERIOD	RECT_HEIGHT
+#define LINE_STYLE_0		MONO_MASK
+#define LINE_STYLE_1		0x8230
+#define LINE_XN			PATTERN_REG
+#define LINE_YN			PATTERN_REG+2
+
+/* Transparent bitblit registers */
+#define TRANS_DST_KEY_HIGH	PAT_FGCOLOR
+#define TRANS_DST_KEY_LOW	PAT_BGCOLOR
+#define TRANS_SRC_KEY_HIGH	SRC_FGCOLOR
+#define TRANS_SRC_KEY_LOW	SRC_BGCOLOR
+
+/* Queue */
+#define Q_BASE_ADDR		0x85C0  /* Base address of software queue (?) */
+#define Q_WRITE_PTR		0x85C4  /* Current write pointer (?) */
+#define Q_READ_PTR		0x85C8  /* Current read pointer (?) */
+#define Q_STATUS		0x85CC  /* queue status */
+
+
+#define MMIO_IN8(base, offset) \
+	*(volatile u8 *)(((u8*)(base)) + (offset))
+#define MMIO_IN16(base, offset) \
+	*(volatile u16 *)(void *)(((u8*)(base)) + (offset))
+#define MMIO_IN32(base, offset) \
+	*(volatile u32 *)(void *)(((u8*)(base)) + (offset))
+#define MMIO_OUT8(base, offset, val) \
+	*(volatile u8 *)(((u8*)(base)) + (offset)) = (val)
+#define MMIO_OUT16(base, offset, val) \
+	*(volatile u16 *)(void *)(((u8*)(base)) + (offset)) = (val)
+#define MMIO_OUT32(base, offset, val) \
+	*(volatile u32 *)(void *)(((u8*)(base)) + (offset)) = (val)
+
+/* ------------- SiS 300 series -------------- */
+
+/* Macros to do useful things with the SIS BitBLT engine */
+
+/* BR(16) (0x8420):
+
+   bit 31 2D engine: 1 is idle,
+   bit 30 3D engine: 1 is idle,
+   bit 29 Command queue: 1 is empty
+
+   bits 28:24: Current CPU driven BitBlt buffer stage bit[4:0]
+
+   bits 15:0:  Current command queue length
+
+*/
+
+/* TW: BR(16)+2 = 0x8242 */
+
+int     CmdQueLen;
+
+#define SiS300Idle \
+  { \
+  while( (MMIO_IN16(ivideo.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
+  while( (MMIO_IN16(ivideo.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
+  while( (MMIO_IN16(ivideo.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
+  CmdQueLen=MMIO_IN16(ivideo.mmio_vbase, 0x8240); \
+  }
+/* TW: (do three times, because 2D engine seems quite unsure about whether or not it's idle) */
+
+#define SiS300SetupSRCBase(base) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(0), base);\
+                CmdQueLen --;
+
+#define SiS300SetupSRCPitch(pitch) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT16(ivideo.mmio_vbase, BR(1), pitch);\
+                CmdQueLen --;
+
+#define SiS300SetupSRCXY(x,y) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(2), (x)<<16 | (y) );\
+                CmdQueLen --;
+
+#define SiS300SetupDSTBase(base) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(4), base);\
+                CmdQueLen --;
+
+#define SiS300SetupDSTXY(x,y) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(3), (x)<<16 | (y) );\
+                CmdQueLen --;
+
+#define SiS300SetupDSTRect(x,y) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(5), (y)<<16 | (x) );\
+                CmdQueLen --;
+
+#define SiS300SetupDSTColorDepth(bpp) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT16(ivideo.mmio_vbase, BR(1)+2, bpp);\
+                CmdQueLen --;
+
+#define SiS300SetupRect(w,h) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(6), (h)<<16 | (w) );\
+                CmdQueLen --;
+
+#define SiS300SetupPATFG(color) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(7), color);\
+                CmdQueLen --;
+
+#define SiS300SetupPATBG(color) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(8), color);\
+                CmdQueLen --;
+
+#define SiS300SetupSRCFG(color) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(9), color);\
+                CmdQueLen --;
+
+#define SiS300SetupSRCBG(color) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(10), color);\
+                CmdQueLen --;
+
+/* 0x8224 src colorkey high */
+/* 0x8228 src colorkey low */
+/* 0x821c dest colorkey high */
+/* 0x8220 dest colorkey low */
+#define SiS300SetupSRCTrans(color) \
+                if (CmdQueLen <= 1)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, 0x8224, color);\
+		MMIO_OUT32(ivideo.mmio_vbase, 0x8228, color);\
+		CmdQueLen -= 2;
+
+#define SiS300SetupDSTTrans(color) \
+		if (CmdQueLen <= 1)  SiS300Idle;\
+		MMIO_OUT32(ivideo.mmio_vbase, 0x821C, color); \
+		MMIO_OUT32(ivideo.mmio_vbase, 0x8220, color); \
+                CmdQueLen -= 2;
+
+#define SiS300SetupMONOPAT(p0,p1) \
+                if (CmdQueLen <= 1)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(11), p0);\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(12), p1);\
+                CmdQueLen -= 2;
+
+#define SiS300SetupClipLT(left,top) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(13), ((left) & 0xFFFF) | (top)<<16 );\
+                CmdQueLen--;
+
+#define SiS300SetupClipRB(right,bottom) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(14), ((right) & 0xFFFF) | (bottom)<<16 );\
+                CmdQueLen--;
+
+/* General */
+#define SiS300SetupROP(rop) \
+                ivideo.CommandReg = (rop) << 8;
+
+#define SiS300SetupCMDFlag(flags) \
+                ivideo.CommandReg |= (flags);
+
+#define SiS300DoCMD \
+                if (CmdQueLen <= 1)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(15), ivideo.CommandReg); \
+                MMIO_OUT32(ivideo.mmio_vbase, BR(16), 0);\
+                CmdQueLen -= 2;
+
+/* Line */
+#define SiS300SetupX0Y0(x,y) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(2), (y)<<16 | (x) );\
+                CmdQueLen--;
+
+#define SiS300SetupX1Y1(x,y) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(3), (y)<<16 | (x) );\
+                CmdQueLen--;
+
+#define SiS300SetupLineCount(c) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT16(ivideo.mmio_vbase, BR(6), c);\
+                CmdQueLen--;
+
+#define SiS300SetupStylePeriod(p) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT16(ivideo.mmio_vbase, BR(6)+2, p);\
+                CmdQueLen--;
+
+#define SiS300SetupStyleLow(ls) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(11), ls);\
+                CmdQueLen--;
+
+#define SiS300SetupStyleHigh(ls) \
+                if (CmdQueLen <= 0)  SiS300Idle;\
+                MMIO_OUT32(ivideo.mmio_vbase, BR(12), ls);\
+                CmdQueLen--;
+
+
+
+/* ----------- SiS 310/325 series --------------- */
+
+/* Q_STATUS:
+   bit 31 = 1: All engines idle and all queues empty
+   bit 30 = 1: Hardware Queue (=HW CQ, 2D queue, 3D queue) empty
+   bit 29 = 1: 2D engine is idle
+   bit 28 = 1: 3D engine is idle
+   bit 27 = 1: HW command queue empty
+   bit 26 = 1: 2D queue empty
+   bit 25 = 1: 3D queue empty
+   bit 24 = 1: SW command queue empty
+   bits 23:16: 2D counter 3
+   bits 15:8:  2D counter 2
+   bits 7:0:   2D counter 1
+
+   Where is the command queue length (current amount of commands the queue
+   can accept) on the 310/325 series? (The current implementation is taken
+   from 300 series and certainly wrong...)
+*/
+
+/* TW: FIXME: CmdQueLen is... where....? */
+#define SiS310Idle \
+  { \
+  while( (MMIO_IN16(ivideo.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+  while( (MMIO_IN16(ivideo.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+  CmdQueLen=MMIO_IN16(ivideo.mmio_vbase, Q_STATUS); \
+  }
+
+#define SiS310SetupSRCBase(base) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, SRC_ADDR, base);\
+      CmdQueLen--;
+
+#define SiS310SetupSRCPitch(pitch) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT16(ivideo.mmio_vbase, SRC_PITCH, pitch);\
+      CmdQueLen--;
+
+#define SiS310SetupSRCXY(x,y) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, SRC_Y, (x)<<16 | (y) );\
+      CmdQueLen--;
+
+#define SiS310SetupDSTBase(base) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, DST_ADDR, base);\
+      CmdQueLen--;
+
+#define SiS310SetupDSTXY(x,y) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, DST_Y, (x)<<16 | (y) );\
+      CmdQueLen--;
+
+#define SiS310SetupDSTRect(x,y) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, DST_PITCH, (y)<<16 | (x) );\
+      CmdQueLen--;
+
+#define SiS310SetupDSTColorDepth(bpp) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT16(ivideo.mmio_vbase, AGP_BASE, bpp);\
+      CmdQueLen--;
+
+#define SiS310SetupRect(w,h) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, RECT_WIDTH, (h)<<16 | (w) );\
+      CmdQueLen--;
+
+#define SiS310SetupPATFG(color) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, PAT_FGCOLOR, color);\
+      CmdQueLen--;
+
+#define SiS310SetupPATBG(color) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, PAT_BGCOLOR, color);\
+      CmdQueLen--;
+
+#define SiS310SetupSRCFG(color) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, SRC_FGCOLOR, color);\
+      CmdQueLen--;
+
+#define SiS310SetupSRCBG(color) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, SRC_BGCOLOR, color);\
+      CmdQueLen--;
+
+#define SiS310SetupSRCTrans(color) \
+      if (CmdQueLen <= 1)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, TRANS_SRC_KEY_HIGH, color);\
+      MMIO_OUT32(ivideo.mmio_vbase, TRANS_SRC_KEY_LOW, color);\
+      CmdQueLen -= 2;
+
+#define SiS310SetupDSTTrans(color) \
+      if (CmdQueLen <= 1)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, TRANS_DST_KEY_HIGH, color); \
+      MMIO_OUT32(ivideo.mmio_vbase, TRANS_DST_KEY_LOW, color); \
+      CmdQueLen -= 2;
+
+#define SiS310SetupMONOPAT(p0,p1) \
+      if (CmdQueLen <= 1)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, MONO_MASK, p0);\
+      MMIO_OUT32(ivideo.mmio_vbase, MONO_MASK+4, p1);\
+      CmdQueLen -= 2;
+
+#define SiS310SetupClipLT(left,top) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16 );\
+      CmdQueLen--;
+
+#define SiS310SetupClipRB(right,bottom) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16 );\
+      CmdQueLen--;
+
+#define SiS310SetupROP(rop) \
+      ivideo.CommandReg = (rop) << 8;
+
+#define SiS310SetupCMDFlag(flags) \
+      ivideo.CommandReg |= (flags);
+
+#define SiS310DoCMD \
+      if (CmdQueLen <= 1)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, COMMAND_READY, ivideo.CommandReg); \
+      MMIO_OUT32(ivideo.mmio_vbase, FIRE_TRIGGER, 0); \
+      CmdQueLen -= 2;
+
+#define SiS310SetupX0Y0(x,y) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, LINE_X0, (y)<<16 | (x) );\
+      CmdQueLen--;
+
+#define SiS310SetupX1Y1(x,y) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, LINE_X1, (y)<<16 | (x) );\
+      CmdQueLen--;
+
+#define SiS310SetupLineCount(c) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT16(ivideo.mmio_vbase, LINE_COUNT, c);\
+      CmdQueLen--;
+
+#define SiS310SetupStylePeriod(p) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT16(ivideo.mmio_vbase, LINE_STYLE_PERIOD, p);\
+      CmdQueLen--;
+
+#define SiS310SetupStyleLow(ls) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, LINE_STYLE_0, ls);\
+      CmdQueLen--;
+
+#define SiS310SetupStyleHigh(ls) \
+      if (CmdQueLen <= 0)  SiS310Idle;\
+      MMIO_OUT32(ivideo.mmio_vbase, LINE_STYLE_1, ls);\
+      CmdQueLen--;
+
+int  sisfb_initaccel(void);
+void sisfb_syncaccel(void);
+
+extern struct video_info ivideo;
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)
+void fbcon_sis_bmove(struct display *p, int srcy, int srcx, int dsty,
+                     int dstx, int height, int width);
+void fbcon_sis_revc(struct display *p, int srcy, int srcx);
+void fbcon_sis_clear8(struct vc_data *conp, struct display *p, int srcy,
+                      int srcx, int height, int width);
+void fbcon_sis_clear16(struct vc_data *conp, struct display *p, int srcy,
+                       int srcx, int height, int width);
+void fbcon_sis_clear32(struct vc_data *conp, struct display *p, int srcy,
+                       int srcx, int height, int width);
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
+extern int sisfb_accel;
+void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
+void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area);
+#endif
+
+#endif
diff -Nru a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
--- a/drivers/video/sis/sis_main.c	Thu Oct 31 12:05:55 2002
+++ b/drivers/video/sis/sis_main.c	Fri Mar  7 11:19:02 2003
@@ -8,14 +8,17 @@
  * Authors:   	SiS (www.sis.com.tw)
  *		(Various others)
  *		Thomas Winischhofer <thomas@winischhofer.net>:
- *			- many fixes and enhancements for 630 & 310/325 series,
- *			- extended bridge handling, TV output for Chrontel
- *                      - 650/LVDS support (for LCD panels up to 1400x1050)
- *                      - 650/Chrontel 7019 support
- *                      - 301B/301LV LCD and TV support
+ *			- SiS Xabre (330) support
+ *			- many fixes and enhancements for all chipset series,
+ *			- extended bridge handling, TV output for Chrontel 7005
+ *                      - 650/LVDS support (for LCD panels up to 1600x1200)
+ *                      - 650/740/Chrontel 7019 support
+ *                      - 30xB/30xLV LCD, TV and VGA2 support
  *			- memory queue handling enhancements,
- *			- everything marked with "TW"
- *			(see http://www.winischhofer.net/linuxsis630.shtml
+ *                      - 2D acceleration and y-panning,
+ *                      - portation to 2.5 API
+ *			- etc.
+ *			(see http://www.winischhofer.net/
  *			for more information and updates)
  */
 
@@ -39,81 +42,74 @@
 #include <linux/capability.h>
 #include <linux/fs.h>
 #include <linux/agp_backend.h>
-
 #include <linux/types.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#include <linux/spinlock.h>
+#endif
+
+#include "osdef.h"
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#include <video/sisfb.h>
+#else
 #include <linux/sisfb.h>
+#endif
 
 #include <asm/io.h>
-#include <asm/mtrr.h> 
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 #include <video/fbcon.h>
 #include <video/fbcon-cfb8.h>
 #include <video/fbcon-cfb16.h>
 #include <video/fbcon-cfb24.h>
 #include <video/fbcon-cfb32.h>
+#endif
 
-#include "osdef.h"
 #include "vgatypes.h"
 #include "sis_main.h"
-//#ifdef LINUXBIOS
-//#include "bios.h"
-//#endif
+#include "sis.h"
+
+#if 0
+#ifdef LINUXBIOS
+#include "bios.h"
+#endif
+#endif
 
 /* -------------------- Macro definitions ---------------------------- */
-// #define SISFBDEBUG
-#undef SISFBDEBUG /* TW */
+
+#undef SISFBDEBUG 	/* TW: no debugging */
+
 #ifdef SISFBDEBUG
 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
 #else
 #define DPRINTK(fmt, args...)
 #endif
 
-#define vgawb(reg,data) \
-           (outb(data, ivideo.vga_base+reg))
-#define vgaww(reg,data) \
-           (outw(data, ivideo.vga_base+reg))
-#define vgawl(reg,data) \
-           (outl(data, ivideo.vga_base+reg))
-#define vgarb(reg)      \
-           (inb(ivideo.vga_base+reg))
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#ifdef SISFBACCEL
+#ifdef FBCON_HAS_CFB8
+extern struct display_switch fbcon_sis8;
+#endif
+#ifdef FBCON_HAS_CFB16
+extern struct display_switch fbcon_sis16;
+#endif
+#ifdef FBCON_HAS_CFB32
+extern struct display_switch fbcon_sis32;
+#endif
+#endif
+#endif
 
 /* --------------- Hardware Access Routines -------------------------- */
 
-void sisfb_set_reg1(u16 port, u16 index, u16 data)
-{
-	outb((u8) (index & 0xff), port);
-	port++;
-	outb((u8) (data & 0xff), port);
-}
-
-void sisfb_set_reg3(u16 port, u16 data)
-{
-	outb((u8) (data & 0xff), port);
-}
-
 void sisfb_set_reg4(u16 port, unsigned long data)
 {
 	outl((u32) (data & 0xffffffff), port);
 }
 
-u8 sisfb_get_reg1(u16 port, u16 index)
-{
-	u8 data;
-
-	outb((u8) (index & 0xff), port);
-	port += 1;
-	data = inb(port);
-	return (data);
-}
-
-u8 sisfb_get_reg2(u16 port)
-{
-	u8 data;
-
-	data = inb(port);
-	return (data);
-}
-
 u32 sisfb_get_reg3(u16 port)
 {
 	u32 data;
@@ -122,25 +118,7 @@
 	return (data);
 }
 
-// Eden Chen
-//void sisfb_clear_DAC(u16 port)
-//{
-//	int i,j;
-//
-//	vgawb(DAC_ADR, 0x00);
-//	for(i=0; i<256; i++)
-//		for(j=0; j<3; j++)
-//			vgawb(DAC_DATA, 0);
-//}
-
-//void sisfb_clear_buffer(PHW_DEVICE_EXTENSION psishw_ext)
-//{
-//	memset((char *) ivideo.video_vbase, 0,
-//		video_linelength * ivideo.video_height);
-//}
-// ~Eden Chen
-
-/* --------------- Interface to BIOS code ---------------------------- */
+/* ------------ Interface for init & mode switching code ------------- */
 
 BOOLEAN
 sisfb_query_VGA_config_space(PSIS_HW_DEVICE_INFO psishw_ext,
@@ -206,6 +184,9 @@
 		case SIS_650:
 			nbridge_id = PCI_DEVICE_ID_SI_650;
 			break;
+		case SIS_740:			
+			nbridge_id = PCI_DEVICE_ID_SI_740;
+			break;
 		default:
 			nbridge_id = 0;
 			break;
@@ -236,186 +217,262 @@
 	return TRUE;
 }
 
-/* -------------------- Export functions ----------------------------- */
+/* ------------------ Internal helper routines ----------------- */
 
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,23)
-static void sis_get_glyph(SIS_GLYINFO *gly)
-#else
-static void sis_get_glyph(struct fb_info *info, SIS_GLYINFO *gly)
-#endif
+static void sisfb_search_mode(const char *name)
 {
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,23)
-	struct display *p = &fb_display[currcon];
-#else
-        struct display *p = &fb_display[info->currcon];
-#endif
-	u16 c;
-	u8 *cdat;
-	int widthb;
-	u8 *gbuf = gly->gmask;
-	int size;
-
-
-	gly->fontheight = fontheight(p);
-	gly->fontwidth = fontwidth(p);
-	widthb = (fontwidth(p) + 7) / 8;
-
-	c = gly->ch & p->charmask;
-	if (fontwidth(p) <= 8)
-		cdat = p->fontdata + c * fontheight(p);
-	else
-		cdat = p->fontdata + (c * fontheight(p) << 1);
+	int i = 0, j = 0;
 
-	size = fontheight(p) * widthb;
-	memcpy(gbuf, cdat, size);
-	gly->ngmask = size;
-}
+	if(name == NULL) {
+	   printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
+	   sisfb_mode_idx = DEFAULT_MODE;
+	   return;
+	}
+		
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)		
+        if (!strcmp(name, sisbios_mode[MODE_INDEX_NONE].name)) {
+	   printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
+	   sisfb_mode_idx = DEFAULT_MODE;
+	   return;
+	}
+#endif		
 
-void sis_dispinfo(struct ap_data *rec)
-{
-	rec->minfo.bpp    = ivideo.video_bpp;
-	rec->minfo.xres   = ivideo.video_width;
-	rec->minfo.yres   = ivideo.video_height;
-	rec->minfo.v_xres = ivideo.video_vwidth;
-	rec->minfo.v_yres = ivideo.video_vheight;
-	rec->minfo.org_x  = ivideo.org_x;
-	rec->minfo.org_y  = ivideo.org_y;
-	rec->minfo.vrate  = ivideo.refresh_rate;
-	rec->iobase       = ivideo.vga_base - 0x30;
-	rec->mem_size     = ivideo.video_size;
-	rec->disp_state   = ivideo.disp_state; 
-	rec->version      = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL; 
-	rec->hasVB        = ivideo.hasVB; 
-	rec->TV_type      = ivideo.TV_type; 
-	rec->TV_plug      = ivideo.TV_plug; 
-	rec->chip         = ivideo.chip;
+	while(sisbios_mode[i].mode_no != 0) {
+		if (!strcmp(name, sisbios_mode[i].name)) {
+			sisfb_mode_idx = i;
+			j = 1;
+			break;
+		}
+		i++;
+	}
+	if(!j) printk(KERN_INFO "sisfb: Invalid mode '%s'\n", name);
 }
 
-/* ------------------ Internal Routines ------------------------------ */
-
-static void sisfb_search_mode(const char *name)
+static void sisfb_search_vesamode(unsigned int vesamode)
 {
-	int i = 0;
+	int i = 0, j = 0;
 
-	if (name == NULL)
+	if(vesamode == 0) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+		sisfb_mode_idx = MODE_INDEX_NONE;
+#else
+		printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
+		sisfb_mode_idx = DEFAULT_MODE;
+#endif		
 		return;
+	}
 
-	while (sisbios_mode[i].mode_no != 0) {
-		if (!strcmp(name, sisbios_mode[i].name)) {
+	vesamode &= 0x1dff;  /* Clean VESA mode number from other flags */
+
+	while(sisbios_mode[i].mode_no != 0) {
+		if( (sisbios_mode[i].vesa_mode_no_1 == vesamode) ||
+		    (sisbios_mode[i].vesa_mode_no_2 == vesamode) ) {
 			sisfb_mode_idx = i;
+			j = 1;
 			break;
 		}
 		i++;
 	}
-	if (sisfb_mode_idx < 0)
-		printk(KERN_INFO "sisfb: Invalid mode '%s'\n", name);
+	if(!j) printk(KERN_INFO "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
 }
 
-static void sisfb_validate_mode(void)
+static int sisfb_validate_mode(int myindex)
 {
    u16 xres, yres;
 
-	switch (ivideo.disp_state & DISPTYPE_DISP2) {
-	case DISPTYPE_LCD:
-	    switch (sishw_ext.ulCRT2LCDType) {
-		case LCD_1024x768:
-			xres = 1024; yres =  768;  break;
-		case LCD_1280x1024:
-		        xres = 1280; yres = 1024;  break;
-		case LCD_1280x960:
-	                xres = 1280; yres =  960;  break;
-		case LCD_2048x1536:
-		        xres = 2048; yres = 1536;  break;
-		case LCD_1920x1440:
-			xres = 1920; yres = 1440;  break;
-		case LCD_1600x1200:
-			xres = 1600; yres = 1200;  break;
-		case LCD_800x600:
-			xres =  800; yres =  600;  break;
-		case LCD_640x480:
-			xres =  640; yres =  480;  break;
-		case LCD_320x480:	/* TW: FSTN */
-			xres =  320; yres =  480;  break;
-                case LCD_1024x600:
-			xres = 1024; yres =  600;  break;
-		case LCD_1152x864:
-			xres = 1152; yres =  864;  break;
-		case LCD_1152x768:
-			xres = 1152; yres =  768;  break;
-		case LCD_1280x768:
-			xres = 1280; yres =  768;  break;
-		case LCD_1400x1050:
-			xres = 1400; yres = 1050;  break;
-		default:
-		        xres =    0; yres =    0;  break;
-		}
-		if(sisbios_mode[sisfb_mode_idx].xres > xres)
-		        sisfb_mode_idx = -1;
-                if(sisbios_mode[sisfb_mode_idx].yres > yres)
-		        sisfb_mode_idx = -1;
-		if (sisbios_mode[sisfb_mode_idx].xres == 720)
-			sisfb_mode_idx = -1;
-		break;
-	case DISPTYPE_TV:
-	    switch (sisbios_mode[sisfb_mode_idx].xres) {
-	        case 512:
-		case 640:
-		case 800:
-			break;
-		case 720:
-			if (ivideo.TV_type == TVMODE_NTSC) {
-				if (sisbios_mode[sisfb_mode_idx].yres != 480)
-					sisfb_mode_idx = -1;
-			} else if (ivideo.TV_type == TVMODE_PAL) {
-				if (sisbios_mode[sisfb_mode_idx].yres != 576)
-					sisfb_mode_idx = -1;
-			}
-			/* TW: LVDS/CHRONTEL does not support 720 */
-			if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
-						ivideo.hasVB == HASVB_CHRONTEL)
-					sisfb_mode_idx = -1;
-			break;
-		case 1024:
-			if (ivideo.TV_type == TVMODE_NTSC) {
-				if(sisbios_mode[sisfb_mode_idx].bpp == 32)
-				       sisfb_mode_idx = -1;
-			}
-			/* TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019)*/
-			if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
-						ivideo.hasVB == HASVB_CHRONTEL) {
-			    if(ivideo.chip < SIS_315H) {
-					sisfb_mode_idx = -1;
-			    }
+#ifdef CONFIG_FB_SIS_300
+   if(sisvga_engine == SIS_300_VGA) {
+       if(!(sisbios_mode[myindex].chipset & MD_SIS300)) {
+           return(-1);
+       }
+   }
+#endif
+#ifdef CONFIG_FB_SIS_315
+   if(sisvga_engine == SIS_315_VGA) {
+       if(!(sisbios_mode[myindex].chipset & MD_SIS315)) {
+	   return(-1);
+       }
+   }
+#endif
+
+   switch (ivideo.disp_state & DISPTYPE_DISP2) {
+     case DISPTYPE_LCD:
+	switch (sishw_ext.ulCRT2LCDType) {
+	case LCD_640x480:
+		xres =  640; yres =  480;  break;
+	case LCD_800x600:
+		xres =  800; yres =  600;  break;
+        case LCD_1024x600:
+		xres = 1024; yres =  600;  break;		
+	case LCD_1024x768:
+	 	xres = 1024; yres =  768;  break;
+	case LCD_1152x768:
+		xres = 1152; yres =  768;  break;		
+	case LCD_1280x960:
+	        xres = 1280; yres =  960;  break;		
+	case LCD_1280x768:
+		xres = 1280; yres =  768;  break;
+	case LCD_1280x1024:
+		xres = 1280; yres = 1024;  break;
+	case LCD_1400x1050:
+		xres = 1400; yres = 1050;  break;		
+	case LCD_1600x1200:
+		xres = 1600; yres = 1200;  break;
+	case LCD_320x480:				/* TW: FSTN */
+		xres =  320; yres =  480;  break;
+	default:
+	        xres =    0; yres =    0;  break;
+	}
+	if(sisbios_mode[myindex].xres > xres) {
+	        return(-1);
+	}
+        if(sisbios_mode[myindex].yres > yres) {
+	        return(-1);
+	}
+	if((sishw_ext.usExternalChip == 0x01) ||   /* LVDS */
+           (sishw_ext.usExternalChip == 0x05) ||   /* LVDS+Chrontel */
+	   (sishw_ext.Is301BDH)) {		   /* 301B-DH */
+	   switch (sisbios_mode[myindex].xres) {
+	   	case 512:
+	       		if(sisbios_mode[myindex].yres != 512) return -1;
+			if(sishw_ext.ulCRT2LCDType == LCD_1024x600) return -1;
+	       		break;
+	   	case 640:
+		       	if((sisbios_mode[myindex].yres != 400) &&
+	           	   (sisbios_mode[myindex].yres != 480))
+		          	return -1;
+	       		break;
+	   	case 800:
+		       	if(sisbios_mode[myindex].yres != 600) return -1;
+	       		break;
+	   	case 1024:
+		       	if((sisbios_mode[myindex].yres != 600) &&
+	           	   (sisbios_mode[myindex].yres != 768))
+		          	return -1;
+			if((sisbios_mode[myindex].yres == 600) &&
+			   (sishw_ext.ulCRT2LCDType != LCD_1024x600))
+			   	return -1;
+			break;
+		case 1152:
+			if((sisbios_mode[myindex].yres) != 768) return -1;
+			if(sishw_ext.ulCRT2LCDType != LCD_1152x768) return -1;
+			break;
+	   	case 1280:
+		   	if((sisbios_mode[myindex].yres != 768) &&
+	           	   (sisbios_mode[myindex].yres != 1024))
+		          	return -1;
+			if((sisbios_mode[myindex].yres == 768) &&
+			   (sishw_ext.ulCRT2LCDType != LCD_1280x768))
+			   	return -1;				
+			break;
+	   	case 1400:
+		   	if(sisbios_mode[myindex].yres != 1050) return -1;
+			break;
+	   	case 1600:
+		   	if(sisbios_mode[myindex].yres != 1200) return -1;
+			break;
+	   	default:
+		        return -1;		
+	   }
+	} else {
+	   switch (sisbios_mode[myindex].xres) {
+	   	case 512:
+	       		if(sisbios_mode[myindex].yres != 512) return -1;
+	       		break;
+	   	case 640:
+		       	if((sisbios_mode[myindex].yres != 400) &&
+	           	   (sisbios_mode[myindex].yres != 480))
+		          	return -1;
+	       		break;
+	   	case 800:
+		       	if(sisbios_mode[myindex].yres != 600) return -1;
+	       		break;
+	   	case 1024:
+		       	if(sisbios_mode[myindex].yres != 768) return -1;
+			break;
+	   	case 1280:
+		   	if((sisbios_mode[myindex].yres != 960) &&
+	           	   (sisbios_mode[myindex].yres != 1024))
+		          	return -1;
+			if(sisbios_mode[myindex].yres == 960) {
+			    if(sishw_ext.ulCRT2LCDType == LCD_1400x1050) 
+			   	return -1;
 			}
 			break;
-		default:
-			sisfb_mode_idx = -1;
+	   	case 1400:
+		   	if(sisbios_mode[myindex].yres != 1050) return -1;
+			break;
+	   	case 1600:
+		   	if(sisbios_mode[myindex].yres != 1200) return -1;
+			break;
+	   	default:
+		        return -1;		
+	   }
+	}
+	break;
+     case DISPTYPE_TV:
+	switch (sisbios_mode[myindex].xres) {
+	case 512:
+	case 640:
+	case 800:
+		break;
+	case 720:
+		if (ivideo.TV_type == TVMODE_NTSC) {
+			if (sisbios_mode[myindex].yres != 480) {
+				return(-1);
+			}
+		} else if (ivideo.TV_type == TVMODE_PAL) {
+			if (sisbios_mode[myindex].yres != 576) {
+				return(-1);
+			}
+		}
+		/* TW: LVDS/CHRONTEL does not support 720 */
+		if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
+					ivideo.hasVB == HASVB_CHRONTEL) {
+				return(-1);
 		}
 		break;
+	case 1024:
+		if (ivideo.TV_type == TVMODE_NTSC) {
+			if(sisbios_mode[myindex].bpp == 32) {
+			       return(-1);
+			}
+		}
+		/* TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019)*/
+		if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
+					ivideo.hasVB == HASVB_CHRONTEL) {
+		    if(ivideo.chip < SIS_315H) {
+				return(-1);
+		    }
+		}
+		break;
+	default:
+		return(-1);
 	}
-
-	if(ivideo.chip < SIS_315H) {
-             if(sisbios_mode[sisfb_mode_idx].xres > 1920)
-	         sisfb_mode_idx = -1;
-	}
-	/* TW: TODO: Validate modes available on either 300 or 310/325 series only */
+	break;
+     case DISPTYPE_CRT2:	
+        if(sisbios_mode[myindex].xres > 1280) return -1;
+	break;	
+     }
+     return(myindex);
 }
 
 static void sisfb_search_crt2type(const char *name)
 {
 	int i = 0;
 
-	if (name == NULL)
+	if(name == NULL)
 		return;
 
-	while (sis_crt2type[i].type_no != -1) {
+	while(sis_crt2type[i].type_no != -1) {
 		if (!strcmp(name, sis_crt2type[i].name)) {
 			sisfb_crt2type = sis_crt2type[i].type_no;
+			sisfb_tvplug = sis_crt2type[i].tvplug_no;
 			break;
 		}
 		i++;
 	}
-	if (sisfb_crt2type < 0)
+	if(sisfb_crt2type < 0)
 		printk(KERN_INFO "sisfb: Invalid CRT2 type: %s\n", name);
 }
 
@@ -423,7 +480,7 @@
 {
 	int i = 0;
 
-	if (name == NULL)
+	if(name == NULL)
 		return;
 
 	while (sis_queuemode[i].type_no != -1) {
@@ -452,7 +509,7 @@
 				sisfb_rate_idx = sisfb_vrate[i].idx;
 				break;
 			} else if (sisfb_vrate[i].refresh > rate) {
-				if ((sisfb_vrate[i].refresh - rate) <= 2) {
+				if ((sisfb_vrate[i].refresh - rate) <= 3) {
 					DPRINTK("sisfb: Adjusting rate from %d up to %d\n",
 						rate, sisfb_vrate[i].refresh);
 					sisfb_rate_idx = sisfb_vrate[i].idx;
@@ -463,9 +520,14 @@
 						rate, sisfb_vrate[i-1].refresh);
 					sisfb_rate_idx = sisfb_vrate[i-1].idx;
 					ivideo.refresh_rate = sisfb_vrate[i-1].refresh;
-				}
+				} 
 				break;
-			}
+			} else if((rate - sisfb_vrate[i].refresh) <= 2) {
+				DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
+						rate, sisfb_vrate[i].refresh);
+	           		sisfb_rate_idx = sisfb_vrate[i].idx;
+		   		break;
+	       		}
 		}
 		i++;
 	}
@@ -478,113 +540,138 @@
 	}
 }
 
-static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
-			 unsigned *transp, struct fb_info *fb_info)
+static void sisfb_search_tvstd(const char *name)
 {
-	if (regno >= video_cmap_len)
-		return 1;
+	int i = 0;
 
-	*red = palette[regno].red;
-	*green = palette[regno].green;
-	*blue = palette[regno].blue;
-	*transp = 0;
-	return 0;
+	if(name == NULL)
+		return;
+
+	while (sis_tvtype[i].type_no != -1) {
+		if (!strcmp(name, sis_tvtype[i].name)) {
+			sisfb_tvmode = sis_tvtype[i].type_no;
+			break;
+		}
+		i++;
+	}
 }
 
+static BOOLEAN sisfb_bridgeisslave(void)
+{
+   unsigned char usScratchP1_00;
 
-static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
-                           unsigned transp, struct fb_info *fb_info)
+   if(ivideo.hasVB == HASVB_NONE) return FALSE;
+
+   inSISIDXREG(SISPART1,0x00,usScratchP1_00);
+   if( ((sisvga_engine == SIS_300_VGA) && (usScratchP1_00 & 0xa0) == 0x20) ||
+       ((sisvga_engine == SIS_315_VGA) && (usScratchP1_00 & 0x50) == 0x10) ) {
+	   return TRUE;
+   } else {
+           return FALSE;
+   }
+}
+
+static BOOLEAN sisfbcheckvretracecrt1(void)
 {
-	if (regno >= video_cmap_len)
-		return 1;
+   unsigned char temp;
 
-	palette[regno].red = red;
-	palette[regno].green = green;
-	palette[regno].blue = blue;
+   inSISIDXREG(SISCR,0x17,temp);
+   if(!(temp & 0x80)) return FALSE;
+   
+   if(sisvga_engine == SIS_315_VGA) {
+      inSISIDXREG(SISSR,0x1f,temp);
+      if(temp & 0xc0) return FALSE;
+   }
 
-	switch (ivideo.video_bpp) {
-#ifdef FBCON_HAS_CFB8
-	case 8:
-		vgawb(DAC_ADR, regno);
-		vgawb(DAC_DATA, red >> 10);
-		vgawb(DAC_DATA, green >> 10);
-		vgawb(DAC_DATA, blue >> 10);
-		if (ivideo.disp_state & DISPTYPE_DISP2) {
-		 	vgawb(DAC2_ADR,  regno);
-			vgawb(DAC2_DATA, red >> 8);
-			vgawb(DAC2_DATA, green >> 8);
-			vgawb(DAC2_DATA, blue >> 8);
-		}
-		break;
-#endif
-#ifdef FBCON_HAS_CFB16
-	case 15:
-	case 16:
-		fbcon_cmap.cfb16[regno] =
-		    ((red & 0xf800)) |
-		    ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
-		break;
-#endif
-#ifdef FBCON_HAS_CFB24
-	case 24:
-		red >>= 8;
-		green >>= 8;
-		blue >>= 8;
-		fbcon_cmap.cfb24[regno] =
-		    (red << 16) | (green << 8) | (blue);
-		break;
-#endif
-#ifdef FBCON_HAS_CFB32
-	case 32:
-		red >>= 8;
-		green >>= 8;
-		blue >>= 8;
-		fbcon_cmap.cfb32[regno] =
-		    (red << 16) | (green << 8) | (blue);
-		break;
-#endif
-	}
-	return 0;
+   if(inSISREG(SISINPSTAT) & 0x08) return TRUE;
+   else 			   return FALSE;
+}
+
+static BOOLEAN sisfbcheckvretracecrt2(void)
+{
+   unsigned char temp, reg;
+
+   switch(sisvga_engine) {
+   case SIS_300_VGA:
+   	reg = 0x25;
+	break;
+   case SIS_315_VGA:
+   	reg = 0x30;
+	break;
+   default:
+        return FALSE;
+   }
+
+   inSISIDXREG(SISPART1, reg, temp);
+   if(temp & 0x02) return FALSE;
+   else 	   return TRUE;
 }
 
+static BOOLEAN sisfb_CheckVBRetrace(void) 
+{
+   if(ivideo.disp_state & DISPTYPE_DISP2) {
+      if(sisfb_bridgeisslave()) {
+         return(sisfbcheckvretracecrt1());
+      } else {
+         return(sisfbcheckvretracecrt2());
+      }
+   } 
+   return(sisfbcheckvretracecrt1());
+}
+
+/* ----------- FBDev related routines for all series ----------- */
+
 static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 		      struct fb_info *info)
 {
 	unsigned int htotal =
 		var->left_margin + var->xres + var->right_margin +
 		var->hsync_len;
-	unsigned int vtotal = 0; /* TW */
-	/*	var->upper_margin + var->yres + var->lower_margin +
-		var->vsync_len;     */
+	unsigned int vtotal = 0; 
 	double drate = 0, hrate = 0;
 	int found_mode = 0;
 	int old_mode;
+	unsigned char reg;
+
+	TWDEBUG("Inside do_set_var");
+	
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+	inSISIDXREG(SISCR,0x34,reg);
+	if(reg & 0x80) {
+	   printk(KERN_INFO "sisfb: Cannot change display mode, X server is active\n");
+	   return -EBUSY;
+	}
+#endif	
 
-	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
+	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
 		vtotal = var->upper_margin + var->yres + var->lower_margin +
-		         var->vsync_len;   /* TW */
+		         var->vsync_len;
 		vtotal <<= 1;
-	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
 		vtotal = var->upper_margin + var->yres + var->lower_margin +
-		         var->vsync_len;   /* TW */
+		         var->vsync_len;
 		vtotal <<= 2;
-	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
 		vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
-		         var->vsync_len;   /* TW */
-		/* var->yres <<= 1; */ /* TW */
+		         var->vsync_len; 
 	} else 	vtotal = var->upper_margin + var->yres + var->lower_margin +
 		         var->vsync_len;
 
-	if (!(htotal) || !(vtotal)) {
+	if(!(htotal) || !(vtotal)) {
 		DPRINTK("sisfb: Invalid 'var' information\n");
 		return -EINVAL;
 	}
 
-	drate = 1E12 / var->pixclock;
-	hrate = drate / htotal;
-	ivideo.refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
+	if(var->pixclock && htotal && vtotal) {
+	   drate = 1E12 / var->pixclock;
+	   hrate = drate / htotal;
+	   ivideo.refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
+	} else ivideo.refresh_rate = 60;
+
+	/* TW: Calculation wrong for 1024x600 - force it to 60Hz */
+	if((var->xres == 1024) && (var->yres == 600)) ivideo.refresh_rate = 60;
 
-	printk("sisfb: Change mode to %dx%dx%d-%dHz\n",
+	printk(KERN_DEBUG "sisfb: Change mode to %dx%dx%d-%dHz\n",
 		var->xres,var->yres,var->bits_per_pixel,ivideo.refresh_rate);
 
 	old_mode = sisfb_mode_idx;
@@ -602,67 +689,440 @@
 		sisfb_mode_idx++;
 	}
 
-	if (found_mode)
-		sisfb_validate_mode();
+	if(found_mode)
+		sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx);
 	else
 		sisfb_mode_idx = -1;
 
-       	if (sisfb_mode_idx < 0) {
-		printk("sisfb: Mode %dx%d-%d not supported\n", var->xres,
+       	if(sisfb_mode_idx < 0) {
+		printk(KERN_ERR "sisfb: Mode %dx%dx%d not supported\n", var->xres,
 		       var->yres, var->bits_per_pixel);
 		sisfb_mode_idx = old_mode;
 		return -EINVAL;
 	}
 
-	if (sisfb_search_refresh_rate(ivideo.refresh_rate) == 0) {
+	if(sisfb_search_refresh_rate(ivideo.refresh_rate) == 0) {
 		sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
 		ivideo.refresh_rate = 60;
 	}
 
-	if (((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
-
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
+#else
+	if(isactive) {
+#endif
 		sisfb_pre_setmode();
 
-		if (SiSSetMode(&sishw_ext, sisfb_mode_no) == 0) {
-			printk("sisfb: Setting mode[0x%x] failed\n", sisfb_mode_no);
-			return -1;
+		if(SiSSetMode(&SiS_Pr, &sishw_ext, sisfb_mode_no) == 0) {
+			printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", sisfb_mode_no);
+			return -EINVAL;
 		}
 
-		vgawb(SEQ_ADR, IND_SIS_PASSWORD);
-		vgawb(SEQ_DATA, SIS_PASSWORD);
+		outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
 
 		sisfb_post_setmode();
 
-		DPRINTK("sisfb: Set new mode: %dx%dx%d-%d \n", sisbios_mode[sisfb_mode_idx].xres,
-			sisbios_mode[sisfb_mode_idx].yres, sisbios_mode[sisfb_mode_idx].bpp,
+		DPRINTK("sisfb: Set new mode: %dx%dx%d-%d \n",
+			sisbios_mode[sisfb_mode_idx].xres,
+			sisbios_mode[sisfb_mode_idx].yres,
+			sisbios_mode[sisfb_mode_idx].bpp,
 			ivideo.refresh_rate);
 
 		ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
 		ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
 		ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
 		ivideo.org_x = ivideo.org_y = 0;
-		video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
+		ivideo.video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
+		ivideo.accel = 0;
+		if(sisfb_accel) {
+		   ivideo.accel = (var->accel_flags & FB_ACCELF_TEXT) ? -1 : 0;
+		}
+		switch(ivideo.video_bpp) {
+        	case 8:
+            		ivideo.DstColor = 0x0000;
+	    		ivideo.SiS310_AccelDepth = 0x00000000;
+			ivideo.video_cmap_len = 256;
+            		break;
+        	case 16:
+            		ivideo.DstColor = 0x8000;
+            		ivideo.SiS310_AccelDepth = 0x00010000;
+			ivideo.video_cmap_len = 16;
+            		break;
+        	case 32:
+            		ivideo.DstColor = 0xC000;
+	    		ivideo.SiS310_AccelDepth = 0x00020000;
+			ivideo.video_cmap_len = 16;
+            		break;
+		default:
+			ivideo.video_cmap_len = 16;
+		        printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
+			ivideo.accel = 0;
+			break;
+    		}
+
+	}
+	TWDEBUG("End of do_set_var");
+	return 0;
+}
+
+#ifdef SISFB_PAN
+static int sisfb_pan_var(struct fb_var_screeninfo *var)
+{
+	unsigned int base;
+
+	TWDEBUG("Inside pan_var");
+	
+	if (var->xoffset > (var->xres_virtual - var->xres)) {
+	        printk(KERN_INFO "Pan: xo: %d xv %d xr %d\n",
+			var->xoffset, var->xres_virtual, var->xres);
+		return -EINVAL;
+	}
+	if(var->yoffset > (var->yres_virtual - var->yres)) {
+		printk(KERN_INFO "Pan: yo: %d yv %d yr %d\n",
+			var->yoffset, var->yres_virtual, var->yres);
+		return -EINVAL;
+	}
+
+        base = var->yoffset * var->xres_virtual + var->xoffset;
+
+        /* calculate base bpp dep. */
+        switch(var->bits_per_pixel) {
+        case 16:
+        	base >>= 1;
+        	break;
+	case 32:
+            	break;
+	case 8:
+        default:
+        	base >>= 2;
+            	break;
+        }
+	
+	outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+
+        outSISIDXREG(SISCR, 0x0D, base & 0xFF);
+	outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
+	outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
+	if(sisvga_engine == SIS_315_VGA) {
+		setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
+	}
+        if(ivideo.disp_state & DISPTYPE_DISP2) {
+		orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
+        	outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
+        	outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
+        	outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF));
+		if(sisvga_engine == SIS_315_VGA) {
+			setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
+		}
+        }
+	TWDEBUG("End of pan_var");
+	return 0;
+}
+#endif
+
+static void sisfb_bpp_to_var(struct fb_var_screeninfo *var)
+{
+	switch(var->bits_per_pixel) {
+	   case 8:
+	   	var->red.offset = var->green.offset = var->blue.offset = 0;
+		var->red.length = var->green.length = var->blue.length = 6;
+		ivideo.video_cmap_len = 256;
+		break;
+	   case 16:
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		ivideo.video_cmap_len = 16;
+		break;
+	   case 32:
+		var->red.offset = 16;
+		var->red.length = 8;
+		var->green.offset = 8;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 24;
+		var->transp.length = 8;
+		ivideo.video_cmap_len = 16;
+		break;
+	}
+}
+
+void sis_dispinfo(struct ap_data *rec)
+{
+	rec->minfo.bpp    = ivideo.video_bpp;
+	rec->minfo.xres   = ivideo.video_width;
+	rec->minfo.yres   = ivideo.video_height;
+	rec->minfo.v_xres = ivideo.video_vwidth;
+	rec->minfo.v_yres = ivideo.video_vheight;
+	rec->minfo.org_x  = ivideo.org_x;
+	rec->minfo.org_y  = ivideo.org_y;
+	rec->minfo.vrate  = ivideo.refresh_rate;
+	rec->iobase       = ivideo.vga_base - 0x30;
+	rec->mem_size     = ivideo.video_size;
+	rec->disp_state   = ivideo.disp_state; 
+	rec->version      = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL; 
+	rec->hasVB        = ivideo.hasVB; 
+	rec->TV_type      = ivideo.TV_type; 
+	rec->TV_plug      = ivideo.TV_plug; 
+	rec->chip         = ivideo.chip;
+}
+
+/* ------------ FBDev related routines for 2.4 series ----------- */
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
+
+static void sisfb_crtc_to_var(struct fb_var_screeninfo *var)
+{
+	u16 VRE, VBE, VRS, VBS, VDE, VT;
+	u16 HRE, HBE, HRS, HBS, HDE, HT;
+	u8  sr_data, cr_data, cr_data2, cr_data3, mr_data;
+	int A, B, C, D, E, F, temp;
+	double hrate, drate;
+
+	TWDEBUG("Inside crtc_to_var");
+	inSISIDXREG(SISSR, IND_SIS_COLOR_MODE, sr_data);
+
+	if (sr_data & SIS_INTERLACED_MODE)
+		var->vmode = FB_VMODE_INTERLACED;
+	else
+		var->vmode = FB_VMODE_NONINTERLACED;
+
+	switch ((sr_data & 0x1C) >> 2) {
+	   case SIS_8BPP_COLOR_MODE:
+		var->bits_per_pixel = 8;
+		break;
+	   case SIS_16BPP_COLOR_MODE:
+		var->bits_per_pixel = 16;
+		break;
+	   case SIS_32BPP_COLOR_MODE:
+		var->bits_per_pixel = 32;
+		break;
+	}
+
+	sisfb_bpp_to_var(var);
+	
+	inSISIDXREG(SISSR, 0x0A, sr_data);
+
+        inSISIDXREG(SISCR, 0x06, cr_data);
+
+        inSISIDXREG(SISCR, 0x07, cr_data2);
+
+	VT = (cr_data & 0xFF) | ((u16) (cr_data2 & 0x01) << 8) |
+	     ((u16) (cr_data2 & 0x20) << 4) | ((u16) (sr_data & 0x01) << 10);
+	A = VT + 2;
+
+	inSISIDXREG(SISCR, 0x12, cr_data);
+
+	VDE = (cr_data & 0xff) | ((u16) (cr_data2 & 0x02) << 7) |
+	      ((u16) (cr_data2 & 0x40) << 3) | ((u16) (sr_data & 0x02) << 9);
+	E = VDE + 1;
+
+	inSISIDXREG(SISCR, 0x10, cr_data);
+
+	VRS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x04) << 6) |
+	      ((u16) (cr_data2 & 0x80) << 2) | ((u16) (sr_data & 0x08) << 7);
+	F = VRS + 1 - E;
+
+	inSISIDXREG(SISCR, 0x15, cr_data);
+
+	inSISIDXREG(SISCR, 0x09, cr_data3);
+
+	VBS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x08) << 5) |
+	      ((u16) (cr_data3 & 0x20) << 4) | ((u16) (sr_data & 0x04) << 8);
+
+	inSISIDXREG(SISCR, 0x16, cr_data);
+
+	VBE = (cr_data & 0xff) | ((u16) (sr_data & 0x10) << 4);
+	temp = VBE - ((E - 1) & 511);
+	B = (temp > 0) ? temp : (temp + 512);
+
+	inSISIDXREG(SISCR, 0x11, cr_data);
+
+	VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
+	temp = VRE - ((E + F - 1) & 31);
+	C = (temp > 0) ? temp : (temp + 32);
+
+	D = B - F - C;
+
+        var->yres = E;
+#ifndef SISFB_PAN
+	var->yres_virtual = E;
+#endif
+	/* TW: We have to report the physical dimension to the console! */
+	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+		var->yres <<= 1;
+#ifndef SISFB_PAN
+		var->yres_virtual <<= 1;
+#endif
+	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+		var->yres >>= 1;
+#ifndef SISFB_PAN
+		var->yres_virtual >>= 1;
+#endif
 	}
+
+	var->upper_margin = D;
+	var->lower_margin = F;
+	var->vsync_len = C;
+
+	inSISIDXREG(SISSR, 0x0b, sr_data);
+
+	inSISIDXREG(SISCR, 0x00, cr_data);
+
+	HT = (cr_data & 0xff) | ((u16) (sr_data & 0x03) << 8);
+	A = HT + 5;
+
+	inSISIDXREG(SISCR, 0x01, cr_data);
+
+	HDE = (cr_data & 0xff) | ((u16) (sr_data & 0x0C) << 6);
+	E = HDE + 1;
+
+	inSISIDXREG(SISCR, 0x04, cr_data);
+
+	HRS = (cr_data & 0xff) | ((u16) (sr_data & 0xC0) << 2);
+	F = HRS - E - 3;
+
+	inSISIDXREG(SISCR, 0x02, cr_data);
+
+	HBS = (cr_data & 0xff) | ((u16) (sr_data & 0x30) << 4);
+
+	inSISIDXREG(SISSR, 0x0c, sr_data);
+
+	inSISIDXREG(SISCR, 0x03, cr_data);
+
+	inSISIDXREG(SISCR, 0x05, cr_data2);
+
+	HBE = (cr_data & 0x1f) | ((u16) (cr_data2 & 0x80) >> 2) |
+	      ((u16) (sr_data & 0x03) << 6);
+	HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
+
+	temp = HBE - ((E - 1) & 255);
+	B = (temp > 0) ? temp : (temp + 256);
+
+	temp = HRE - ((E + F + 3) & 63);
+	C = (temp > 0) ? temp : (temp + 64);
+
+	D = B - F - C;
+
+	var->xres = var->xres_virtual = E * 8;
+	var->left_margin = D * 8;
+	var->right_margin = F * 8;
+	var->hsync_len = C * 8;
+
+	var->activate = FB_ACTIVATE_NOW;
+
+	var->sync = 0;
+
+	mr_data = inSISREG(SISMISCR);
+	if (mr_data & 0x80)
+		var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
+	else
+		var->sync |= FB_SYNC_VERT_HIGH_ACT;
+
+	if (mr_data & 0x40)
+		var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
+	else
+		var->sync |= FB_SYNC_HOR_HIGH_ACT;
+
+	VT += 2;
+	VT <<= 1;
+	HT = (HT + 5) * 8;
+
+	hrate = (double) ivideo.refresh_rate * (double) VT / 2;
+	drate = hrate * HT;
+	var->pixclock = (u32) (1E12 / drate);
+
+#ifdef SISFB_PAN
+	if(sisfb_ypan) {
+	    var->yres_virtual = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
+	    if(var->yres_virtual <= var->yres) {
+	        var->yres_virtual = var->yres;
+	    }
+	} else
+#endif
+	   var->yres_virtual = var->yres;
+
+        TWDEBUG("end of crtc_to_var");
+}
+
+static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
+			 unsigned *transp, struct fb_info *fb_info)
+{
+	if (regno >= ivideo.video_cmap_len)
+		return 1;
+
+	*red = sis_palette[regno].red;
+	*green = sis_palette[regno].green;
+	*blue = sis_palette[regno].blue;
+	*transp = 0;
 	return 0;
 }
 
-static void sisfb_set_disp(int con, struct fb_var_screeninfo *var)
+static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+                           unsigned transp, struct fb_info *fb_info)
+{
+	if (regno >= ivideo.video_cmap_len)
+		return 1;
+
+	sis_palette[regno].red = red;
+	sis_palette[regno].green = green;
+	sis_palette[regno].blue = blue;
+
+	switch (ivideo.video_bpp) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+	        outSISREG(SISDACA, regno);
+		outSISREG(SISDACD, (red >> 10));
+		outSISREG(SISDACD, (green >> 10));
+		outSISREG(SISDACD, (blue >> 10));
+		if (ivideo.disp_state & DISPTYPE_DISP2) {
+		        outSISREG(SISDAC2A, regno);
+			outSISREG(SISDAC2D, (red >> 8));
+			outSISREG(SISDAC2D, (green >> 8));
+			outSISREG(SISDAC2D, (blue >> 8));
+		}
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		sis_fbcon_cmap.cfb16[regno] =
+		    ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
+		break;
+#endif
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		red >>= 8;
+		green >>= 8;
+		blue >>= 8;
+		sis_fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);
+		break;
+#endif
+	}
+	return 0;
+}
+
+static void sisfb_set_disp(int con, struct fb_var_screeninfo *var,
+                           struct fb_info *info)
 {
 	struct fb_fix_screeninfo fix;
+	long   flags;
 	struct display *display;
 	struct display_switch *sw;
-	long flags;
 
-	if (con >= 0)
+	if(con >= 0)
 		display = &fb_display[con];
 	else
-		display = &disp;	
+		display = &sis_disp;
 
 	sisfb_get_fix(&fix, con, 0);
 
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,23)
 	display->screen_base = ivideo.video_vbase;
-#endif
 	display->visual = fix.visual;
 	display->type = fix.type;
 	display->type_aux = fix.type_aux;
@@ -675,29 +1135,35 @@
 	display->var = *var;
 
 	save_flags(flags);
+
 	switch (ivideo.video_bpp) {
 #ifdef FBCON_HAS_CFB8
 	   case 8:
+#ifdef SISFBACCEL
+		sw = ivideo.accel ? &fbcon_sis8 : &fbcon_cfb8;
+#else
 		sw = &fbcon_cfb8;
+#endif
 		break;
 #endif
 #ifdef FBCON_HAS_CFB16
-	   case 15:
 	   case 16:
+#ifdef SISFBACCEL
+		sw = ivideo.accel ? &fbcon_sis16 : &fbcon_cfb16;
+#else
 		sw = &fbcon_cfb16;
-		display->dispsw_data = fbcon_cmap.cfb16;
-		break;
 #endif
-#ifdef FBCON_HAS_CFB24
-	   case 24:
-		sw = &fbcon_cfb24;
-		display->dispsw_data = fbcon_cmap.cfb24;
+		display->dispsw_data = sis_fbcon_cmap.cfb16;
 		break;
 #endif
 #ifdef FBCON_HAS_CFB32
 	   case 32:
+#ifdef SISFBACCEL
+		sw = ivideo.accel ? &fbcon_sis32 : &fbcon_cfb32;
+#else
 		sw = &fbcon_cfb32;
-		display->dispsw_data = fbcon_cmap.cfb32;
+#endif
+		display->dispsw_data = sis_fbcon_cmap.cfb32;
 		break;
 #endif
 	   default:
@@ -708,37 +1174,919 @@
 	display->dispsw = &sisfb_sw;
 	restore_flags(flags);
 
+#ifdef SISFB_PAN
+        if((ivideo.accel) && (sisfb_ypan)) {
+  	    /* display->scrollmode = SCROLL_YPAN; - not defined */
+	} else {
+	    display->scrollmode = SCROLL_YREDRAW;
+	    sisfb_sw.bmove = fbcon_redraw_bmove;
+	}
+#else
 	display->scrollmode = SCROLL_YREDRAW;
 	sisfb_sw.bmove = fbcon_redraw_bmove;
+#endif
 }
 
 static void sisfb_do_install_cmap(int con, struct fb_info *info)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
-	if (con != info->currcon)
-		return;
-
-        if (fb_display[con].cmap.len)
-                fb_set_cmap(&fb_display[con].cmap, 1, info);
-        else
-		fb_set_cmap(fb_default_cmap(video_cmap_len), 1, info);
-#else
         if (con != currcon)
 		return;
 
         if (fb_display[con].cmap.len)
 		fb_set_cmap(&fb_display[con].cmap, 1, sisfb_setcolreg, info);
         else
-		fb_set_cmap(fb_default_cmap(video_cmap_len), 1,
+		fb_set_cmap(fb_default_cmap(ivideo.video_cmap_len), 1,
 			    sisfb_setcolreg, info);
+}
+
+
+static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
+{
+	TWDEBUG("inside get_var");
+	if(con == -1)
+		memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
+	else
+		*var = fb_display[con].var;
+
+ 	/* For FSTN, DSTN */
+	if (var->xres == 320 && var->yres == 480)
+		var->yres = 240;
+		
+	TWDEBUG("end of get_var");
+	return 0;
+}
+
+static int sisfb_set_var(struct fb_var_screeninfo *var, int con,
+			 struct fb_info *info)
+{
+	int err;
+	unsigned int cols, rows;
+
+	TWDEBUG("inside set_var");
+
+	fb_display[con].var.activate = FB_ACTIVATE_NOW;
+        if(sisfb_do_set_var(var, con == currcon, info)) {
+		sisfb_crtc_to_var(var);
+		return -EINVAL;
+	}
+
+	sisfb_crtc_to_var(var);
+
+	sisfb_set_disp(con, var, info);
+
+	if(info->changevar)
+		(*info->changevar) (con);
+
+	if((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0)))
+		return err;
+
+	sisfb_do_install_cmap(con, info);
+
+	cols = sisbios_mode[sisfb_mode_idx].cols;
+	rows = sisbios_mode[sisfb_mode_idx].rows;
+	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
+
+	TWDEBUG("end of set_var");
+	return 0;
+}
+
+static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
+{
+	TWDEBUG("inside get_cmap");
+        if (con == currcon)
+		return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
+
+	else if (fb_display[con].cmap.len)
+		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+	else
+		fb_copy_cmap(fb_default_cmap(ivideo.video_cmap_len), cmap, kspc ? 0 : 2);
+
+	TWDEBUG("end of get_cmap");
+	return 0;
+}
+
+static int sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			  struct fb_info *info)
+{
+	int err;
+
+	TWDEBUG("inside set_cmap");
+	if (!fb_display[con].cmap.len) {
+		err = fb_alloc_cmap(&fb_display[con].cmap, ivideo.video_cmap_len, 0);
+		if (err)
+			return err;
+	}
+        
+	if (con == currcon)
+		return fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);
+
+	else
+		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+	TWDEBUG("end of set_cmap");
+	return 0;
+}
+
+#ifdef SISFB_PAN
+static int sisfb_pan_display(struct fb_var_screeninfo *var, int con,
+			     struct fb_info* info)
+{
+	int err;
+	
+	TWDEBUG("inside pan_display");
+	if (var->vmode & FB_VMODE_YWRAP) {
+		if (var->yoffset < 0 || var->yoffset >= fb_display[con].var.yres_virtual || var->xoffset)
+			return -EINVAL;
+	} else {
+		if (var->xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual ||
+		    var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)
+			return -EINVAL;
+	}
+
+        if(con == currcon) {
+	   if((err = sisfb_pan_var(var)) < 0) return err;
+	}
+
+	fb_display[con].var.xoffset = var->xoffset;
+	fb_display[con].var.yoffset = var->yoffset;
+	if (var->vmode & FB_VMODE_YWRAP)
+		fb_display[con].var.vmode |= FB_VMODE_YWRAP;
+	else
+		fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
+
+	TWDEBUG("end of pan_display");
+	return 0;
+}
 #endif
 
+static int sisfb_mmap(struct fb_info *info, struct file *file,
+		      struct vm_area_struct *vma)
+{
+	struct fb_var_screeninfo var;
+	unsigned long start;
+	unsigned long off;
+	u32 len, mmio_off;
+
+	TWDEBUG("inside mmap");
+	if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT))  return -EINVAL;
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
+
+	start = (unsigned long) ivideo.video_base;
+	len = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.video_size);
+#if 0
+	if (off >= len) {
+		off -= len;
+#endif
+	/* By Jake Page: Treat mmap request with offset beyond heapstart
+	 *               as request for mapping the mmio area 
+	 */
+	mmio_off = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.heapstart);
+	if(off >= mmio_off) {
+		off -= mmio_off;		
+		sisfb_get_var(&var, currcon, info);
+		if(var.accel_flags) return -EINVAL;
+
+		start = (unsigned long) ivideo.mmio_base;
+		len = PAGE_ALIGN((start & ~PAGE_MASK) + sisfb_mmio_size);
+	}
+
+	start &= PAGE_MASK;
+	if((vma->vm_end - vma->vm_start + off) > len)	return -EINVAL;
+
+	off += start;
+	vma->vm_pgoff = off >> PAGE_SHIFT;
+	vma->vm_flags |= VM_IO;   /* by Jake Page; is that really needed? */
+
+#if defined(__i386__) || defined(__x86_64__)
+	if (boot_cpu_data.x86 > 3)
+		pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+#endif
+	if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start,
+				vma->vm_page_prot))
+		return -EAGAIN;
+
+        TWDEBUG("end of mmap");
+	return 0;
 }
 
+static void sis_get_glyph(struct fb_info *info, SIS_GLYINFO *gly)
+{
+	struct display *p = &fb_display[currcon];
+	u16 c;
+	u8 *cdat;
+	int widthb;
+	u8 *gbuf = gly->gmask;
+	int size;
+
+	TWDEBUG("Inside get_glyph");
+	gly->fontheight = fontheight(p);
+	gly->fontwidth = fontwidth(p);
+	widthb = (fontwidth(p) + 7) / 8;
+
+	c = gly->ch & p->charmask;
+	if (fontwidth(p) <= 8)
+		cdat = p->fontdata + c * fontheight(p);
+	else
+		cdat = p->fontdata + (c * fontheight(p) << 1);
+
+	size = fontheight(p) * widthb;
+	memcpy(gbuf, cdat, size);
+	gly->ngmask = size;
+	TWDEBUG("End of get_glyph");
+}
+
+static int sisfb_update_var(int con, struct fb_info *info)
+{
+#ifdef SISFB_PAN
+        return(sisfb_pan_var(&fb_display[con].var));
+#else
+	return 0;
+#endif	
+}
+
+static int sisfb_switch(int con, struct fb_info *info)
+{
+	int cols, rows;
+
+        if(fb_display[currcon].cmap.len)
+		fb_get_cmap(&fb_display[currcon].cmap, 1, sis_getcolreg, info);
+
+	fb_display[con].var.activate = FB_ACTIVATE_NOW;
+
+	if(!memcmp(&fb_display[con].var, &fb_display[currcon].var,
+	                           sizeof(struct fb_var_screeninfo))) {
+		currcon = con;
+		return 1;
+	}
+
+	currcon = con;
+
+	sisfb_do_set_var(&fb_display[con].var, 1, info);
+
+	sisfb_set_disp(con, &fb_display[con].var, info);
+
+	sisfb_do_install_cmap(con, info);
+
+	cols = sisbios_mode[sisfb_mode_idx].cols;
+	rows = sisbios_mode[sisfb_mode_idx].rows;
+	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
+
+	sisfb_update_var(con, info);
+
+	return 1;
+}
+
+static void sisfb_blank(int blank, struct fb_info *info)
+{
+	u8 reg;
 
-/* --------------- Chip-dependent Routines --------------------------- */
+	inSISIDXREG(SISCR, 0x17, reg);
+
+	if(blank > 0)
+		reg &= 0x7f;
+	else
+		reg |= 0x80;
+
+        outSISIDXREG(SISCR, 0x17, reg);		
+	outSISIDXREG(SISSR, 0x00, 0x01);    /* Synchronous Reset */
+	outSISIDXREG(SISSR, 0x00, 0x03);    /* End Reset */
+	printk(KERN_DEBUG "sisfb_blank() called (%d)\n", blank);
+}
+
+
+static int sisfb_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg, int con,
+		       struct fb_info *info)
+{
+	TWDEBUG("inside ioctl");
+	switch (cmd) {
+	   case FBIO_ALLOC:
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+		sis_malloc((struct sis_memreq *) arg);
+		break;
+	   case FBIO_FREE:
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+		sis_free(*(unsigned long *) arg);
+		break;
+	   case FBIOGET_GLYPH:
+                sis_get_glyph(info,(SIS_GLYINFO *) arg);
+		break;	
+	   case FBIOGET_HWCINFO:
+		{
+			unsigned long *hwc_offset = (unsigned long *) arg;
+
+			if (sisfb_caps & HW_CURSOR_CAP)
+				*hwc_offset = sisfb_hwcursor_vbase -
+				    (unsigned long) ivideo.video_vbase;
+			else
+				*hwc_offset = 0;
+
+			break;
+		}
+	   case FBIOPUT_MODEINFO:
+		{
+			struct mode_info *x = (struct mode_info *)arg;
+
+			ivideo.video_bpp        = x->bpp;
+			ivideo.video_width      = x->xres;
+			ivideo.video_height     = x->yres;
+			ivideo.video_vwidth     = x->v_xres;
+			ivideo.video_vheight    = x->v_yres;
+			ivideo.org_x            = x->org_x;
+			ivideo.org_y            = x->org_y;
+			ivideo.refresh_rate     = x->vrate;
+			ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
+			switch(ivideo.video_bpp) {
+        		case 8:
+            			ivideo.DstColor = 0x0000;
+	    			ivideo.SiS310_AccelDepth = 0x00000000;
+				ivideo.video_cmap_len = 256;
+            			break;
+        		case 16:
+            			ivideo.DstColor = 0x8000;
+            			ivideo.SiS310_AccelDepth = 0x00010000;
+				ivideo.video_cmap_len = 16;
+            			break;
+        		case 32:
+            			ivideo.DstColor = 0xC000;
+	    			ivideo.SiS310_AccelDepth = 0x00020000;
+				ivideo.video_cmap_len = 16;
+            			break;
+			default:
+				ivideo.video_cmap_len = 16;
+		       	 	printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
+				ivideo.accel = 0;
+				break;
+    			}
+
+			break;
+		}
+	   case FBIOGET_DISPINFO:
+		sis_dispinfo((struct ap_data *)arg);
+		break;
+	   case SISFB_GET_INFO:  /* TW: New for communication with X driver */
+	        {
+			sisfb_info *x = (sisfb_info *)arg;
+
+			x->sisfb_id = SISFB_ID;
+			x->sisfb_version = VER_MAJOR;
+			x->sisfb_revision = VER_MINOR;
+			x->sisfb_patchlevel = VER_LEVEL;
+			x->chip_id = ivideo.chip_id;
+			x->memory = ivideo.video_size / 1024;
+			x->heapstart = ivideo.heapstart / 1024;
+			x->fbvidmode = sisfb_mode_no;
+			x->sisfb_caps = sisfb_caps;
+			x->sisfb_tqlen = 512; /* yet unused */
+			x->sisfb_pcibus = ivideo.pcibus;
+			x->sisfb_pcislot = ivideo.pcislot;
+			x->sisfb_pcifunc = ivideo.pcifunc;
+			x->sisfb_lcdpdc = sisfb_detectedpdc;
+			x->sisfb_lcda = sisfb_detectedlcda;
+	                break;
+		}
+	   case SISFB_GET_VBRSTATUS:
+	        {
+			unsigned long *vbrstatus = (unsigned long *) arg;
+			if(sisfb_CheckVBRetrace()) *vbrstatus = 1;
+			else		           *vbrstatus = 0;
+		}
+	   default:
+		return -EINVAL;
+	}
+	TWDEBUG("end of ioctl");
+	return 0;
+
+}
+#endif
+
+/* ------------ FBDev related routines for 2.5 series ----------- */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+
+static int sisfb_open(struct fb_info *info, int user)
+{
+    return 0;
+}
+
+static int sisfb_release(struct fb_info *info, int user)
+{
+    return 0;
+}
+
+static int sisfb_get_cmap_len(const struct fb_var_screeninfo *var)
+{
+	int rc = 16;		
+
+	switch(var->bits_per_pixel) {
+	case 8:
+		rc = 256;	
+		break;
+	case 16:
+		rc = 16;	
+		break;		
+	case 32:
+		rc = 16;
+		break;	
+	}
+	return rc;
+}
+
+static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+                           unsigned transp, struct fb_info *info)
+{
+	if (regno >= sisfb_get_cmap_len(&info->var))
+		return 1;
+
+	switch (info->var.bits_per_pixel) {
+	case 8:
+	        outSISREG(SISDACA, regno);
+		outSISREG(SISDACD, (red >> 10));
+		outSISREG(SISDACD, (green >> 10));
+		outSISREG(SISDACD, (blue >> 10));
+		if (ivideo.disp_state & DISPTYPE_DISP2) {
+		        outSISREG(SISDAC2A, regno);
+			outSISREG(SISDAC2D, (red >> 8));
+			outSISREG(SISDAC2D, (green >> 8));
+			outSISREG(SISDAC2D, (blue >> 8));
+		}
+		break;
+	case 16:
+		((u32 *)(info->pseudo_palette))[regno] =
+		    ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
+		break;
+	case 32:
+		red >>= 8;
+		green >>= 8;
+		blue >>= 8;
+		((u32 *) (info->pseudo_palette))[regno] = 
+			(red << 16) | (green << 8) | (blue);
+		break;
+	}
+	return 0;
+}
+
+static int sisfb_set_par(struct fb_info *info)
+{
+	int err;
+
+	TWDEBUG("inside set_par");
+        if((err = sisfb_do_set_var(&info->var, 1, info)))
+		return err;
+
+	sisfb_get_fix(&info->fix, info->currcon, info);
+
+	TWDEBUG("end of set_par");
+	return 0;
+}
+
+static int sisfb_check_var(struct fb_var_screeninfo *var,
+                           struct fb_info *info)
+{
+	unsigned int htotal =
+		var->left_margin + var->xres + var->right_margin +
+		var->hsync_len;
+	unsigned int vtotal = 0;
+	double drate = 0, hrate = 0;
+	int found_mode = 0;
+	int refresh_rate, search_idx;
+
+	TWDEBUG("Inside check_var");
+
+	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
+		vtotal = var->upper_margin + var->yres + var->lower_margin +
+		         var->vsync_len;   
+		vtotal <<= 1;
+	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+		vtotal = var->upper_margin + var->yres + var->lower_margin +
+		         var->vsync_len;   
+		vtotal <<= 2;
+	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+		vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
+		         var->vsync_len;   
+	} else 	vtotal = var->upper_margin + var->yres + var->lower_margin +
+		         var->vsync_len;
+
+	if(!(htotal) || !(vtotal)) {
+		SISFAIL("sisfb: no valid timing data");
+	}
+
+	if((var->pixclock) && (htotal)) {
+	   drate = 1E12 / var->pixclock;
+	   hrate = drate / htotal;
+	   refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
+	} else refresh_rate = 60;
+
+	/* TW: Calculation wrong for 1024x600 - force it to 60Hz */
+	if((var->xres == 1024) && (var->yres == 600)) refresh_rate = 60;
+
+	search_idx = 0;
+	while( (sisbios_mode[search_idx].mode_no != 0) &&
+	       (sisbios_mode[search_idx].xres <= var->xres) ) {
+		if( (sisbios_mode[search_idx].xres == var->xres) &&
+		    (sisbios_mode[search_idx].yres == var->yres) &&
+		    (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {
+		        if(sisfb_validate_mode(search_idx) > 0) {
+			   found_mode = 1;
+			   break;
+			}
+		}
+		search_idx++;
+	}
+
+	if(!found_mode) {
+	
+		printk(KERN_ERR "sisfb: %dx%dx%d is no valid mode\n", 
+			var->xres, var->yres, var->bits_per_pixel);
+			
+                search_idx = 0;
+		while(sisbios_mode[search_idx].mode_no != 0) {
+		       
+		   if( (var->xres <= sisbios_mode[search_idx].xres) &&
+		       (var->yres <= sisbios_mode[search_idx].yres) && 
+		       (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {
+		          if(sisfb_validate_mode(search_idx) > 0) {
+			     found_mode = 1;
+			     break;
+			  }
+		   }
+		   search_idx++;
+	        }			
+		if(found_mode) {
+			var->xres = sisbios_mode[search_idx].xres;
+		      	var->yres = sisbios_mode[search_idx].yres;
+		      	printk(KERN_DEBUG "sisfb: Adapted to mode %dx%dx%d\n",
+		   		var->xres, var->yres, var->bits_per_pixel);
+		   
+		} else {
+		   	printk(KERN_ERR "sisfb: Failed to find similar mode to %dx%dx%d\n", 
+				var->xres, var->yres, var->bits_per_pixel);
+		   	return -EINVAL;
+		}
+	}
+
+	/* TW: TODO: Check the refresh rate */		
+	
+	/* Adapt RGB settings */
+	sisfb_bpp_to_var(var);	
+	
+	/* Sanity check for offsets */
+	if (var->xoffset < 0)
+		var->xoffset = 0;
+	if (var->yoffset < 0)
+		var->yoffset = 0;
+
+	/* Horiz-panning not supported */
+	if(var->xres != var->xres_virtual)
+		var->xres_virtual = var->xres;
+
+	if(!sisfb_ypan) {
+		if(var->yres != var->yres_virtual)
+			var->yres_virtual = var->yres;
+	} else {
+	   /* TW: Now patch yres_virtual if we use panning */
+	   /* *** May I do this? *** */
+	   var->yres_virtual = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
+	    if(var->yres_virtual <= var->yres) {
+	    	/* TW: Paranoia check */
+	        var->yres_virtual = var->yres;
+	    }
+	}
+	
+	/* Truncate offsets to maximum if too high */
+	if (var->xoffset > var->xres_virtual - var->xres)
+		var->xoffset = var->xres_virtual - var->xres - 1;
+
+	if (var->yoffset > var->yres_virtual - var->yres)
+		var->yoffset = var->yres_virtual - var->yres - 1;
+	
+	/* Set everything else to 0 */
+	var->red.msb_right = 
+	    var->green.msb_right =
+	    var->blue.msb_right =
+	    var->transp.offset = var->transp.length = var->transp.msb_right = 0;		
+		
+	TWDEBUG("end of check_var");
+	return 0;
+}
+
+#ifdef SISFB_PAN
+static int sisfb_pan_display(struct fb_var_screeninfo *var,
+			     struct fb_info* info)
+{
+	int err;
+	
+	TWDEBUG("inside pan_display");
+	
+	if (var->xoffset > (var->xres_virtual - var->xres))
+		return -EINVAL;
+	if (var->yoffset > (var->yres_virtual - var->yres))
+		return -EINVAL;
+
+	if (var->vmode & FB_VMODE_YWRAP) {
+		if (var->yoffset < 0
+		    || var->yoffset >= info->var.yres_virtual
+		    || var->xoffset) return -EINVAL;
+	} else {
+		if (var->xoffset + info->var.xres > info->var.xres_virtual ||
+		    var->yoffset + info->var.yres > info->var.yres_virtual)
+			return -EINVAL;
+	}
+    
+	if((err = sisfb_pan_var(var)) < 0) return err;
+
+	info->var.xoffset = var->xoffset;
+	info->var.yoffset = var->yoffset;
+	if (var->vmode & FB_VMODE_YWRAP)
+		info->var.vmode |= FB_VMODE_YWRAP;
+	else
+		info->var.vmode &= ~FB_VMODE_YWRAP;
+
+	TWDEBUG("end of pan_display");
+	return 0;
+}
+#endif
+
+static int sisfb_mmap(struct fb_info *info, struct file *file,
+		      struct vm_area_struct *vma)
+{
+	unsigned long start;
+	unsigned long off;
+	u32 len, mmio_off;
+
+	TWDEBUG("inside mmap");
+	if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT))  return -EINVAL;
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
+
+	start = (unsigned long) ivideo.video_base;
+	len = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.video_size);
+#if 0
+	if (off >= len) {
+		off -= len;
+#endif
+	/* By Jake Page: Treat mmap request with offset beyond heapstart
+	 *               as request for mapping the mmio area 
+	 */
+	mmio_off = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.heapstart);
+	if(off >= mmio_off) {
+		off -= mmio_off;		
+		if(info->var.accel_flags) return -EINVAL;
+
+		start = (unsigned long) ivideo.mmio_base;
+		len = PAGE_ALIGN((start & ~PAGE_MASK) + sisfb_mmio_size);
+	}
+
+	start &= PAGE_MASK;
+	if((vma->vm_end - vma->vm_start + off) > len)	return -EINVAL;
+
+	off += start;
+	vma->vm_pgoff = off >> PAGE_SHIFT;
+	vma->vm_flags |= VM_IO;   /* by Jake Page; is that really needed? */
+
+#if defined(__i386__) || defined(__x86_64__)
+	if (boot_cpu_data.x86 > 3)
+		pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+#endif
+	if (io_remap_page_range(vma, vma->vm_start, off, vma->vm_end - vma->vm_start,
+				vma->vm_page_prot))
+		return -EAGAIN;
+
+        TWDEBUG("end of mmap");
+	return 0;
+}
+
+static int sisfb_blank(int blank, struct fb_info *info)
+{
+	u8 reg;
+
+	inSISIDXREG(SISCR, 0x17, reg);
+
+	if(blank > 0)
+		reg &= 0x7f;
+	else
+		reg |= 0x80;
+
+        outSISIDXREG(SISCR, 0x17, reg);		
+	outSISIDXREG(SISSR, 0x00, 0x01);    /* Synchronous Reset */
+	outSISIDXREG(SISSR, 0x00, 0x03);    /* End Reset */
+        return(0);
+}
+
+static int sisfb_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg, 
+		       struct fb_info *info)
+{
+	TWDEBUG("inside ioctl");
+	switch (cmd) {
+	   case FBIO_ALLOC:
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+		sis_malloc((struct sis_memreq *) arg);
+		break;
+	   case FBIO_FREE:
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+		sis_free(*(unsigned long *) arg);
+		break;
+	   case FBIOGET_HWCINFO:
+		{
+			unsigned long *hwc_offset = (unsigned long *) arg;
+
+			if (sisfb_caps & HW_CURSOR_CAP)
+				*hwc_offset = sisfb_hwcursor_vbase -
+				    (unsigned long) ivideo.video_vbase;
+			else
+				*hwc_offset = 0;
+
+			break;
+		}
+	   case FBIOPUT_MODEINFO:
+		{
+			struct mode_info *x = (struct mode_info *)arg;
+
+			ivideo.video_bpp        = x->bpp;
+			ivideo.video_width      = x->xres;
+			ivideo.video_height     = x->yres;
+			ivideo.video_vwidth     = x->v_xres;
+			ivideo.video_vheight    = x->v_yres;
+			ivideo.org_x            = x->org_x;
+			ivideo.org_y            = x->org_y;
+			ivideo.refresh_rate     = x->vrate;
+			ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
+			switch(ivideo.video_bpp) {
+        		case 8:
+            			ivideo.DstColor = 0x0000;
+	    			ivideo.SiS310_AccelDepth = 0x00000000;
+				ivideo.video_cmap_len = 256;
+            			break;
+        		case 16:
+            			ivideo.DstColor = 0x8000;
+            			ivideo.SiS310_AccelDepth = 0x00010000;
+				ivideo.video_cmap_len = 16;
+            			break;
+        		case 32:
+            			ivideo.DstColor = 0xC000;
+	    			ivideo.SiS310_AccelDepth = 0x00020000;
+				ivideo.video_cmap_len = 16;
+            			break;
+			default:
+				ivideo.video_cmap_len = 16;
+		       	 	printk(KERN_ERR "sisfb: Unsupported accel depth %d", ivideo.video_bpp);
+				ivideo.accel = 0;
+				break;
+    			}
+
+			break;
+		}
+	   case FBIOGET_DISPINFO:
+		sis_dispinfo((struct ap_data *)arg);
+		break;
+	   case SISFB_GET_INFO:  /* TW: New for communication with X driver */
+	        {
+			sisfb_info *x = (sisfb_info *)arg;
+
+			x->sisfb_id = SISFB_ID;
+			x->sisfb_version = VER_MAJOR;
+			x->sisfb_revision = VER_MINOR;
+			x->sisfb_patchlevel = VER_LEVEL;
+			x->chip_id = ivideo.chip_id;
+			x->memory = ivideo.video_size / 1024;
+			x->heapstart = ivideo.heapstart / 1024;
+			x->fbvidmode = sisfb_mode_no;
+			x->sisfb_caps = sisfb_caps;
+			x->sisfb_tqlen = 512; /* yet unused */
+			x->sisfb_pcibus = ivideo.pcibus;
+			x->sisfb_pcislot = ivideo.pcislot;
+			x->sisfb_pcifunc = ivideo.pcifunc;
+			x->sisfb_lcdpdc = sisfb_detectedpdc;
+			x->sisfb_lcda = sisfb_detectedlcda;
+	                break;
+		}
+	   case SISFB_GET_VBRSTATUS:
+	        {
+			unsigned long *vbrstatus = (unsigned long *) arg;
+			if(sisfb_CheckVBRetrace()) *vbrstatus = 1;
+			else		           *vbrstatus = 0;
+		}
+	   default:
+		return -EINVAL;
+	}
+	TWDEBUG("end of ioctl");
+	return 0;
+
+}
+
+#endif
+
+/* ----------- FBDev related routines for all series ---------- */
+
+static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			 struct fb_info *info)
+{
+	TWDEBUG("inside get_fix");
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+	strcpy(fix->id, sis_fb_info.modename);
+#else
+	strcpy(fix->id, myid);
+#endif	
+
+	fix->smem_start = ivideo.video_base;
+
+        /* TW */
+        if((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
+	    if (ivideo.video_size > 0x1000000) {
+	        fix->smem_len = 0xc00000;
+	    } else if (ivideo.video_size > 0x800000)
+		fix->smem_len = 0x800000;
+	    else
+		fix->smem_len = 0x400000;
+        } else
+		fix->smem_len = sisfb_mem * 1024;
+
+	fix->type        = video_type;
+	fix->type_aux    = 0;
+	if(ivideo.video_bpp == 8)
+		fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	else
+		fix->visual = FB_VISUAL_TRUECOLOR;
+	fix->xpanstep    = 0;
+#ifdef SISFB_PAN
+        if(sisfb_ypan) 	 fix->ypanstep = 1;
+#endif
+	fix->ywrapstep   = 0;
+	fix->line_length = ivideo.video_linelength;
+	fix->mmio_start  = ivideo.mmio_base;
+	fix->mmio_len    = sisfb_mmio_size;
+	if(sisvga_engine == SIS_300_VGA) 
+	   fix->accel    = FB_ACCEL_SIS_GLAMOUR;
+	else if(ivideo.chip == SIS_330)
+	   fix->accel    = FB_ACCEL_SIS_XABRE;
+	else 
+	   fix->accel    = FB_ACCEL_SIS_GLAMOUR_2;
+	
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		
+	fix->reserved[0] = ivideo.video_size & 0xFFFF;
+	fix->reserved[1] = (ivideo.video_size >> 16) & 0xFFFF;
+	fix->reserved[2] = sisfb_caps;
+#endif	
+
+	TWDEBUG("end of get_fix");
+	return 0;
+}
+
+/* ----------------  fb_ops structures ----------------- */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+static struct fb_ops sisfb_ops = {
+	owner:		THIS_MODULE,
+	fb_get_fix:	sisfb_get_fix,
+	fb_get_var:	sisfb_get_var,
+	fb_set_var:	sisfb_set_var,
+	fb_get_cmap:	sisfb_get_cmap,
+	fb_set_cmap:	sisfb_set_cmap,
+#ifdef SISFB_PAN
+        fb_pan_display:	sisfb_pan_display,
+#endif
+	fb_ioctl:	sisfb_ioctl,
+	fb_mmap:	sisfb_mmap,
+};
+#endif
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+static struct fb_ops sisfb_ops = {
+	.owner        =	THIS_MODULE,
+	.fb_open      = sisfb_open,
+	.fb_release   = sisfb_release,
+	.fb_check_var = sisfb_check_var,
+	.fb_set_par   = sisfb_set_par,
+	.fb_setcolreg = sisfb_setcolreg,
+#ifdef SISFB_PAN
+        .fb_pan_display = sisfb_pan_display,
+#endif	
+        .fb_blank     = sisfb_blank,
+	.fb_fillrect  = fbcon_sis_fillrect,
+	.fb_copyarea  = fbcon_sis_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_cursor    = soft_cursor,	
+	.fb_sync      = fbcon_sis_sync,
+	.fb_ioctl     =	sisfb_ioctl,
+	.fb_mmap      =	sisfb_mmap,
+};
+#endif
+
+
+/* ---------------- Chip generation dependent routines ---------------- */
 
 #ifdef CONFIG_FB_SIS_300 /* for SiS 300/630/540/730 */
+
 static int sisfb_get_dram_size_300(void)
 {
 	struct pci_dev *pdev = NULL;
@@ -762,20 +2110,23 @@
 	}
 
 	if (nbridge_id == 0) {  /* 300 */
-		vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
+
+	        inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE,reg);
 		ivideo.video_size =
-		        ((unsigned int) ((vgarb(SEQ_DATA) & SIS_DRAM_SIZE_MASK) + 1) << 20);
+		        ((unsigned int) ((reg & SIS_DRAM_SIZE_MASK) + 1) << 20);
+
 	} else {		/* 540, 630, 730 */
+
 		pci_for_each_dev(pdev) {
+
 			if ((pdev->vendor == PCI_VENDOR_ID_SI) 
-				&& (pdev->device == nbridge_id)) {
+				       && (pdev->device == nbridge_id)) {
 				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);
 				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
 				ivideo.video_size = (unsigned int)(1 << (pci_data+21));
 				pdev_valid = 1;
 	
 				reg = SIS_DATA_BUS_64 << 6;
-				vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
 				switch (pci_data) {
 				   case BRI_DRAM_SIZE_2MB:
 					reg |= SIS_DRAM_SIZE_2MB;
@@ -796,13 +2147,12 @@
 					reg |= SIS_DRAM_SIZE_64MB;
 					break;
 				}
-				vgawb(SEQ_DATA, reg);
+				outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
 				break;
 			}  
 		}   
 	
-		if (!pdev_valid)
-			return -1;
+		if (!pdev_valid)  return -1;
 	}
 	return 0;
 }
@@ -811,13 +2161,24 @@
 {
 	u8 sr16, sr17, cr32, temp;
 
-	vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_17);
-	sr17 = vgarb(SEQ_DATA);
-	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR32);
-	cr32 = vgarb(CRTC_DATA);
-
 	ivideo.TV_plug = ivideo.TV_type = 0;
+
+        switch(ivideo.hasVB) {
+	  case HASVB_LVDS_CHRONTEL:
+	  case HASVB_CHRONTEL:
+	     SiS_SenseCh();
+	     break;
+	  case HASVB_301:
+	  case HASVB_302:
+	     SiS_Sense30x();
+	     break;
+	}
+
+	inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17);
+        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);
+
 	if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
+
 		if ((sr17 & 0x01) && !sisfb_crt1off)
 			sisfb_crt1off = 0;
 		else {
@@ -830,27 +2191,31 @@
 		if (sisfb_crt2type != -1)
 			/* TW: override detected CRT2 type */
 			ivideo.disp_state = sisfb_crt2type;
+                else if (sr17 & 0x04)
+			ivideo.disp_state = DISPTYPE_TV;			
+		else if (sr17 & 0x02)
+			ivideo.disp_state = DISPTYPE_LCD;			
 		else if (sr17 & 0x08 )
 			ivideo.disp_state = DISPTYPE_CRT2;
-		else if (sr17 & 0x02)
-			ivideo.disp_state = DISPTYPE_LCD;
-		else if (sr17 & 0x04)
-			ivideo.disp_state = DISPTYPE_TV;
 		else
 			ivideo.disp_state = 0;
 
-		if (sr17 & 0x20)
+		if(sisfb_tvplug != -1)
+			/* PR/TW: override detected TV type */
+			ivideo.TV_plug = sisfb_tvplug;
+		else if (sr17 & 0x20)
 			ivideo.TV_plug = TVPLUG_SVIDEO;
 		else if (sr17 & 0x10)
 			ivideo.TV_plug = TVPLUG_COMPOSITE;
 
-		vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_16);
-		sr16 = vgarb(SEQ_DATA);
+		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_16, sr16);
 		if (sr16 & 0x20)
 			ivideo.TV_type = TVMODE_PAL;
 		else
 			ivideo.TV_type = TVMODE_NTSC;
+
 	} else {
+
 		if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
 			sisfb_crt1off = 0;
 		else {
@@ -863,17 +2228,20 @@
 		if (sisfb_crt2type != -1)
 			/* TW: override detected CRT2 type */
 			ivideo.disp_state = sisfb_crt2type;
-		else if (cr32 & SIS_VB_CRT2)
-			ivideo.disp_state = DISPTYPE_CRT2;
-		else if (cr32 & SIS_VB_LCD)
-			ivideo.disp_state = DISPTYPE_LCD;
 		else if (cr32 & SIS_VB_TV)
 			ivideo.disp_state = DISPTYPE_TV;
+		else if (cr32 & SIS_VB_LCD)
+			ivideo.disp_state = DISPTYPE_LCD;
+		else if (cr32 & SIS_VB_CRT2)
+			ivideo.disp_state = DISPTYPE_CRT2;
 		else
 			ivideo.disp_state = 0;
 
-		/* TW: Detect TV plug & type anyway */
-		if (cr32 & SIS_VB_HIVISION) {
+		/* TW: Detect TV plug & type */
+		if(sisfb_tvplug != -1)
+			/* PR/TW: override with option */
+		        ivideo.TV_plug = sisfb_tvplug;
+		else if (cr32 & SIS_VB_HIVISION) {
 			ivideo.TV_type = TVMODE_HIVISION;
 			ivideo.TV_plug = TVPLUG_SVIDEO;
 		}
@@ -885,34 +2253,19 @@
 			ivideo.TV_plug = TVPLUG_SCART;
 
 		if (ivideo.TV_type == 0) {
-			// Eden Chen
-			//temp = *((u8 *)(sishw_ext.VirtualRomBase+0x52));
-			//if (temp&0x40) {
-			//	temp=*((u8 *)(sishw_ext.VirtualRomBase+0x53));
-				//} else {
-			vgawb(SEQ_ADR, IND_SIS_POWER_ON_TRAP);
-			temp = vgarb(SEQ_DATA);
-			//}
-			// ~Eden Chen
+		        inSISIDXREG(SISSR, IND_SIS_POWER_ON_TRAP, temp);
 			if (temp & 0x01)
 				ivideo.TV_type = TVMODE_PAL;
 			else
 				ivideo.TV_type = TVMODE_NTSC;
 		}
+
 	}
 
 	/* TW: Copy forceCRT1 option to CRT1off if option is given */
     	if (sisfb_forcecrt1 != -1) {
-		vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_17);
-    		sr17 = vgarb(SEQ_DATA);
-    		if (sisfb_forcecrt1) {
-			sisfb_crt1off=0;
-			sr17 |= 0x80;
-		} else {
-			sisfb_crt1off=1;
-			sr17 &= ~0x80;
-		}
-		vgawb(SEQ_DATA, sr17);
+    		if(sisfb_forcecrt1) sisfb_crt1off = 0;
+		else                sisfb_crt1off = 1;
     	}
 }
 
@@ -920,15 +2273,10 @@
 {
 	u8 reg;
 
-	if (ivideo.chip != SIS_300) {
-		if (!sisfb_has_VB_300()) {
-			vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR37);
-			reg = vgarb(CRTC_DATA);
-
+	if(ivideo.chip != SIS_300) {
+		if(!sisfb_has_VB_300()) {
+		        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
 			switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
-			   case SIS_EXTERNAL_CHIP_SIS301:
-				ivideo.hasVB = HASVB_301;
-				break;
 			   case SIS_EXTERNAL_CHIP_LVDS:
 				ivideo.hasVB = HASVB_LVDS;
 				break;
@@ -952,17 +2300,9 @@
 
 static int sisfb_has_VB_300(void)
 {
-	// Eden Chen
-	//u8 sr38, sr39, vb_chipid;
 	u8 vb_chipid;
 
-	//vgawb(SEQ_ADR, IND_SIS_POWER_ON_TRAP);
-	//sr38 = vgarb(SEQ_DATA);
-	//vgawb(SEQ_ADR, IND_SIS_POWER_ON_TRAP2);
-	//sr39 = vgarb(SEQ_DATA);
-	vgawb(VB_PART4_ADR, 0x0);
-	vb_chipid = vgarb(VB_PART4_DATA);
-
+	inSISIDXREG(SISPART4, 0x00, vb_chipid);
 	switch (vb_chipid) {
 	   case 0x01:
 		ivideo.hasVB = HASVB_301;
@@ -970,40 +2310,19 @@
 	   case 0x02:
 		ivideo.hasVB = HASVB_302;
 		break;
-	   case 0x03:
-		ivideo.hasVB = HASVB_303;
-		break;
 	   default:
 		ivideo.hasVB = HASVB_NONE;
 		return FALSE;
 	}
 	return TRUE;
 
-	//if (
-	//	( (ivideo.chip == SIS_300) && (sr38 & 0x20) )
-	//	||
-	//	( (ivideo.chip == SIS_540) && (sr38 & 0x20) && (!(sr39 & 0x80)) )
-	//	||
-	//	( (ivideo.chip == SIS_630 ) && (sr38 & 0x20) && (!(sr39 & 0x80)) && 
-	//		((ivideo.revision_id & 0xf0) < 0x30) && (vb_chipid == 1) ) 
-	//	||
-	//	( (ivideo.chip == SIS_630 ) && ((ivideo.revision_id & 0xf0) >= 0x30) && 
-	//		(vb_chipid == 1) ) 
-	//	||
-	//	( (ivideo.chip == SIS_730) && (vb_chipid == 1) ) /* 730 */
-	//) {
-	//	ivideo.hasVB = HASVB_301;
-	//	return TRUE;
-	//} else {
-	//	ivideo.hasVB = HASVB_NONE;
-	//	return FALSE;
-	//}
-
-	// ~Eden Chen
 }
+
 #endif  /* CONFIG_FB_SIS_300 */
 
-#ifdef CONFIG_FB_SIS_315    /* for SiS 315/550/650/740 */
+
+#ifdef CONFIG_FB_SIS_315    /* for SiS 315/550/650/740/330 */
+
 static int sisfb_get_dram_size_315(void)
 {
 	struct pci_dev *pdev = NULL;
@@ -1011,26 +2330,26 @@
 	u8  pci_data;
 	u8  reg = 0;
 
-	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650) {
+	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 || ivideo.chip == SIS_740) {
+
 #ifdef LINUXBIOS
+
 		pci_for_each_dev(pdev) {
+
 			if ( (pdev->vendor == PCI_VENDOR_ID_SI)
-				&& ( (pdev->device == PCI_DEVICE_ID_SI_550)
-				  || (pdev->device == PCI_DEVICE_ID_SI_650))) {
+				&& ( (pdev->device == PCI_DEVICE_ID_SI_550) ||
+				     (pdev->device == PCI_DEVICE_ID_SI_650) ||
+				     (pdev->device == PCI_DEVICE_ID_SI_740))) {
 				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
 				                     &pci_data);
 				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
-				ivideo.video_size =
-				    (unsigned int)(1 << (pci_data+21));
+				ivideo.video_size = (unsigned int)(1 << (pci_data + 21));
 				pdev_valid = 1;
 
 				/* TW: Initialize SR14 "by hand" */
-				vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
-				reg = vgarb(SEQ_DATA) & 0xC0;
-
+				inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
+				reg &= 0xC0;
 				switch (pci_data) {
-				//case BRI_DRAM_SIZE_2MB:
-				//	reg |= (SIS315_DRAM_SIZE_2MB << 4); break;
 				   case BRI_DRAM_SIZE_4MB:
 					reg |= SIS550_DRAM_SIZE_4MB;
 					break;
@@ -1046,22 +2365,20 @@
 				   case BRI_DRAM_SIZE_64MB:
 					reg |= SIS550_DRAM_SIZE_64MB;
 					break;
-				   /* case BRI_DRAM_SIZE_128MB:
-					reg |= (SIS315_DRAM_SIZE_128MB << 4); break; */
 				}
 
-			        /* TODO : set Dual channel and bus width bits here */
+			        /* TODO: set Dual channel and bus width bits here */
 
-				vgawb(SEQ_DATA, reg);
+				outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
 				break;
 			}  
 		}
 	
-		if (!pdev_valid)
-			return -1;
+		if (!pdev_valid)  return -1;
+
 #else
-		vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
-		reg = vgarb(SEQ_DATA);
+
+                inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
 		switch (reg & SIS550_DRAM_SIZE_MASK) {
 		   case SIS550_DRAM_SIZE_4MB:
 			ivideo.video_size = 0x400000;   break;
@@ -1090,17 +2407,20 @@
 			       "sisfb: Warning: Could not determine memory size, "
 			       "now reading from PCI config\n");
 			pdev_valid = 0;
+
 			pci_for_each_dev(pdev) {
+
 			   if ( (pdev->vendor == PCI_VENDOR_ID_SI)
 			         && (pdev->device == PCI_DEVICE_ID_SI_550) ) {
+
 				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
 				                     &pci_data);
 				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
 				ivideo.video_size = (unsigned int)(1 << (pci_data+21));
 				pdev_valid = 1;
 				/* TW: Initialize SR14=IND_SIS_DRAM_SIZE */
-				vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
-				reg = vgarb(SEQ_DATA) & 0xC0;
+				inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
+				reg &= 0xC0;
 				switch (pci_data) {
 				   case BRI_DRAM_SIZE_4MB:
 					reg |= SIS550_DRAM_SIZE_4MB;  break;
@@ -1112,13 +2432,11 @@
 					reg |= SIS550_DRAM_SIZE_32MB; break;
 				   case BRI_DRAM_SIZE_64MB:
 					reg |= SIS550_DRAM_SIZE_64MB; break;
-				   /* case BRI_DRAM_SIZE_128MB:
-					reg |= (SIS315_DRAM_SIZE_128MB << 4); break; */
 				   default:
 				   	printk(KERN_INFO "sisfb: Unable to determine memory size, giving up.\n");
 					return -1;
 				}
-				vgawb(SEQ_DATA, reg);
+				outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
 			   }
 			}
 			if (!pdev_valid) {
@@ -1129,9 +2447,10 @@
 		}
 #endif
 		return 0;
+
 	} else {	/* 315 */
-		vgawb(SEQ_ADR, IND_SIS_DRAM_SIZE);
-		reg = vgarb(SEQ_DATA);
+
+	        inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
 		switch ((reg & SIS315_DRAM_SIZE_MASK) >> 4) {
 		   case SIS315_DRAM_SIZE_2MB:
 			ivideo.video_size = 0x200000;
@@ -1157,33 +2476,55 @@
 		   default:
 			return -1;
 		}
-	}
+		
+		reg &= SIS315_DUAL_CHANNEL_MASK;
+		reg >>= 2;
+		
+		if(ivideo.chip == SIS_330) {
+		
+		   if(reg) ivideo.video_size <<= 1;
+		
+		} else {
+		   
+		   switch (reg) {
+		      case SIS315_SINGLE_CHANNEL_2_RANK:
+			   ivideo.video_size <<= 1;
+			   break;
+		      case SIS315_DUAL_CHANNEL_1_RANK:
+			   ivideo.video_size <<= 1;
+			   break;
+		      case SIS315_ASYM_DDR:		/* TW: DDR asymentric */
+			   ivideo.video_size += (ivideo.video_size/2);
+			   break;
+		   }
+		}
 
-	reg &= SIS315_DUAL_CHANNEL_MASK;
-	reg >>= 2;
-	switch (reg) {
-	   case SIS315_SINGLE_CHANNEL_2_RANK:
-		ivideo.video_size <<= 1;
-		break;
-	   case SIS315_DUAL_CHANNEL_1_RANK:
-		ivideo.video_size <<= 1;
-		break;
-	   case SIS315_ASYM_DDR:		/* TW: DDR asymentric */
-		ivideo.video_size += (ivideo.video_size/2);
-		break;
+		return 0;
 	}
-
-	return 0;
+	
+	return -1;
+	
 }
 
 static void sisfb_detect_VB_connect_315(void)
 {
-	u8 sr17, cr32, temp;
-
-	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR32);
-	cr32 = vgarb(CRTC_DATA);
+	u8 cr32, temp=0;
 
 	ivideo.TV_plug = ivideo.TV_type = 0;
+
+        switch(ivideo.hasVB) {
+	  case HASVB_LVDS_CHRONTEL:
+	  case HASVB_CHRONTEL:
+	     SiS_SenseCh();
+	     break;
+	  case HASVB_301:
+	  case HASVB_302:
+	     SiS_Sense30x();
+	     break;
+	}
+
+	inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);
+
 	if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
 		sisfb_crt1off = 0;
 	else {
@@ -1196,42 +2537,43 @@
 	if (sisfb_crt2type != -1)
 		/* TW: Override with option */
 		ivideo.disp_state = sisfb_crt2type;
+	else if (cr32 & SIS_VB_TV)
+		ivideo.disp_state = DISPTYPE_TV;		
+	else if (cr32 & SIS_VB_LCD)
+		ivideo.disp_state = DISPTYPE_LCD;		
 	else if (cr32 & SIS_VB_CRT2)
 		ivideo.disp_state = DISPTYPE_CRT2;
-	else if (cr32 & SIS_VB_LCD)
-		ivideo.disp_state = DISPTYPE_LCD;
-	else if (cr32 & SIS_VB_TV)
-		ivideo.disp_state = DISPTYPE_TV;
 	else
 		ivideo.disp_state = 0;
 
-	if (cr32 & SIS_VB_HIVISION) {
+	if(sisfb_tvplug != -1)
+		/* PR/TW: Override with option */
+	        ivideo.TV_plug = sisfb_tvplug;
+	else if (cr32 & SIS_VB_HIVISION) {
 		ivideo.TV_type = TVMODE_HIVISION;
 		ivideo.TV_plug = TVPLUG_SVIDEO;
-	} else if (cr32 & SIS_VB_SVIDEO)
+	}
+	else if (cr32 & SIS_VB_SVIDEO)
 		ivideo.TV_plug = TVPLUG_SVIDEO;
 	else if (cr32 & SIS_VB_COMPOSITE)
 		ivideo.TV_plug = TVPLUG_COMPOSITE;
 	else if (cr32 & SIS_VB_SCART)
 		ivideo.TV_plug = TVPLUG_SCART;
 
-	if (ivideo.TV_type == 0) {
-	    /* TW: PAL/NTSC changed for 315/650 */
-	    if(ivideo.chip <= SIS_315PRO) {
-#if 0
-		vgawb(SEQ_ADR, IND_SIS_POWER_ON_TRAP);
-		temp = vgarb(SEQ_DATA);
-#endif
-                vgawb(CRTC_ADR, 0x38);
-		temp = vgarb(CRTC_DATA);
-		if (temp & 0x10)
+	if(ivideo.TV_type == 0) {
+	    /* TW: PAL/NTSC changed for 650 */
+	    if((ivideo.chip <= SIS_315PRO) || (ivideo.chip >= SIS_330)) {
+
+                inSISIDXREG(SISCR, 0x38, temp);
+		if(temp & 0x10)
 			ivideo.TV_type = TVMODE_PAL;
 		else
 			ivideo.TV_type = TVMODE_NTSC;
+
 	    } else {
-	        vgawb(CRTC_ADR, 0x79);
-		temp = vgarb(CRTC_DATA);
-		if (temp & 0x20)
+
+	        inSISIDXREG(SISCR, 0x79, temp);
+		if(temp & 0x20)
 			ivideo.TV_type = TVMODE_PAL;
 		else
 			ivideo.TV_type = TVMODE_NTSC;
@@ -1240,16 +2582,8 @@
 
 	/* TW: Copy forceCRT1 option to CRT1off if option is given */
     	if (sisfb_forcecrt1 != -1) {
-		vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_17);
-    		sr17 = vgarb(SEQ_DATA);
-    		if (sisfb_forcecrt1) {
-			sisfb_crt1off=0;
-			sr17 |= 0x80;
-		} else {
-			sisfb_crt1off=1;
-			sr17 &= ~0x80;
-		}
-		vgawb(SEQ_DATA, sr17);
+    		if (sisfb_forcecrt1) sisfb_crt1off = 0;
+		else   	             sisfb_crt1off = 1;
     	}
 }
 
@@ -1257,25 +2591,19 @@
 {
 	u8 reg;
 
-		if (!sisfb_has_VB_315()) {
-			vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR37);
-			reg = vgarb(CRTC_DATA);
-
-			/* TW: CR37 changed on 310/325 series */
-			switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
-			   case SIS_EXTERNAL_CHIP_SIS301:
-				ivideo.hasVB = HASVB_301;
-				break;
-			   case SIS310_EXTERNAL_CHIP_LVDS:
-				ivideo.hasVB = HASVB_LVDS;
-				break;
-			   case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
-				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
-				break;
-			   default:
-				break;
-			}
+	if (!sisfb_has_VB_315()) {
+	        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
+		switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
+	 	   case SIS310_EXTERNAL_CHIP_LVDS:
+			ivideo.hasVB = HASVB_LVDS;
+			break;
+		   case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
+			ivideo.hasVB = HASVB_LVDS_CHRONTEL;
+			break;
+		   default:
+			break;
 		}
+	}
 }
 
 
@@ -1283,9 +2611,7 @@
 {
 	u8 vb_chipid;
 
-	vgawb(VB_PART4_ADR, 0x00);
-	vb_chipid = vgarb(VB_PART4_DATA);
-
+	inSISIDXREG(SISPART4, 0x00, vb_chipid);
 	switch (vb_chipid) {
 	   case 0x01:
 		ivideo.hasVB = HASVB_301;
@@ -1293,9 +2619,6 @@
 	   case 0x02:
 		ivideo.hasVB = HASVB_302;
 		break;
-	   case 0x03:
-		ivideo.hasVB = HASVB_303;
-		break;
 	   default:
 		ivideo.hasVB = HASVB_NONE;
 		return FALSE;
@@ -1305,7 +2628,233 @@
 
 #endif   /* CONFIG_FB_SIS_315 */
 
-/* --------------------- Heap Routines ------------------------------- */
+/* ------------------ Sensing routines ------------------ */
+
+/* TW: Determine and detect attached devices on SiS30x */
+int
+SISDoSense(int tempbl, int tempbh, int tempcl, int tempch)
+{
+    int temp,i;
+
+    outSISIDXREG(SISPART4,0x11,tempbl);
+    temp = tempbh | tempcl;
+    setSISIDXREG(SISPART4,0x10,0xe0,temp);
+    for(i=0; i<10; i++) SiS_LongWait(&SiS_Pr);
+    tempch &= 0x7f;
+    inSISIDXREG(SISPART4,0x03,temp);
+    temp ^= 0x0e;
+    temp &= tempch;
+    return(temp);
+}
+
+void
+SiS_Sense30x(void)
+{
+  u8 backupP4_0d;
+  u8 testsvhs_tempbl, testsvhs_tempbh;
+  u8 testsvhs_tempcl, testsvhs_tempch;
+  u8 testcvbs_tempbl, testcvbs_tempbh;
+  u8 testcvbs_tempcl, testcvbs_tempch;
+  u8 testvga2_tempbl, testvga2_tempbh;
+  u8 testvga2_tempcl, testvga2_tempch;
+  int myflag, result;
+
+  inSISIDXREG(SISPART4,0x0d,backupP4_0d);
+  outSISIDXREG(SISPART4,0x0d,(backupP4_0d | 0x04));
+
+  if(sisvga_engine == SIS_300_VGA) {
+
+  	testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
+        testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
+	testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+	if((sishw_ext.ujVBChipID != VB_CHIP_301) &&
+	   (sishw_ext.ujVBChipID != VB_CHIP_302) ) {
+	   testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
+	   testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
+	   testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
+	}
+	inSISIDXREG(SISPART4,0x01,myflag);
+	if(myflag & 0x04) {
+	   testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd;
+	   testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd;
+	   testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
+	}
+	testvga2_tempch = 0x0e;	testvga2_tempcl = 0x08;
+	testsvhs_tempch = 0x06;	testsvhs_tempcl = 0x04;
+	testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
+	if(ivideo.chip == SIS_300) {
+	   inSISIDXREG(SISSR,0x3b,myflag);
+	   if(!(myflag & 0x01)) {
+	      testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
+	      testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
+	   }
+	}
+
+  } else {
+
+	testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
+        testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
+	testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
+	if((sishw_ext.ujVBChipID != VB_CHIP_301) &&
+	   (sishw_ext.ujVBChipID != VB_CHIP_302)) {
+	      testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
+	      testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
+	      testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
+	      if(sishw_ext.ujVBChipID == VB_CHIP_301LV ||
+	         sishw_ext.ujVBChipID == VB_CHIP_302LV) {
+	         testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
+	         testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00;
+	         testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00;
+	      }
+	}
+	if(sishw_ext.ujVBChipID != VB_CHIP_301LV &&
+	   sishw_ext.ujVBChipID != VB_CHIP_302LV) {
+	   inSISIDXREG(SISPART4,0x01,myflag);
+	   if(myflag & 0x04) {
+	      testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd;
+	      testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd;
+	      testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
+	   }
+	}
+	if((sishw_ext.ujVBChipID == VB_CHIP_301LV) ||
+	   (sishw_ext.ujVBChipID == VB_CHIP_302LV) ) {
+	   testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
+	   testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
+	   testsvhs_tempch = 0x04; testsvhs_tempcl = 0x08;
+	   testcvbs_tempch = 0x08; testcvbs_tempcl = 0x08;
+	} else {
+	   testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
+	   testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
+	   testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
+	}
+    } 
+
+    if(testvga2_tempch || testvga2_tempcl || testvga2_tempbh || testvga2_tempbl) {
+        result = SISDoSense(testvga2_tempbl, testvga2_tempbh,
+                            testvga2_tempcl, testvga2_tempch);
+ 	if(result) {
+        	printk(KERN_INFO "sisfb: Detected secondary VGA connection\n");
+		orSISIDXREG(SISCR, 0x32, 0x10);
+	}
+    }
+    
+    result = SISDoSense(testsvhs_tempbl, testsvhs_tempbh,
+                        testsvhs_tempcl, testsvhs_tempch);
+    if(result) {
+        printk(KERN_INFO "sisfb: Detected TV connected to SVHS output\n");
+        /* TW: So we can be sure that there IS a SVHS output */
+	ivideo.TV_plug = TVPLUG_SVIDEO;
+	orSISIDXREG(SISCR, 0x32, 0x02);
+    }
+
+    if(!result) {
+        result = SISDoSense(testcvbs_tempbl, testcvbs_tempbh,
+	                    testcvbs_tempcl, testcvbs_tempch);
+	if(result) {
+	    printk(KERN_INFO "sisfb: Detected TV connected to CVBS output\n");
+	    /* TW: So we can be sure that there IS a CVBS output */
+	    ivideo.TV_plug = TVPLUG_COMPOSITE;
+	    orSISIDXREG(SISCR, 0x32, 0x01);
+	}
+    }
+    SISDoSense(0, 0, 0, 0);
+
+    outSISIDXREG(SISPART4,0x0d,backupP4_0d);
+}
+
+/* TW: Determine and detect attached TV's on Chrontel */
+void
+SiS_SenseCh(void)
+{
+
+   u8 temp1;
+#ifdef CONFIG_FB_SIS_315
+   u8 temp2;
+#endif
+
+   if(ivideo.chip < SIS_315H) {
+
+#ifdef CONFIG_FB_SIS_300
+       SiS_Pr.SiS_IF_DEF_CH70xx = 1;		/* TW: Chrontel 7005 */
+       temp1 = SiS_GetCH700x(&SiS_Pr, 0x25);
+       if ((temp1 >= 50) && (temp1 <= 100)) {
+	   /* TW: Read power status */
+	   temp1 = SiS_GetCH700x(&SiS_Pr, 0x0e);
+	   if((temp1 & 0x03) != 0x03) {
+     	        /* TW: Power all outputs */
+		SiS_SetCH70xxANDOR(&SiS_Pr, 0x030E,0xF8);
+	   }
+	   /* TW: Sense connected TV devices */
+	   SiS_SetCH700x(&SiS_Pr, 0x0110);
+	   SiS_SetCH700x(&SiS_Pr, 0x0010);
+	   temp1 = SiS_GetCH700x(&SiS_Pr, 0x10);
+	   if(!(temp1 & 0x08)) {
+		printk(KERN_INFO
+		   "sisfb: Chrontel: Detected TV connected to SVHS output\n");
+		/* TW: So we can be sure that there IS a SVHS output */
+		ivideo.TV_plug = TVPLUG_SVIDEO;
+		orSISIDXREG(SISCR, 0x32, 0x02);
+	   } else if (!(temp1 & 0x02)) {
+		printk(KERN_INFO
+		   "sisfb: Chrontel: Detected TV connected to CVBS output\n");
+		/* TW: So we can be sure that there IS a CVBS output */
+		ivideo.TV_plug = TVPLUG_COMPOSITE;
+		orSISIDXREG(SISCR, 0x32, 0x01);
+	   } else {
+ 		SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
+	   }
+       } else if(temp1 == 0) {
+	  SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
+       }
+#endif
+
+   } else {
+
+#ifdef CONFIG_FB_SIS_315
+	SiS_Pr.SiS_IF_DEF_CH70xx = 2;		/* TW: Chrontel 7019 */
+        temp1 = SiS_GetCH701x(&SiS_Pr, 0x49);
+	SiS_SetCH701x(&SiS_Pr, 0x2049);
+	SiS_DDC2Delay(&SiS_Pr, 0x96);
+	temp2 = SiS_GetCH701x(&SiS_Pr, 0x20);
+	temp2 |= 0x01;
+	SiS_SetCH701x(&SiS_Pr, (temp2 << 8) | 0x20);
+	SiS_DDC2Delay(&SiS_Pr, 0x96);
+	temp2 ^= 0x01;
+	SiS_SetCH701x(&SiS_Pr, (temp2 << 8) | 0x20);
+	SiS_DDC2Delay(&SiS_Pr, 0x96);
+	temp2 = SiS_GetCH701x(&SiS_Pr, 0x20);
+	SiS_SetCH701x(&SiS_Pr, (temp1 << 8) | 0x49);
+        temp1 = 0;
+	if(temp2 & 0x02) temp1 |= 0x01;
+	if(temp2 & 0x10) temp1 |= 0x01;
+	if(temp2 & 0x04) temp1 |= 0x02;
+	if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04;
+	switch(temp1) {
+	case 0x01:
+	     printk(KERN_INFO
+		"sisfb: Chrontel: Detected TV connected to CVBS output\n");
+	     ivideo.TV_plug = TVPLUG_COMPOSITE;
+	     orSISIDXREG(SISCR, 0x32, 0x01);
+             break;
+	case 0x02:
+	     printk(KERN_INFO
+		"sisfb: Chrontel: Detected TV connected to SVHS output\n");
+	     ivideo.TV_plug = TVPLUG_SVIDEO;
+	     orSISIDXREG(SISCR, 0x32, 0x02);
+             break;
+	case 0x04:
+	     /* TW: This should not happen */
+	     printk(KERN_INFO
+		"sisfb: Chrontel: Detected TV connected to SCART output\n");
+             break;
+	}
+#endif
+
+   }
+}
+
+
+/* ------------------------ Heap routines -------------------------- */
 
 static int sisfb_heap_init(void)
 {
@@ -1357,8 +2906,8 @@
 #ifdef CONFIG_FB_SIS_315
      if (sisvga_engine == SIS_315_VGA) {
         /* TW: Now initialize the 310 series' command queue mode.
-	 * On 310, there are three queue modes available which
-	 *     are chosen by setting bits 7:5 in SR26:
+	 * On 310/325, there are three queue modes available which
+	 * are chosen by setting bits 7:5 in SR26:
 	 * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
 	 *    track of the queue, the FIFO, command parsing and so
 	 *    on. This is the one comparable to the 300 series.
@@ -1419,7 +2968,7 @@
 		}
 	}
 #else
-	agp_enabled= 0;
+	agp_enabled = 0;
 #endif
 
 	/* TW: Now select the queue mode */
@@ -1454,26 +3003,22 @@
 	switch (cmd_type) {
 	   case AGP_CMD_QUEUE:
 #ifndef AGPOFF
-		DPRINTK("sisfb: AGP buffer base:0x%lx, offset:0x%x, size: %dK\n",
+		DPRINTK("sisfb: AGP buffer base = 0x%lx, offset = 0x%x, size = %dK\n",
 			agp_info->aper_base, agp->physical, agp_size/1024);
 
 		agp_phys = agp_info->aper_base + agp->physical;
 
-		vgawb(CRTC_ADR, IND_SIS_AGP_IO_PAD);
-		vgawb(CRTC_DATA, 0);
-		vgawb(CRTC_DATA, SIS_AGP_2X);
+		outSISIDXREG(SISCR,  IND_SIS_AGP_IO_PAD, 0);
+		outSISIDXREG(SISCR,  IND_SIS_AGP_IO_PAD, SIS_AGP_2X);
 
-		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);
-		vgawb(SEQ_DATA, COMMAND_QUEUE_THRESHOLD);
+                outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
 
-		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb(SEQ_DATA, SIS_CMD_QUEUE_RESET);
+		outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
 
 		*write_port = *read_port;
 
 		temp |= SIS_AGP_CMDQUEUE_ENABLE;
-		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb(SEQ_DATA, temp);
+		outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
 
 		*cmdq_baseport = agp_phys;
 
@@ -1485,17 +3030,14 @@
 		sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
 		sisfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
 
-		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);
-		vgawb(SEQ_DATA, COMMAND_QUEUE_THRESHOLD);
+		outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
 
-		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb(SEQ_DATA, SIS_CMD_QUEUE_RESET);
+		outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
 
 		*write_port = *read_port;
 
 		temp |= SIS_VRAM_CMDQUEUE_ENABLE;
-		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb(SEQ_DATA, temp);
+		outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
 
 		*cmdq_baseport = ivideo.video_size - COMMAND_QUEUE_AREA_SIZE;
 
@@ -1513,23 +3055,19 @@
 	   	sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
 		sisfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
 
-		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_THRESHOLD);
-		vgawb(SEQ_DATA, COMMAND_QUEUE_THRESHOLD);
-
-		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb(SEQ_DATA, SIS_CMD_QUEUE_RESET);
+		outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
+		outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
 
 		*write_port = *read_port;
 
-		/* TW: Set Auto_Correction bit; this works in sisfb lite,
-		 * so why not.
-		 */
+		/* TW: Set Auto_Correction bit */
 		temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
-		vgawb(SEQ_ADR, IND_SIS_CMDQUEUE_SET);
-		vgawb(SEQ_DATA, temp);
+		outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
 
 		*cmdq_baseport = ivideo.video_size - COMMAND_QUEUE_AREA_SIZE;
 
+		sisfb_caps |= MMIO_CMD_QUEUE_CAP;
+
 		DPRINTK("sisfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n",
 			*cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
 		break;
@@ -1547,15 +3085,16 @@
 
 		tqueue_pos = (ivideo.video_size -
 		       TURBO_QUEUE_AREA_SIZE) / (64 * 1024);
+
 		temp = (u8) (tqueue_pos & 0xff);
-		vgawb(SEQ_ADR, IND_SIS_TURBOQUEUE_SET);
-		tq_state = vgarb(SEQ_DATA);
+
+		inSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
 		tq_state |= 0xf0;
 		tq_state &= 0xfc;
 		tq_state |= (u8) (tqueue_pos >> 8);
-		vgawb(SEQ_DATA, tq_state);
-		vgawb(SEQ_ADR, IND_SIS_TURBOQUEUE_ADR);
-		vgawb(SEQ_DATA, temp);
+		outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
+
+		outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_ADR, temp);
 
 		sisfb_caps |= TURBO_QUEUE_CAP;
 
@@ -1566,9 +3105,9 @@
 	    }
      }
 #endif
-        /* TW: Now reserve memory for the HWCursor. It is always located at the very
-               top of the videoRAM, right below the TB memory area (if used). */
-	if (sisfb_heap_size >= sisfb_hwcursor_size) {
+     /* TW: Now reserve memory for the HWCursor. It is always located at the very
+            top of the videoRAM, right below the TB memory area (if used). */
+     if (sisfb_heap_size >= sisfb_hwcursor_size) {
 		sisfb_heap_end -= sisfb_hwcursor_size;
 		sisfb_heap_size -= sisfb_hwcursor_size;
 		sisfb_hwcursor_vbase = sisfb_heap_end;
@@ -1577,58 +3116,54 @@
 
 		DPRINTK("sisfb: Hardware Cursor start at 0x%lx, size is %dK\n",
 			sisfb_heap_end, sisfb_hwcursor_size/1024);
-	}
+     }
 
-	sisfb_heap.poha_chain = NULL;
-	sisfb_heap.poh_freelist = NULL;
+     sisfb_heap.poha_chain = NULL;
+     sisfb_heap.poh_freelist = NULL;
 
-	poh = sisfb_poh_new_node();
+     poh = sisfb_poh_new_node();
 
-	if (poh == NULL)
-		return 1;
+     if(poh == NULL)  return 1;
 	
-	poh->poh_next = &sisfb_heap.oh_free;
-	poh->poh_prev = &sisfb_heap.oh_free;
-	poh->size = sisfb_heap_end - sisfb_heap_start + 1;
-	poh->offset = sisfb_heap_start - (unsigned long) ivideo.video_vbase;
+     poh->poh_next = &sisfb_heap.oh_free;
+     poh->poh_prev = &sisfb_heap.oh_free;
+     poh->size = sisfb_heap_end - sisfb_heap_start + 1;
+     poh->offset = sisfb_heap_start - (unsigned long) ivideo.video_vbase;
 
-	DPRINTK("sisfb: Heap start:0x%p, end:0x%p, len=%dk\n",
+     DPRINTK("sisfb: Heap start:0x%p, end:0x%p, len=%dk\n",
 		(char *) sisfb_heap_start, (char *) sisfb_heap_end,
 		(unsigned int) poh->size / 1024);
 
-	DPRINTK("sisfb: First Node offset:0x%x, size:%dk\n",
+     DPRINTK("sisfb: First Node offset:0x%x, size:%dk\n",
 		(unsigned int) poh->offset, (unsigned int) poh->size / 1024);
-	
-	sisfb_heap.oh_free.poh_next = poh;
-	sisfb_heap.oh_free.poh_prev = poh;
-	sisfb_heap.oh_free.size = 0;
-	sisfb_heap.max_freesize = poh->size;
-
-	sisfb_heap.oh_used.poh_next = &sisfb_heap.oh_used;
-	sisfb_heap.oh_used.poh_prev = &sisfb_heap.oh_used;
-	sisfb_heap.oh_used.size = SENTINEL;
 
-	return 0;
+     sisfb_heap.oh_free.poh_next = poh;
+     sisfb_heap.oh_free.poh_prev = poh;
+     sisfb_heap.oh_free.size = 0;
+     sisfb_heap.max_freesize = poh->size;
+
+     sisfb_heap.oh_used.poh_next = &sisfb_heap.oh_used;
+     sisfb_heap.oh_used.poh_prev = &sisfb_heap.oh_used;
+     sisfb_heap.oh_used.size = SENTINEL;
+
+     return 0;
 }
 
 static SIS_OH *sisfb_poh_new_node(void)
 {
-	int i;
+	int           i;
 	unsigned long cOhs;
-	SIS_OHALLOC *poha;
-	SIS_OH *poh;
+	SIS_OHALLOC   *poha;
+	SIS_OH        *poh;
 
 	if (sisfb_heap.poh_freelist == NULL) {
 		poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);
-		if(!poha)
-		    return NULL;
+		if(!poha) return NULL;
 
 		poha->poha_next = sisfb_heap.poha_chain;
 		sisfb_heap.poha_chain = poha;
 
-		cOhs =
-		    (OH_ALLOC_SIZE -
-		     sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1;
+		cOhs = (OH_ALLOC_SIZE - sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1;
 
 		poh = &poha->aoh[0];
 		for (i = cOhs - 1; i != 0; i--) {
@@ -1650,7 +3185,7 @@
 {
 	SIS_OH *pohThis;
 	SIS_OH *pohRoot;
-	int bAllocated = 0;
+	int     bAllocated = 0;
 
 	if (size > sisfb_heap.max_freesize) {
 		DPRINTK("sisfb: Can't allocate %dk size on offscreen\n",
@@ -1704,14 +3239,12 @@
 	SIS_OH *poh_prev;
 	SIS_OH *poh_next;
 
-
 	poh_prev = poh->poh_prev;
 	poh_next = poh->poh_next;
 
 	poh_prev->poh_next = poh_next;
 	poh_next->poh_prev = poh_prev;
 
-	return;
 }
 
 static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
@@ -1739,8 +3272,8 @@
 
 	poh_freed = sisfb_heap.oh_used.poh_next;
 
-	while (poh_freed != &sisfb_heap.oh_used) {
-		if (poh_freed->offset == base) {
+	while(poh_freed != &sisfb_heap.oh_used) {
+		if(poh_freed->offset == base) {
 			foundNode = 1;
 			break;
 		}
@@ -1748,8 +3281,7 @@
 		poh_freed = poh_freed->poh_next;
 	}
 
-	if (!foundNode)
-		return (NULL);
+	if (!foundNode)  return (NULL);
 
 	sisfb_heap.max_freesize += poh_freed->size;
 
@@ -1800,14 +3332,11 @@
 
 static void sisfb_free_node(SIS_OH *poh)
 {
-	if (poh == NULL) {
-		return;
-	}
+	if(poh == NULL) return;
 
 	poh->poh_next = sisfb_heap.poh_freelist;
 	sisfb_heap.poh_freelist = poh;
 
-	return;
 }
 
 void sis_malloc(struct sis_memreq *req)
@@ -1816,14 +3345,13 @@
 
 	poh = sisfb_poh_allocate(req->size);
 
-	if (poh == NULL) {
+	if(poh == NULL) {
 		req->offset = 0;
 		req->size = 0;
 		DPRINTK("sisfb: Video RAM allocation failed\n");
 	} else {
 		DPRINTK("sisfb: Video RAM allocation succeeded: 0x%p\n",
-			(char *) (poh->offset +
-				  (unsigned long) ivideo.video_vbase));
+			(char *) (poh->offset + (unsigned long) ivideo.video_vbase));
 
 		req->offset = poh->offset;
 		req->size = poh->size;
@@ -1837,34 +3365,31 @@
 
 	poh = sisfb_poh_free(base);
 
-	if (poh == NULL) {
+	if(poh == NULL) {
 		DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n",
 			(unsigned int) base);
 	}
 }
 
-/* ------------------ SetMode Routines ------------------------------- */
+/* --------------------- SetMode routines ------------------------- */
 
 static void sisfb_pre_setmode(void)
 {
 	u8 cr30 = 0, cr31 = 0;
 
-	vgawb(CRTC_ADR, 0x31);
-	cr31 = vgarb(CRTC_DATA) & ~0x60;
+	inSISIDXREG(SISCR, 0x31, cr31);
+	cr31 &= ~0x60;
 
 	switch (ivideo.disp_state & DISPTYPE_DISP2) {
 	   case DISPTYPE_CRT2:
-		printk(KERN_INFO "sisfb: CRT2 type is VGA\n");
 		cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		cr31 |= SIS_DRIVER_MODE;
 		break;
 	   case DISPTYPE_LCD:
-		printk(KERN_INFO "sisfb: CRT2 type is LCD\n");
 		cr30  = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		cr31 |= SIS_DRIVER_MODE;
 		break;
 	   case DISPTYPE_TV:
-		printk(KERN_INFO "sisfb: CRT2 type is TV\n");
 		if (ivideo.TV_type == TVMODE_HIVISION)
 			cr30 = (SIS_VB_OUTPUT_HIVISION | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		else if (ivideo.TV_plug == TVPLUG_SVIDEO)
@@ -1874,90 +3399,79 @@
 		else if (ivideo.TV_plug == TVPLUG_SCART)
 			cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
 		cr31 |= SIS_DRIVER_MODE;
-		/* cr31 &= ~0x04; */ /* TW @@@ 5/5/02 */ /* TW: No NotSimuMode by default  */
-                /*karl*/
+
 	        if (sisfb_tvmode == 1 || ivideo.TV_type == TVMODE_PAL)
-			cr31 |= 0x1;
-                if (sisfb_tvmode == 2 || ivideo.TV_type == TVMODE_NTSC)
-                        cr31 &= ~0x1;
+			cr31 |= 0x01;
+                else
+                        cr31 &= ~0x01;
 		break;
-	   default:	/* CRT2 disable */
-		printk(KERN_INFO "sisfb: CRT2 is disabled\n");
+	   default:	/* disable CRT2 */
 		cr30 = 0x00;
 		cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
 	}
 
-	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR30);
-	vgawb(CRTC_DATA, cr30);
-	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR31);
-	vgawb(CRTC_DATA, cr31);
-
-	vgawb(CRTC_ADR, IND_SIS_SCRATCH_REG_CR33);
-/*
-	if (ivideo.disp_state & DISPTYPE_CRT2) {
-		sisfb_rate_idx &= 0x0F;
-		sisfb_rate_idx |= (sisfb_rate_idx << 4);
-		vgawb(CRTC_DATA, sisfb_rate_idx);
-	} else {
-		vgawb(CRTC_DATA, sisfb_rate_idx & 0x0F);
-	}
-*/
-	vgawb(CRTC_DATA, sisfb_rate_idx & 0x0F);
+	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR30, cr30);
+	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR31, cr31);
+
+        outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR33, (sisfb_rate_idx & 0x0F));
+
+	if(ivideo.accel) sisfb_syncaccel();
+
+	SiS_Pr.SiS_UseOEM = sisfb_useoem;
 }
 
 static void sisfb_post_setmode(void)
 {
 	u8 reg;
-
-	/* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
-	if ((ivideo.hasVB == HASVB_LVDS) || (ivideo.hasVB == HASVB_LVDS_CHRONTEL)) {
-		if (ivideo.video_bpp == 8) {
-			sisfb_crt1off = 0;
-		}
-	}
-
-	/* TW: We can't switch off CRT1 on 630+301B in 8bpp Modes */
-	if ( (sishw_ext.ujVBChipID == VB_CHIP_301B) && (sisvga_engine == SIS_300_VGA) &&
-	     (ivideo.disp_state & DISPTYPE_LCD) ) {
-	        if (ivideo.video_bpp == 8) {
-			sisfb_crt1off = 0;
+	BOOLEAN doit = TRUE;
+#if 0	/* TW: Wrong: Is not in MMIO space, but in RAM */
+	/* Backup mode number to MMIO space */
+	if(ivideo.mmio_vbase) {
+	  *(volatile u8 *)(((u8*)ivideo.mmio_vbase) + 0x449) = (unsigned char)sisfb_mode_no;
+	}
+#endif	
+
+	if (ivideo.video_bpp == 8) {
+		/* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
+		if ((ivideo.hasVB == HASVB_LVDS) || (ivideo.hasVB == HASVB_LVDS_CHRONTEL)) {
+			doit = FALSE;
+		}
+		/* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
+		if ( (sishw_ext.Is301BDH) && (ivideo.disp_state & DISPTYPE_LCD) ) {
+	        	doit = FALSE;
 	        }
 	}
 
 	/* TW: We can't switch off CRT1 if bridge is in slave mode */
-	vgawb(VB_PART1_ADR,0x00);
-	reg = vgarb(VB_PART1_DATA);
-	if(sisvga_engine == SIS_300_VGA) {
-		if((reg & 0xa0) == 0x20) {
-			sisfb_crt1off = 0;
+	if(ivideo.hasVB != HASVB_NONE) {
+		inSISIDXREG(SISPART1, 0x00, reg);
+		if(sisvga_engine == SIS_300_VGA) {
+			if((reg & 0xa0) == 0x20) {
+				doit = FALSE;
+			}
 		}
-	}
-	if(sisvga_engine == SIS_315_VGA) {
-		if((reg & 0x50) == 0x10) {
-			sisfb_crt1off = 0;
+		if(sisvga_engine == SIS_315_VGA) {
+			if((reg & 0x50) == 0x10) {
+				doit = FALSE;
+			}
 		}
-	}
+	} else sisfb_crt1off = 0;
 
-	vgawb(CRTC_ADR, 0x17);
-	reg = vgarb(CRTC_DATA);
-	if (sisfb_crt1off)	  
+	inSISIDXREG(SISCR, 0x17, reg);
+	if((sisfb_crt1off) && (doit))
 		reg &= ~0x80;
 	else 	      
 		reg |= 0x80;
-	vgawb(CRTC_DATA, reg);
-	
-	vgawb(SEQ_ADR, IND_SIS_RAMDAC_CONTROL);
-	reg = vgarb(SEQ_DATA);
-	reg &= ~0x04;
-	vgawb(SEQ_DATA, reg);
-
-	if ((ivideo.disp_state & DISPTYPE_TV) && (ivideo.hasVB == HASVB_301)) {
-
-	   vgawb(VB_PART4_ADR,0x01);
-	   reg = vgarb(VB_PART4_DATA);
-	   if (reg < 0xB0)        	/* 301B Revision ID */
-           {	
-		// Eden Chen
+	outSISIDXREG(SISCR, 0x17, reg);
+
+        andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
+
+	if((ivideo.disp_state & DISPTYPE_TV) && (ivideo.hasVB == HASVB_301)) {
+
+	   inSISIDXREG(SISPART4, 0x01, reg);
+
+	   if(reg < 0xB0) {        	/* Set filter for SiS301 */
+
 		switch (ivideo.video_width) {
 		   case 320:
 			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 4 : 12;
@@ -1975,117 +3489,78 @@
 			filter = -1;
 			break;
 		}
-		// ~Eden Chen
 
-		// Eden Chen
-		//vgawb(VB_PART1_ADR,  0x24);
-		vgawb(VB_PART1_ADR,  sisfb_CRT2_write_enable);
-		// ~Eden Chen
-		vgawb(VB_PART1_DATA, 0x01);
-		
-		if (ivideo.TV_type == TVMODE_NTSC) {
-			vgawb(VB_PART2_ADR, 0x3A);
-			reg = vgarb(VB_PART2_DATA);
-			reg &= 0x1F;
-			vgawb(VB_PART2_DATA, reg);
+		orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
+
+		if(ivideo.TV_type == TVMODE_NTSC) {
+
+		        andSISIDXREG(SISPART2, 0x3a, 0x1f);
 
 			if (ivideo.TV_plug == TVPLUG_SVIDEO) {
-				vgawb(VB_PART2_ADR, 0x30);
-				reg = vgarb(VB_PART2_DATA);
-				reg &= 0xDF;
-				vgawb(VB_PART2_DATA, reg);
+
+			        andSISIDXREG(SISPART2, 0x30, 0xdf);
+
 			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
-				vgawb(VB_PART2_ADR, 0x30);
-				reg = vgarb(VB_PART2_DATA);
-				reg |= 0x20;
-				vgawb(VB_PART2_DATA, reg);
+
+			        orSISIDXREG(SISPART2, 0x30, 0x20);
 
 				switch (ivideo.video_width) {
 				case 640:
-					vgawb(VB_PART2_ADR,  0x35);
-					vgawb(VB_PART2_DATA, 0xEB);
-					vgawb(VB_PART2_ADR,  0x36);
-					vgawb(VB_PART2_DATA, 0x04);
-					vgawb(VB_PART2_ADR,  0x37);
-					vgawb(VB_PART2_DATA, 0x25);
-					vgawb(VB_PART2_ADR,  0x38);
-					vgawb(VB_PART2_DATA, 0x18);
+				        outSISIDXREG(SISPART2, 0x35, 0xEB);
+					outSISIDXREG(SISPART2, 0x36, 0x04);
+					outSISIDXREG(SISPART2, 0x37, 0x25);
+					outSISIDXREG(SISPART2, 0x38, 0x18);
 					break;
 				case 720:
-					vgawb(VB_PART2_ADR,  0x35);
-					vgawb(VB_PART2_DATA, 0xEE);
-					vgawb(VB_PART2_ADR,  0x36);
-					vgawb(VB_PART2_DATA, 0x0C);
-					vgawb(VB_PART2_ADR,  0x37);
-					vgawb(VB_PART2_DATA, 0x22);
-					vgawb(VB_PART2_ADR,  0x38);
-					vgawb(VB_PART2_DATA, 0x08);
+					outSISIDXREG(SISPART2, 0x35, 0xEE);
+					outSISIDXREG(SISPART2, 0x36, 0x0C);
+					outSISIDXREG(SISPART2, 0x37, 0x22);
+					outSISIDXREG(SISPART2, 0x38, 0x08);
 					break;
 				case 800:
-					vgawb(VB_PART2_ADR,  0x35);
-					vgawb(VB_PART2_DATA, 0xEB);
-					vgawb(VB_PART2_ADR,  0x36);
-					vgawb(VB_PART2_DATA, 0x15);
-					vgawb(VB_PART2_ADR,  0x37);
-					vgawb(VB_PART2_DATA, 0x25);
-					vgawb(VB_PART2_ADR,  0x38);
-					vgawb(VB_PART2_DATA, 0xF6);
+					outSISIDXREG(SISPART2, 0x35, 0xEB);
+					outSISIDXREG(SISPART2, 0x36, 0x15);
+					outSISIDXREG(SISPART2, 0x37, 0x25);
+					outSISIDXREG(SISPART2, 0x38, 0xF6);
 					break;
 				}
 			}
-		} else if (ivideo.TV_type == TVMODE_PAL) {
-			vgawb(VB_PART2_ADR, 0x3A);
-			reg = vgarb(VB_PART2_DATA);
-			reg &= 0x1F;
-			vgawb(VB_PART2_DATA, reg);
+
+		} else if(ivideo.TV_type == TVMODE_PAL) {
+
+			andSISIDXREG(SISPART2, 0x3A, 0x1F);
 
 			if (ivideo.TV_plug == TVPLUG_SVIDEO) {
-				vgawb(VB_PART2_ADR, 0x30);
-				reg = vgarb(VB_PART2_DATA);
-				reg &= 0xDF;
-				vgawb(VB_PART2_DATA, reg);
+
+			        andSISIDXREG(SISPART2, 0x30, 0xDF);
+
 			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
-				vgawb(VB_PART2_ADR, 0x30);
-				reg = vgarb(VB_PART2_DATA);
-				reg |= 0x20;
-				vgawb(VB_PART2_DATA, reg);
+
+			        orSISIDXREG(SISPART2, 0x30, 0x20);
 
 				switch (ivideo.video_width) {
 				case 640:
-					vgawb(VB_PART2_ADR,  0x35);
-					vgawb(VB_PART2_DATA, 0xF1);
-					vgawb(VB_PART2_ADR,  0x36);
-					vgawb(VB_PART2_DATA, 0xF7);
-					vgawb(VB_PART2_ADR,  0x37);
-					vgawb(VB_PART2_DATA, 0x1F);
-					vgawb(VB_PART2_ADR,  0x38);
-					vgawb(VB_PART2_DATA, 0x32);
+					outSISIDXREG(SISPART2, 0x35, 0xF1);
+					outSISIDXREG(SISPART2, 0x36, 0xF7);
+					outSISIDXREG(SISPART2, 0x37, 0x1F);
+					outSISIDXREG(SISPART2, 0x38, 0x32);
 					break;
 				case 720:
-					vgawb(VB_PART2_ADR,  0x35);
-					vgawb(VB_PART2_DATA, 0xF3);
-					vgawb(VB_PART2_ADR,  0x36);
-					vgawb(VB_PART2_DATA, 0x00);
-					vgawb(VB_PART2_ADR,  0x37);
-					vgawb(VB_PART2_DATA, 0x1D);
-					vgawb(VB_PART2_ADR,  0x38);
-					vgawb(VB_PART2_DATA, 0x20);
+					outSISIDXREG(SISPART2, 0x35, 0xF3);
+					outSISIDXREG(SISPART2, 0x36, 0x00);
+					outSISIDXREG(SISPART2, 0x37, 0x1D);
+					outSISIDXREG(SISPART2, 0x38, 0x20);
 					break;
 				case 800:
-					vgawb(VB_PART2_ADR,  0x35);
-					vgawb(VB_PART2_DATA, 0xFC);
-					vgawb(VB_PART2_ADR,  0x36);
-					vgawb(VB_PART2_DATA, 0xFB);
-					vgawb(VB_PART2_ADR,  0x37);
-					vgawb(VB_PART2_DATA, 0x14);
-					vgawb(VB_PART2_ADR,  0x38);
-					vgawb(VB_PART2_DATA, 0x2A);
+					outSISIDXREG(SISPART2, 0x35, 0xFC);
+					outSISIDXREG(SISPART2, 0x36, 0xFB);
+					outSISIDXREG(SISPART2, 0x37, 0x14);
+					outSISIDXREG(SISPART2, 0x38, 0x2A);
 					break;
 				}
 			}
 		}
 
-		// Eden 
 		if ((filter >= 0) && (filter <=7)) {
 			DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter, 
 				sis_TV_filter[filter_tb].filter[filter][0],
@@ -2093,583 +3568,57 @@
 				sis_TV_filter[filter_tb].filter[filter][2],
 				sis_TV_filter[filter_tb].filter[filter][3]
 			);
-			vgawb(VB_PART2_ADR,  0x35);
-			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][0]);
-			vgawb(VB_PART2_ADR,  0x36);
-			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][1]);
-			vgawb(VB_PART2_ADR,  0x37);
-			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][2]);
-			vgawb(VB_PART2_ADR,  0x38);
-			vgawb(VB_PART2_DATA, sis_TV_filter[filter_tb].filter[filter][3]);
+			outSISIDXREG(SISPART2, 0x35, (sis_TV_filter[filter_tb].filter[filter][0]));
+			outSISIDXREG(SISPART2, 0x36, (sis_TV_filter[filter_tb].filter[filter][1]));
+			outSISIDXREG(SISPART2, 0x37, (sis_TV_filter[filter_tb].filter[filter][2]));
+			outSISIDXREG(SISPART2, 0x38, (sis_TV_filter[filter_tb].filter[filter][3]));
 		}
-		// ~Eden 
+
 	     }
 	  
 	}
 
 }
 
-static void sisfb_crtc_to_var(struct fb_var_screeninfo *var)
-{
-	u16 VRE, VBE, VRS, VBS, VDE, VT;
-	u16 HRE, HBE, HRS, HBS, HDE, HT;
-	u8  sr_data, cr_data, cr_data2, cr_data3, mr_data;
-	int A, B, C, D, E, F, temp;
-	double hrate, drate;
-
-	vgawb(SEQ_ADR, IND_SIS_COLOR_MODE);
-	sr_data = vgarb(SEQ_DATA);
-
-	if (sr_data & SIS_INTERLACED_MODE)
-		var->vmode = FB_VMODE_INTERLACED;
-	else
-		var->vmode = FB_VMODE_NONINTERLACED;
-
-	switch ((sr_data & 0x1C) >> 2) {
-	   case SIS_8BPP_COLOR_MODE:
-		var->bits_per_pixel = 8;
-		break;
-	   case SIS_16BPP_COLOR_MODE:
-		var->bits_per_pixel = 16;
-		break;
-	   case SIS_32BPP_COLOR_MODE:
-		var->bits_per_pixel = 32;
-		break;
-	}
-
-	switch (var->bits_per_pixel) {
-	   case 8:
-		var->red.length = 6;
-		var->green.length = 6;
-		var->blue.length = 6;
-		video_cmap_len = 256;
-		break;
-	   case 16:
-		var->red.offset = 11;
-		var->red.length = 5;
-		var->green.offset = 5;
-		var->green.length = 6;
-		var->blue.offset = 0;
-		var->blue.length = 5;
-		var->transp.offset = 0;
-		var->transp.length = 0;
-		video_cmap_len = 16;
-		break;
-	   case 24:
-		var->red.offset = 16;
-		var->red.length = 8;
-		var->green.offset = 8;
-		var->green.length = 8;
-		var->blue.offset = 0;
-		var->blue.length = 8;
-		var->transp.offset = 0;
-		var->transp.length = 0;
-		video_cmap_len = 16;
-		break;
-	   case 32:
-		var->red.offset = 16;
-		var->red.length = 8;
-		var->green.offset = 8;
-		var->green.length = 8;
-		var->blue.offset = 0;
-		var->blue.length = 8;
-		var->transp.offset = 24;
-		var->transp.length = 8;
-		video_cmap_len = 16;
-		break;
-	}
-
-	vgawb(SEQ_ADR, 0xA);
-	sr_data = vgarb(SEQ_DATA);
-
-	vgawb(CRTC_ADR, 0x6);
-	cr_data = vgarb(CRTC_DATA);
-	vgawb(CRTC_ADR, 0x7);
-	cr_data2 = vgarb(CRTC_DATA);
-	VT = (cr_data & 0xFF) | ((u16) (cr_data2 & 0x01) << 8) |
-	     ((u16) (cr_data2 & 0x20) << 4) | ((u16) (sr_data & 0x01) <<
-					      10);
-	A = VT + 2;
-
-	vgawb(CRTC_ADR, 0x12);
-	cr_data = vgarb(CRTC_DATA);
-	VDE = (cr_data & 0xff) | ((u16) (cr_data2 & 0x02) << 7) |
-	      ((u16) (cr_data2 & 0x40) << 3) | ((u16) (sr_data & 0x02) << 9);
-	E = VDE + 1;
-
-	vgawb(CRTC_ADR, 0x10);
-	cr_data = vgarb(CRTC_DATA);
-	VRS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x04) << 6) |
-	      ((u16) (cr_data2 & 0x80) << 2) | ((u16) (sr_data & 0x08) << 7);
-	F = VRS + 1 - E;
-
-	vgawb(CRTC_ADR, 0x15);
-	cr_data = vgarb(CRTC_DATA);
-	vgawb(CRTC_ADR, 0x9);
-	cr_data3 = vgarb(CRTC_DATA);
-	VBS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x08) << 5) |
-	      ((u16) (cr_data3 & 0x20) << 4) | ((u16) (sr_data & 0x04) << 8);
-
-	vgawb(CRTC_ADR, 0x16);
-	cr_data = vgarb(CRTC_DATA);
-	VBE = (cr_data & 0xff) | ((u16) (sr_data & 0x10) << 4);
-	temp = VBE - ((E - 1) & 511);
-	B = (temp > 0) ? temp : (temp + 512);
-
-	vgawb(CRTC_ADR, 0x11);
-	cr_data = vgarb(CRTC_DATA);
-	VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
-	temp = VRE - ((E + F - 1) & 31);
-	C = (temp > 0) ? temp : (temp + 32);
-
-	D = B - F - C;
-
-	var->yres = var->yres_virtual = E;
-	/* TW: We have to report the physical dimension to the console! */
-	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-		var->yres <<= 1;
-		var->yres_virtual <<=1;
-	}
-	/* TW end */
-	var->upper_margin = D;
-	var->lower_margin = F;
-	var->vsync_len = C;
-
-	vgawb(SEQ_ADR, 0xb);
-	sr_data = vgarb(SEQ_DATA);
-
-	vgawb(CRTC_ADR, 0x0);
-	cr_data = vgarb(CRTC_DATA);
-	HT = (cr_data & 0xff) | ((u16) (sr_data & 0x03) << 8);
-	A = HT + 5;
-
-	vgawb(CRTC_ADR, 0x1);
-	cr_data = vgarb(CRTC_DATA);
-	HDE = (cr_data & 0xff) | ((u16) (sr_data & 0x0C) << 6);
-	E = HDE + 1;
-
-	vgawb(CRTC_ADR, 0x4);
-	cr_data = vgarb(CRTC_DATA);
-	HRS = (cr_data & 0xff) | ((u16) (sr_data & 0xC0) << 2);
-	F = HRS - E - 3;
-
-	vgawb(CRTC_ADR, 0x2);
-	cr_data = vgarb(CRTC_DATA);
-	HBS = (cr_data & 0xff) | ((u16) (sr_data & 0x30) << 4);
-
-	vgawb(SEQ_ADR, 0xc);
-	sr_data = vgarb(SEQ_DATA);
-	vgawb(CRTC_ADR, 0x3);
-	cr_data = vgarb(CRTC_DATA);
-	vgawb(CRTC_ADR, 0x5);
-	cr_data2 = vgarb(CRTC_DATA);
-	HBE = (cr_data & 0x1f) | ((u16) (cr_data2 & 0x80) >> 2) |
-	      ((u16) (sr_data & 0x03) << 6);
-	HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
-
-	temp = HBE - ((E - 1) & 255);
-	B = (temp > 0) ? temp : (temp + 256);
-
-	temp = HRE - ((E + F + 3) & 63);
-	C = (temp > 0) ? temp : (temp + 64);
-
-	D = B - F - C;
-
-	var->xres = var->xres_virtual = E * 8;
-	var->left_margin = D * 8;
-	var->right_margin = F * 8;
-	var->hsync_len = C * 8;
-
-	var->activate = FB_ACTIVATE_NOW;
-
-	var->sync = 0;
-
-	mr_data = vgarb(0x1C);
-	if (mr_data & 0x80)
-		var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
-	else
-		var->sync |= FB_SYNC_VERT_HIGH_ACT;
-
-	if (mr_data & 0x40)
-		var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
-	else
-		var->sync |= FB_SYNC_HOR_HIGH_ACT;
-
-	VT += 2;
-	VT <<= 1;
-	HT = (HT + 5) * 8;
-
-	hrate = (double) ivideo.refresh_rate * (double) VT / 2;
-	drate = hrate * HT;
-	var->pixclock = (u32) (1E12 / drate);
-}
-
-/* ------------------ Public Routines -------------------------------- */
-
-static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			 struct fb_info *info)
-{
-	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-	strcpy(fix->id, fb_info.modename);
-
-	fix->smem_start = ivideo.video_base;
-        
-        /*karl:10/01/2001*/ /* TW */
-        if ((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
-	    if (ivideo.video_size > 0x1000000) {
-	        fix->smem_len = 0xc00000;
-	    } else if (ivideo.video_size > 0x800000)
-		fix->smem_len = 0x800000;
-	    else
-		fix->smem_len = 0x400000;
-        } else
-		fix->smem_len = sisfb_mem * 1024;
-
-	fix->type = video_type;
-	fix->type_aux = 0;
-	if (ivideo.video_bpp == 8)
-		fix->visual = FB_VISUAL_PSEUDOCOLOR;
-	else
-		fix->visual = FB_VISUAL_TRUECOLOR;
-	fix->xpanstep = 0;
-	fix->ypanstep = 0;
-	fix->ywrapstep = 0;
-	fix->line_length = video_linelength;
-	fix->mmio_start = ivideo.mmio_base;
-	fix->mmio_len = sisfb_mmio_size;
-	fix->accel = FB_ACCEL_SIS_GLAMOUR;
-	fix->reserved[0] = ivideo.video_size & 0xFFFF;
-	fix->reserved[1] = (ivideo.video_size >> 16) & 0xFFFF;
-	fix->reserved[2] = sisfb_caps;
-
-	return 0;
-}
-
-static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info)
-{
-	if (con == -1)
-		memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
-	else
-		*var = fb_display[con].var;
-
-	/* JennyLee 2001126: for FSTN */
-	if (var->xres == 320 && var->yres == 480)
-		var->yres = 240;
-	/* ~JennyLee */
-
-	return 0;
-}
-
-static int sisfb_set_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info)
-{
-	int err;
-	unsigned int cols, rows;
-
-	fb_display[con].var.activate = FB_ACTIVATE_NOW;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
-	if (sisfb_do_set_var(var, con == info->currcon, info)) {
-#else
-        if (sisfb_do_set_var(var, con == currcon, info)) {
-#endif
-		sisfb_crtc_to_var(var);
-		return -EINVAL;
-	}
-
-	sisfb_crtc_to_var(var);
-	
-	sisfb_set_disp(con, var);
-
-	if (info->changevar)
-		(*info->changevar) (con);
-
-	if ((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0)))
-		return err;
-
-	sisfb_do_install_cmap(con, info);
-	
-	cols = sisbios_mode[sisfb_mode_idx].cols;
-	rows = sisbios_mode[sisfb_mode_idx].rows;
-	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
-
-	return 0;
-}
-
-static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info)
-{
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
-	if (con == info->currcon)
-#else
-        if (con == currcon)
-#endif
-		return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
-	else if (fb_display[con].cmap.len)	
-		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-	else
-		fb_copy_cmap(fb_default_cmap(video_cmap_len), cmap, kspc ? 0 : 2);
-
-	return 0;
-}
-
-static int sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info)
-{
-	int err;
-
-	if (!fb_display[con].cmap.len) {
-		err = fb_alloc_cmap(&fb_display[con].cmap, video_cmap_len, 0);
-		if (err)
-			return err;
-	}
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
-	if (con == info->currcon)
-		return fb_set_cmap(cmap, kspc, info);
-#else
-        if (con == currcon)
-		return fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);
-#endif
-	else
-		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
-	return 0;
-}
-
-static int sisfb_ioctl(struct inode *inode, struct file *file,
-		       unsigned int cmd, unsigned long arg, int con,
-		       struct fb_info *info)
-{
-	switch (cmd) {
-	   case FBIO_ALLOC:
-		if (!capable(CAP_SYS_RAWIO))
-			return -EPERM;
-		sis_malloc((struct sis_memreq *) arg);
-		break;
-	   case FBIO_FREE:
-		if (!capable(CAP_SYS_RAWIO))
-			return -EPERM;
-		sis_free(*(unsigned long *) arg);
-		break;
-	   case FBIOGET_GLYPH:
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,23)
-		sis_get_glyph((SIS_GLYINFO *) arg);
-#else
-                sis_get_glyph(info,(SIS_GLYINFO *) arg);
-#endif
-		break;
-	   case FBIOGET_HWCINFO:
-		{
-			unsigned long *hwc_offset = (unsigned long *) arg;
-
-			if (sisfb_caps & HW_CURSOR_CAP)
-				*hwc_offset = sisfb_hwcursor_vbase -
-				    (unsigned long) ivideo.video_vbase;
-			else
-				*hwc_offset = 0;
-
-			break;
-		}
-	   case FBIOPUT_MODEINFO:
-		{
-			struct mode_info *x = (struct mode_info *)arg;
-			
-			ivideo.video_bpp      = x->bpp;
-			ivideo.video_width    = x->xres;
-			ivideo.video_height   = x->yres;
-			ivideo.video_vwidth   = x->v_xres;
-			ivideo.video_vheight  = x->v_yres;
-			ivideo.org_x          = x->org_x;
-			ivideo.org_y          = x->org_y;
-			ivideo.refresh_rate   = x->vrate;
-			
-			break;
-		}
-	   case FBIOGET_DISPINFO:
-		sis_dispinfo((struct ap_data *)arg);
-		break;
-	   case SISFB_GET_INFO:  /* TW: New for communication with X driver */
-	        {
-			sisfb_info *x = (sisfb_info *)arg;
-
-			x->sisfb_id = SISFB_ID;
-			x->sisfb_version = VER_MAJOR;
-			x->sisfb_revision = VER_MINOR;
-			x->sisfb_patchlevel = VER_LEVEL;
-			x->chip_id = ivideo.chip_id;
-			x->memory = ivideo.video_size / 1024;
-			x->heapstart = ivideo.heapstart / 1024;
-			x->fbvidmode = sisfb_mode_no;
-	                break;
-		}
-	   default:
-		return -EINVAL;
-	}
-	return 0;
-
-}
-
-static int sisfb_mmap(struct fb_info *info, struct file *file,
-		      struct vm_area_struct *vma)
-{
-	struct fb_var_screeninfo var;
-	unsigned long start;
-	unsigned long off;
-	u32 len;
-
-	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
-		return -EINVAL;
-	off = vma->vm_pgoff << PAGE_SHIFT;
-	
-	start = (unsigned long) ivideo.video_base;
-	len = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.video_size);
-
-	if (off >= len) {
-		off -= len;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
-		sisfb_get_var(&var, info->currcon, info);
-#else
-		sisfb_get_var(&var, currcon, info);
-#endif
-		if (var.accel_flags)
-			return -EINVAL;
-		start = (unsigned long) ivideo.mmio_base;
-		len = PAGE_ALIGN((start & ~PAGE_MASK) + sisfb_mmio_size);
-	}
-
-	start &= PAGE_MASK;
-	if ((vma->vm_end - vma->vm_start + off) > len)
-		return -EINVAL;
-	off += start;
-	vma->vm_pgoff = off >> PAGE_SHIFT;
-
-#if defined(__i386__) || defined(__x86_64__)
-	if (boot_cpu_data.x86 > 3)
-		pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start,
-				vma->vm_page_prot))
-#else	/* TW: 2.5 API */
-	if (io_remap_page_range(vma, vma->vm_start, off, vma->vm_end - vma->vm_start,
-				vma->vm_page_prot))
-#endif
-		return -EAGAIN;
-	return 0;
-
-}
-
-static struct fb_ops sisfb_ops = {
-	.owner		= THIS_MODULE,
-	.fb_get_fix	= sisfb_get_fix,
-	.fb_get_var	= sisfb_get_var,
-	.fb_set_var	= sisfb_set_var,
-	.fb_get_cmap	= sisfb_get_cmap,
-	.fb_set_cmap	= sisfb_set_cmap,
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
-        .fb_setcolreg	= sisfb_setcolreg,
-        .fb_blank	= sisfb_blank,
-#endif
-	.fb_ioctl	= sisfb_ioctl,
-	.fb_mmap	= sisfb_mmap,
-};
-
-/* ------------ Interface to the low level console driver -------------*/
-
-static int sisfb_update_var(int con, struct fb_info *info)
-{
-	return 0;
-}
-
-static int sisfb_switch(int con, struct fb_info *info)
-{
-	int cols, rows;
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
-	if (fb_display[info->currcon].cmap.len)
-		fb_get_cmap(&fb_display[info->currcon].cmap, 1, sis_getcolreg, info);
-#else
-        if (fb_display[currcon].cmap.len)
-		fb_get_cmap(&fb_display[currcon].cmap, 1, sis_getcolreg, info);
-#endif
-
-	fb_display[con].var.activate = FB_ACTIVATE_NOW;
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
-	if (!memcmp(&fb_display[con].var, &fb_display[info->currcon].var,
-	                           sizeof(struct fb_var_screeninfo))) {
-		info->currcon = con;
-		return 1;
-	}
-
-	info->currcon = con;
-#else
-	if (!memcmp(&fb_display[con].var, &fb_display[currcon].var,
-	                           sizeof(struct fb_var_screeninfo))) {
-		currcon = con;
-		return 1;
-	}
-
-	currcon = con;
-#endif
-
-	sisfb_do_set_var(&fb_display[con].var, 1, info);
-
-	sisfb_set_disp(con, &fb_display[con].var);
-	
-	sisfb_do_install_cmap(con, info);
-
-	cols = sisbios_mode[sisfb_mode_idx].cols;
-	rows = sisbios_mode[sisfb_mode_idx].rows;
-	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
-
-	sisfb_update_var(con, info);
-
-	return 1;
-}
-
-static void sisfb_blank(int blank, struct fb_info *info)
-{
-	u8 reg;
-
-	vgawb(CRTC_ADR, 0x17);
-	reg = vgarb(CRTC_DATA);
-
-	if (blank > 0)		
-		reg &= 0x7f;
-	else			
-		reg |= 0x80;
-
-	vgawb(CRTC_ADR, 0x17);
-	vgawb(CRTC_DATA, reg);
-}
-
+#ifndef MODULE
 int sisfb_setup(char *options)
 {
 	char *this_opt;
+	
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	sis_fb_info.fontname[0] = '\0';
+#endif	
 
-	fb_info.fontname[0] = '\0';
 	ivideo.refresh_rate = 0;
 
+        printk(KERN_INFO "sisfb: Options %s\n", options);
+
 	if (!options || !*options)
 		return 0;
 
 	while((this_opt = strsep(&options, ",")) != NULL) {
-		if (!*this_opt)
-			continue;
 
-		if (!strcmp(this_opt, "inverse")) {
+		if (!*this_opt)	continue;
+
+		if (!strncmp(this_opt, "mode:", 5)) {
+			sisfb_search_mode(this_opt + 5);
+		} else if (!strncmp(this_opt, "vesa:", 5)) {
+			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)			
+		} else if (!strcmp(this_opt, "inverse")) {
 			sisfb_inverse = 1;
-			fb_invert_cmaps();
+			/* fb_invert_cmaps(); */
 		} else if (!strncmp(this_opt, "font:", 5)) {
-			strcpy(fb_info.fontname, this_opt + 5);
+			strcpy(sis_fb_info.fontname, this_opt + 5);
+#endif			
 		} else if (!strncmp(this_opt, "mode:", 5)) {
 			sisfb_search_mode(this_opt + 5);
+		} else if (!strncmp(this_opt, "vesa:", 5)) {
+			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
 		} else if (!strncmp(this_opt, "vrate:", 6)) {
-			ivideo.refresh_rate =
-			    simple_strtoul(this_opt + 6, NULL, 0);
+			ivideo.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
 		} else if (!strncmp(this_opt, "rate:", 5)) {
-			ivideo.refresh_rate =
-			    simple_strtoul(this_opt + 5, NULL, 0);
+			ivideo.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
 		} else if (!strncmp(this_opt, "off", 3)) {
 			sisfb_off = 1;
 		} else if (!strncmp(this_opt, "crt1off", 7)) {
@@ -2681,16 +3630,15 @@
 		} else if (!strncmp(this_opt, "forcecrt1:", 10)) {
 			sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
                 } else if (!strncmp(this_opt, "tvmode:",7)) {
-                        if (!strncmp(this_opt + 7, "pal",3))
-                         	sisfb_tvmode = 1;
-                        if (!strncmp(this_opt + 7, "ntsc",4))
-                         	sisfb_tvmode = 2;
+		        sisfb_search_tvstd(this_opt + 7);
+                } else if (!strncmp(this_opt, "tvstandard:",11)) {
+			sisfb_search_tvstd(this_opt + 7);
                 } else if (!strncmp(this_opt, "mem:",4)) {
 		        sisfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
-                } else if (!strncmp(this_opt, "dstn:", 5)) {
-			enable_dstn = simple_strtoul(this_opt + 5, NULL, 0);
+                } else if (!strncmp(this_opt, "dstn", 4)) {
+			enable_dstn = 1;
 			/* TW: DSTN overrules forcecrt2type */
-			if (enable_dstn) sisfb_crt2type = DISPTYPE_LCD;
+			sisfb_crt2type = DISPTYPE_LCD;
 		} else if (!strncmp(this_opt, "queuemode:", 10)) {
 			sisfb_search_queuemode(this_opt + 10);
 		} else if (!strncmp(this_opt, "pdc:", 4)) {
@@ -2699,25 +3647,120 @@
 			   printk(KERN_INFO "sisfb: Illegal pdc parameter\n");
 			   sisfb_pdc = 0;
 		        }
+		} else if (!strncmp(this_opt, "noaccel", 7)) {
+			sisfb_accel = 0;
+		} else if (!strncmp(this_opt, "noypan", 6)) {
+		        sisfb_ypan = 0;
+		} else if (!strncmp(this_opt, "userom:", 7)) {
+			sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
+		} else if (!strncmp(this_opt, "useoem:", 7)) {
+			sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
 		} else {
-			printk(KERN_INFO "sisfb: Invalid parameter %s\n", this_opt);
+			printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt);
+		}
+
+		/* TW: Acceleration only with MMIO mode */
+		if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
+			sisfb_ypan = 0;
+			sisfb_accel = 0;
 		}
+		/* TW: Panning only with acceleration */
+		if(sisfb_accel == 0) sisfb_ypan = 0;
+
 	}
 	return 0;
 }
+#endif
+
+static char *sis_find_rom(void)
+{
+#if defined(__i386__)
+        u32  segstart;
+        unsigned char *rom_base;
+        unsigned char *rom;
+        int  stage;
+        int  i;
+        char sis_rom_sig[] = "Silicon Integrated Systems";
+        char *sis_sig_300[4] = {
+          "300", "540", "630", "730"
+        };
+        char *sis_sig_310[7] = {
+          "315", "315", "315", "5315", "6325", "6325", "Xabre"
+        };
+	ushort sis_nums_300[4] = {
+	  SIS_300, SIS_540, SIS_630, SIS_730
+	};
+	unsigned short sis_nums_310[7] = {
+	  SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740, SIS_330
+	};
+
+        for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
+
+                stage = 1;
+
+                rom_base = (char *)ioremap(segstart, 0x1000);
+
+                if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))
+                   stage = 2;
+
+                if (stage != 2) {
+                   iounmap(rom_base);
+                   continue;
+                }
+
+
+		rom = rom_base + (unsigned short)(*(rom_base + 0x12) | (*(rom_base + 0x13) << 8));
+                if(strncmp(sis_rom_sig, rom, strlen(sis_rom_sig)) == 0) {
+                    stage = 3;
+		}
+                if(stage != 3) {
+                    iounmap(rom_base);
+                    continue;
+                }
+
+		rom = rom_base + (unsigned short)(*(rom_base + 0x14) | (*(rom_base + 0x15) << 8));
+                for(i = 0;(i < 4) && (stage != 4); i++) {
+                    if(strncmp(sis_sig_300[i], rom, strlen(sis_sig_300[i])) == 0) {
+                        if(sis_nums_300[i] == ivideo.chip) {
+			   stage = 4;
+                           break;
+			}
+                    }
+                }
+		if(stage != 4) {
+                   for(i = 0;(i < 7) && (stage != 4); i++) {
+                      if(strncmp(sis_sig_310[i], rom, strlen(sis_sig_310[i])) == 0) {
+		          if(sis_nums_310[i] == ivideo.chip) {
+                             stage = 4;
+                             break;
+			  }
+                      }
+                   }
+		}
+
+                if(stage != 4) {
+                        iounmap(rom_base);
+                        continue;
+                }
+
+                return rom_base;
+        }
+#endif
+        return NULL;
+}
+
+
 
 int __init sisfb_init(void)
 {
 	struct pci_dev *pdev = NULL;
 	struct board *b;
 	int pdev_valid = 0;
-	//unsigned long rom_vbase;
 	u32 reg32;
 	u16 reg16;
-	u8  reg;
-	int temp1, temp2;
+	u8  reg, reg1;
 
-	outb(0x77, 0x80);
+	/* outb(0x77, 0x80); */  /* What is this? */
 
 #if 0 	
 	/* for DOC VB */
@@ -2732,20 +3775,37 @@
 		return -ENXIO;
 
 	if (enable_dstn)
-		SetEnableDstn();
+		SiS_SetEnableDstn(&SiS_Pr);
+		
+	sisfb_registered = 0;
+
+	memset(&sis_fb_info, 0, sizeof(sis_fb_info));
+	
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+	memset(&sis_disp, 0, sizeof(sis_disp));
+#endif	
 
 	pci_for_each_dev(pdev) {
 		for (b = sisdev_list; b->vendor; b++) {
 			if ((b->vendor == pdev->vendor)
 			    && (b->device == pdev->device)) {
 				pdev_valid = 1;
-				strcpy(fb_info.modename, b->name);
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)				
+				strcpy(sis_fb_info.modename, b->name);
+#else				
+				strcpy(myid, b->name);
+#endif				
 				ivideo.chip_id = pdev->device;
 				pci_read_config_byte(pdev, PCI_REVISION_ID,
 				                     &ivideo.revision_id);
 				pci_read_config_word(pdev, PCI_COMMAND, &reg16);
 				sishw_ext.jChipRevision = ivideo.revision_id;
-				sisvga_enabled = reg16 & 0x1;
+				sisvga_enabled = reg16 & 0x01;
+				ivideo.pcibus = pdev->bus->number;
+				ivideo.pcislot = PCI_SLOT(pdev->devfn);
+				ivideo.pcifunc = PCI_FUNC(pdev->devfn);
+				ivideo.subsysvendor = pdev->subsystem_vendor;
+				ivideo.subsysdevice = pdev->subsystem_device;
 				break;
 			}
 		}
@@ -2755,157 +3815,182 @@
 	}
 
 	if (!pdev_valid)
-		return -1;
+		return -ENODEV;
 
-// Eden Chen
 	switch (ivideo.chip_id) {
+#ifdef CONFIG_FB_SIS_300
 	   case PCI_DEVICE_ID_SI_300:
 		ivideo.chip = SIS_300;
 		sisvga_engine = SIS_300_VGA;
-		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300 * 2;  /* New X driver uses 2 buffers */
 		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
 		break;
 	   case PCI_DEVICE_ID_SI_630_VGA:
 		{
 			sisfb_set_reg4(0xCF8, 0x80000000);
 			reg32 = sisfb_get_reg3(0xCFC);
-			if (reg32 == 0x07301039) {
+			if(reg32 == 0x07301039) {
 				ivideo.chip = SIS_730;
-				strcpy(fb_info.modename, "SIS 730");
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)				
+				strcpy(sis_fb_info.modename, "SIS 730");
+#else
+				strcpy(myid, "SIS 730");
+#endif				
 			} else
 				ivideo.chip = SIS_630;
 
 			sisvga_engine = SIS_300_VGA;
-			sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300;
+			sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300 * 2;
 			sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
 			break;
 		}
 	   case PCI_DEVICE_ID_SI_540_VGA:
 		ivideo.chip = SIS_540;
 		sisvga_engine = SIS_300_VGA;
-		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300 * 2;
 		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
 		break;
+#endif
+#ifdef CONFIG_FB_SIS_315
 	   case PCI_DEVICE_ID_SI_315H:
 		ivideo.chip = SIS_315H;
 		sisvga_engine = SIS_315_VGA;
-		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
 		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
 	   case PCI_DEVICE_ID_SI_315:
 		ivideo.chip = SIS_315;
 		sisvga_engine = SIS_315_VGA;
-		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
 		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
 	   case PCI_DEVICE_ID_SI_315PRO:
 		ivideo.chip = SIS_315PRO;
 		sisvga_engine = SIS_315_VGA;
-		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
 		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
 	   case PCI_DEVICE_ID_SI_550_VGA:
 		ivideo.chip = SIS_550;
 		sisvga_engine = SIS_315_VGA;
-		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
 		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
 	   case PCI_DEVICE_ID_SI_650_VGA:
-		ivideo.chip = SIS_650;
+	   	{
+			ivideo.chip = SIS_650;  
+			sisfb_set_reg4(0xCF8, 0x80000000);
+			reg32 = sisfb_get_reg3(0xCFC);
+			if(reg32 == 0x07401039) {
+				ivideo.chip = SIS_740;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)				
+				strcpy(sis_fb_info.modename, "SIS 740");
+#else
+				strcpy(myid, "SIS 740");				
+#endif				
+			}
+			sisvga_engine = SIS_315_VGA;
+			sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
+			sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
+			break;
+		}
+	   case PCI_DEVICE_ID_SI_330:
+		ivideo.chip = SIS_330;
 		sisvga_engine = SIS_315_VGA;
-		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315;
+		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
 		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
+#endif
+           default:
+	        return -ENODEV;
 	}
 	sishw_ext.jChipType = ivideo.chip;
-	// for Debug
-	if ((sishw_ext.jChipType == SIS_315PRO) 
-	   || (sishw_ext.jChipType == SIS_315) )
-		sishw_ext.jChipType = SIS_315H;
 
-	DPRINTK("%s is used as %s device(VGA Engine %d).\n", 
-		fb_info.modename, sisvga_enabled ? "primary" : "secondary", sisvga_engine);
+	/* for Debug */
+	if( (sishw_ext.jChipType == SIS_315PRO) ||
+	    (sishw_ext.jChipType == SIS_315) )
+		sishw_ext.jChipType = SIS_315H;
 
 	ivideo.video_base = pci_resource_start(pdev, 0);
 	ivideo.mmio_base = pci_resource_start(pdev, 1);
 	sishw_ext.ulIOAddress = (unsigned short) ivideo.vga_base =
-		                   pci_resource_start(pdev, 2) + 0x30;
+	    (unsigned short) SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
 
 	sisfb_mmio_size =  pci_resource_len(pdev, 1);
 
-	if (!sisvga_enabled)
+	if(!sisvga_enabled) {
 		if (pci_enable_device(pdev))   return -EIO;
+	}
 
-// Eden Eden
-//#ifdef LINUXBIOS
-//	sishw_ext.VirtualRomBase = rom_vbase = (unsigned long) rom_data;
-//#else
-//	{
-//	unsigned long rom_base  = 0x000C0000;
-//
-//	request_region(rom_base, 32, "sisfb");
-//	sishw_ext.VirtualRomBase = rom_vbase 
-//		= (unsigned long) ioremap(rom_base, MAX_ROM_SCAN);
-//	}
-//#endif
-// ~Eden Chen
-	
-	vgawb(SEQ_ADR, IND_SIS_PASSWORD);
-	vgawb(SEQ_DATA, SIS_PASSWORD);
-
-        /* TW: Debug kernel 2.5 problem */
-	vgawb(SEQ_ADR, 0x14);
-	reg = vgarb(SEQ_DATA);
-	printk("sisfb: SR14 = 0x%02x\n", reg);
-	/* /TW */
+	SiS_Pr.SiS_Backup70xx = 0xff;
+        SiS_Pr.SiS_CHOverScan = -1;
+        SiS_Pr.SiS_ChSW = FALSE;
+	SiS_Pr.SiS_UseLCDA = FALSE;
+	SiS_Pr.UsePanelScaler = -1;
+	SiSRegInit(&SiS_Pr, (USHORT)sishw_ext.ulIOAddress);
+
+#ifdef CONFIG_FB_SIS_300
+	/* TW: Find PCI systems for Chrontel/ISA bridge manipulation */
+	if(ivideo.chip == SIS_630) {
+	  int i=0;
+          do {
+	    if(mychswtable[i].subsysVendor == ivideo.subsysvendor &&
+	       mychswtable[i].subsysCard   == ivideo.subsysdevice) {
+		SiS_Pr.SiS_ChSW = TRUE;
+            }
+            i++;
+          } while(mychswtable[i].subsysVendor != 0);
+	}
+#endif
+
+        outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		
+#ifdef MODULE	
+	inSISIDXREG(SISCR,0x34,reg);
+	if(reg & 0x80) {
+	   if((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {
+	      printk(KERN_INFO "sisfb: Cannot initialize display mode, X server is active\n");
+	      return -EBUSY;
+	   }
+	}
+#endif	
+#endif
+
+#ifdef LINUXBIOS  /* -------------------------------- */
 
-#ifdef LINUXBIOS
 #ifdef CONFIG_FB_SIS_300
 	if (sisvga_engine == SIS_300_VGA) {
-		vgawb(SEQ_ADR, 0x28);
-		vgawb(SEQ_DATA, 0x37);
+	        outSISIDXREG(SISSR, 0x28, 0x37);
 
-		vgawb(SEQ_ADR, 0x29);
-		vgawb(SEQ_DATA, 0x61);
+                outSISIDXREG(SISSR, 0x29, 0x61);
 
-		vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_1A);
-		reg = vgarb(SEQ_DATA);
-		reg |= SIS_SCRATCH_REG_1A_MASK;
-		vgawb(SEQ_DATA, reg);
+                orSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_1A, SIS_SCRATCH_REG_1A_MASK);
 	}
 #endif
 #ifdef CONFIG_FB_SIS_315
-	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650) {
-		vgawb(SEQ_ADR,  0x28);
-		vgawb(SEQ_DATA, 0x5A);
+	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 || ivideo.chip == SIS_740) {
+	        outSISIDXREG(SISSR, 0x28, 0x5a);
 
-		vgawb(SEQ_ADR,  0x29);
-		vgawb(SEQ_DATA, 0x64);
+                outSISIDXREG(SISSR, 0x29, 0x64);
 
-		vgawb(CRTC_ADR,  0x3A);
-		vgawb(CRTC_DATA, 0x00);
+                outSISIDXREG(SISCR, 0x3a, 0x00);
 	}
-#endif
-#endif /* LinuxBIOS */
+#endif		
+
+#endif /* LinuxBIOS  -------------------------------- */
 
 	if (sisvga_engine == SIS_315_VGA) {
 		switch (ivideo.chip) {
 		   case SIS_315H:
 		   case SIS_315:
+		   case SIS_330:
 			sishw_ext.bIntegratedMMEnabled = TRUE;
 			break;
 		   case SIS_550:
 		   case SIS_650:
-			// Eden Chen
-			//vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_1A);
-			//reg = vgarb(SEQ_DATA);
-			//if (reg & SIS_SCRATCH_REG_1A_MASK)
-			//	sishw_ext.bIntegratedMMEnabled = TRUE;
-			//else
-			//	sishw_ext.bIntegratedMMEnabled = FALSE;
-			//for Debug
+		   case SIS_740:
 			sishw_ext.bIntegratedMMEnabled = TRUE;
-			// ~Eden Chen
 			break;
 		   default:
 			break;
@@ -2914,8 +3999,7 @@
 		if (ivideo.chip == SIS_300) {
 			sishw_ext.bIntegratedMMEnabled = TRUE;
 		} else {
-			vgawb(SEQ_ADR, IND_SIS_SCRATCH_REG_1A);
-			reg = vgarb(SEQ_DATA);
+		        inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_1A, reg);
 			if (reg & SIS_SCRATCH_REG_1A_MASK)
 				sishw_ext.bIntegratedMMEnabled = TRUE;
 			else
@@ -2924,7 +4008,21 @@
 	}
 
 	sishw_ext.pDevice = NULL;
-	sishw_ext.pjVirtualRomBase = NULL;
+	if(sisfb_userom) {
+	    sishw_ext.pjVirtualRomBase = sis_find_rom();
+	    if(sishw_ext.pjVirtualRomBase) {
+		printk(KERN_INFO "sisfb: Video ROM found and mapped to %p\n",
+		        sishw_ext.pjVirtualRomBase);
+		sishw_ext.UseROM = TRUE;
+	    } else {
+	        sishw_ext.UseROM = FALSE;
+	        printk(KERN_INFO "sisfb: Video ROM not found\n");
+	    }
+	} else {
+	    sishw_ext.pjVirtualRomBase = NULL;
+	    sishw_ext.UseROM = FALSE;
+	    printk(KERN_INFO "sisfb: Video ROM usage disabled\n");
+	}
 	sishw_ext.pjCustomizedROMImage = NULL;
 	sishw_ext.bSkipDramSizing = 0;
 	sishw_ext.pQueryVGAConfigSpace = &sisfb_query_VGA_config_space;
@@ -2941,48 +4039,49 @@
 
 	sishw_ext.pSR = vmalloc(sizeof(SIS_DSReg) * SR_BUFFER_SIZE);
 	if (sishw_ext.pSR == NULL) {
-		printk(KERN_INFO "sisfb: Fatal error: Allocating SRReg space failed.\n");
+		printk(KERN_ERR "sisfb: Fatal error: Allocating SRReg space failed.\n");
 		return -ENODEV;
 	}
 	sishw_ext.pSR[0].jIdx = sishw_ext.pSR[0].jVal = 0xFF;
 
 	sishw_ext.pCR = vmalloc(sizeof(SIS_DSReg) * CR_BUFFER_SIZE);
 	if (sishw_ext.pCR == NULL) {
-		printk(KERN_INFO "sisfb: Fatal error: Allocating CRReg space failed.\n");
+	        vfree(sishw_ext.pSR);
+		printk(KERN_ERR "sisfb: Fatal error: Allocating CRReg space failed.\n");
 		return -ENODEV;
 	}
 	sishw_ext.pCR[0].jIdx = sishw_ext.pCR[0].jVal = 0xFF;
 
 #ifdef CONFIG_FB_SIS_300
-	if (sisvga_engine == SIS_300_VGA) {
-		if (!sisvga_enabled) {
+	if(sisvga_engine == SIS_300_VGA) {
+		if(!sisvga_enabled) {
+		        /* Mapping Max FB Size for 300 Init */
 			sishw_ext.pjVideoMemoryAddress
-				= ioremap(ivideo.video_base, 0x2000000);
-			if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
-				SiSInit(&sishw_ext);
-				vgawb(SEQ_ADR, IND_SIS_PASSWORD);
-				vgawb(SEQ_DATA, SIS_PASSWORD);
+				= ioremap(ivideo.video_base, 0x4000000);
+			if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
+#ifdef LINUXBIOS		/* TW: SiSInit now for LinuxBIOS only */	        
+				SiSInit(&SiS_Pr, &sishw_ext);
+#endif
+				outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
 			}
 		}
 #ifdef LINUXBIOS
 		else {
 			sishw_ext.pjVideoMemoryAddress
-				= ioremap(ivideo.video_base, 0x2000000);
-			if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
-				SiSInit(&sishw_ext);
-				vgawb(SEQ_ADR, IND_SIS_PASSWORD);
-				vgawb(SEQ_DATA, SIS_PASSWORD);
-			}
-		}
-		if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
-			vgawb(SEQ_ADR, 0x7);
-			reg = vgarb(SEQ_DATA);
-			reg |= 0x10;
-			vgawb(SEQ_DATA, reg);
+				= ioremap(ivideo.video_base, 0x4000000);
+			if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
+				SiSInit(&SiS_Pr, &sishw_ext);
+				outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+			}
+		}
+		if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) { 
+		        orSISIDXREG(SISSR, 0x07, 0x10);
 		}
 #endif
-		if (sisfb_get_dram_size_300()) {
-			printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size\n");
+		if(sisfb_get_dram_size_300()) {
+		        vfree(sishw_ext.pSR);
+			vfree(sishw_ext.pCR);
+			printk(KERN_ERR "sisfb: Fatal error: Unable to determine RAM size\n");
 			return -ENODEV;
 		}
 	}
@@ -2992,24 +4091,22 @@
 	if (sisvga_engine == SIS_315_VGA) {
 		if (!sisvga_enabled) {
 			/* Mapping Max FB Size for 315 Init */
-			// Eden Chen
-			//sishw_ext.VirtualVideoMemoryAddress 
 			sishw_ext.pjVideoMemoryAddress 
 				= ioremap(ivideo.video_base, 0x8000000);
-			if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
-				SiSInit(&sishw_ext);
+			if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) { 
+#ifdef LINUXBIOS
+			        /* TW: SISInit is now for LINUXBIOS only */
+				SiSInit(&SiS_Pr, &sishw_ext);
+#endif
 
-				vgawb(SEQ_ADR, IND_SIS_PASSWORD);
-				vgawb(SEQ_DATA, SIS_PASSWORD);
+				outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
 
 				sishw_ext.bSkipDramSizing = TRUE;
-				vgawb(SEQ_ADR, 0x13);
 				sishw_ext.pSR[0].jIdx = 0x13;
-				sishw_ext.pSR[0].jVal = vgarb(SEQ_DATA);
-				vgawb(SEQ_ADR, 0x14);
 				sishw_ext.pSR[1].jIdx = 0x14;
-				sishw_ext.pSR[1].jVal = vgarb(SEQ_DATA);
 				sishw_ext.pSR[2].jIdx = 0xFF;
+				inSISIDXREG(SISSR, 0x13, sishw_ext.pSR[0].jVal);
+				inSISIDXREG(SISSR, 0x14, sishw_ext.pSR[1].jVal);
 				sishw_ext.pSR[2].jVal = 0xFF;
 			}
 		}
@@ -3017,41 +4114,38 @@
 		else {
 			sishw_ext.pjVideoMemoryAddress
 				= ioremap(ivideo.video_base, 0x8000000);
-			if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
-				SiSInit(&sishw_ext);
-				vgawb(SEQ_ADR, IND_SIS_PASSWORD);
-				vgawb(SEQ_DATA, SIS_PASSWORD);
+			if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) { 
+
+				SiSInit(&SiS_Pr, &sishw_ext);
+
+				outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
 
 				sishw_ext.bSkipDramSizing = TRUE;
-				vgawb(SEQ_ADR, 0x13);
 				sishw_ext.pSR[0].jIdx = 0x13;
-				sishw_ext.pSR[0].jVal = vgarb(SEQ_DATA);
-				vgawb(SEQ_ADR, 0x14);
 				sishw_ext.pSR[1].jIdx = 0x14;
-				sishw_ext.pSR[1].jVal = vgarb(SEQ_DATA);
 				sishw_ext.pSR[2].jIdx = 0xFF;
+				inSISIDXREG(SISSR, 0x13, sishw_ext.pSR[0].jVal);
+				inSISIDXREG(SISSR, 0x14, sishw_ext.pSR[1].jVal);
 				sishw_ext.pSR[2].jVal = 0xFF;
 			}
 		}
 #endif
 		if (sisfb_get_dram_size_315()) {
+			vfree(sishw_ext.pSR);
+			vfree(sishw_ext.pCR);
 			printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size.\n");
 			return -ENODEV;
 		}
 	}
 #endif
-	if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
 
-		vgawb(SEQ_ADR, IND_SIS_PCI_ADDRESS_SET);
-		reg = vgarb(SEQ_DATA);
-		reg |= SIS_PCI_ADDR_ENABLE;    	/* Enable PCI_LINEAR_ADDRESSING */
-		reg |= SIS_MEM_MAP_IO_ENABLE;  	/* Enable MMIO_ENABLE */
-		vgawb(SEQ_DATA, reg);
-
-		vgawb(SEQ_ADR, IND_SIS_MODULE_ENABLE);
-		reg = vgarb(SEQ_DATA);
-		reg |= SIS_ENABLE_2D;		/* Enable 2D accelerator engine */
-		vgawb(SEQ_DATA, reg);
+	if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) { 
+
+	        /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE  */
+	        orSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
+
+                /* Enable 2D accelerator engine */
+	        orSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
 
 	}
 
@@ -3066,86 +4160,95 @@
 	if (!request_mem_region(ivideo.video_base, ivideo.video_size, "sisfb FB")) {
 		printk(KERN_ERR "sisfb: Fatal error: Unable to reserve frame buffer memory\n");
 		printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n");
+		vfree(sishw_ext.pSR);
+		vfree(sishw_ext.pCR);
 		return -ENODEV;
 	}
 
 	if (!request_mem_region(ivideo.mmio_base, sisfb_mmio_size, "sisfb MMIO")) {
 		printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n");
 		release_mem_region(ivideo.video_base, ivideo.video_size);
+		vfree(sishw_ext.pSR);
+		vfree(sishw_ext.pCR);
 		return -ENODEV;
 	}
 
-	sishw_ext.pjVideoMemoryAddress = ivideo.video_vbase
-		= ioremap(ivideo.video_base, ivideo.video_size);
+	ivideo.video_vbase = sishw_ext.pjVideoMemoryAddress = 
+		ioremap(ivideo.video_base, ivideo.video_size);
 	ivideo.mmio_vbase = ioremap(ivideo.mmio_base, sisfb_mmio_size);
 
-	printk(KERN_INFO
-	       "sisfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
+	printk(KERN_INFO "sisfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
 	       ivideo.video_base, ivideo.video_vbase,
 	       ivideo.video_size / 1024);
 
-	printk(KERN_INFO
-	       "sisfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
+	printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
 	       ivideo.mmio_base, ivideo.mmio_vbase,
 	       sisfb_mmio_size / 1024);
 
-	if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
+	if(sisfb_heap_init()) {
+		printk(KERN_WARNING "sisfb: Failed to initialize offscreen memory heap\n");
+	}
+
+	ivideo.mtrr = (unsigned int) 0;
+
+	if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) { 
 
 #ifdef CONFIG_FB_SIS_300
 		if (sisvga_engine == SIS_300_VGA) {
 			sisfb_get_VB_type_300();
-			if (ivideo.hasVB != HASVB_NONE) {
-				sisfb_detect_VB_connect_300();
-			}
 		}
 #endif
 
 #ifdef CONFIG_FB_SIS_315
 		if (sisvga_engine == SIS_315_VGA) {
 			sisfb_get_VB_type_315();
-			if (ivideo.hasVB != HASVB_NONE) {
-				sisfb_detect_VB_connect_315();
-			}
 		}
 #endif
 
 		sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
+		sishw_ext.Is301BDH = FALSE;
 		sishw_ext.usExternalChip = 0;
 
 		switch (ivideo.hasVB) {
 
 		case HASVB_301:
-			vgawb(VB_PART4_ADR,0x01);
-			reg = vgarb(VB_PART4_DATA);
-			if (reg >= 0xD0) {
+		        inSISIDXREG(SISPART4, 0x01, reg);
+			if (reg >= 0xE0) {
+				sishw_ext.ujVBChipID = VB_CHIP_302LV;
+				printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
+	  		} else if (reg >= 0xD0) {
 				sishw_ext.ujVBChipID = VB_CHIP_301LV;
 				printk(KERN_INFO "sisfb: SiS301LV bridge detected (revision 0x%02x)\n",reg);
 	  		} else if (reg >= 0xB0) {
 				sishw_ext.ujVBChipID = VB_CHIP_301B;
-				printk(KERN_INFO "sisfb: SiS301B bridge detected (revision 0x%02x\n",reg);
+				inSISIDXREG(SISPART4,0x23,reg1);
+				if(!(reg1 & 0x02)) sishw_ext.Is301BDH = TRUE;
+				printk(KERN_INFO "sisfb: SiS301B%s bridge detected (revision 0x%02x)\n",
+					(sishw_ext.Is301BDH ? "-DH" : ""), reg);
 			} else {
 				sishw_ext.ujVBChipID = VB_CHIP_301;
 				printk(KERN_INFO "sisfb: SiS301 bridge detected\n");
 			}
 			break;
 		case HASVB_302:
-			vgawb(VB_PART4_ADR,0x01);
-			reg = vgarb(VB_PART4_DATA);
-			if (reg >= 0xD0) {
+		        inSISIDXREG(SISPART4, 0x01, reg);
+			if (reg >= 0xE0) {
 				sishw_ext.ujVBChipID = VB_CHIP_302LV;
 				printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
+	  		} else if (reg >= 0xD0) {
+				sishw_ext.ujVBChipID = VB_CHIP_301LV;
+				printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
 	  		} else if (reg >= 0xB0) {
+				inSISIDXREG(SISPART4,0x23,reg1);
+				if(!(reg1 & 0x02)) sishw_ext.Is301BDH = TRUE;
 			        sishw_ext.ujVBChipID = VB_CHIP_302B;
-				printk(KERN_INFO "sisfb: SiS302B bridge detected (revision 0x%02x)\n",reg);
+				printk(KERN_INFO "sisfb: SiS302B%s bridge detected (revision 0x%02x)\n",
+					(sishw_ext.Is301BDH ? "-DH" : ""), reg);
 			} else {
 			        sishw_ext.ujVBChipID = VB_CHIP_302;
 				printk(KERN_INFO "sisfb: SiS302 bridge detected\n");
 			}
 			break;
-		case HASVB_303:
-			sishw_ext.ujVBChipID = VB_CHIP_303;
-			printk(KERN_INFO "sisfb: SiS303 bridge detected (not supported)\n");
-			break;
 		case HASVB_LVDS:
 			sishw_ext.usExternalChip = 0x1;
 			printk(KERN_INFO "sisfb: LVDS transmitter detected\n");
@@ -3167,93 +4270,18 @@
 			break;
 		}
 
-		/* TW: Determine and detect attached TV's on Chrontel */
-		if (sishw_ext.usExternalChip == 0x04 || sishw_ext.usExternalChip == 0x05) {
-		    SiSRegInit(sishw_ext.ulIOAddress);
-		    if(ivideo.chip < SIS_315H) {    /* TW: Chrontel 7005 */
+		if (ivideo.hasVB != HASVB_NONE) {
 #ifdef CONFIG_FB_SIS_300
-                       SiS_IF_DEF_CH70xx = 1;
-		       temp1=SiS_GetCH700x(0x25);
-		       if ((temp1 >= 50) && (temp1 <= 100)) {
-	    		   /* TW: Read power status */
-	    		   temp1 = SiS_GetCH700x(0x0e);
-	    		   if ((temp1&0x03)!=0x03) {
-		        	/* TW: Power all outputs */
-	        		SiS_SetCH70xxANDOR(0x030E,0xF8);
-	    		   }
-			   /* TW: Sense connected TV devices */
-	    		   SiS_SetCH700x(0x0110);
-	    		   SiS_SetCH700x(0x0010);
-	    		   temp1 = SiS_GetCH700x(0x10);
-	    		   if (!(temp1 & 0x08)) {
-				/* TW: So we can be sure that there IS a SVHS output */
-				printk(KERN_INFO
-				   "sisfb: Chrontel: Detected TV connected to SVHS output\n");
-				ivideo.TV_plug = TVPLUG_SVIDEO;
-				vgawb(CRTC_ADR, 0x32);
-				temp2 = vgarb(CRTC_DATA) | 0x02;
-				vgawb(CRTC_DATA, temp2);
-			   } else if (!(temp1 & 0x02)) {
-				/* TW: So we can be sure that there IS a CVBS output */
-				printk(KERN_INFO
-				   "sisfb: Chrontel: Detected TV connected to CVBS output\n");
-				ivideo.TV_plug = TVPLUG_COMPOSITE;
-				vgawb(CRTC_ADR, 0x32);
-				temp2 = vgarb(CRTC_DATA) | 0x01;
-				vgawb(CRTC_DATA, temp2);
-	    		   } else {
-		    		SiS_SetCH70xxANDOR(0x010E,0xF8);
-	    		   }
-		       } else if (temp1==0) {
-	    		        SiS_SetCH70xxANDOR(0x010E,0xF8);
-	    	       }
+		      if (sisvga_engine == SIS_300_VGA) {
+				sisfb_detect_VB_connect_300();
+                      }
 #endif
-		   } else {  /* TW: Chrontel 7019 */
 #ifdef CONFIG_FB_SIS_315
-			SiS_IF_DEF_CH70xx = 2;
-                        temp1 = SiS_GetCH701x(0x49);
-			SiS_SetCH701x(0x2049);
-			SiS_DDC2Delay(0x96);
-			temp2 = SiS_GetCH701x(0x20);
-			temp2 |= 0x01;
-			SiS_SetCH701x((temp2 << 8) | 0x20);
-			SiS_DDC2Delay(0x96);
-			temp2 ^= 0x01;
-			SiS_SetCH701x((temp2 << 8) | 0x20);
-			SiS_DDC2Delay(0x96);
-			temp2 = SiS_GetCH701x(0x20);
-			SiS_SetCH701x((temp1 << 8) | 0x49);
-                        temp1 = 0;
-			if(temp2 & 0x02) temp1 |= 0x01;
-			if(temp2 & 0x10) temp1 |= 0x01;
-			if(temp2 & 0x04) temp1 |= 0x02;
-			if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04;
-			switch(temp1) {
-			case 0x01:
-			     printk(KERN_INFO
-				"sisfb: Chrontel: Detected TV connected to CVBS output\n");
-			     ivideo.TV_plug = TVPLUG_COMPOSITE;
-			     vgawb(CRTC_ADR, 0x32);
-                             temp2 = vgarb(CRTC_DATA) | 0x01;
-			     vgawb(CRTC_DATA, temp2);
-                             break;
-			case 0x02:
-			     printk(KERN_INFO
-				"sisfb: Chrontel: Detected TV connected to SVHS output\n");
-			     ivideo.TV_plug = TVPLUG_SVIDEO;
-			     vgawb(CRTC_ADR, 0x32);
-			     temp2 = vgarb(CRTC_DATA) | 0x02;
-			     vgawb(CRTC_DATA, temp2);
-                             break;
-			case 0x04:
-			     /* TW: This should not happen */
-			     printk(KERN_INFO
-				"sisfb: Chrontel: Detected TV connected to SCART output!?\n");
-                             break;
-			}
+		      if (sisvga_engine == SIS_315_VGA) {
+				sisfb_detect_VB_connect_315();
+                      }
 #endif
-		   }
-	    	}
+		}
 
 		if (ivideo.disp_state & DISPTYPE_DISP2) {
 			if (sisfb_crt1off)
@@ -3266,8 +4294,8 @@
 
 		if (ivideo.disp_state & DISPTYPE_LCD) {
 		    if (!enable_dstn) {
-			vgawb(CRTC_ADR, IND_SIS_LCD_PANEL);
-			reg = vgarb(CRTC_DATA) & 0x0f;
+		        inSISIDXREG(SISCR, IND_SIS_LCD_PANEL, reg);
+			reg &= 0x0f;
 			if (sisvga_engine == SIS_300_VGA) {
 			    sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
 			} else {
@@ -3278,9 +4306,84 @@
 			sishw_ext.ulCRT2LCDType = LCD_320x480;
 		    }
 		}
+		
+		sisfb_detectedpdc = 0;
+#ifndef LINUXBIOS
+#ifdef CONFIG_FB_SIS_300
+                /* TW: Save the current PanelDelayCompensation if the LCD is currently used */
+		if(sisvga_engine == SIS_300_VGA) {
+	          if((sishw_ext.usExternalChip == 0x01) ||   /* LVDS */
+		     (sishw_ext.usExternalChip == 0x05) ||   /* LVDS+Chrontel */
+		     (sishw_ext.Is301BDH)) {		     /* 301B-DH */
+		       int tmp;
+		       inSISIDXREG(SISCR,0x30,tmp);
+		       if(tmp & 0x20) {
+		          /* Currently on LCD? If yes, read current pdc */
+		          inSISIDXREG(SISPART1,0x13,sisfb_detectedpdc);
+			  sisfb_detectedpdc &= 0x3c;
+			  if(sishw_ext.pdc == 0) {
+			     /* Let option override detection */
+			     sishw_ext.pdc = sisfb_detectedpdc;
+			  }
+			  printk(KERN_INFO
+			         "sisfb: Detected LCD PanelDelayCompensation %d\n",
+  			         sisfb_detectedpdc);
+		       }
+		       if((sishw_ext.pdc) && (sishw_ext.pdc != sisfb_detectedpdc)) {
+		          printk(KERN_INFO
+			         "sisfb: Using LCD PanelDelayCompensation %d\n",
+				 sishw_ext.pdc);
+		       }
+	          }
+		}
+#endif
+#endif
+	        sisfb_detectedlcda = 0xff;
+#ifndef LINUXBIOS
+#ifdef CONFIG_FB_SIS_315
+                /* TW: Try to find about LCDA */
+		if(sisvga_engine == SIS_315_VGA) {
+	          if((sishw_ext.ujVBChipID == VB_CHIP_302B) ||
+		     (sishw_ext.ujVBChipID == VB_CHIP_301LV) ||
+		     (sishw_ext.ujVBChipID == VB_CHIP_302LV)) {
+		       int tmp;
+		       inSISIDXREG(SISCR,0x34,tmp);
+		       if(tmp <= 0x13) {	
+		          /* Currently on LCDA? (Some BIOSes leave CR38) */
+		          inSISIDXREG(SISCR,0x38,tmp);
+			  if((tmp & 0x03) == 0x03) {
+			     SiS_Pr.SiS_UseLCDA = TRUE;
+			  } else {
+			     /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
+			     inSISIDXREG(SISCR,0x35,tmp);
+			     if(tmp & 0x01) {
+			        SiS_Pr.SiS_UseLCDA = TRUE;
+			     } else {
+			        /* Currently on LCD? If so, we can find out 
+				   by peeking the mode register 
+				 */
+			        inSISIDXREG(SISCR,0x30,tmp);
+			        if(tmp & 0x20) {
+			           inSISIDXREG(SISPART1,0x13,tmp);
+				   if(tmp & 0x04) {
+				      SiS_Pr.SiS_UseLCDA = TRUE;
+				   }
+			        }
+			     }
+			  }
+		       } 
+		       if(SiS_Pr.SiS_UseLCDA) {
+		          sisfb_detectedlcda = 0x03;
+		          printk(KERN_INFO
+			         "sisfb: Bridge uses LCDA for low resolution and text modes\n");
+		       }
+	          }
+		}
+#endif
+#endif
 
 		if (sisfb_mode_idx >= 0)
-			sisfb_validate_mode();
+			sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx);
 
 		if (sisfb_mode_idx < 0) {
 			switch (ivideo.disp_state & DISPTYPE_DISP2) {
@@ -3310,214 +4413,388 @@
 		ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
 		ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
 		ivideo.org_x = ivideo.org_y = 0;
-		video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
+		ivideo.video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
+		switch(ivideo.video_bpp) {
+        	case 8:
+            		ivideo.DstColor = 0x0000;
+	    		ivideo.SiS310_AccelDepth = 0x00000000;
+			ivideo.video_cmap_len = 256;
+            		break;
+        	case 16:
+            		ivideo.DstColor = 0x8000;
+            		ivideo.SiS310_AccelDepth = 0x00010000;
+			ivideo.video_cmap_len = 16;
+            		break;
+        	case 32:
+            		ivideo.DstColor = 0xC000;
+	    		ivideo.SiS310_AccelDepth = 0x00020000;
+			ivideo.video_cmap_len = 16;
+            		break;
+		default:
+			ivideo.video_cmap_len = 16;
+		        printk(KERN_INFO "sisfb: Unsupported depth %d", ivideo.video_bpp);
+			break;
+    		}
+		
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
 
-		printk(KERN_INFO "sisfb: Mode is %dx%dx%d (%dHz), linelength=%d\n",
+		/* ---------------- For 2.4: Now switch the mode ------------------ */		
+		
+		printk(KERN_INFO "sisfb: Mode is %dx%dx%d (%dHz)\n",
 	       		ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
-			ivideo.refresh_rate, video_linelength);
-
-		// Eden Chen
-		// Check interface correction  For Debug
-		DPRINTK("VM Adr=0x%p\n", sishw_ext.pjVideoMemoryAddress);
-		DPRINTK("VM Size=%ldK\n", sishw_ext.ulVideoMemorySize/1024);
-		DPRINTK("IO Adr=0x%lx\n", sishw_ext.ulIOAddress);
-		DPRINTK("Chip=%d\n", sishw_ext.jChipType);
-		DPRINTK("ChipRevision=%d\n", sishw_ext.jChipRevision);
-		DPRINTK("VBChip=%d\n", sishw_ext.ujVBChipID);
-		DPRINTK("ExtVB=%d\n", sishw_ext.usExternalChip);
-		DPRINTK("LCD=%ld\n", sishw_ext.ulCRT2LCDType);
-		DPRINTK("bIntegratedMMEnabled=%d\n", sishw_ext.bIntegratedMMEnabled);
-		// ~Eden Chen
+			ivideo.refresh_rate);
 
 		sisfb_pre_setmode();
 
-		if (SiSSetMode(&sishw_ext, sisfb_mode_no) == 0) {
-			printk("sisfb: Setting mode[0x%x] failed, using default mode\n", sisfb_mode_no);
+		if (SiSSetMode(&SiS_Pr, &sishw_ext, sisfb_mode_no) == 0) {
+			printk(KERN_ERR "sisfb: Setting mode[0x%x] failed, using default mode\n", 
+				sisfb_mode_no);
 			return -1;
 		}
 
-		vgawb(SEQ_ADR, IND_SIS_PASSWORD);
-		vgawb(SEQ_DATA, SIS_PASSWORD);
+		outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
 
 		sisfb_post_setmode();
 
 		sisfb_crtc_to_var(&default_var);
+		
+#else		/* --------- For 2.5: Setup a somewhat sane default var ------------ */
 
-		fb_info.changevar = NULL;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-		fb_info.node = -1;
-#else
-		fb_info.node = NODEV;
-#endif
-		fb_info.fbops = &sisfb_ops;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,23)
-		fb_info.screen_base = ivideo.video_vbase;
-		fb_info.currcon = -1;
+		printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
+	       		ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
+			ivideo.refresh_rate);
+			
+		default_var.xres = default_var.xres_virtual = ivideo.video_width;
+		default_var.yres = default_var.yres_virtual = ivideo.video_height;
+		default_var.bits_per_pixel = ivideo.video_bpp;
+		
+		sisfb_bpp_to_var(&default_var);
+		
+		default_var.pixclock = (u32) (1E12 /
+				sisfb_mode_rate_to_dclock(&SiS_Pr, &sishw_ext,
+						sisfb_mode_no, sisfb_rate_idx));
+						
+		if(sisfb_mode_rate_to_ddata(&SiS_Pr, &sishw_ext,
+			 sisfb_mode_no, sisfb_rate_idx,
+			 &default_var.left_margin, &default_var.right_margin, 
+			 &default_var.upper_margin, &default_var.lower_margin,
+			 &default_var.hsync_len, &default_var.vsync_len,
+			 &default_var.sync, &default_var.vmode)) {
+			 
+		   if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+		      default_var.yres <<= 1;
+		      default_var.yres_virtual <<= 1;
+		   } else if((default_var.vmode	& FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+		      default_var.pixclock >>= 1;
+		      default_var.yres >>= 1;
+		      default_var.yres_virtual >>= 1;
+		   }
+		   
+	        }
+#ifdef SISFB_PAN
+		if(sisfb_ypan) {
+	    		default_var.yres_virtual = 
+				ivideo.heapstart / (default_var.xres * (default_var.bits_per_pixel >> 3));
+	    		if(default_var.yres_virtual <= default_var.yres) {
+	        		default_var.yres_virtual = default_var.yres;
+	    		}
+		} 
 #endif
-		fb_info.disp = &disp;
-		fb_info.switch_con = &sisfb_switch;
-		fb_info.updatevar = &sisfb_update_var;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,23)
-		fb_info.blank = &sisfb_blank;
+		
 #endif
-		fb_info.flags = FBINFO_FLAG_DEFAULT;
-
-		sisfb_set_disp(-1, &default_var);
 
-	} /* TW: if mode = "none" */
+		ivideo.accel = 0;
+		if(sisfb_accel) {
+		   ivideo.accel = -1;
+		   default_var.accel_flags |= FB_ACCELF_TEXT;
+		   sisfb_initaccel();
+		}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		/* ---- 2.4 series init ---- */
+		sis_fb_info.node = -1;
+		sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
+		sis_fb_info.blank = &sisfb_blank;
+		sis_fb_info.fbops = &sisfb_ops;
+		sis_fb_info.switch_con = &sisfb_switch;
+		sis_fb_info.updatevar = &sisfb_update_var;
+		sis_fb_info.changevar = NULL;
+		sis_fb_info.disp = &sis_disp;
+			
+		sisfb_set_disp(-1, &default_var, &sis_fb_info);
+#endif
 
-	if (sisfb_heap_init()) {
-		printk("sisfb: Failed to initialize offscreen memory heap\n");
-	}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)		/* ---- 2.5 series init ---- */
+		sis_fb_info.node = NODEV;
+		sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
+		sis_fb_info.var = default_var;
+		sis_fb_info.fix = sisfb_fix;
+		sis_fb_info.par = &ivideo;
+		sis_fb_info.screen_base = ivideo.video_vbase;
+		sis_fb_info.fbops = &sisfb_ops;
+		sisfb_get_fix(&sis_fb_info.fix, -1, &sis_fb_info);
+		sis_fb_info.pseudo_palette = pseudo_palette;
+		
+		fb_alloc_cmap(&sis_fb_info.cmap, 256 , 0);
+#endif
 
-        ivideo.mtrr = (unsigned int) 0;
-	if ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {   /* TW: for mode "none" */
-         	/*H.C.*/
+#ifdef CONFIG_MTRR
 		ivideo.mtrr = mtrr_add((unsigned int) ivideo.video_base,
 				(unsigned int) ivideo.video_size,
 				MTRR_TYPE_WRCOMB, 1);
-		/*
-		if (ivideo.mtrr >= 0) {
-           	    printk(KERN_INFO "Succeed to turn on Write-Combining on VideoMemory %08XH, Size: %08XH\n",
-					ivideo.video_base, ivideo.video_size);
-      		} else	{
-           	    printk(KERN_INFO "Fail to turn on Write-Combining on Video Memory 0x%08X, Size: 0x%08X\n",
-					ivideo.video_base, ivideo.video_size);
-      		}
-		*/
+		if(ivideo.mtrr) {
+			printk(KERN_INFO "sisfb: Added MTRRs\n");
+		}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		vc_resize_con(1, 1, 0);
+#endif
 
-		if (register_framebuffer(&fb_info) < 0)
+		TWDEBUG("Before calling register_framebuffer");
+		
+		if(register_framebuffer(&sis_fb_info) < 0)
 			return -EINVAL;
+			
+		sisfb_registered = 1;			
 
+		printk(KERN_INFO "sisfb: Installed SISFB_GET_INFO ioctl (%x)\n", SISFB_GET_INFO);
+		
+		printk(KERN_INFO "sisfb: 2D acceleration is %s, scrolling mode %s\n",
+		     sisfb_accel ? "enabled" : "disabled",
+		     sisfb_ypan  ? "ypan" : "redraw");
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
-	       		minor(fb_info.node), fb_info.modename, VER_MAJOR, VER_MINOR,
-	       		VER_LEVEL);
+	       		GET_FB_IDX(sis_fb_info.node), sis_fb_info.modename, VER_MAJOR, VER_MINOR,
+	       		VER_LEVEL);		     
+#endif
 
-		printk(KERN_INFO "sisfb: Added SISFB_GET_INFO ioctl = %x\n", SISFB_GET_INFO);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+		printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
+	       		minor(sis_fb_info.node), myid, VER_MAJOR, VER_MINOR, VER_LEVEL);			     
+#endif
 
 	}	/* TW: if mode = "none" */
 	return 0;
 }
 
+
 #ifdef MODULE
 
-static char *mode = NULL;
+static char         *mode = NULL;
+static int          vesa = -1;
 static unsigned int rate = 0;
 static unsigned int crt1off = 1;
 static unsigned int mem = 0;
 static unsigned int dstn = 0;
-static char *forcecrt2type = NULL;
-static int forcecrt1 = -1;
-static char *queuemode = NULL;
-static int pdc = 0;
-
-MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/740 framebuffer driver");
-MODULE_LICENSE("GPL");    /* TW (Code is officially open says SiS) */
-MODULE_AUTHOR("Various; SiS; Thomas Winischhofer <thomas@winischhofer.net>");
+static char         *forcecrt2type = NULL;
+static int          forcecrt1 = -1;
+static char         *queuemode = NULL;
+static int          pdc = 0;
+static int          noaccel = -1;
+static int          noypan  = -1;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+static int          inverse = 0;
+#endif
+static int          userom = 1;
+static int          useoem = -1;
+static char         *tvstandard = NULL;
+
+MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/740/330 framebuffer driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("SiS; Thomas Winischhofer <thomas@winischhofer.net>; Various others");
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+MODULE_PARM(mode, "s");
+MODULE_PARM_DESC(mode,
+       "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
+         "800x600x16 (default: none if sisfb is a module; this leaves the\n"
+	 "console untouched and the driver will only do the video memory\n"
+	 "management for eg. DRM/DRI; 800x600x8 if sisfb is in the kernel)");
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	 
 MODULE_PARM(mode, "s");
 MODULE_PARM_DESC(mode,
-       "Selects the desired display mode in the format [X]x[Y]x[Depth], eg. 800x600x16 "
-       "(default: none; this leaves the console untouched and the driver will only do "
-       "the video memory management for eg. DRM/DRI)");
+       "\nSelects the desired default display mode in the format [X]x[Y]x[Depth],\n"
+         "eg. 1024x768x16 (default: 800x600x8)");
+#endif	 
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+MODULE_PARM(vesa, "i");
+MODULE_PARM_DESC(vesa,
+       "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n"
+         "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n"
+	 "and the driver will only do the video memory management for eg. DRM/DRI;\n"
+	 "0x0103 if sisfb is in the kernel)");
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	 
+MODULE_PARM(vesa, "i");
+MODULE_PARM_DESC(vesa,
+       "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
+         "0x117 (default: 0x0103)");
+#endif	 
 
 MODULE_PARM(rate, "i");
 MODULE_PARM_DESC(rate,
-	"Selects the desired vertical refresh rate for CRT1 (external VGA) in Hz. "
+	"\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
 	"(default: 60)");
 
 MODULE_PARM(crt1off,   "i");
 MODULE_PARM_DESC(crt1off,
-	"If this option is set, the driver will switch off CRT1 (external VGA). "
 	"(Deprecated, please use forcecrt1)");
 
 MODULE_PARM(filter, "i");
 MODULE_PARM_DESC(filter,
-	"Selects TV flicker filter type (only for SiS30x video bridges). "
-	"(Possible values 0-7, default: [no filter])");
+	"\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
+	  "(Possible values 0-7, default: [no filter])");
 
-MODULE_PARM(dstn,   "i"); /* JennyLee 20011211 */
+MODULE_PARM(dstn,   "i");
 MODULE_PARM_DESC(dstn,
-	"Selects DSTN/FSTN display mode for SiS550. This sets CRT2 type to LCD and "
-	"overrides forcecrt2type setting. (1=ON, 0=OFF) (default: 0)");
+	"\nSelects DSTN/FSTN display mode for SiS550. This sets CRT2 type to LCD and\n"
+	  "overrides forcecrt2type setting. (1=ON, 0=OFF) (default: 0)");
 
 MODULE_PARM(queuemode,   "s");
 MODULE_PARM_DESC(queuemode,
-	"Selects the queue mode on 315/550/650/740. Possible choices are AGP, VRAM "
-	"or MMIO. AGP is only available if the kernel has AGP support. "
-	"The queue mode is important to programs using the 2D/3D accelerator of "
-	"the SiS chip. The modes require a totally different way of programming "
-	"the engines. On 300/540/630/730, this option is ignored. (default: MMIO)");
+	"\nSelects the queue mode on 315/550/650/740/330. Possible choices are AGP, VRAM or\n"
+  	  "MMIO. AGP is only available if the kernel has AGP support. The queue mode is\n"
+	  "important to programs using the 2D/3D accelerator of the SiS chip. The modes\n"
+	  "require a totally different way of programming the engines. If any mode than\n"
+	  "MMIO is selected, sisfb will disable its own 2D acceleration. On\n"
+	  "300/540/630/730, this option is ignored. (default: MMIO)");
 
 /* TW: "Import" the options from the X driver */
 MODULE_PARM(mem,    "i");
 MODULE_PARM_DESC(mem,
-	"Determines the beginning of the video memory heap in KB. This heap is used for "
-	"video RAM management for eg. DRM/DRI. The default depends on the amount of video "
-	"memory available. If 8MB of video RAM or less is available, "
-	"the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB, otherwise at 12288MB."
-	"The value is to be specified without 'KB' and should match MaxXFBMem setting for "
-	"XFree 4.x (x>=2). See http://www.winischhofer.net/linuxsis630.shtml for a closer description.");
+	"\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
+	  "for video RAM management for eg. DRM/DRI. The default depends on the amount\n"
+	  "of video RAM available. If 8MB of video RAM or less is available, the heap\n"
+	  "starts at 4096KB, if between 8 and 16MB are available at 8192KB, otherwise\n"
+	  "at 12288KB. The value is to be specified without 'KB' and should match\n"
+	  "the MaxXFBMem setting for XFree 4.x (x>=2).");
 
 MODULE_PARM(forcecrt2type, "s");
 MODULE_PARM_DESC(forcecrt2type,
-	"If this option is omitted, the driver autodetects CRT2 output devices, such as LCD, "
-	"TV or secondary VGA (in this order; so if eg. an LCD is there, it will be used regardless "
-	"of a connected TV set). With this option, this autodetection can be overridden. "
-	"Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2 and makes it "
-	"possible to use higher resolutions on CRT1 than eg. your LCD panel supports. TV "
-	"selects TV output (only resolutions 640x480 and 800x600 are supported for TV!). "
-	"VGA refers to _secondary_ VGA which is unlikely to be available; the VGA plug found "
-	"on most machines is CRT1. (default: [autodetected])");
+	"\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
+	  "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
+	  "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
+	  "On systems with a 301(B/LV) bridge, parameters SVIDEO, COMPOSITE or SCART can be\n"
+	  "used instead of TV to override the TV detection. (default: [autodetected])");
 
 MODULE_PARM(forcecrt1, "i");
 MODULE_PARM_DESC(forcecrt1,
-	"Normally, the driver autodetects whether or not CRT1 (external VGA) is connected. "
-	"With this option, the detection can be overridden (1=CRT1 ON, 0=CRT1 off) "
-	"(default: [autodetected])");
+	"\nNormally, the driver autodetects whether or not CRT1 (external VGA) is \n"
+	  "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
+	  " 0=CRT1 off) (default: [autodetected])");
 
 MODULE_PARM(pdc, "i");
 MODULE_PARM_DESC(pdc,
-        "(300 series only) This is for manually selecting the LCD panel delay compensation. The "
-	"driver should detect this correctly in most cases; however, sometimes this is not possible. If "
-	"you see 'small waves' on the LCD, try setting this to 4, 32 or 24. If the problem persists, "
-	"try other values between 4 and 60 in steps of 4. "
-	"(default: [autodetected])");
-
+        "\n(300 series only) This is for manually selecting the LCD panel delay\n"
+	  "compensation. The driver should detect this correctly in most cases; however,\n"
+	  "sometimes this is not possible. If you see 'small waves' on the LCD, try\n"
+	  "setting this to 4, 32 or 24. If the problem persists, try other values\n"
+	  "between 4 and 60 in steps of 4. (default: [autodetected])");
+
+MODULE_PARM(noaccel, "i");
+MODULE_PARM_DESC(noaccel,
+        "\nIf set to anything other than 0, 2D acceleration and y-panning will be\n"
+	"disabled. (default: 0)");
+
+MODULE_PARM(noypan, "i");
+MODULE_PARM_DESC(noypan,
+        "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
+	"will be performed by redrawing the screen. This required 2D acceleration, so\n"
+	"if the option noaccel is set, y-panning will be disabled. (default: 0)");
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+MODULE_PARM(inverse, "i");
+MODULE_PARM_DESC(inverse,
+        "\nSetting this to anything but 0 should invert the display colors, but this\n"
+	"does not seem to work. (default: 0)");
+#endif	
+
+MODULE_PARM(userom, "i");
+MODULE_PARM_DESC(userom,
+        "\nSetting this to 0 keeps sisfb from using the video BIOS data which is needed\n"
+	"for some LCD and TV setup. (default: 1)");
+
+MODULE_PARM(useoem, "i");
+MODULE_PARM_DESC(useoem,
+        "\nSetting this to 0 keeps sisfb from using its internel OEM data for some LCD\n"
+	"panels and TV connector types. (default: auto)");
+
+MODULE_PARM(tvstandard, "s");
+MODULE_PARM_DESC(tvstandard,
+	"\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
+	"pal and ntsc. (default: auto)");
 
 int init_module(void)
 {
-	if (mode)
+	int err;
+	
+	if(mode)
 		sisfb_search_mode(mode);
-	else  /* TW: set mode=none if no mode parameter is given */
+	else if(vesa != -1)
+		sisfb_search_vesamode(vesa);
+	else  
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+		/* For 2.4, set mode=none if no mode is given  */
 		sisfb_mode_idx = MODE_INDEX_NONE;
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+		/* For 2.5, we don't need this "mode=none" stuff anymore */	
+		sisfb_mode_idx = DEFAULT_MODE;
+#endif
 
 	ivideo.refresh_rate = rate;
 
-	if (forcecrt2type)
+	if(forcecrt2type)
 		sisfb_search_crt2type(forcecrt2type);
 
-	if (crt1off == 0)
+	if(tvstandard)
+		sisfb_search_tvstd(tvstandard);
+
+	if(crt1off == 0)
 		sisfb_crt1off = 1;
 	else
 		sisfb_crt1off = 0;
 
 	sisfb_forcecrt1 = forcecrt1;
-	if (forcecrt1 == 1)
+	if(forcecrt1 == 1)
 		sisfb_crt1off = 0;
-	else if (forcecrt1 == 0)
+	else if(forcecrt1 == 0)
 		sisfb_crt1off = 1;
 
-	if (mem)
-		sisfb_mem = mem;
+	if(noaccel == 1)      sisfb_accel = 0;
+	else if(noaccel == 0) sisfb_accel = 1;
+
+	if(noypan == 1)       sisfb_ypan = 0;
+	else if(noypan == 0)  sisfb_ypan = 1;
+
+	/* TW: Panning only with acceleration */
+	if(sisfb_accel == 0)  sisfb_ypan = 0;
+	
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	if(inverse)           sisfb_inverse = 1;
+#endif
+
+	if(mem)		      sisfb_mem = mem;
+
+	sisfb_userom = userom;
+
+	sisfb_useoem = useoem;
+
+	enable_dstn = dstn;
 
-	enable_dstn = dstn; /* JennyLee 20011211 */
 	/* TW: DSTN overrules forcecrt2type */
-	if (enable_dstn) sisfb_crt2type = DISPTYPE_LCD;
+	if (enable_dstn)      sisfb_crt2type = DISPTYPE_LCD;
 
-	if (queuemode)
-		sisfb_search_queuemode(queuemode);
+	if (queuemode)        sisfb_search_queuemode(queuemode);
+	
+	/* TW: If other queuemode than MMIO, disable 2D accel and ypan */
+	if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
+	        sisfb_accel = 0;
+		sisfb_ypan = 0;
+	}
 
         if(pdc) {
 	   if(!(pdc & ~0x3c)) {
@@ -3525,7 +4802,7 @@
 	   }
 	}
 
-	sisfb_init();
+	if((err = sisfb_init()) < 0) return err;
 
 	return 0;
 }
@@ -3535,12 +4812,26 @@
 	/* TW: Release mem regions */
 	release_mem_region(ivideo.video_base, ivideo.video_size);
 	release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
+	
+#ifdef CONFIG_MTRR
 	/* TW: Release MTRR region */
-	if (ivideo.mtrr) mtrr_del(ivideo.mtrr, 
-			      (unsigned int)ivideo.video_base,
-	                      (unsigned int)ivideo.video_size);
+	if(ivideo.mtrr) {
+		mtrr_del(ivideo.mtrr,
+		      (unsigned int)ivideo.video_base,
+	              (unsigned int)ivideo.video_size);
+	}
+#endif
+
 	/* Unregister the framebuffer */
-	unregister_framebuffer(&fb_info);
+	if(sisfb_registered) {
+		unregister_framebuffer(&sis_fb_info);
+	}
+	
+	if(sishw_ext.pSR) vfree(sishw_ext.pSR);
+	if(sishw_ext.pCR) vfree(sishw_ext.pCR);
+	
+	/* TODO: Restore the initial mode */
+	
 	printk(KERN_INFO "sisfb: Module unloaded\n");
 }
 
diff -Nru a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h
--- a/drivers/video/sis/sis_main.h	Thu Jul 11 10:30:30 2002
+++ b/drivers/video/sis/sis_main.h	Fri Mar  7 11:19:02 2003
@@ -1,17 +1,23 @@
 #ifndef _SISFB_MAIN
 #define _SISFB_MAIN
 
-/* Comments and changes marked with "TW" by Thomas Winischhofer <tw@webit.com> */
+/* Comments and changes marked with "TW" by Thomas Winischhofer <thomas@winischhofer.net> */
+
+#include "vstruct.h"
 
 /* ------------------- Constant Definitions ------------------------- */
 
-#undef LINUXBIOS   /* turn on when use LINUXBIOS */
+#undef LINUXBIOS   /* turn this on when compiling for LINUXBIOS */
 #define AGPOFF     /* default is turn off AGP */
 
+#define SISFAIL(x) do { printk(x "\n"); return -EINVAL; } while(0)
+
 #define VER_MAJOR                 1
-#define VER_MINOR                 4
+#define VER_MINOR                 6
 #define VER_LEVEL                 1
 
+#include "sis.h"
+
 /* TW: To be included in pci_ids.h */
 #ifndef PCI_DEVICE_ID_SI_650_VGA
 #define PCI_DEVICE_ID_SI_650_VGA  0x6325
@@ -19,14 +25,28 @@
 #ifndef PCI_DEVICE_ID_SI_650
 #define PCI_DEVICE_ID_SI_650      0x0650
 #endif
-/* TW end */
+#ifndef PCI_DEVICE_ID_SI_740
+#define PCI_DEVICE_ID_SI_740      0x0740
+#endif
+#ifndef PCI_DEVICE_ID_SI_330
+#define PCI_DEVICE_ID_SI_330      0x0330
+#endif
+
+/* To be included in fb.h */
+#ifndef FB_ACCEL_SIS_GLAMOUR_2
+#define FB_ACCEL_SIS_GLAMOUR_2  40	/* SiS 315, 650, 740		*/
+#endif
+#ifndef FB_ACCEL_SIS_XABRE
+#define FB_ACCEL_SIS_XABRE      41	/* SiS 330 ("Xabre")		*/
+#endif
 
 #define MAX_ROM_SCAN              0x10000
 
-#define TURBO_QUEUE_CAP           0x80
-#define HW_CURSOR_CAP             0x40
-#define AGP_CMD_QUEUE_CAP         0x80
-#define VM_CMD_QUEUE_CAP          0x20
+#define HW_CURSOR_CAP             0x80
+#define TURBO_QUEUE_CAP           0x40
+#define AGP_CMD_QUEUE_CAP         0x20
+#define VM_CMD_QUEUE_CAP          0x10
+#define MMIO_CMD_QUEUE_CAP        0x08
 
 /* For 300 series */
 #ifdef CONFIG_FB_SIS_300
@@ -63,6 +83,20 @@
 #define VB_PART4_ADR              (0x14-0x30)
 #define VB_PART4_DATA             (0x15-0x30)
 
+#define SISSR			  SiS_Pr.SiS_P3c4
+#define SISCR                     SiS_Pr.SiS_P3d4
+#define SISDACA                   SiS_Pr.SiS_P3c8
+#define SISDACD                   SiS_Pr.SiS_P3c9
+#define SISPART1                  SiS_Pr.SiS_Part1Port
+#define SISPART2                  SiS_Pr.SiS_Part2Port
+#define SISPART3                  SiS_Pr.SiS_Part3Port
+#define SISPART4                  SiS_Pr.SiS_Part4Port
+#define SISPART5                  SiS_Pr.SiS_Part5Port
+#define SISDAC2A                  SISPART5
+#define SISDAC2D                  (SISPART5 + 1)
+#define SISMISCR                  (SiS_Pr.RelIO + 0x1c)
+#define SISINPSTAT		  (SiS_Pr.RelIO + 0x2a)  
+
 #define IND_SIS_PASSWORD          0x05  /* SRs */
 #define IND_SIS_COLOR_MODE        0x06
 #define IND_SIS_RAMDAC_CONTROL    0x07
@@ -93,10 +127,8 @@
 #define MMIO_QUEUE_WRITEPORT      0x85C4
 #define MMIO_QUEUE_READPORT       0x85C8
 
-/* Eden Chen; TW */
 #define IND_SIS_CRT2_WRITE_ENABLE_300 0x24
 #define IND_SIS_CRT2_WRITE_ENABLE_315 0x2F
-/* ~Eden Chen; TW */
 
 #define SIS_PASSWORD              0x86  /* SR05 */
 #define SIS_INTERLACED_MODE       0x20  /* SR06 */
@@ -104,7 +136,7 @@
 #define SIS_15BPP_COLOR_MODE      0x1 
 #define SIS_16BPP_COLOR_MODE      0x2 
 #define SIS_32BPP_COLOR_MODE      0x4 
-#define SIS_DRAM_SIZE_MASK        0x3F  /* SR14 */
+#define SIS_DRAM_SIZE_MASK        0x3F  /* 300/630/730 SR14 */
 #define SIS_DRAM_SIZE_1MB         0x00
 #define SIS_DRAM_SIZE_2MB         0x01
 #define SIS_DRAM_SIZE_4MB         0x03
@@ -204,23 +236,55 @@
 #define BRI_DRAM_SIZE_32MB        0x04
 #define BRI_DRAM_SIZE_64MB        0x05
 
-// Eden Chen
 #define HW_DEVICE_EXTENSION	  SIS_HW_DEVICE_INFO
 #define PHW_DEVICE_EXTENSION      PSIS_HW_DEVICE_INFO
 
 #define SR_BUFFER_SIZE            5
 #define CR_BUFFER_SIZE            5
-// ~Eden Chen
+
+/* Useful macros */
+#define inSISREG(base)          inb(base)
+#define outSISREG(base,val)     outb(val,base)
+#define orSISREG(base,val)      do { \
+                                  unsigned char __Temp = inb(base); \
+                                  outSISREG(base, __Temp | (val)); \
+                                } while (0)
+#define andSISREG(base,val)     do { \
+                                  unsigned char __Temp = inb(base); \
+                                  outSISREG(base, __Temp & (val)); \
+                                } while (0)
+#define inSISIDXREG(base,idx,var)   do { \
+                                      outb(idx,base); var=inb((base)+1); \
+                                    } while (0)
+#define outSISIDXREG(base,idx,val)  do { \
+                                      outb(idx,base); outb((val),(base)+1); \
+                                    } while (0)
+#define orSISIDXREG(base,idx,val)   do { \
+                                      unsigned char __Temp; \
+                                      outb(idx,base);   \
+                                      __Temp = inb((base)+1)|(val); \
+                                      outSISIDXREG(base,idx,__Temp); \
+                                    } while (0)
+#define andSISIDXREG(base,idx,and)  do { \
+                                      unsigned char __Temp; \
+                                      outb(idx,base);   \
+                                      __Temp = inb((base)+1)&(and); \
+                                      outSISIDXREG(base,idx,__Temp); \
+                                    } while (0)
+#define setSISIDXREG(base,idx,and,or)   do { \
+                                          unsigned char __Temp; \
+                                          outb(idx,base);   \
+                                          __Temp = (inb((base)+1)&(and))|(or); \
+                                          outSISIDXREG(base,idx,__Temp); \
+                                        } while (0)
 
 /* ------------------- Global Variables ----------------------------- */
 
 /* Fbcon variables */
-static struct fb_info fb_info;
-static struct display disp;
-static int video_type = FB_TYPE_PACKED_PIXELS;
-static int video_linelength;
-static int video_cmap_len;
-static struct display_switch sisfb_sw;
+static struct fb_info sis_fb_info;
+
+static int    video_type = FB_TYPE_PACKED_PIXELS;
+
 static struct fb_var_screeninfo default_var = {
 	xres:           0,
 	yres:           0,
@@ -248,51 +312,79 @@
 	vsync_len:      0,
 	sync:           0,
 	vmode:          FB_VMODE_NONINTERLACED,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
 	reserved:       {0, 0, 0, 0, 0, 0}
+#endif	
 };
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+static struct fb_fix_screeninfo sisfb_fix = {
+	id:		"SiS",
+	type:		FB_TYPE_PACKED_PIXELS,
+	xpanstep:	1,
+	ypanstep:	1,
+};
+static char myid[20];
+static u32 pseudo_palette[17];
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+static struct display sis_disp;
+
+static struct display_switch sisfb_sw;	
+
 static struct {
 	u16 blue, green, red, pad;
-} palette[256];
+} sis_palette[256];
+
 static union {
 #ifdef FBCON_HAS_CFB16
 	u16 cfb16[16];
 #endif
-#ifdef FBCON_HAS_CFB24
-	u32 cfb24[16];
-#endif
 #ifdef FBCON_HAS_CFB32
 	u32 cfb32[16];
 #endif
-} fbcon_cmap;
+} sis_fbcon_cmap;
+
+static int sisfb_inverse = 0;
+#endif
 
 /* display status */
 static int sisfb_off = 0;
 static int sisfb_crt1off = 0;
 static int sisfb_forcecrt1 = -1;
-static int sisfb_inverse = 0;
 static int sisvga_enabled = 0;
+static int sisfb_userom = 1;
+static int sisfb_useoem = -1;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 static int currcon = 0;
+#endif
+
+/* global flags */
+static int sisfb_registered;
 static int sisfb_tvmode = 0;
 static int sisfb_mem = 0;
 static int sisfb_pdc = 0;
 static int enable_dstn = 0;
+static int sisfb_ypan = -1;
 
-static enum _VGA_ENGINE {
-	UNKNOWN_VGA = 0,
-	SIS_300_VGA,
-	SIS_315_VGA,
-} sisvga_engine = UNKNOWN_VGA;
+VGA_ENGINE sisvga_engine = UNKNOWN_VGA;
+int 	   sisfb_accel = -1;
 
 /* TW: These are to adapted according to VGA_ENGINE type */
 static int sisfb_hwcursor_size = 0;
 static int sisfb_CRT2_write_enable = 0;
 
-int sisfb_crt2type = -1;	/* TW: CRT2 type (for overriding autodetection) */
+int sisfb_crt2type  = -1;	/* TW: CRT2 type (for overriding autodetection) */
+int sisfb_tvplug    = -1;	/* PR: Tv plug type (for overriding autodetection) */
+
+int sisfb_queuemode = -1; 	/* TW: Use MMIO queue mode by default (310/325 series only) */
 
-int sisfb_queuemode = -1; 	/* TW: Use MMIO queue mode by default (310 series only) */
+unsigned char sisfb_detectedpdc = 0;
 
-/* data for sis components*/
+unsigned char sisfb_detectedlcda = 0xff;
+
+/* data for sis components */
 struct video_info ivideo;
 
 /* TW: For ioctl SISFB_GET_INFO */
@@ -300,16 +392,19 @@
 
 /* TW: Hardware extension; contains data on hardware */
 HW_DEVICE_EXTENSION sishw_ext = {
-	NULL, NULL, NULL, NULL,
+	NULL, NULL, FALSE, NULL, NULL,
 	0, 0, 0, 0, 0, 0, 0, 0, 0,
 	NULL, NULL, NULL, NULL,
 	{0, 0, 0, 0},
 	0
 };
 
+/* TW: SiS private structure */
+SiS_Private  SiS_Pr;
+
 /* card parameters */
 static unsigned long sisfb_mmio_size = 0;
-static u8 sisfb_caps = 0;
+static u8            sisfb_caps = 0;
 
 typedef enum _SIS_CMDTYPE {
 	MMIO_CMD = 0,
@@ -323,138 +418,157 @@
 	const char *name;
 } sisdev_list[] = {
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300,     "SIS 300"},
-	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, "SIS 540"},
-	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, "SIS 630/730"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, "SIS 540 VGA"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, "SIS 630/730 VGA"},
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315H,    "SIS 315H"},
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315,     "SIS 315"},
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315PRO,  "SIS 315PRO"},
-	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, "SIS 550"},
-	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 650/M650/740 VGA"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, "SIS 550 VGA"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 650/M650/651/740 VGA"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330,     "SIS 330"},
 	{0, 0, NULL}
 };
 
+#define MD_SIS300 1
+#define MD_SIS315 2
+
 /* mode table */
+/* NOT const - will be patched for 1280x960 mode number chaos reasons */
 struct _sisbios_mode {
 	char name[15];
 	u8 mode_no;
+	u16 vesa_mode_no_1;  /* "SiS defined" VESA mode number */
+	u16 vesa_mode_no_2;  /* Real VESA mode numbers */
 	u16 xres;
 	u16 yres;
 	u16 bpp;
 	u16 rate_idx;
 	u16 cols;
 	u16 rows;
+	u8  chipset;
 } sisbios_mode[] = {
 #define MODE_INDEX_NONE           0  /* TW: index for mode=none */
-	{"none",         0xFF,    0,    0,  0, 0,   0,  0},  /* TW: for mode "none" */
-	{"320x240x16",   0x56,  320,  240, 16, 1,  40, 15},
-	{"320x480x8",    0x5A,  320,  480,  8, 1,  40, 30},  /* TW: FSTN */
-	{"320x480x16",   0x5B,  320,  480, 16, 1,  40, 30},  /* TW: FSTN */
-	{"640x480x8",    0x2E,  640,  480,  8, 1,  80, 30},
-	{"640x480x16",   0x44,  640,  480, 16, 1,  80, 30},
-	{"640x480x24",   0x62,  640,  480, 32, 1,  80, 30},  /* TW: That's for people who mix up color- and fb depth */
-	{"640x480x32",   0x62,  640,  480, 32, 1,  80, 30},
-	{"720x480x8",    0x31,  720,  480,  8, 1,  90, 30},
-	{"720x480x16",   0x33,  720,  480, 16, 1,  90, 30},
-	{"720x480x24",   0x35,  720,  480, 32, 1,  90, 30},
-	{"720x480x32",   0x35,  720,  480, 32, 1,  90, 30},
-	{"720x576x8",    0x32,  720,  576,  8, 1,  90, 36},
-	{"720x576x16",   0x34,  720,  576, 16, 1,  90, 36},
-	{"720x576x24",   0x36,  720,  576, 32, 1,  90, 36},
-	{"720x576x32",   0x36,  720,  576, 32, 1,  90, 36},
-	{"800x480x8",    0x70,  800,  480,  8, 1, 100, 30},  /* TW: 310/325 series only */
-	{"800x480x16",   0x7a,  800,  480, 16, 1, 100, 30},
-	{"800x480x24",   0x76,  800,  480, 32, 1, 100, 30},
-	{"800x480x32",   0x76,  800,  480, 32, 1, 100, 30},
+	{"none",         0xFF, 0x0000, 0x0000,    0,    0,  0, 0,   0,  0, MD_SIS300|MD_SIS315},  /* TW: for mode "none" */
+	{"320x240x16",   0x56, 0x0000, 0x0000,  320,  240, 16, 1,  40, 15,           MD_SIS315},
+	{"320x480x8",    0x5A, 0x0000, 0x0000,  320,  480,  8, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
+	{"320x480x16",   0x5B, 0x0000, 0x0000,  320,  480, 16, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
+	{"640x480x8",    0x2E, 0x0101, 0x0101,  640,  480,  8, 1,  80, 30, MD_SIS300|MD_SIS315},
+	{"640x480x16",   0x44, 0x0111, 0x0111,  640,  480, 16, 1,  80, 30, MD_SIS300|MD_SIS315},
+	{"640x480x24",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},  /* TW: That's for people who mix up color- and fb depth */
+	{"640x480x32",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},
+	{"720x480x8",    0x31, 0x0000, 0x0000,  720,  480,  8, 1,  90, 30, MD_SIS300|MD_SIS315},
+	{"720x480x16",   0x33, 0x0000, 0x0000,  720,  480, 16, 1,  90, 30, MD_SIS300|MD_SIS315},
+	{"720x480x24",   0x35, 0x0000, 0x0000,  720,  480, 32, 1,  90, 30, MD_SIS300|MD_SIS315},
+	{"720x480x32",   0x35, 0x0000, 0x0000,  720,  480, 32, 1,  90, 30, MD_SIS300|MD_SIS315},
+	{"720x576x8",    0x32, 0x0000, 0x0000,  720,  576,  8, 1,  90, 36, MD_SIS300|MD_SIS315},
+	{"720x576x16",   0x34, 0x0000, 0x0000,  720,  576, 16, 1,  90, 36, MD_SIS300|MD_SIS315},
+	{"720x576x24",   0x36, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36, MD_SIS300|MD_SIS315},
+	{"720x576x32",   0x36, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36, MD_SIS300|MD_SIS315},
+	{"800x480x8",    0x70, 0x0000, 0x0000,  800,  480,  8, 1, 100, 30, MD_SIS300|MD_SIS315},
+	{"800x480x16",   0x7a, 0x0000, 0x0000,  800,  480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
+	{"800x480x24",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
+	{"800x480x32",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
 #define DEFAULT_MODE              20 /* TW: index for 800x600x8 */
 #define DEFAULT_LCDMODE           20 /* TW: index for 800x600x8 */
 #define DEFAULT_TVMODE            20 /* TW: index for 800x600x8 */
-	{"800x600x8",    0x30,  800,  600,  8, 2, 100, 37},
-	{"800x600x16",   0x47,  800,  600, 16, 2, 100, 37},
-	{"800x600x24",   0x63,  800,  600, 32, 2, 100, 37},
-	{"800x600x32",   0x63,  800,  600, 32, 2, 100, 37},
-	{"1024x576x8",   0x71, 1024,  576,  8, 1, 128, 36},  /* TW: 310/325 series only */
-	{"1024x576x16",  0x74, 1024,  576, 16, 1, 128, 36},
-	{"1024x576x24",  0x77, 1024,  576, 32, 1, 128, 36},
-	{"1024x576x32",  0x77, 1024,  576, 32, 1, 128, 36},
-	{"1024x600x8",   0x20, 1024,  600,  8, 1, 128, 37},  /* TW: 300 series only */
-	{"1024x600x16",  0x21, 1024,  600, 16, 1, 128, 37},
-	{"1024x600x24",  0x22, 1024,  600, 32, 1, 128, 37},
-	{"1024x600x32",  0x22, 1024,  600, 32, 1, 128, 37},
-	{"1024x768x8",   0x38, 1024,  768,  8, 2, 128, 48},
-	{"1024x768x16",  0x4A, 1024,  768, 16, 2, 128, 48},
-	{"1024x768x24",  0x64, 1024,  768, 32, 2, 128, 48},
-	{"1024x768x32",  0x64, 1024,  768, 32, 2, 128, 48},
-	{"1152x768x8",   0x23, 1152,  768,  8, 1, 144, 48},  /* TW: 300 series only */
-	{"1152x768x16",  0x24, 1152,  768, 16, 1, 144, 48},
-	{"1152x768x24",  0x25, 1152,  768, 32, 1, 144, 48},
-	{"1152x768x32",  0x25, 1152,  768, 32, 1, 144, 48},
-	{"1280x720x8",   0x79, 1280,  720,  8, 1, 160, 45},  /* TW: 310/325 series only */
-	{"1280x720x16",  0x75, 1280,  720, 16, 1, 160, 45},
-	{"1280x720x24",  0x78, 1280,  720, 32, 1, 160, 45},
-	{"1280x720x32",  0x78, 1280,  720, 32, 1, 160, 45},
-	{"1280x768x8",   0x23, 1280,  768,  8, 1, 160, 48},  /* TW: 3107325 series only */
-	{"1280x768x16",  0x24, 1280,  768, 16, 1, 160, 48},
-	{"1280x768x24",  0x25, 1280,  768, 32, 1, 160, 48},
-	{"1280x768x32",  0x25, 1280,  768, 32, 1, 160, 48},
+	{"800x600x8",    0x30, 0x0103, 0x0103,  800,  600,  8, 2, 100, 37, MD_SIS300|MD_SIS315},
+	{"800x600x16",   0x47, 0x0114, 0x0114,  800,  600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
+	{"800x600x24",   0x63, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
+	{"800x600x32",   0x63, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
+	{"1024x576x8",   0x71, 0x0000, 0x0000, 1024,  576,  8, 1, 128, 36, MD_SIS300|MD_SIS315},
+	{"1024x576x16",  0x74, 0x0000, 0x0000, 1024,  576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
+	{"1024x576x24",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
+	{"1024x576x32",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
+	{"1024x600x8",   0x20, 0x0000, 0x0000, 1024,  600,  8, 1, 128, 37, MD_SIS300          },  /* TW: 300 series only */
+	{"1024x600x16",  0x21, 0x0000, 0x0000, 1024,  600, 16, 1, 128, 37, MD_SIS300          },
+	{"1024x600x24",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
+	{"1024x600x32",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
+	{"1024x768x8",   0x38, 0x0105, 0x0105, 1024,  768,  8, 2, 128, 48, MD_SIS300|MD_SIS315},
+	{"1024x768x16",  0x4A, 0x0117, 0x0117, 1024,  768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
+	{"1024x768x24",  0x64, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
+	{"1024x768x32",  0x64, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
+	{"1152x768x8",   0x23, 0x0000, 0x0000, 1152,  768,  8, 1, 144, 48, MD_SIS300          },  /* TW: 300 series only */
+	{"1152x768x16",  0x24, 0x0000, 0x0000, 1152,  768, 16, 1, 144, 48, MD_SIS300          },
+	{"1152x768x24",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
+	{"1152x768x32",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
+	{"1280x720x8",   0x79, 0x0000, 0x0000, 1280,  720,  8, 1, 160, 45, MD_SIS300|MD_SIS315},
+	{"1280x720x16",  0x75, 0x0000, 0x0000, 1280,  720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
+	{"1280x720x24",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
+	{"1280x720x32",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
+	{"1280x768x8",   0x23, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48,           MD_SIS315},  /* TW: 310/325 series only */
+	{"1280x768x16",  0x24, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48,           MD_SIS315},
+	{"1280x768x24",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,           MD_SIS315},
+	{"1280x768x32",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,           MD_SIS315},
 #define MODEINDEX_1280x960 48
-	{"1280x960x8",   0x7C, 1280,  960,  8, 1, 160, 60},  /* TW: Modenumbers being patched */
-	{"1280x960x16",  0x7D, 1280,  960, 16, 1, 160, 60},
-	{"1280x960x24",  0x7E, 1280,  960, 32, 1, 160, 60},
-	{"1280x960x32",  0x7E, 1280,  960, 32, 1, 160, 60},
-	{"1280x1024x8",  0x3A, 1280, 1024,  8, 2, 160, 64},
-	{"1280x1024x16", 0x4D, 1280, 1024, 16, 2, 160, 64},
-	{"1280x1024x24", 0x65, 1280, 1024, 32, 2, 160, 64},
-	{"1280x1024x32", 0x65, 1280, 1024, 32, 2, 160, 64},
-	{"1400x1050x8",  0x26, 1400, 1050,  8, 1, 175, 65},  /* TW: 310/325 series only */
-	{"1400x1050x16", 0x27, 1400, 1050, 16, 1, 175, 65},
-	{"1400x1050x24", 0x28, 1400, 1050, 32, 1, 175, 65},
-	{"1400x1050x32", 0x28, 1400, 1050, 32, 1, 175, 65},
-	{"1600x1200x8",  0x3C, 1600, 1200,  8, 1, 200, 75},
-	{"1600x1200x16", 0x3D, 1600, 1200, 16, 1, 200, 75},
-	{"1600x1200x24", 0x66, 1600, 1200, 32, 1, 200, 75},
-	{"1600x1200x32", 0x66, 1600, 1200, 32, 1, 200, 75},
-	{"1920x1440x8",  0x68, 1920, 1440,  8, 1, 240, 75},
-	{"1920x1440x16", 0x69, 1920, 1440, 16, 1, 240, 75},
-	{"1920x1440x24", 0x6B, 1920, 1440, 32, 1, 240, 75},
-	{"1920x1440x32", 0x6B, 1920, 1440, 32, 1, 240, 75},
-	{"2048x1536x8",  0x6c, 2048, 1536,  8, 1, 256, 96},  /* TW: 310/325 series only */
-	{"2048x1536x16", 0x6d, 2048, 1536, 16, 1, 256, 96},
-	{"2048x1536x24", 0x6e, 2048, 1536, 32, 1, 256, 96},
-	{"2048x1536x32", 0x6e, 2048, 1536, 32, 1, 256, 96},
-	{"\0", 0x00, 0, 0, 0, 0, 0, 0}
+	{"1280x960x8",   0x7C, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_SIS300|MD_SIS315},  /* TW: Modenumbers being patched */
+	{"1280x960x16",  0x7D, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
+	{"1280x960x24",  0x7E, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
+	{"1280x960x32",  0x7E, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
+	{"1280x1024x8",  0x3A, 0x0107, 0x0107, 1280, 1024,  8, 2, 160, 64, MD_SIS300|MD_SIS315},
+	{"1280x1024x16", 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
+	{"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
+	{"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
+	{"1400x1050x8",  0x26, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,           MD_SIS315},  /* TW: 310/325 series only */
+	{"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65,           MD_SIS315},
+	{"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
+	{"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
+	{"1600x1200x8",  0x3C, 0x0130, 0x011c, 1600, 1200,  8, 1, 200, 75, MD_SIS300|MD_SIS315},
+	{"1600x1200x16", 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
+	{"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
+	{"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
+	{"1920x1440x8",  0x68, 0x013f, 0x0000, 1920, 1440,  8, 1, 240, 75, MD_SIS300|MD_SIS315},
+	{"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
+	{"1920x1440x24", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+	{"1920x1440x32", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+	{"2048x1536x8",  0x6c, 0x0000, 0x0000, 2048, 1536,  8, 1, 256, 96,           MD_SIS315},  /* TW: 310/325 series only */
+	{"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96,           MD_SIS315},
+	{"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
+	{"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
+	{"\0", 0x00, 0, 0, 0, 0, 0, 0, 0}
 };
 
 /* mode-related variables */
-int sisfb_mode_idx = MODE_INDEX_NONE;
-u8  sisfb_mode_no = 0;
+#ifdef MODULE
+int sisfb_mode_idx = MODE_INDEX_NONE;  /* Don't use a mode by default if we are a module */
+#else
+int sisfb_mode_idx = -1;               /* Use a default mode if we are inside the kernel */
+#endif
+u8  sisfb_mode_no  = 0;
 u8  sisfb_rate_idx = 0;
 
 /* TW: CR36 evaluation */
-USHORT sis300paneltype[] =
+const USHORT sis300paneltype[] =
     { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
       LCD_1280x960,  LCD_640x480,  LCD_1024x600,  LCD_1152x768,
       LCD_320x480,   LCD_1024x768, LCD_1024x768,  LCD_1024x768,
       LCD_1024x768,  LCD_1024x768, LCD_1024x768,  LCD_1024x768 };
 
-USHORT sis310paneltype[] =
+const USHORT sis310paneltype[] =
     { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
       LCD_640x480,   LCD_1024x600, LCD_1152x864,  LCD_1280x960,
       LCD_1152x768,  LCD_1400x1050,LCD_1280x768,  LCD_1600x1200,
       LCD_320x480,   LCD_1024x768, LCD_1024x768,  LCD_1024x768 };
 
 static const struct _sis_crt2type {
-	char name[6];
+	char name[10];
 	int type_no;
+	int tvplug_no;
 } sis_crt2type[] = {
-	{"NONE", 0},
-	{"LCD",  DISPTYPE_LCD},
-	{"TV",   DISPTYPE_TV},
-	{"VGA",  DISPTYPE_CRT2},
-	{"none", 0},	/* TW: make it fool-proof */
-	{"lcd",  DISPTYPE_LCD},
-	{"tv",   DISPTYPE_TV},
-	{"vga",  DISPTYPE_CRT2},
-	{"\0",  -1}
+	{"NONE", 	0, 		-1},
+	{"LCD",  	DISPTYPE_LCD, 	-1},
+	{"TV",   	DISPTYPE_TV, 	-1},
+	{"VGA",  	DISPTYPE_CRT2, 	-1},
+	{"SVIDEO", 	DISPTYPE_TV, 	TVPLUG_SVIDEO},
+	{"COMPOSITE", 	DISPTYPE_TV, 	TVPLUG_COMPOSITE},
+	{"SCART", 	DISPTYPE_TV, 	TVPLUG_SCART},
+	{"none", 	0, 		-1},
+	{"lcd",  	DISPTYPE_LCD, 	-1},
+	{"tv",   	DISPTYPE_TV, 	-1},
+	{"vga",  	DISPTYPE_CRT2, 	-1},
+	{"svideo", 	DISPTYPE_TV, 	TVPLUG_SVIDEO},
+	{"composite", 	DISPTYPE_TV, 	TVPLUG_COMPOSITE},
+	{"scart", 	DISPTYPE_TV, 	TVPLUG_SCART},
+	{"\0",  	-1, 		-1}
 };
 
 /* Queue mode selection for 310 series */
@@ -462,16 +576,28 @@
 	char name[6];
 	int type_no;
 } sis_queuemode[] = {
-	{"AGP",  AGP_CMD_QUEUE},
-	{"VRAM", VM_CMD_QUEUE},
-	{"MMIO", MMIO_CMD},
-	{"agp",  AGP_CMD_QUEUE},
-	{"vram", VM_CMD_QUEUE},
-	{"mmio", MMIO_CMD},
-	{"\0",  -1}
+	{"AGP",  	AGP_CMD_QUEUE},
+	{"VRAM", 	VM_CMD_QUEUE},
+	{"MMIO", 	MMIO_CMD},
+	{"agp",  	AGP_CMD_QUEUE},
+	{"vram", 	VM_CMD_QUEUE},
+	{"mmio", 	MMIO_CMD},
+	{"\0",   	-1}
+};
+
+/* TV standard */
+static const struct _sis_tvtype {
+	char name[6];
+	int type_no;
+} sis_tvtype[] = {
+	{"PAL",  	1},
+	{"NTSC", 	2},
+	{"pal", 	1},
+	{"ntsc",  	2},
+	{"\0",   	-1}
 };
 
-static struct _sis_vrate {
+static const struct _sis_vrate {
 	u16 idx;
 	u16 xres;
 	u16 yres;
@@ -486,25 +612,34 @@
 	{5,  800,  600, 85}, {6,  800,  600, 100}, {7, 800,   600, 120}, {8,  800, 600, 160},
 	{1, 1024,  768, 43}, {2, 1024,  768,  60}, {3, 1024,  768,  70}, {4, 1024, 768,  75},
 	{5, 1024,  768, 85}, {6, 1024,  768, 100}, {7, 1024,  768, 120},
-	{1, 1024,  576, 60}, {2, 1024,  576,  65}, {3, 1024,  576,  75},
+	{1, 1024,  576, 60}, {2, 1024,  576,  75}, {3, 1024,  576,  85},
 	{1, 1024,  600, 60},
 	{1, 1152,  768, 60},
 	{1, 1280,  720, 60}, {2, 1280,  720,  75}, {3, 1280,  720,  85},
 	{1, 1280,  768, 60},
 	{1, 1280, 1024, 43}, {2, 1280, 1024,  60}, {3, 1280, 1024,  75}, {4, 1280, 1024,  85},
-	{1, 1280,  960, 60},
+	{1, 1280,  960, 70},
 	{1, 1400, 1050, 60},
 	{1, 1600, 1200, 60}, {2, 1600, 1200,  65}, {3, 1600, 1200,  70}, {4, 1600, 1200,  75},
 	{5, 1600, 1200, 85}, {6, 1600, 1200, 100}, {7, 1600, 1200, 120},
-	/* TW: Clock values for 1920x1440 guessed (except for the first one) */
-	{1, 1920, 1440, 60}, {2, 1920, 1440,  70}, {3, 1920, 1440,  75}, {4, 1920, 1440,  85},
-	{5, 1920, 1440,100}, {6, 1920, 1440, 120},
-	/* TW: Clock values for 2048x1536 guessed */
-	{1, 2048, 1536, 60}, {2, 2048, 1536,  70}, {3, 2048, 1536,  75}, {4, 2048, 1536,  85},
-	{5, 2048, 1536,100},
+	{1, 1920, 1440, 60}, {2, 1920, 1440,  65}, {3, 1920, 1440,  70}, {4, 1920, 1440,  75},
+	{5, 1920, 1440, 85}, {6, 1920, 1440, 100},
+	{1, 2048, 1536, 60}, {2, 2048, 1536,  65}, {3, 2048, 1536,  70}, {4, 2048, 1536,  75},
+	{5, 2048, 1536, 85},
 	{0, 0, 0, 0}
 };
 
+static const struct _chswtable {
+    int subsysVendor;
+    int subsysCard;
+    char *vendorName;
+    char *cardName;
+} mychswtable[] = {
+        { 0x1631, 0x1002, "Mitachi", "0x1002" },
+	{ 0,      0,      ""       , ""       }
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 /* Offscreen layout */
 typedef struct _SIS_GLYINFO {
 	unsigned char ch;
@@ -513,6 +648,7 @@
 	u8 gmask[72];
 	int ngmask;
 } SIS_GLYINFO;
+#endif
 
 typedef struct _SIS_OH {
 	struct _SIS_OH *poh_next;
@@ -539,10 +675,10 @@
 static unsigned long sisfb_heap_start;
 static unsigned long sisfb_heap_end;
 static unsigned long sisfb_heap_size;
-static SIS_HEAP sisfb_heap;
+static SIS_HEAP      sisfb_heap;
 
 // Eden Chen
-static struct _sis_TV_filter {
+static const struct _sis_TV_filter {
 	u8 filter[9][4];
 } sis_TV_filter[] = {
 	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_0 */
@@ -691,114 +827,176 @@
 	   {0xFF,0xFF,0xFF,0xFF} }}
 };
 
-static int filter = -1;
+static int           filter = -1;
 static unsigned char filter_tb;
 //~Eden Chen
 
-/* ---------------------- Routine Prototype ------------------------- */
+/* ---------------------- Routine prototypes ------------------------- */
 
 /* Interface used by the world */
-int sisfb_setup(char *options);
-static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			 struct fb_info *info);
-static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info);
-static int sisfb_set_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info);
-static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info);
-static int sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info);
-static int sisfb_ioctl(struct inode *inode, struct file *file,
-		       unsigned int cmd, unsigned long arg, int con,
-		       struct fb_info *info);
+#ifndef MODULE
+int             sisfb_setup(char *options);
+#endif
 
 /* Interface to the low level console driver */
-int sisfb_init(void);
-static int sisfb_update_var(int con, struct fb_info *info);
-static int sisfb_switch(int con, struct fb_info *info);
-static void sisfb_blank(int blank, struct fb_info *info);
-
-/* hardware access routines */
-void sisfb_set_reg1(u16 port, u16 index, u16 data);
-void sisfb_set_reg3(u16 port, u16 data);
-void sisfb_set_reg4(u16 port, unsigned long data);
-u8   sisfb_get_reg1(u16 port, u16 index);
-u8   sisfb_get_reg2(u16 port);
-u32  sisfb_get_reg3(u16 port);
-
-/* Internal routines */
-static void sisfb_search_mode(const char *name);
-static void sisfb_validate_mode(void);
-static u8   sisfb_search_refresh_rate(unsigned int rate);
-static int  sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
-			 unsigned *blue, unsigned *transp,
-			 struct fb_info *fb_info);
-static int  sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
-			 unsigned blue, unsigned transp,
-			 struct fb_info *fb_info);
-static int  sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
-		      struct fb_info *info);
-static void sisfb_set_disp(int con, struct fb_var_screeninfo *var);
-static void sisfb_do_install_cmap(int con, struct fb_info *info);
+int             sisfb_init(void);
+
+/* fbdev routines */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+static int      sisfb_get_fix(struct fb_fix_screeninfo *fix, 
+			      int con,
+			      struct fb_info *info);
+static int      sisfb_get_var(struct fb_var_screeninfo *var, 
+			      int con,
+			      struct fb_info *info);
+static int      sisfb_set_var(struct fb_var_screeninfo *var, 
+			      int con,
+			      struct fb_info *info);
+static void     sisfb_crtc_to_var(struct fb_var_screeninfo *var);			      
+static int      sisfb_get_cmap(struct fb_cmap *cmap, 
+			       int kspc, 
+			       int con,
+			       struct fb_info *info);
+static int      sisfb_set_cmap(struct fb_cmap *cmap, 
+			       int kspc, 
+			       int con,
+			       struct fb_info *info);			
+static int      sisfb_update_var(int con, 
+				 struct fb_info *info);
+static int      sisfb_switch(int con, 
+			     struct fb_info *info);
+static void     sisfb_blank(int blank, 
+			    struct fb_info *info);
+static void     sisfb_set_disp(int con, 
+			       struct fb_var_screeninfo *var, 
+                               struct fb_info *info);
+static int      sis_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			      unsigned *blue, unsigned *transp,
+			      struct fb_info *fb_info);
+static void     sisfb_do_install_cmap(int con, 
+                                      struct fb_info *info);
+static void     sis_get_glyph(struct fb_info *info, 
+                              SIS_GLYINFO *gly);
+static int 	sisfb_mmap(struct fb_info *info, struct file *file,
+		           struct vm_area_struct *vma);	
+static int      sisfb_ioctl(struct inode *inode, struct file *file,
+		       	    unsigned int cmd, unsigned long arg, int con,
+		       	    struct fb_info *info);		      
+#endif			
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+static int      sisfb_set_par(struct fb_info *info);
+static int      sisfb_blank(int blank, 
+                            struct fb_info *info);			
+static int 	sisfb_mmap(struct fb_info *info, struct file *file,
+		           struct vm_area_struct *vma);			    
+extern void     fbcon_sis_fillrect(struct fb_info *info, 
+                                   const struct fb_fillrect *rect);
+extern void     fbcon_sis_copyarea(struct fb_info *info, 
+                                   const struct fb_copyarea *area);
+#if 0				   
+extern void     cfb_imageblit(struct fb_info *info, 
+                              const struct fb_image *image);
+#endif			      
+extern int      fbcon_sis_sync(struct fb_info *info);
+static int      sisfb_ioctl(struct inode *inode, 
+	 		    struct file *file,
+		       	    unsigned int cmd, 
+			    unsigned long arg, 
+		       	    struct fb_info *info);
+extern int	sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, 
+			      PSIS_HW_DEVICE_INFO HwDeviceExtension,
+			      unsigned char modeno, unsigned char rateindex);	
+extern int      sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+			 unsigned char modeno, unsigned char rateindex,
+			 unsigned int *left_margin, unsigned int *right_margin, 
+			 unsigned int *upper_margin, unsigned int *lower_margin,
+			 unsigned int *hsync_len, unsigned int *vsync_len,
+			 unsigned int *sync, unsigned int *vmode);			      		    			      
+#endif
+			
+static int      sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+			      struct fb_info *info);
+
+/* Internal 2D accelerator functions */
+extern int      sisfb_initaccel(void);
+extern void     sisfb_syncaccel(void);
+
+/* Internal general routines */
+static void     sisfb_search_mode(const char *name);
+static int      sisfb_validate_mode(int modeindex);
+static u8       sisfb_search_refresh_rate(unsigned int rate);
+static int      sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			unsigned blue, unsigned transp,
+			struct fb_info *fb_info);
+static int      sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
+		      	struct fb_info *info);
+static void     sisfb_pre_setmode(void);
+static void     sisfb_post_setmode(void);
+
+static char *   sis_find_rom(void);
+static BOOLEAN  sisfb_CheckVBRetrace(void);
+static BOOLEAN  sisfbcheckvretracecrt2(void);
+static BOOLEAN  sisfbcheckvretracecrt1(void);
+static BOOLEAN  sisfb_bridgeisslave(void);
+
+/* SiS-specific Export functions */
+void            sis_dispinfo(struct ap_data *rec);
+void            sis_malloc(struct sis_memreq *req);
+void            sis_free(unsigned long base);
+
+/* Internal hardware access routines */
+void            sisfb_set_reg4(u16 port, unsigned long data);
+u32             sisfb_get_reg3(u16 port);
 
-/* Chip-dependent Routines */
+/* Chipset-dependent internal routines */
 #ifdef CONFIG_FB_SIS_300
-static int sisfb_get_dram_size_300(void);
-static void sisfb_detect_VB_connect_300(void);
-static void sisfb_get_VB_type_300(void);
-static int sisfb_has_VB_300(void);
+static int      sisfb_get_dram_size_300(void);
+static void     sisfb_detect_VB_connect_300(void);
+static void     sisfb_get_VB_type_300(void);
+static int      sisfb_has_VB_300(void);
 #endif
 #ifdef CONFIG_FB_SIS_315
-static int sisfb_get_dram_size_315(void);
-static void sisfb_detect_VB_connect_315(void);
-static void sisfb_get_VB_type_315(void);
-static int sisfb_has_VB_315(void);
+static int      sisfb_get_dram_size_315(void);
+static void     sisfb_detect_VB_connect_315(void);
+static void     sisfb_get_VB_type_315(void);
+static int      sisfb_has_VB_315(void);
 #endif
 
-/* Routines from init.c/init301.c */
+/* Internal heap routines */
+static int      sisfb_heap_init(void);
+static SIS_OH   *sisfb_poh_new_node(void);
+static SIS_OH   *sisfb_poh_allocate(unsigned long size);
+static void     sisfb_delete_node(SIS_OH *poh);
+static void     sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh);
+static SIS_OH   *sisfb_poh_free(unsigned long base);
+static void     sisfb_free_node(SIS_OH *poh);
+
+/* Internal routines to access PCI configuration space */
+BOOLEAN         sisfb_query_VGA_config_space(PSIS_HW_DEVICE_INFO psishw_ext,
+	          	unsigned long offset, unsigned long set, unsigned long *value);
+BOOLEAN         sisfb_query_north_bridge_space(PSIS_HW_DEVICE_INFO psishw_ext,
+	         	unsigned long offset, unsigned long set, unsigned long *value);
 
-extern void 	SiSRegInit(USHORT BaseAddr);
-extern BOOLEAN  SiSInit(PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN  SiSSetMode(PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo);
-extern void     SetEnableDstn(void);
 
-/* TW: Chrontel TV functions */
-extern USHORT   SiS_IF_DEF_CH70xx;
-extern USHORT 	SiS_GetCH700x(USHORT tempbx);
-extern void 	SiS_SetCH700x(USHORT tempbx);
-extern USHORT 	SiS_GetCH701x(USHORT tempbx);
-extern void 	SiS_SetCH701x(USHORT tempbx);
-extern void     SiS_SetCH70xxANDOR(USHORT tempax,USHORT tempbh);
-extern void     SiS_DDC2Delay(USHORT delaytime);
-
-static void sisfb_pre_setmode(void);
-static void sisfb_post_setmode(void);
-static void sisfb_crtc_to_var(struct fb_var_screeninfo *var);
-
-/* Export functions  */
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,23)
-static void sis_get_glyph(SIS_GLYINFO *gly);
-#else
-static void sis_get_glyph(struct fb_info *info, SIS_GLYINFO *gly);
-#endif
-void sis_dispinfo(struct ap_data *rec);
-void sis_malloc(struct sis_memreq *req);
-void sis_free(unsigned long base);
-
-/* heap routines */
-static int sisfb_heap_init(void);
-static SIS_OH *sisfb_poh_new_node(void);
-static SIS_OH *sisfb_poh_allocate(unsigned long size);
-static void sisfb_delete_node(SIS_OH *poh);
-static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh);
-static SIS_OH *sisfb_poh_free(unsigned long base);
-static void sisfb_free_node(SIS_OH *poh);
-
-/* routines to access PCI configuration space */
-BOOLEAN sisfb_query_VGA_config_space(PSIS_HW_DEVICE_INFO psishw_ext, 
-	unsigned long offset, unsigned long set, unsigned long *value);
-BOOLEAN sisfb_query_north_bridge_space(PSIS_HW_DEVICE_INFO psishw_ext, 
-	unsigned long offset, unsigned long set, unsigned long *value);
+/* Routines from init.c/init301.c */
+extern void 	SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr);
+extern BOOLEAN  SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+extern BOOLEAN  SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo);
+extern void     SiS_SetEnableDstn(SiS_Private *SiS_Pr);
+extern void     SiS_LongWait(SiS_Private *SiS_Pr);
 
+/* TW: Chrontel TV functions */
+extern USHORT 	SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
+extern void 	SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
+extern USHORT 	SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
+extern void 	SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
+extern void     SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
+extern void     SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
+
+/* TW: Sensing routines */
+void            SiS_Sense30x(void);
+int             SISDoSense(int tempbl, int tempbh, int tempcl, int tempch);
+void            SiS_SenseCh(void);			
+			
 #endif
diff -Nru a/drivers/video/sis/sisfb.h b/drivers/video/sis/sisfb.h
--- a/drivers/video/sis/sisfb.h	Thu Jul 11 10:24:03 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,153 +0,0 @@
-#ifndef _LINUX_SISFB
-#define _LINUX_SISFB
-
-#include <asm/ioctl.h>
-#include <asm/types.h>
-
-#define DISPTYPE_CRT1       0x00000008L
-#define DISPTYPE_CRT2       0x00000004L
-#define DISPTYPE_LCD        0x00000002L
-#define DISPTYPE_TV         0x00000001L
-#define DISPTYPE_DISP1      DISPTYPE_CRT1
-#define DISPTYPE_DISP2      (DISPTYPE_CRT2 | DISPTYPE_LCD | DISPTYPE_TV)
-#define DISPMODE_SINGLE	    0x00000020L
-#define DISPMODE_MIRROR	    0x00000010L
-#define DISPMODE_DUALVIEW   0x00000040L
-
-#define HASVB_NONE      	0x00
-#define HASVB_301       	0x01
-#define HASVB_LVDS      	0x02
-#define HASVB_TRUMPION  	0x04
-#define HASVB_LVDS_CHRONTEL	0x10
-#define HASVB_302       	0x20
-#define HASVB_303       	0x40
-#define HASVB_CHRONTEL  	0x80
-
-/* TW: *Never* change the order of the following enum */
-typedef enum _SIS_CHIP_TYPE {
-	SIS_VGALegacy = 0,
-	SIS_300,
-	SIS_630,
-	SIS_540,
-	SIS_730, 
-	SIS_315H,
-	SIS_315,
-	SIS_550,
-	SIS_315PRO,
-	SIS_640,
-	SIS_740,
-	SIS_650,
-	SIS_330,
-	MAX_SIS_CHIP
-} SIS_CHIP_TYPE;
-
-typedef enum _TVTYPE {
-	TVMODE_NTSC = 0,
-	TVMODE_PAL,
-	TVMODE_HIVISION,
-	TVMODE_TOTAL
-} SIS_TV_TYPE;
-
-typedef enum _TVPLUGTYPE {
-	TVPLUG_Legacy = 0,
-	TVPLUG_COMPOSITE,
-	TVPLUG_SVIDEO,
-	TVPLUG_SCART,
-	TVPLUG_TOTAL
-} SIS_TV_PLUG;
-
-struct sis_memreq {
-	unsigned long offset;
-	unsigned long size;
-};
-
-struct mode_info {
-	int    bpp;
-	int    xres;
-	int    yres;
-	int    v_xres;
-	int    v_yres;
-	int    org_x;
-	int    org_y;
-	unsigned int  vrate;
-};
-
-struct ap_data {
-	struct mode_info minfo;
-	unsigned long iobase;
-	unsigned int  mem_size;
-	unsigned long disp_state;    	
-	SIS_CHIP_TYPE chip;
-	unsigned char hasVB;
-	SIS_TV_TYPE TV_type;
-	SIS_TV_PLUG TV_plug;
-	unsigned long version;
-	char reserved[256];
-};
-
-struct video_info {
-	int    chip_id;
-	unsigned int  video_size;
-	unsigned long video_base;
-	char  *video_vbase;
-	unsigned long mmio_base;
-	char  *mmio_vbase; 
-	unsigned long vga_base;
-	unsigned long mtrr;
-	unsigned long heapstart;
-
-	int    video_bpp;
-	int    video_width;
-	int    video_height;
-	int    video_vwidth;
-	int    video_vheight;
-	int    org_x;
-	int    org_y;
-	unsigned int refresh_rate;
-
-	unsigned long disp_state;
-	unsigned char hasVB;
-	unsigned char TV_type;
-	unsigned char TV_plug;
-
-	SIS_CHIP_TYPE chip;
-	unsigned char revision_id;
-
-	char reserved[256];
-};
-
-
-/* TW: Addtional IOCTL for communication sisfb <> X driver                 */
-/*     If changing this, vgatypes.h must also be changed (for X driver)    */
-
-/* TW: ioctl for identifying and giving some info (esp. memory heap start) */
-#define SISFB_GET_INFO	  _IOR('n',0xF8,sizeof(__u32))
-
-/* TW: Structure argument for SISFB_GET_INFO ioctl  */
-typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
-
-struct _SISFB_INFO {
-	unsigned long sisfb_id;         /* for identifying sisfb */
-#ifndef SISFB_ID
-#define SISFB_ID	  0x53495346    /* Identify myself with 'SISF' */
-#endif
- 	int    chip_id;			/* PCI ID of detected chip */
-	int    memory;			/* video memory in KB which sisfb manages */
-	int    heapstart;               /* heap start (= sisfb "mem" argument) in KB */
-	unsigned char fbvidmode;	/* current sisfb mode */
-	
-	unsigned char sisfb_version;
-	unsigned char sisfb_revision;
-	unsigned char sisfb_patchlevel;
-
-	char reserved[253]; 		/* for future use */
-};
-
-#ifdef __KERNEL__
-extern struct video_info ivideo;
-
-extern void sis_malloc(struct sis_memreq *req);
-extern void sis_free(unsigned long base);
-extern void sis_dispinfo(struct ap_data *rec);
-#endif
-#endif
diff -Nru a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
--- a/drivers/video/sis/vgatypes.h	Thu Jul 11 10:30:30 2002
+++ b/drivers/video/sis/vgatypes.h	Wed Mar  5 09:22:36 2003
@@ -99,9 +99,8 @@
     SIS_315,
     SIS_315PRO, /* SiS 325 */
     SIS_550,
-    SIS_640,
-    SIS_740,
     SIS_650,
+    SIS_740,
     SIS_330, 
     MAX_SIS_CHIP
 } SIS_CHIP_TYPE;
@@ -119,7 +118,6 @@
     VB_CHIP_302,
     VB_CHIP_302B,
     VB_CHIP_302LV,
-    VB_CHIP_303,
     VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */
     MAX_VB_CHIP
 } SIS_VB_CHIP_TYPE;
@@ -174,6 +172,7 @@
                                  /* if NULL, then read from pjROMImage; */
                                  /* Note:ROM image file is the file of VBIOS ROM */
 
+    BOOLEAN UseROM;		 /* TW: Use the ROM image if provided */
  
     UCHAR  *pjCustomizedROMImage;/* base virtual address of ROM image file. */
                                  /* wincE:ROM image file is the file for OEM */
@@ -208,6 +207,7 @@
                                  /*             011:Trumpion LVDS Scaling Chip */
                                  /*             100:LVDS(LCD-out)+Chrontel 7005 */
                                  /*             101:Single Chrontel 7005 */
+				 /* TW: This has changed on 310/325 series! */
 
     ULONG  ulCRT2LCDType;        /* defined in the data structure type */
                                  /* "SIS_LCD_TYPE" */
@@ -234,13 +234,17 @@
     UCHAR  szVBIOSVer[VBIOS_VER_MAX_LENGTH];
 
     UCHAR  pdc;			/* TW: PanelDelayCompensation */
+    
+#ifdef LINUX_KERNEL
+    BOOLEAN Is301BDH;
+#endif        
 
 #ifdef LINUX_XF86
     PCITAG PciTag;		/* PCI Tag for Linux XF86 */
 #endif
 };
 #endif
-#endif /*~ mark by Paul ,Move definition to sisv.h  */
+#endif 
 
 
 /* TW: Addtional IOCTL for communication sisfb <> X driver        */
@@ -268,7 +272,19 @@
 	unsigned char sisfb_revision;
 	unsigned char sisfb_patchlevel;
 
-	char reserved[253]; 		/* for future use */
+	unsigned char sisfb_caps;	/* sisfb's capabilities */
+
+	int    sisfb_tqlen;		/* turbo queue length (in KB) */
+
+	unsigned int sisfb_pcibus;      /* The card's PCI ID */
+	unsigned int sisfb_pcislot;
+	unsigned int sisfb_pcifunc;
+
+	unsigned char sisfb_lcdpdc;
+	
+	unsigned char sisfb_lcda;
+
+	char reserved[235]; 		/* for future use */
 };
 #endif
 
diff -Nru a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h
--- a/drivers/video/sis/vstruct.h	Thu Jul 11 10:30:30 2002
+++ b/drivers/video/sis/vstruct.h	Fri Mar  7 11:19:02 2003
@@ -4,9 +4,12 @@
 #define EXTERN extern
 #endif /* _INIT_ */
 
+#ifndef _VSTRUCT_
+#define _VSTRUCT_
+
 typedef struct _SiS_PanelDelayTblStruct
 {
- UCHAR timer[2];
+ 	UCHAR timer[2];
 } SiS_PanelDelayTblStruct;
 
 typedef struct _SiS_LCDDataStruct
@@ -28,12 +31,12 @@
 	USHORT TVHDE;
 	USHORT TVVDE;
 	USHORT RVBHRS;
-	UCHAR FlickerMode;
+	UCHAR  FlickerMode;
 	USHORT HALFRVBHRS;
-	UCHAR RY1COE;
-	UCHAR RY2COE;
-	UCHAR RY3COE;
-	UCHAR RY4COE;
+	UCHAR  RY1COE;
+	UCHAR  RY2COE;
+	UCHAR  RY3COE;
+	UCHAR  RY4COE;
 } SiS_TVDataStruct;
 
 typedef struct _SiS_LVDSDataStruct
@@ -52,30 +55,30 @@
 
 typedef struct _SiS_LVDSCRT1DataStruct
 {
-	UCHAR CR[15];
+	UCHAR  CR[15];
 } SiS_LVDSCRT1DataStruct;
 
 /*add for LCDA*/
 typedef struct _SiS_LCDACRT1DataStruct
 {
-	UCHAR CR[17];
+	UCHAR  CR[17];
 } SiS_LCDACRT1DataStruct;
 
 typedef struct _SiS_CHTVRegDataStruct
 {
-	UCHAR Reg[16];
+	UCHAR  Reg[16];
 } SiS_CHTVRegDataStruct;
 
 typedef struct _SiS_StStruct
 {
-	UCHAR St_ModeID;
+	UCHAR  St_ModeID;
 	USHORT St_ModeFlag;
-	UCHAR St_StTableIndex;
-	UCHAR St_CRT2CRTC;
-	UCHAR St_ResInfo;
-	UCHAR VB_StTVFlickerIndex;
-	UCHAR VB_StTVEdgeIndex;
-	UCHAR VB_StTVYFilterIndex;
+	UCHAR  St_StTableIndex;
+	UCHAR  St_CRT2CRTC;
+	UCHAR  St_ResInfo;
+	UCHAR  VB_StTVFlickerIndex;
+	UCHAR  VB_StTVEdgeIndex;
+	UCHAR  VB_StTVYFilterIndex;
 } SiS_StStruct;
 
 typedef struct _SiS_VBModeStruct
@@ -92,38 +95,38 @@
 
 typedef struct _SiS_StandTableStruct
 {
-	UCHAR CRT_COLS;
-	UCHAR ROWS;
-	UCHAR CHAR_HEIGHT;
+	UCHAR  CRT_COLS;
+	UCHAR  ROWS;
+	UCHAR  CHAR_HEIGHT;
 	USHORT CRT_LEN;
-	UCHAR SR[4];
-	UCHAR MISC;
-	UCHAR CRTC[0x19];
-	UCHAR ATTR[0x14];
-	UCHAR GRC[9];
+	UCHAR  SR[4];
+	UCHAR  MISC;
+	UCHAR  CRTC[0x19];
+	UCHAR  ATTR[0x14];
+	UCHAR  GRC[9];
 } SiS_StandTableStruct;
 
 typedef struct _SiS_ExtStruct
 {
-	UCHAR Ext_ModeID;
+	UCHAR  Ext_ModeID;
 	USHORT Ext_ModeFlag;
 	USHORT Ext_ModeInfo;
 	USHORT Ext_Point;
 	USHORT Ext_VESAID;
-	UCHAR Ext_VESAMEMSize;
-	UCHAR Ext_RESINFO;
-	UCHAR VB_ExtTVFlickerIndex;
-	UCHAR VB_ExtTVEdgeIndex;
-	UCHAR VB_ExtTVYFilterIndex;
-	UCHAR REFindex;
+	UCHAR  Ext_VESAMEMSize;
+	UCHAR  Ext_RESINFO;
+	UCHAR  VB_ExtTVFlickerIndex;
+	UCHAR  VB_ExtTVEdgeIndex;
+	UCHAR  VB_ExtTVYFilterIndex;
+	UCHAR  REFindex;
 } SiS_ExtStruct;
 
 typedef struct _SiS_Ext2Struct
 {
 	USHORT Ext_InfoFlag;
-	UCHAR Ext_CRT1CRTC;
-	UCHAR Ext_CRTVCLK;
-	UCHAR Ext_CRT2CRTC;
+	UCHAR  Ext_CRT1CRTC;
+	UCHAR  Ext_CRTVCLK;
+	UCHAR  Ext_CRT2CRTC;
 	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
@@ -132,35 +135,35 @@
 
 typedef struct _SiS_Part2PortTblStruct
 {
- 	UCHAR CR[12];
+ 	UCHAR  CR[12];
 } SiS_Part2PortTblStruct;
 
 typedef struct _SiS_CRT1TableStruct
 {
-	UCHAR CR[17];
+	UCHAR  CR[17];
 } SiS_CRT1TableStruct;
 
 typedef struct _SiS_MCLKDataStruct
 {
-	UCHAR SR28,SR29,SR2A;
+	UCHAR  SR28,SR29,SR2A;
 	USHORT CLOCK;
 } SiS_MCLKDataStruct;
 
 typedef struct _SiS_ECLKDataStruct
 {
-	UCHAR SR2E,SR2F,SR30;
+	UCHAR  SR2E,SR2F,SR30;
 	USHORT CLOCK;
 } SiS_ECLKDataStruct;
 
 typedef struct _SiS_VCLKDataStruct
 {
-	UCHAR SR2B,SR2C;
+	UCHAR  SR2B,SR2C;
 	USHORT CLOCK;
 } SiS_VCLKDataStruct;
 
 typedef struct _SiS_VBVCLKDataStruct
 {
-	UCHAR Part4_A,Part4_B;
+	UCHAR  Part4_A,Part4_B;
 	USHORT CLOCK;
 } SiS_VBVCLKDataStruct;
 
@@ -178,213 +181,405 @@
 	UCHAR  YChar;
 } SiS_ModeResInfoStruct;
 
-EXTERN SiS_StStruct *SiS_SModeIDTable;
-EXTERN SiS_StandTableStruct *SiS_StandTable;
-EXTERN SiS_ExtStruct  *SiS_EModeIDTable;
-EXTERN SiS_Ext2Struct  *SiS_RefIndex;
-EXTERN SiS_VBModeStruct *SiS_VBModeIDTable;
-EXTERN SiS_CRT1TableStruct  *SiS_CRT1Table;
-EXTERN SiS_MCLKDataStruct  *SiS_MCLKData_0;
-EXTERN SiS_MCLKDataStruct  *SiS_MCLKData_1;
-EXTERN SiS_ECLKDataStruct  *SiS_ECLKData;
-EXTERN SiS_VCLKDataStruct  *SiS_VCLKData;
-EXTERN SiS_VBVCLKDataStruct  *SiS_VBVCLKData;
-EXTERN SiS_StResInfoStruct  *SiS_StResInfo;
-EXTERN SiS_ModeResInfoStruct  *SiS_ModeResInfo;
-EXTERN UCHAR *SiS_ScreenOffset;
-
-EXTERN UCHAR *pSiS_OutputSelect;
-EXTERN UCHAR *pSiS_SoftSetting;
-EXTERN UCHAR *pSiS_SR07;
-
 typedef UCHAR DRAM4Type[4];
-EXTERN DRAM4Type *SiS_SR15; /* pointer : point to array */
-EXTERN DRAM4Type *SiS_CR40; /* pointer : point to array */
-EXTERN UCHAR *SiS_CR49;
-EXTERN UCHAR *SiS_SR25;
-
-EXTERN UCHAR *pSiS_SR1F;
-EXTERN UCHAR *pSiS_SR21;
-EXTERN UCHAR *pSiS_SR22;
-EXTERN UCHAR *pSiS_SR23;
-EXTERN UCHAR *pSiS_SR24;
-EXTERN UCHAR *pSiS_SR31;
-EXTERN UCHAR *pSiS_SR32;
-EXTERN UCHAR *pSiS_SR33;
-EXTERN UCHAR *pSiS_CRT2Data_1_2;
-EXTERN UCHAR *pSiS_CRT2Data_4_D;
-EXTERN UCHAR *pSiS_CRT2Data_4_E;
-EXTERN UCHAR *pSiS_CRT2Data_4_10;
-EXTERN USHORT *pSiS_RGBSenseData;
-EXTERN USHORT *pSiS_VideoSenseData;
-EXTERN USHORT *pSiS_YCSenseData;
-EXTERN USHORT *pSiS_RGBSenseData2; /*301b*/
-EXTERN USHORT *pSiS_VideoSenseData2;
-EXTERN USHORT *pSiS_YCSenseData2;
-
-EXTERN UCHAR *SiS_NTSCPhase;
-EXTERN UCHAR *SiS_PALPhase;
-EXTERN UCHAR *SiS_NTSCPhase2;
-EXTERN UCHAR *SiS_PALPhase2;
-EXTERN UCHAR *SiS_PALMPhase;
-EXTERN UCHAR *SiS_PALNPhase;
-EXTERN UCHAR *SiS_PALMPhase2;
-EXTERN UCHAR *SiS_PALNPhase2;
-EXTERN SiS_LCDDataStruct  *SiS_StLCD1024x768Data;
-EXTERN SiS_LCDDataStruct  *SiS_ExtLCD1024x768Data;
-EXTERN SiS_LCDDataStruct  *SiS_St2LCD1024x768Data;
-EXTERN SiS_LCDDataStruct  *SiS_StLCD1280x1024Data;
-EXTERN SiS_LCDDataStruct  *SiS_ExtLCD1280x1024Data;
-EXTERN SiS_LCDDataStruct  *SiS_St2LCD1280x1024Data;
-EXTERN SiS_LCDDataStruct  *SiS_NoScaleData1024x768;
-EXTERN SiS_LCDDataStruct  *SiS_NoScaleData1280x1024;
-EXTERN SiS_LCDDataStruct  *SiS_LCD1280x960Data;
-EXTERN SiS_TVDataStruct   *SiS_StPALData;
-EXTERN SiS_TVDataStruct   *SiS_ExtPALData;
-EXTERN SiS_TVDataStruct   *SiS_StNTSCData;
-EXTERN SiS_TVDataStruct   *SiS_ExtNTSCData;
-EXTERN SiS_TVDataStruct   *SiS_St1HiTVData;
-EXTERN SiS_TVDataStruct   *SiS_St2HiTVData;
-EXTERN SiS_TVDataStruct   *SiS_ExtHiTVData;
-EXTERN UCHAR *SiS_NTSCTiming;
-EXTERN UCHAR *SiS_PALTiming;
-EXTERN UCHAR *SiS_HiTVExtTiming;
-EXTERN UCHAR *SiS_HiTVSt1Timing;
-EXTERN UCHAR *SiS_HiTVSt2Timing;
-EXTERN UCHAR *SiS_HiTVTextTiming;
-EXTERN UCHAR *SiS_HiTVGroup3Data;
-EXTERN UCHAR *SiS_HiTVGroup3Simu;
-EXTERN UCHAR *SiS_HiTVGroup3Text;
-
-EXTERN SiS_PanelDelayTblStruct *SiS_PanelDelayTbl;
-EXTERN SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS800x600Data_1;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS800x600Data_2;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS1024x768Data_1;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS1024x768Data_2;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS1280x1024Data_1;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS1280x1024Data_2;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS1280x960Data_1;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS1280x960Data_2;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS1400x1050Data_1;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS1400x1050Data_2;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS1024x600Data_1;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS1024x600Data_2;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_1;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_2;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS640x480Data_1;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDS320x480Data_1;
-EXTERN SiS_LVDSDataStruct  *SiS_LVDSXXXxXXXData_1;
-EXTERN SiS_LVDSDataStruct  *SiS_CHTVUNTSCData;
-EXTERN SiS_LVDSDataStruct  *SiS_CHTVONTSCData;
-EXTERN SiS_LVDSDataStruct  *SiS_CHTVUPALData;
-EXTERN SiS_LVDSDataStruct  *SiS_CHTVOPALData;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType00_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType01_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType02_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType03_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType04_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType05_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType06_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType07_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType08_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType09_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType0a_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType0b_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType0c_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType0d_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType0e_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType0f_1;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType00_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType01_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType02_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType03_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType04_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType05_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType06_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType07_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType08_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType09_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType0a_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType0b_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType0c_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType0d_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType0e_2;
-EXTERN SiS_LVDSDesStruct  *SiS_PanelType0f_2;
-
-EXTERN SiS_LVDSDesStruct  *LVDS1024x768Des_1;
-EXTERN SiS_LVDSDesStruct  *LVDS1280x1024Des_1;
-EXTERN SiS_LVDSDesStruct  *LVDS1280x960Des_1;
-EXTERN SiS_LVDSDesStruct  *LVDS1024x768Des_2;
-EXTERN SiS_LVDSDesStruct  *LVDS1280x1024Des_2;
-EXTERN SiS_LVDSDesStruct  *LVDS1280x960Des_2;
-
-EXTERN SiS_LVDSDesStruct  *SiS_CHTVUNTSCDesData;
-EXTERN SiS_LVDSDesStruct  *SiS_CHTVONTSCDesData;
-EXTERN SiS_LVDSDesStruct  *SiS_CHTVUPALDesData;
-EXTERN SiS_LVDSDesStruct  *SiS_CHTVOPALDesData;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_1;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_1;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_1;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_1;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_1;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_1;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_1_H;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_1_H;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_1_H;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_1_H;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_1_H;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_1_H;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_2;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_2;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_2;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_2;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_2;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_2;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_2_H;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_2_H;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_2_H;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_2_H;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_2_H;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_2_H;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1_H;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UNTSC;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1ONTSC;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UPAL;
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1OPAL;
-
-EXTERN SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1320x480_1;
-
-EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_1;
-EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_1;
-EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_1;
-EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_1_H;
-EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_1_H;
-EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_1_H;
-EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_2;
-EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_2;
-EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_2;
-EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_2_H;
-EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_2_H;
-EXTERN SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_2_H;
-
-/* TW: New from 650/301LV BIOS */
-EXTERN SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
-EXTERN SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
-EXTERN SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_2;
-EXTERN SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_2;
-EXTERN SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_3;
-EXTERN SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_3;
-
-EXTERN SiS_CHTVRegDataStruct *SiS_CHTVReg_UNTSC;
-EXTERN SiS_CHTVRegDataStruct *SiS_CHTVReg_ONTSC;
-EXTERN SiS_CHTVRegDataStruct *SiS_CHTVReg_UPAL;
-EXTERN SiS_CHTVRegDataStruct *SiS_CHTVReg_OPAL;
-EXTERN UCHAR *SiS_CHTVVCLKUNTSC;
-EXTERN UCHAR *SiS_CHTVVCLKONTSC;
-EXTERN UCHAR *SiS_CHTVVCLKUPAL;
-EXTERN UCHAR *SiS_CHTVVCLKOPAL;
 
+typedef struct _SiS_Private
+{
+#ifdef LINUX_KERNEL
+        USHORT RelIO;
+#endif
+	USHORT SiS_P3c4;
+	USHORT SiS_P3d4;
+	USHORT SiS_P3c0;
+	USHORT SiS_P3ce;
+	USHORT SiS_P3c2;
+	USHORT SiS_P3ca;
+	USHORT SiS_P3c6;
+	USHORT SiS_P3c7;
+	USHORT SiS_P3c8;
+	USHORT SiS_P3c9;
+	USHORT SiS_P3da;
+	USHORT SiS_Part1Port;
+	USHORT SiS_Part2Port;
+	USHORT SiS_Part3Port;
+	USHORT SiS_Part4Port;
+	USHORT SiS_Part5Port;
+	USHORT SiS_IF_DEF_LVDS;
+	USHORT SiS_IF_DEF_TRUMPION;
+	USHORT SiS_IF_DEF_DSTN;
+	USHORT SiS_IF_DEF_FSTN;
+	USHORT SiS_IF_DEF_CH70xx;
+	USHORT SiS_IF_DEF_HiVision;
+	UCHAR  SiS_VGAINFO;
+	BOOLEAN SiS_UseROM;
+	int    SiS_CHOverScan;
+	BOOLEAN SiS_CHSOverScan;
+	BOOLEAN SiS_ChSW;
+	BOOLEAN SiS_UseLCDA;
+	int    SiS_UseOEM;
+	USHORT SiS_Backup70xx;
+	USHORT SiS_CRT1Mode;
+	USHORT SiS_flag_clearbuffer;
+	int    SiS_RAMType;
+	UCHAR  SiS_ChannelAB;
+	UCHAR  SiS_DataBusWidth;
+	USHORT SiS_ModeType;
+	USHORT SiS_VBInfo;
+	USHORT SiS_LCDResInfo;
+	USHORT SiS_LCDTypeInfo;
+	USHORT SiS_LCDInfo;
+	USHORT SiS_VBType;
+	USHORT SiS_VBExtInfo;
+	USHORT SiS_HiVision;
+	USHORT SiS_SelectCRT2Rate;
+	USHORT SiS_SetFlag;
+	USHORT SiS_RVBHCFACT;
+	USHORT SiS_RVBHCMAX;
+	USHORT SiS_RVBHRS;
+	USHORT SiS_VGAVT;
+	USHORT SiS_VGAHT;
+	USHORT SiS_VT;
+	USHORT SiS_HT;
+	USHORT SiS_VGAVDE;
+	USHORT SiS_VGAHDE;
+	USHORT SiS_VDE;
+	USHORT SiS_HDE;
+	USHORT SiS_NewFlickerMode;
+	USHORT SiS_RY1COE;
+	USHORT SiS_RY2COE;
+	USHORT SiS_RY3COE;
+	USHORT SiS_RY4COE;
+	USHORT SiS_LCDHDES;
+	USHORT SiS_LCDVDES;
+	USHORT SiS_DDC_Port;
+	USHORT SiS_DDC_Index;
+	USHORT SiS_DDC_Data;
+	USHORT SiS_DDC_Clk;
+	USHORT SiS_DDC_DataShift;
+	USHORT SiS_DDC_DeviceAddr;
+	USHORT SiS_DDC_ReadAddr;
+	USHORT SiS_DDC_SecAddr;
+	USHORT SiS_Panel800x600;
+	USHORT SiS_Panel1024x768;
+	USHORT SiS_Panel1280x1024;
+	USHORT SiS_Panel1600x1200;
+	USHORT SiS_Panel1280x960;
+	USHORT SiS_Panel1400x1050;
+	USHORT SiS_Panel320x480;
+	USHORT SiS_Panel1152x768;
+	USHORT SiS_Panel1280x768;
+	USHORT SiS_Panel1024x600;
+	USHORT SiS_Panel640x480;
+	USHORT SiS_Panel1152x864;
+	USHORT SiS_PanelMax;
+	USHORT SiS_PanelMinLVDS;
+	USHORT SiS_PanelMin301;
+	USHORT SiS_ChrontelInit;
+	
+	/* Pointers: */
+	const SiS_StStruct          *SiS_SModeIDTable;
+	const SiS_StandTableStruct  *SiS_StandTable;
+	const SiS_ExtStruct         *SiS_EModeIDTable;
+	const SiS_Ext2Struct        *SiS_RefIndex;
+	const SiS_VBModeStruct      *SiS_VBModeIDTable;
+	const SiS_CRT1TableStruct   *SiS_CRT1Table;
+	const SiS_MCLKDataStruct    *SiS_MCLKData_0;
+	const SiS_MCLKDataStruct    *SiS_MCLKData_1;
+	const SiS_ECLKDataStruct    *SiS_ECLKData;
+	const SiS_VCLKDataStruct    *SiS_VCLKData;
+	const SiS_VBVCLKDataStruct  *SiS_VBVCLKData;
+	const SiS_StResInfoStruct   *SiS_StResInfo;
+	const SiS_ModeResInfoStruct *SiS_ModeResInfo;
+	const UCHAR                 *SiS_ScreenOffset;
+
+	const UCHAR                 *pSiS_OutputSelect;
+	const UCHAR                 *pSiS_SoftSetting;
+
+	const DRAM4Type *SiS_SR15; /* pointer : point to array */
+#ifndef LINUX_XF86
+	UCHAR *pSiS_SR07;
+	const DRAM4Type *SiS_CR40; /* pointer : point to array */
+	UCHAR *SiS_CR49;
+	UCHAR *SiS_SR25;
+	UCHAR *pSiS_SR1F;
+	UCHAR *pSiS_SR21;
+	UCHAR *pSiS_SR22;
+	UCHAR *pSiS_SR23;
+	UCHAR *pSiS_SR24;
+	UCHAR *pSiS_SR31;
+	UCHAR *pSiS_SR32;
+	UCHAR *pSiS_SR33;
+	UCHAR *pSiS_CRT2Data_1_2;
+	UCHAR *pSiS_CRT2Data_4_D;
+	UCHAR *pSiS_CRT2Data_4_E;
+	UCHAR *pSiS_CRT2Data_4_10;
+	const USHORT *pSiS_RGBSenseData;
+	const USHORT *pSiS_VideoSenseData;
+	const USHORT *pSiS_YCSenseData;
+	const USHORT *pSiS_RGBSenseData2; /*301b*/
+	const USHORT *pSiS_VideoSenseData2;
+	const USHORT *pSiS_YCSenseData2;
+#endif
+	const UCHAR *SiS_NTSCPhase;
+	const UCHAR *SiS_PALPhase;
+	const UCHAR *SiS_NTSCPhase2;
+	const UCHAR *SiS_PALPhase2;
+	const UCHAR *SiS_PALMPhase;
+	const UCHAR *SiS_PALNPhase;
+	const UCHAR *SiS_PALMPhase2;
+	const UCHAR *SiS_PALNPhase2;
+	const UCHAR *SiS_SpecialPhase;
+	const SiS_LCDDataStruct  *SiS_StLCD1024x768Data;
+	const SiS_LCDDataStruct  *SiS_ExtLCD1024x768Data;
+	const SiS_LCDDataStruct  *SiS_St2LCD1024x768Data;
+	const SiS_LCDDataStruct  *SiS_StLCD1280x1024Data;
+	const SiS_LCDDataStruct  *SiS_ExtLCD1280x1024Data;
+	const SiS_LCDDataStruct  *SiS_St2LCD1280x1024Data;
+	const SiS_LCDDataStruct  *SiS_NoScaleData1024x768;
+	const SiS_LCDDataStruct  *SiS_NoScaleData1280x1024;
+	const SiS_LCDDataStruct  *SiS_LCD1280x960Data;
+	const SiS_LCDDataStruct  *SiS_NoScaleData1400x1050;
+	const SiS_LCDDataStruct  *SiS_NoScaleData1600x1200;
+	const SiS_LCDDataStruct  *SiS_StLCD1400x1050Data;
+	const SiS_LCDDataStruct  *SiS_StLCD1600x1200Data;
+	const SiS_LCDDataStruct  *SiS_ExtLCD1400x1050Data;
+	const SiS_LCDDataStruct  *SiS_ExtLCD1600x1200Data;
+	const SiS_TVDataStruct   *SiS_StPALData;
+	const SiS_TVDataStruct   *SiS_ExtPALData;
+	const SiS_TVDataStruct   *SiS_StNTSCData;
+	const SiS_TVDataStruct   *SiS_ExtNTSCData;
+/*	const SiS_TVDataStruct   *SiS_St1HiTVData;  */
+	const SiS_TVDataStruct   *SiS_St2HiTVData;
+	const SiS_TVDataStruct   *SiS_ExtHiTVData;
+	const UCHAR *SiS_NTSCTiming;
+	const UCHAR *SiS_PALTiming;
+	const UCHAR *SiS_HiTVExtTiming;
+	const UCHAR *SiS_HiTVSt1Timing;
+	const UCHAR *SiS_HiTVSt2Timing;
+	const UCHAR *SiS_HiTVTextTiming;
+	const UCHAR *SiS_HiTVGroup3Data;
+	const UCHAR *SiS_HiTVGroup3Simu;
+	const UCHAR *SiS_HiTVGroup3Text;
+	const SiS_PanelDelayTblStruct *SiS_PanelDelayTbl;
+	const SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS;
+	const SiS_LVDSDataStruct  *SiS_LVDS800x600Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDS800x600Data_2;
+	const SiS_LVDSDataStruct  *SiS_LVDS1024x768Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDS1024x768Data_2;
+	const SiS_LVDSDataStruct  *SiS_LVDS1280x1024Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDS1280x1024Data_2;
+	const SiS_LVDSDataStruct  *SiS_LVDS1280x960Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDS1280x960Data_2;
+	const SiS_LVDSDataStruct  *SiS_LVDS1400x1050Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDS1400x1050Data_2;
+	const SiS_LVDSDataStruct  *SiS_LVDS1600x1200Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDS1600x1200Data_2;
+	const SiS_LVDSDataStruct  *SiS_LVDS1280x768Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDS1280x768Data_2;
+	const SiS_LVDSDataStruct  *SiS_LVDS1024x600Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDS1024x600Data_2;
+	const SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_2;
+	const SiS_LVDSDataStruct  *SiS_LVDS640x480Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDS320x480Data_1;
+	const SiS_LVDSDataStruct  *SiS_LCDA1400x1050Data_1;
+	const SiS_LVDSDataStruct  *SiS_LCDA1400x1050Data_2;
+	const SiS_LVDSDataStruct  *SiS_LCDA1600x1200Data_1;
+	const SiS_LVDSDataStruct  *SiS_LCDA1600x1200Data_2;
+	const SiS_LVDSDataStruct  *SiS_LVDSXXXxXXXData_1;
+	const SiS_LVDSDataStruct  *SiS_CHTVUNTSCData;
+	const SiS_LVDSDataStruct  *SiS_CHTVONTSCData;
+	const SiS_LVDSDataStruct  *SiS_CHTVUPALData;
+	const SiS_LVDSDataStruct  *SiS_CHTVOPALData;
+	const SiS_LVDSDataStruct  *SiS_CHTVUPALMData;
+	const SiS_LVDSDataStruct  *SiS_CHTVOPALMData;
+	const SiS_LVDSDataStruct  *SiS_CHTVUPALNData;
+	const SiS_LVDSDataStruct  *SiS_CHTVOPALNData;
+	const SiS_LVDSDataStruct  *SiS_CHTVSOPALData;
+	const SiS_LVDSDesStruct  *SiS_PanelType00_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType01_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType02_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType03_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType04_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType05_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType06_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType07_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType08_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType09_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType0a_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType0b_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType0c_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType0d_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType0e_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType0f_1;
+	const SiS_LVDSDesStruct  *SiS_PanelTypeNS_1;
+	const SiS_LVDSDesStruct  *SiS_PanelType00_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType01_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType02_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType03_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType04_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType05_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType06_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType07_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType08_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType09_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType0a_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType0b_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType0c_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType0d_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType0e_2;
+	const SiS_LVDSDesStruct  *SiS_PanelType0f_2;
+	const SiS_LVDSDesStruct  *SiS_PanelTypeNS_2;
+
+	const SiS_LVDSDesStruct  *LVDS1024x768Des_1;
+	const SiS_LVDSDesStruct  *LVDS1280x1024Des_1;
+	const SiS_LVDSDesStruct  *LVDS1400x1050Des_1;
+	const SiS_LVDSDesStruct  *LVDS1600x1200Des_1;
+	const SiS_LVDSDesStruct  *LVDS1024x768Des_2;
+	const SiS_LVDSDesStruct  *LVDS1280x1024Des_2;
+	const SiS_LVDSDesStruct  *LVDS1400x1050Des_2;
+	const SiS_LVDSDesStruct  *LVDS1600x1200Des_2;
+
+	const SiS_LVDSDesStruct  *SiS_CHTVUNTSCDesData;
+	const SiS_LVDSDesStruct  *SiS_CHTVONTSCDesData;
+	const SiS_LVDSDesStruct  *SiS_CHTVUPALDesData;
+	const SiS_LVDSDesStruct  *SiS_CHTVOPALDesData;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_1;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_1;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_1;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_1;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x768_1;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_1;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_1;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11600x1200_1;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_1_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_1_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_1_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_1_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x768_1_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_1_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_1_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11600x1200_1_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_2;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_2;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_2;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_2;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x768_2;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_2;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_2;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11600x1200_2;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1800x600_2_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x768_2_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x1024_2_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11400x1050_2_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11280x768_2_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11024x600_2_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11152x768_2_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11600x1200_2_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UNTSC;
+	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1ONTSC;
+	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UPAL;
+	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1OPAL;
+	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1SOPAL;
+
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1320x480_1;
+
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_1;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_1;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_1;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_1;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_1;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_1_H;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_1_H;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_1_H;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_1_H;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_1_H;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_2;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_2;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_2;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_2;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_2;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_2_H;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_2_H;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_2_H;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_2_H;
+	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_2_H;
+
+	/* TW: New for 650/301LV */
+	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
+	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
+	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_1;
+	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_1;
+	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_2;
+	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_2;
+	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_2;
+	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_2;
+	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_3;
+	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_3;
+	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_3;
+	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_3;
+
+	const SiS_CHTVRegDataStruct *SiS_CHTVReg_UNTSC;
+	const SiS_CHTVRegDataStruct *SiS_CHTVReg_ONTSC;
+	const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPAL;
+	const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPAL;
+	const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALM;
+	const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALM;
+	const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALN;
+	const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALN;
+	const SiS_CHTVRegDataStruct *SiS_CHTVReg_SOPAL;
+	const UCHAR *SiS_CHTVVCLKUNTSC;
+	const UCHAR *SiS_CHTVVCLKONTSC;
+	const UCHAR *SiS_CHTVVCLKUPAL;
+	const UCHAR *SiS_CHTVVCLKOPAL;
+	const UCHAR *SiS_CHTVVCLKUPALM;
+	const UCHAR *SiS_CHTVVCLKOPALM;
+	const UCHAR *SiS_CHTVVCLKUPALN;
+	const UCHAR *SiS_CHTVVCLKOPALN;
+	const UCHAR *SiS_CHTVVCLKSOPAL;
+	
+	BOOLEAN UseCustomMode;
+	BOOLEAN CRT1UsesCustomMode;
+	USHORT  CHDisplay;
+	USHORT  CHSyncStart;
+	USHORT  CHSyncEnd;
+	USHORT  CHTotal;
+	USHORT  CHBlankStart;
+	USHORT  CHBlankEnd;
+	USHORT  CVDisplay;
+	USHORT  CVSyncStart;
+	USHORT  CVSyncEnd;
+	USHORT  CVTotal;
+	USHORT  CVBlankStart;
+	USHORT  CVBlankEnd;
+	ULONG   CDClock;
+	ULONG   CFlags;   
+	UCHAR   CCRT1CRTC[17];
+	UCHAR   CSR2B;
+	UCHAR   CSR2C;
+	USHORT  CSRClock;
+	USHORT  CModeFlag;
+	USHORT  CInfoFlag;
+	BOOLEAN SiS_CHPALM;
+	BOOLEAN SiS_CHPALN;
+	
+	BOOLEAN Backup;
+	UCHAR Backup_Mode;
+	UCHAR Backup_14;
+	UCHAR Backup_15;
+	UCHAR Backup_16;
+	UCHAR Backup_17;
+	UCHAR Backup_18;
+	UCHAR Backup_19;
+	UCHAR Backup_1a;
+	UCHAR Backup_1b;
+	UCHAR Backup_1c;
+	UCHAR Backup_1d;
+	
+	int    UsePanelScaler;
+} SiS_Private;
 
+#endif
 
diff -Nru a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
--- a/drivers/video/skeletonfb.c	Fri Feb  7 00:20:33 2003
+++ b/drivers/video/skeletonfb.c	Fri Feb  7 14:44:36 2003
@@ -384,7 +384,7 @@
  *	depending on the rastering operation with the value of color which
  *	is in the current color depth format.
  */
-void xxfb_fillrect(struct fb_info *p, struct fb_fillrect *region)
+void xxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region)
 {
 /*	Meaning of struct fb_fillrect
  *
@@ -410,7 +410,7 @@
  *      This drawing operation copies a rectangular area from one area of the
  *	screen to another area.
  */
-void xxxfb_copyarea(struct fb_info *p, struct fb_copyarea *area) 
+void xxxfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) 
 {
 /*
  *      @dx: The x and y coordinates of the upper left hand corner of the
@@ -435,7 +435,7 @@
  *	mono image (needed for font handling) or a color image (needed for
  *	tux). 
  */
-void xxxfb_imageblit(struct fb_info *p, struct fb_image *image) 
+void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image) 
 {
 /*
  *      @dx: The x and y coordinates of the upper left hand corner of the
diff -Nru a/drivers/video/softcursor.c b/drivers/video/softcursor.c
--- a/drivers/video/softcursor.c	Fri Nov 22 13:47:01 2002
+++ b/drivers/video/softcursor.c	Fri Mar 21 12:30:05 2003
@@ -19,39 +19,80 @@
 
 int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
-	int i, size = ((cursor->image.width + 7) / 8) * cursor->image.height;
-	struct fb_image image;
-	static char data[64];
+	unsigned int scan_align = info->pixmap.scan_align - 1;
+	unsigned int buf_align = info->pixmap.buf_align - 1;
+	unsigned int i, size, dsize, s_pitch, d_pitch;
+	u8 *dst, src[64];
 
-	if (cursor->enable) {
+	info->cursor.enable = (cursor->set & FB_CUR_SETCUR) ? 1 : 0;
+
+	if (cursor->set & FB_CUR_SETSIZE) {
+		info->cursor.image.width = cursor->image.width;
+		info->cursor.image.height = cursor->image.height;
+		cursor->set |= FB_CUR_SETSHAPE;
+	}
+
+	s_pitch = (info->cursor.image.width + 7) >> 3;
+	dsize = s_pitch * info->cursor.image.height;
+	d_pitch = (s_pitch + scan_align) & ~scan_align;
+	size = d_pitch * info->cursor.image.height + buf_align;
+	size &= ~buf_align;
+	dst = info->pixmap.addr + fb_get_buffer_offset(info, size);
+	info->cursor.image.data = dst;
+
+	if (cursor->set & FB_CUR_SETSHAPE) {
+		if (info->cursor.mask)
+			kfree(info->cursor.mask);
+		info->cursor.mask = kmalloc(dsize, GFP_KERNEL);
+		if (cursor->mask)
+			memcpy(info->cursor.mask, cursor->mask, dsize);
+		else
+			memset(info->cursor.mask, 0, dsize);
+	}
+
+	if (cursor->set & FB_CUR_SETPOS) {
+		info->cursor.image.dx = cursor->image.dx;
+		info->cursor.image.dy = cursor->image.dy;
+	}
+
+	if (cursor->set & FB_CUR_SETHOT)
+		info->cursor.hot = cursor->hot;
+
+	if (cursor->set & FB_CUR_SETCMAP) {
+		if (cursor->image.depth == 0) {
+			info->cursor.image.bg_color = cursor->image.bg_color;
+			info->cursor.image.fg_color = cursor->image.fg_color;
+		} else {
+			if (cursor->image.cmap.len)
+				fb_copy_cmap(&cursor->image.cmap, &info->cursor.image.cmap, 0);
+		}
+		info->cursor.image.depth = cursor->image.depth;
+	}
+
+	if (info->cursor.enable) {
 		switch (cursor->rop) {
 		case ROP_XOR:
-			for (i = 0; i < size; i++)
-				data[i] = (cursor->image.data[i] &
-					   cursor->mask[i]) ^
-				    	   cursor->dest[i];
+			for (i = 0; i < dsize; i++) {
+				src[i] = (cursor->image.data[i] &
+					  cursor->mask[i]) ^
+				    	  cursor->dest[i];
+			}
 			break;
 		case ROP_COPY:
 		default:
-			for (i = 0; i < size; i++)
-				data[i] =
-				    cursor->image.data[i] & cursor->mask[i];
+			for (i = 0; i < dsize; i++) {
+				src[i] = cursor->image.data[i] &
+				    	 cursor->mask[i];
+			}
 			break;
 		}
-	} else
-		memcpy(data, cursor->dest, size);
-
-	image.bg_color = cursor->image.bg_color;
-	image.fg_color = cursor->image.fg_color;
-	image.dx = cursor->image.dx;
-	image.dy = cursor->image.dy;
-	image.width = cursor->image.width;
-	image.height = cursor->image.height;
-	image.depth = cursor->image.depth;
-	image.data = data;
-
-	if (info->fbops->fb_imageblit)
-		info->fbops->fb_imageblit(info, &image);
+		move_buf_aligned(info, dst, src, d_pitch, s_pitch,
+				 cursor->image.height);
+	} else {
+		move_buf_aligned(info, dst, cursor->dest, s_pitch, d_pitch,
+				 cursor->image.height);
+	}
+	info->fbops->fb_imageblit(info, &info->cursor.image);
 	return 0;
 }
 
diff -Nru a/drivers/video/sstfb.c b/drivers/video/sstfb.c
--- a/drivers/video/sstfb.c	Tue Feb 25 02:46:56 2003
+++ b/drivers/video/sstfb.c	Mon Mar  3 19:41:18 2003
@@ -96,12 +96,10 @@
 #include <linux/init.h>
 #include <linux/version.h>
 #include <linux/slab.h>
-
 #include <asm/io.h>
 #include <asm/ioctl.h>
 #include <asm/uaccess.h>
-
-#include "sstfb.h"
+#include <video/sstfb.h>
 
 
 /* initialized by setup */
@@ -835,7 +833,7 @@
  * Screen-to-Screen BitBlt 2D command (for the bmove fb op.) - Voodoo2 only
  */
 #if 0
-static void sstfb_copyarea(struct fb_info *info, struct fb_copyarea *area)  
+static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
 	struct sstfb_par *par = (struct sstfb_par *) info->par;
 	u32 stride = info->fix.line_length;
@@ -860,7 +858,7 @@
 /*
  * FillRect 2D command (solidfill or invert (via ROP_XOR)) - Voodoo2 only
  */
-static void sstfb_fillrect(struct fb_info *info, struct fb_fillrect *rect) 
+static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 
 {
 	struct sstfb_par *par = (struct sstfb_par *) info->par;
 	u32 stride = info->fix.line_length;
@@ -1638,15 +1636,15 @@
 #endif
 }
 
-static void sstfb_fillrect_softw( struct fb_info *info, struct fb_fillrect *rect)
+static void sstfb_fillrect_softw( struct fb_info *info, const struct fb_fillrect *rect)
 {
 	unsigned long fbbase_virt = (unsigned long) info->screen_base;
-	unsigned long p;
 	int x, y, w = info->var.bits_per_pixel == 16 ? 2 : 4;
-	u32 color = rect->color;
+	u32 color = rect->color, height = rect->height;
+	unsigned long p;
 	
 	if (w==2) color |= color<<16;
-	for (y=rect->dy; rect->height; y++, rect->height--) {
+	for (y=rect->dy; height; y++, height--) {
 		p = fbbase_virt + y*info->fix.line_length + rect->dx*w;
 		x = rect->width;
 		if (w==2) x>>=1;
diff -Nru a/drivers/video/sstfb.h b/drivers/video/sstfb.h
--- a/drivers/video/sstfb.h	Mon Jan  6 14:40:01 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,355 +0,0 @@
-/*
- * linux/drivers/video/sstfb.h -- voodoo graphics frame buffer
- *
- *     Copyright (c) 2000,2001 Ghozlane Toumi <gtoumi@messel.emse.fr>
- *
- *     Created 28 Aug 2001 by Ghozlane Toumi
- */
-
-
-#ifndef _SSTFB_H_
-#define _SSTFB_H_
-
-/*
- *
- *  Debug Stuff
- *
- */
-
-#ifdef SST_DEBUG
-#  define dprintk(X...)		printk("sstfb: " X)
-#else
-#  define dprintk(X...)
-#  undef SST_DEBUG_REG
-#  undef SST_DEBUG_FUNC
-#  undef SST_DEBUG_VAR
-#endif
-
-#if (SST_DEBUG_REG > 0)
-#  define r_dprintk(X...)	dprintk(X)
-#else
-#  define r_dprintk(X...)
-#endif
-#if (SST_DEBUG_REG > 1)
-#  define r_ddprintk(X...)	dprintk(" " X)
-#else
-#  define r_ddprintk(X...)
-#endif
-
-#if (SST_DEBUG_FUNC > 0)
-#  define f_dprintk(X...)	dprintk(X)
-#else
-#  define f_dprintk(X...)
-#endif
-#if (SST_DEBUG_FUNC > 1)
-#  define f_ddprintk(X...)	dprintk(" " X)
-#else
-#  define f_ddprintk(X...)
-#endif
-#if (SST_DEBUG_FUNC > 2)
-#  define f_dddprintk(X...)	dprintk(" " X)
-#else
-#  define f_dddprintk(X...)
-#endif
-
-#if (SST_DEBUG_VAR > 0)
-#  define v_dprintk(X...)	dprintk(X)
-#  define print_var(V, X...)	\
-   {				\
-     dprintk(X);		\
-     printk(" :\n");		\
-     sst_dbg_print_var(V);	\
-   }
-#else
-#  define v_dprintk(X...)
-#  define print_var(X,Y...)
-#endif
-
-#define eprintk(X...)	printk(KERN_ERR "sstfb: " X)
-#define iprintk(X...)	printk(KERN_INFO "sstfb: " X)
-#define wprintk(X...)	printk(KERN_WARNING "sstfb: " X)
-
-#define BIT(x)		(1ul<<(x))
-#define POW2(x)		(1ul<<(x))
-
-#ifndef ABS
-# define ABS(x)		(((x)<0)?-(x):(x))
-#endif
-
-/*
- *
- *  Const
- *
- */
-
-/* pci stuff */
-#define PCI_INIT_ENABLE		0x40
-#  define PCI_EN_INIT_WR	  BIT(0)
-#  define PCI_EN_FIFO_WR	  BIT(1)
-#  define PCI_REMAP_DAC		  BIT(2)
-#define PCI_VCLK_ENABLE		0xc0	/* enable video */
-#define PCI_VCLK_DISABLE	0xe0
-
-/* register offsets from memBaseAddr */
-#define STATUS			0x0000
-#  define STATUS_FBI_BUSY	  BIT(7)
-#define FBZMODE			0x0110
-#  define EN_CLIPPING		  BIT(0)	/* enable clipping */
-#  define EN_RGB_WRITE		  BIT(9)	/* enable writes to rgb area */
-#  define EN_ALPHA_WRITE	  BIT(10)
-#  define ENGINE_INVERT_Y	  BIT(17)	/* invert Y origin (pipe) */
-#define LFBMODE			0x0114
-#  define LFB_565		  0		/* bits 3:0 .16 bits RGB */
-#  define LFB_888		  4		/* 24 bits RGB */
-#  define LFB_8888		  5		/* 32 bits ARGB */
-#  define WR_BUFF_FRONT		  0		/* write buf select (front) */
-#  define WR_BUFF_BACK		  (1 << 4)	/* back */
-#  define RD_BUFF_FRONT		  0		/* read buff select (front) */
-#  define RD_BUFF_BACK		  (1 << 6)	/* back */
-#  define EN_PXL_PIPELINE	  BIT(8)	/* pixel pipeline (clip..)*/
-#  define LFB_WORD_SWIZZLE_WR	  BIT(11)	/* enable write-wordswap (big-endian) */
-#  define LFB_BYTE_SWIZZLE_WR	  BIT(12)	/* enable write-byteswap (big-endian) */
-#  define LFB_INVERT_Y		  BIT(13)	/* invert Y origin (LFB) */
-#  define LFB_WORD_SWIZZLE_RD	  BIT(15)	/* enable read-wordswap (big-endian) */
-#  define LFB_BYTE_SWIZZLE_RD	  BIT(16)	/* enable read-byteswap (big-endian) */
-#define CLIP_LEFT_RIGHT		0x0118
-#define CLIP_LOWY_HIGHY		0x011c
-#define NOPCMD			0x0120
-#define FASTFILLCMD		0x0124
-#define SWAPBUFFCMD		0x0128
-#define FBIINIT4		0x0200		/* misc controls */
-#  define FAST_PCI_READS	  0		/* 1 waitstate */
-#  define SLOW_PCI_READS	  BIT(0)	/* 2 ws */
-#  define LFB_READ_AHEAD	  BIT(1)
-#define BACKPORCH		0x0208
-#define VIDEODIMENSIONS		0x020c
-#define FBIINIT0		0x0210		/* misc+fifo  controls */
-#  define EN_VGA_PASSTHROUGH	  BIT(0)
-#  define FBI_RESET		  BIT(1)
-#  define FIFO_RESET		  BIT(2)
-#define FBIINIT1		0x0214		/* PCI + video controls */
-#  define VIDEO_MASK		  0x8080010f	/* masks video related bits V1+V2*/
-#  define FAST_PCI_WRITES	  0		/* 0 ws */
-#  define SLOW_PCI_WRITES	  BIT(1)	/* 1 ws */
-#  define EN_LFB_READ		  BIT(3)
-#  define TILES_IN_X_SHIFT	  4
-#  define VIDEO_RESET		  BIT(8)
-#  define EN_BLANKING		  BIT(12)
-#  define EN_DATA_OE		  BIT(13)
-#  define EN_BLANK_OE		  BIT(14)
-#  define EN_HVSYNC_OE		  BIT(15)
-#  define EN_DCLK_OE		  BIT(16)
-#  define SEL_INPUT_VCLK_2X	  0		/* bit 17 */
-#  define SEL_INPUT_VCLK_SLAVE	  BIT(17)
-#  define SEL_SOURCE_VCLK_SLAVE	  0		/* bits 21:20 */
-#  define SEL_SOURCE_VCLK_2X_DIV2 (0x01 << 20)
-#  define SEL_SOURCE_VCLK_2X_SEL  (0x02 << 20)
-#  define EN_24BPP		  BIT(22)
-#  define TILES_IN_X_MSB_SHIFT	  24		/* v2 */
-#  define VCLK_2X_SEL_DEL_SHIFT	  27		/* vclk out delay 0,4,6,8ns */
-#  define VCLK_DEL_SHIFT	  29		/* vclk in delay */
-#define FBIINIT2		0x0218		/* Dram controls */
-#  define EN_FAST_RAS_READ	  BIT(5)
-#  define EN_DRAM_OE		  BIT(6)
-#  define EN_FAST_RD_AHEAD_WR	  BIT(7)
-#  define VIDEO_OFFSET_SHIFT	  11		/* unit: #rows tile 64x16/2 */
-#  define SWAP_DACVSYNC		  0
-#  define SWAP_DACDATA0		  (1 << 9)
-#  define SWAP_FIFO_STALL	  (2 << 9)
-#  define EN_RD_AHEAD_FIFO	  BIT(21)
-#  define EN_DRAM_REFRESH	  BIT(22)
-#  define DRAM_REFRESH_16	  (0x30 << 23)	/* dram 16 ms */
-#define DAC_READ		FBIINIT2	/* in remap mode */
-#define FBIINIT3		0x021c		/* fbi controls */
-#  define DISABLE_TEXTURE	  BIT(6)
-#  define Y_SWAP_ORIGIN_SHIFT	  22		/* Y swap substraction value */
-#define HSYNC			0x0220
-#define VSYNC			0x0224
-#define DAC_DATA		0x022c
-#  define DAC_READ_CMD		  BIT(11)	/* set read dacreg mode */
-#define FBIINIT5		0x0244		/* v2 specific */
-#  define FBIINIT5_MASK		  0xfa40ffff    /* mask video bits*/
-#  define HDOUBLESCAN		  BIT(20)
-#  define VDOUBLESCAN		  BIT(21)
-#  define HSYNC_HIGH 		  BIT(23)
-#  define VSYNC_HIGH 		  BIT(24)
-#  define INTERLACE		  BIT(26)
-#define FBIINIT6		0x0248		/* v2 specific */
-#  define TILES_IN_X_LSB_SHIFT	  30		/* v2 */
-#define FBIINIT7		0x024c		/* v2 specific */
-
-#define BLTSRCBASEADDR		0x02c0	/* BitBLT Source base address */
-#define BLTDSTBASEADDR		0x02c4	/* BitBLT Destination base address */
-#define BLTXYSTRIDES		0x02c8	/* BitBLT Source and Destination strides */
-#define BLTSRCCHROMARANGE	0x02cc	/* BitBLT Source Chroma key range */
-#define BLTDSTCHROMARANGE	0x02d0	/* BitBLT Destination Chroma key range */
-#define BLTCLIPX		0x02d4	/* BitBLT Min/Max X clip values */
-#define BLTCLIPY		0x02d8	/* BitBLT Min/Max Y clip values */
-#define BLTSRCXY		0x02e0	/* BitBLT Source starting XY coordinates */
-#define BLTDSTXY		0x02e4	/* BitBLT Destination starting XY coordinates */
-#define BLTSIZE			0x02e8	/* BitBLT width and height */
-#define BLTROP			0x02ec	/* BitBLT Raster operations */
-#  define BLTROP_COPY		  0x0cccc
-#  define BLTROP_INVERT		  0x05555
-#  define BLTROP_XOR		  0x06666
-#define BLTCOLOR		0x02f0	/* BitBLT and foreground background colors */
-#define BLTCOMMAND		0x02f8	/* BitBLT command mode (v2 specific) */
-# define BLT_SCR2SCR_BITBLT	  0	  /* Screen-to-Screen BitBLT */
-# define BLT_CPU2SCR_BITBLT	  1	  /* CPU-to-screen BitBLT */
-# define BLT_RECFILL_BITBLT	  2	  /* BitBLT Rectangle Fill */
-# define BLT_16BPP_FMT		  2	  /* 16 BPP (5-6-5 RGB) */
-#define BLTDATA			0x02fc	/* BitBLT data for CPU-to-Screen BitBLTs */
-#  define LAUNCH_BITBLT		  BIT(31) /* Launch BitBLT in BltCommand, bltDstXY or bltSize */
-
-/* Dac Registers */
-#define DACREG_WMA		0x0	/* pixel write mode address */
-#define DACREG_LUT		0x01	/* color value */
-#define DACREG_RMR		0x02	/* pixel mask */
-#define DACREG_RMA		0x03	/* pixel read mode address */
-/*Dac registers in indexed mode (TI, ATT dacs) */
-#define DACREG_ADDR_I		DACREG_WMA
-#define DACREG_DATA_I		DACREG_RMR
-#define DACREG_RMR_I		0x00
-#define DACREG_CR0_I		0x01
-#  define DACREG_CR0_EN_INDEXED	  BIT(0)	/* enable indexec mode */
-#  define DACREG_CR0_8BIT	  BIT(1)	/* set dac to 8 bits/read */
-#  define DACREG_CR0_PWDOWN	  BIT(3)	/* powerdown dac */
-#  define DACREG_CR0_16BPP	  0x30		/* mode 3 */
-#  define DACREG_CR0_24BPP	  0x50		/* mode 5 */
-#define	DACREG_CR1_I		0x05
-#define DACREG_CC_I		0x06
-#  define DACREG_CC_CLKA	  BIT(7)	/* clk A controled by regs */
-#  define DACREG_CC_CLKA_C	  (2<<4)	/* clk A uses reg C */
-#  define DACREG_CC_CLKB	  BIT(3)	/* clk B controled by regs */
-#  define DACREG_CC_CLKB_D	  3		/* clkB uses reg D */
-#define DACREG_AC0_I		0x48		/* clock A reg C */
-#define DACREG_AC1_I		0x49
-#define DACREG_BD0_I		0x6c		/* clock B reg D */
-#define DACREG_BD1_I		0x6d
-
-/* identification constants */
-#define DACREG_MIR_TI		0x97
-#define DACREG_DIR_TI		0x09
-#define DACREG_MIR_ATT		0x84
-#define DACREG_DIR_ATT		0x09
-/* ics dac specific registers */
-#define DACREG_ICS_PLLWMA	0x04	/* PLL write mode address */
-#define DACREG_ICS_PLLDATA	0x05	/* PLL data /parameter */
-#define DACREG_ICS_CMD		0x06	/* command */
-#  define DACREG_ICS_CMD_16BPP	  0x50	/* ics color mode 6 (16bpp bypass)*/
-#  define DACREG_ICS_CMD_24BPP	  0x70	/* ics color mode 7 (24bpp bypass)*/
-#  define DACREG_ICS_CMD_PWDOWN BIT(0)	/* powerdown dac */
-#define DACREG_ICS_PLLRMA	0x07	/* PLL read mode address */
-/*
- * pll parameter register:
- * indexed : write addr to PLLWMA, write data in PLLDATA.
- * for reads use PLLRMA .
- * 8 freq registers (0-7) for video clock (CLK0)
- * 2 freq registers (a-b) for graphic clock (CLK1)
- */
-#define DACREG_ICS_PLL_CLK0_1_INI 0x55	/* initial pll M value for freq f1  */
-#define DACREG_ICS_PLL_CLK0_7_INI 0x71	/* f7 */
-#define DACREG_ICS_PLL_CLK1_B_INI 0x79	/* fb */
-#define DACREG_ICS_PLL_CTRL	0x0e
-#  define DACREG_ICS_CLK0	  BIT(5)
-#  define DACREG_ICS_CLK0_0	  0
-#  define DACREG_ICS_CLK1_A	  0	/* bit4 */
-
-/* sst default init registers */
-#define FBIINIT0_DEFAULT EN_VGA_PASSTHROUGH
-
-#define FBIINIT1_DEFAULT 	\
-	(			\
-	  FAST_PCI_WRITES	\
-/*	  SLOW_PCI_WRITES*/	\
-	| VIDEO_RESET		\
-	| 10 << TILES_IN_X_SHIFT\
-	| SEL_SOURCE_VCLK_2X_SEL\
-	| EN_LFB_READ		\
-	)
-
-#define FBIINIT2_DEFAULT	\
-	(			\
-	 SWAP_DACVSYNC		\
-	| EN_DRAM_OE		\
-	| DRAM_REFRESH_16	\
-	| EN_DRAM_REFRESH	\
-	| EN_FAST_RAS_READ	\
-	| EN_RD_AHEAD_FIFO	\
-	| EN_FAST_RD_AHEAD_WR	\
-	)
-
-#define FBIINIT3_DEFAULT 	\
-	( DISABLE_TEXTURE )
-
-#define FBIINIT4_DEFAULT	\
-	(			\
-	  FAST_PCI_READS	\
-/*	  SLOW_PCI_READS*/	\
-	| LFB_READ_AHEAD	\
-	)
-/* Careful with this one : writing back the data just read will trash the DAC
-   reading some fields give logic value on pins, but setting this field will
-   set the source signal driving the pin. conclusion : just use the default
-   as a base before writing back .
-*/
-#define FBIINIT6_DEFAULT	(0x0)
-
-/*
- *
- * Misc Const
- *
- */
-
-/* used to know witch clock to set */
-enum {
-	VID_CLOCK=0,
-	GFX_CLOCK=1,
-};
-
-/* freq max */
-#define DAC_FREF	14318	/* DAC reference freq (Khz) */
-#define VCO_MAX		260000
-
-/*
- *  driver structs
- */
-
-struct pll_timing {
-	unsigned int m;
-	unsigned int n;
-	unsigned int p;
-};
-
-struct dac_switch {
-	char * name;
-	int (*detect) (struct fb_info *info);
-	int (*set_pll) (struct fb_info *info, const struct pll_timing *t, const int clock);
-	void (*set_vidmod) (struct fb_info *info, const int bpp);
-};
-
-struct sst_spec {
-	char * name;
-	int default_gfx_clock;	/* 50000 for voodoo1, 75000 for voodoo2 */
-	int max_gfxclk; 	/* ! in Mhz ie 60 for voodoo 1 */
-};
-
-struct sstfb_par {
-	unsigned int yDim;
-	unsigned int hSyncOn;	/* hsync_len */
-	unsigned int hSyncOff;	/* left_margin + xres + right_margin */
-	unsigned int hBackPorch;/* left_margin */
-	unsigned int vSyncOn;
-	unsigned int vSyncOff;
-	unsigned int vBackPorch;
-	struct pll_timing pll;
-	unsigned int tiles_in_X;/* num of tiles in X res */
-	unsigned long mmio_vbase;
-	struct dac_switch 	dac_sw;	/* dac specific functions */
-	struct pci_dev		*dev;
-	int	type;
-	u8	revision;
-	int	gfx_clock;	/* status */
-};
-
-#endif /* _SSTFB_H_ */
diff -Nru a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
--- a/drivers/video/tdfxfb.c	Tue Jan 14 14:48:30 2003
+++ b/drivers/video/tdfxfb.c	Mon Mar  3 19:41:18 2003
@@ -162,9 +162,9 @@
 			    u_int transp, struct fb_info *info); 
 static int tdfxfb_blank(int blank, struct fb_info *info); 
 static int tdfxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
-static void tdfxfb_fillrect(struct fb_info *info, struct fb_fillrect *rect);
-static void tdfxfb_copyarea(struct fb_info *info, struct fb_copyarea *area);  
-static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *image); 
+static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
+static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);  
+static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image); 
 static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor);
 static int banshee_wait_idle(struct fb_info *info);
 
@@ -872,7 +872,7 @@
 /*
  * FillRect 2D command (solidfill or invert (via ROP_XOR))   
  */
-static void tdfxfb_fillrect(struct fb_info *info, struct fb_fillrect *rect) 
+static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 
 {
 	struct tdfx_par *par = (struct tdfx_par *) info->par;
 	u32 bpp = info->var.bits_per_pixel;
@@ -897,25 +897,26 @@
 /*
  * Screen-to-Screen BitBlt 2D command (for the bmove fb op.) 
  */
-static void tdfxfb_copyarea(struct fb_info *info, struct fb_copyarea *area)  
+static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)  
 {
 	struct tdfx_par *par = (struct tdfx_par *) info->par;
+   	u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
 	u32 bpp = info->var.bits_per_pixel;
 	u32 stride = info->fix.line_length;
 	u32 blitcmd = COMMAND_2D_S2S_BITBLT | (TDFX_ROP_COPY << 24);
 	u32 fmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); 
-   
+	
 	if (area->sx <= area->dx) {
 		//-X 
 		blitcmd |= BIT(14);
-		area->sx += area->width - 1;
-		area->dx += area->width - 1;
+		sx += area->width - 1;
+		dx += area->width - 1;
 	}
 	if (area->sy <= area->dy) {
 		//-Y  
 		blitcmd |= BIT(15);
-		area->sy += area->height - 1;
-		area->dy += area->height - 1;
+		sy += area->height - 1;
+		dy += area->height - 1;
 	}
    
 	banshee_make_room(par, 6);
@@ -924,12 +925,12 @@
 	tdfx_outl(par,	DSTFORMAT, fmt);
 	tdfx_outl(par,	COMMAND_2D, blitcmd); 
 	tdfx_outl(par,	DSTSIZE,   area->width | (area->height << 16));
-	tdfx_outl(par,	DSTXY,     area->dx | (area->dy << 16));
-	tdfx_outl(par,	LAUNCH_2D, area->sx | (area->sy << 16)); 
+	tdfx_outl(par,	DSTXY,     dx | (dy << 16));
+	tdfx_outl(par,	LAUNCH_2D, sx | (sy << 16)); 
 	banshee_wait_idle(info);
 }
 
-static void tdfxfb_imageblit(struct fb_info *info, struct fb_image *pixmap) 
+static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *pixmap) 
 {
 	struct tdfx_par *par = (struct tdfx_par *) info->par;
 	int size = pixmap->height*((pixmap->width*pixmap->depth + 7)>>3);
@@ -939,7 +940,7 @@
 	u8 *chardata = (u8 *) pixmap->data;
 	u32 srcfmt;
 
-	if (pixmap->depth != 1) {
+	if (pixmap->depth != 0) {
 		//banshee_make_room(par, 6 + ((size + 3) >> 2));
 		//srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000;
 		cfb_imageblit(info, pixmap);
@@ -1069,7 +1070,7 @@
 		 * the two monochrome patterns.
 		 */
 		u8 *cursorbase = (u8 *) info->cursor.image.data;
-		char *bitmap = cursor->image.data;
+		char *bitmap = (char *)cursor->image.data;
 		char *mask = cursor->mask;
 		int i, j, k, h = 0;
 
diff -Nru a/drivers/video/tgafb.c b/drivers/video/tgafb.c
--- a/drivers/video/tgafb.c	Thu Jan  2 02:11:34 2003
+++ b/drivers/video/tgafb.c	Mon Mar  3 19:41:18 2003
@@ -22,12 +22,10 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/fb.h>
-#include <linux/selection.h>
 #include <linux/pci.h>
 #include <asm/io.h>
 #include <video/tgafb.h>
 
-
 /*
  * Local functions.
  */
@@ -40,9 +38,9 @@
 static int tgafb_blank(int, struct fb_info *);
 static void tgafb_init_fix(struct fb_info *);
 
-static void tgafb_imageblit(struct fb_info *, struct fb_image *);
-static void tgafb_fillrect(struct fb_info *, struct fb_fillrect *);
-static void tgafb_copyarea(struct fb_info *, struct fb_copyarea *);
+static void tgafb_imageblit(struct fb_info *, const struct fb_image *);
+static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *);
+static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *);
 
 static int tgafb_pci_register(struct pci_dev *, const struct pci_device_id *);
 #ifdef MODULE
@@ -520,7 +518,7 @@
  *      @image: structure defining the image.
  */
 static void
-tgafb_imageblit(struct fb_info *info, struct fb_image *image)
+tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
 	static unsigned char const bitrev[256] = {
 		0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
@@ -585,7 +583,7 @@
 	   can do better than the generic code.  */
 	/* ??? There is a DMA write mode; I wonder if that could be
 	   made to pull the data from the image buffer...  */
-	if (image->depth > 1) {
+	if (image->depth > 0) {
 		cfb_imageblit(info, image);
 		return;
 	}
@@ -779,7 +777,7 @@
  *      @rect: structure defining the rectagle and operation.
  */
 static void
-tgafb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+tgafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
 	struct tga_par *par = (struct tga_par *) info->par;
 	int is8bpp = info->var.bits_per_pixel == 8;
@@ -1162,7 +1160,7 @@
 static inline void
 copyarea_backward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,
 		       u32 height, u32 width, u32 line_length,
-		       struct fb_copyarea *area)
+		       const struct fb_copyarea *area)
 {
 	struct tga_par *par = (struct tga_par *) info->par;
 	unsigned long i, left, yincr;
@@ -1261,7 +1259,7 @@
 }
 
 static void
-tgafb_copyarea(struct fb_info *info, struct fb_copyarea *area) 
+tgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 
 {
 	unsigned long dx, dy, width, height, sx, sy, vxres, vyres;
 	unsigned long line_length, bpp;
diff -Nru a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
--- a/drivers/video/tridentfb.c	Sat Jan 11 10:28:32 2003
+++ b/drivers/video/tridentfb.c	Mon Mar  3 19:41:18 2003
@@ -451,7 +451,7 @@
  * Accel functions called by the upper layers
  */
 
-static void tridentfb_fillrect(struct fb_info * info, struct fb_fillrect *fr)
+static void tridentfb_fillrect(struct fb_info * info, const struct fb_fillrect *fr)
 {
 	int bpp = info->var.bits_per_pixel;
 	int dx,dy,w,h,col;
@@ -468,7 +468,7 @@
 	acc->fill_rect(fr->dx, fr->dy, fr->width, fr->height, col, fr->rop);
 	acc->wait_engine();
 }
-static void tridentfb_copyarea(struct fb_info *info, struct fb_copyarea *ca)
+static void tridentfb_copyarea(struct fb_info *info, const struct fb_copyarea *ca)
 {
 	acc->copy_rect(ca->sx,ca->sy,ca->dx,ca->dy,ca->width,ca->height);
 	acc->wait_engine();
diff -Nru a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
--- a/drivers/video/vga16fb.c	Sat Dec 28 14:39:38 2002
+++ b/drivers/video/vga16fb.c	Mon Mar  3 19:41:19 2003
@@ -305,7 +305,8 @@
 
 	if (!cnt) {
 		memset(&par->state, 0, sizeof(struct vgastate));
-		par->state.flags = 8;
+		par->state.flags = VGA_SAVE_FONTS | VGA_SAVE_MODE |
+			VGA_SAVE_CMAP;
 		save_vga(&par->state);
 	}
 	atomic_inc(&par->ref_count);
@@ -874,8 +875,9 @@
 	return 0;
 }
 
-void vga_8planes_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+void vga_8planes_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
+	u32 dx = rect->dx, width = rect->width;
         char oldindex = getindex();
         char oldmode = setmode(0x40);
         char oldmask = selectmask();
@@ -883,15 +885,15 @@
         char oldop, oldsr;
         char *where;
 
-        rect->dx /= 4;
-        where = info->screen_base + rect->dx + rect->dy * info->fix.line_length;
+        dx /= 4;
+        where = info->screen_base + dx + rect->dy * info->fix.line_length;
 
         if (rect->rop == ROP_COPY) {
                 oldop = setop(0);
                 oldsr = setsr(0);
 
-                rect->width /= 4;
-                line_ofs = info->fix.line_length - rect->width;
+                width /= 4;
+                line_ofs = info->fix.line_length - width;
                 setmask(0xff);
 
                 height = rect->height;
@@ -900,7 +902,7 @@
                         int x;
 
                         /* we can do memset... */
-                        for (x = rect->width; x > 0; --x) {
+                        for (x = width; x > 0; --x) {
                                 writeb(rect->color, where);
                                 where++;
                         }
@@ -927,7 +929,7 @@
         setindex(oldindex);
 }
 
-void vga16fb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+void vga16fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
 	int x, x2, y2, vxres, vyres, width, height, line_ofs;
 	char *dst;
@@ -945,7 +947,7 @@
 	y2 = rect->dy + rect->height;
 	x2 = x2 < vxres ? x2 : vxres;
 	y2 = y2 < vyres ? y2 : vyres;
-	rect->width = x2 - rect->dx;
+	width = x2 - rect->dx;
 
 	switch (info->fix.type) {
 	case FB_TYPE_VGA_PLANES:
@@ -1002,27 +1004,28 @@
 	}
 }
 
-void vga_8planes_copyarea(struct fb_info *info, struct fb_copyarea *area)
+void vga_8planes_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
-        int height, line_ofs, x;
         char oldindex = getindex();
         char oldmode = setmode(0x41);
         char oldop = setop(0);
         char oldsr = setsr(0xf);
-        char *dest, *src;
+        int height, line_ofs, x;
+	u32 sx, dx, width;
+	char *dest, *src;
 
         height = area->height;
 
-        area->sx = area->sx / 4;
-        area->dx = area->dx / 4;
-        area->width = area->width / 4;
-
-        if (area->dy < area->sy || (area->dy == area->sy && area->dx < area->sx)) {
-                line_ofs = info->fix.line_length - area->width;
-                dest = info->screen_base + area->dx + area->dy * info->fix.line_length;
-                src = info->screen_base + area->sx + area->sy * info->fix.line_length;
+        sx = area->sx / 4;
+        dx = area->dx / 4;
+        width = area->width / 4;
+
+        if (area->dy < area->sy || (area->dy == area->sy && dx < sx)) {
+                line_ofs = info->fix.line_length - width;
+                dest = info->screen_base + dx + area->dy * info->fix.line_length;
+                src = info->screen_base + sx + area->sy * info->fix.line_length;
                 while (height--) {
-                        for (x = 0; x < area->width; x++) {
+                        for (x = 0; x < width; x++) {
                                 readb(src);
                                 writeb(0, dest);
                                 src++;
@@ -1032,13 +1035,13 @@
                         dest += line_ofs;
                 }
         } else {
-                line_ofs = info->fix.line_length - area->width;
-                dest = info->screen_base + area->dx + area->width +
+                line_ofs = info->fix.line_length - width;
+                dest = info->screen_base + dx + width +
 			(area->dy + height - 1) * info->fix.line_length;
-                src = info->screen_base + area->sx + area->width +
+                src = info->screen_base + sx + width +
 			(area->sy + height - 1) * info->fix.line_length;
                 while (height--) {
-                        for (x = 0; x < area->width; x++) {
+                        for (x = 0; x < width; x++) {
                                 --src;
                                 --dest;
                                 readb(src);
@@ -1055,8 +1058,9 @@
         setindex(oldindex);
 }
 
-void vga16fb_copyarea(struct fb_info *info, struct fb_copyarea *area)
+void vga16fb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
+	u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy; 
 	int x, x2, y2, old_dx, old_dy, vxres, vyres;
 	int height, width, line_ofs;
 	char *dst = NULL, *src = NULL;
@@ -1078,37 +1082,35 @@
 	 */
 	x2 = area->dx + area->width;
 	y2 = area->dy + area->height;
-	area->dx = area->dx > 0 ? area->dx : 0;
-	area->dy = area->dy > 0 ? area->dy : 0;
+	dx = area->dx > 0 ? area->dx : 0;
+	dy = area->dy > 0 ? area->dy : 0;
 	x2 = x2 < vxres ? x2 : vxres;
 	y2 = y2 < vyres ? y2 : vyres;
-	area->width = x2 - area->dx;
-	area->height = y2 - area->dy;
+	width = x2 - dx;
+	height = y2 - dy;
 
 	/* update sx1,sy1 */
-	area->sx += (area->dx - old_dx);
-	area->sy += (area->dy - old_dy);
+	sx += (dx - old_dx);
+	sy += (dy - old_dy);
 
 	/* the source must be completely inside the virtual screen */
-	if (area->sx < 0 || area->sy < 0 ||
-	    (area->sx + area->width) > vxres ||
-	    (area->sy + area->height) > vyres)
+	if (sx < 0 || sy < 0 || (sx + width) > vxres || (sy + height) > vyres)
 		return;
 
 	switch (info->fix.type) {
 	case FB_TYPE_VGA_PLANES:
 		if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
-			width = area->width/8;
-			height = area->height;
+			width = width/8;
+			height = height;
 			line_ofs = info->fix.line_length - width;
 
 			setmode(1);
 			setop(0);
 			setsr(0xf);
 
-			if (area->dy < area->sy || (area->dy == area->sy && area->dx < area->sx)) {
-				dst = info->screen_base + (area->dx/8) + area->dy * info->fix.line_length;
-				src = info->screen_base + (area->sx/8) + area->sy * info->fix.line_length;
+			if (dy < sy || (dy == sy && dx < sx)) {
+				dst = info->screen_base + (dx/8) + dy * info->fix.line_length;
+				src = info->screen_base + (sx/8) + sy * info->fix.line_length;
 				while (height--) {
 					for (x = 0; x < width; x++) {
 						readb(src);
@@ -1120,10 +1122,10 @@
 					dst += line_ofs;
 				}
 			} else {
-				dst = info->screen_base + (area->dx/8) + width + 
-					(area->dy + height - 1) * info->fix.line_length;
-				src = info->screen_base + (area->sx/8) + width + 
-					(area->sy + height  - 1) * info->fix.line_length;
+				dst = info->screen_base + (dx/8) + width + 
+					(dy + height - 1) * info->fix.line_length;
+				src = info->screen_base + (sx/8) + width + 
+					(sy + height  - 1) * info->fix.line_length;
 				while (height--) {
 					for (x = 0; x < width; x++) {
 						dst--;
@@ -1163,19 +1165,20 @@
 #endif
 #endif
 
-void vga_8planes_imageblit(struct fb_info *info, struct fb_image *image)
+void vga_8planes_imageblit(struct fb_info *info, const struct fb_image *image)
 {
         char oldindex = getindex();
         char oldmode = setmode(0x40);
         char oldop = setop(0);
         char oldsr = setsr(0);
         char oldmask = selectmask();
-        u8 *cdat = image->data;
+        const char *cdat = image->data;
+	u32 dx = image->dx;
         char *where;
         int y;
 
-        image->dx /= 4;
-        where = info->screen_base + image->dx + image->dy * info->fix.line_length;
+        dx /= 4;
+        where = info->screen_base + dx + image->dy * info->fix.line_length;
 
         setmask(0xff);
         writeb(image->bg_color, where);
@@ -1193,12 +1196,12 @@
         setindex(oldindex);
 }
 
-void vga_imageblit_expand(struct fb_info *info, struct fb_image *image)
+void vga_imageblit_expand(struct fb_info *info, const struct fb_image *image)
 {
 	char *where = info->screen_base + (image->dx/8) + 
 		image->dy * info->fix.line_length;
 	struct vga16fb_par *par = (struct vga16fb_par *) info->par;
-	u8 *cdat = image->data, *dst;
+	char *cdat = (char *) image->data, *dst;
 	int x, y;
 
 	switch (info->fix.type) {
@@ -1256,7 +1259,7 @@
 	}
 }
 
-void vga_imageblit_color(struct fb_info *info, struct fb_image *image) 
+void vga_imageblit_color(struct fb_info *info, const struct fb_image *image) 
 {
 	/*
 	 * Draw logo 
@@ -1264,7 +1267,7 @@
 	struct vga16fb_par *par = (struct vga16fb_par *) info->par;
 	char *where = info->screen_base + image->dy * info->fix.line_length + 
 		image->dx/8;
-	char *cdat = image->data, *dst;
+	const char *cdat = image->data, *dst;
 	int x, y;
 
 	switch (info->fix.type) {
@@ -1299,9 +1302,9 @@
 	}
 }
 				
-void vga16fb_imageblit(struct fb_info *info, struct fb_image *image)
+void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
-	if (image->depth == 1)
+	if (image->depth == 0)
 		vga_imageblit_expand(info, image);
 	else if (image->depth == info->var.bits_per_pixel)
 		vga_imageblit_color(info, image);
diff -Nru a/fs/Kconfig b/fs/Kconfig
--- a/fs/Kconfig	Sun Mar 16 11:38:31 2003
+++ b/fs/Kconfig	Fri Mar 21 10:23:06 2003
@@ -1357,6 +1357,35 @@
 	tristate
 	default NFSD
 
+config SUNRPC
+	tristate
+	default m if NFS_FS!=y && NFSD!=y && (NFS_FS=m || NFSD=m)
+	default y if NFS_FS=y || NFSD=y
+
+config SUNRPC_GSS
+	tristate "Provide RPCSEC_GSS authentication (EXPERIMENTAL)"
+	depends on SUNRPC && EXPERIMENTAL
+	default SUNRPC if NFS_V4=y
+	help
+	  Provides cryptographic authentication for NFS rpc requests.  To
+	  make this useful, you must also select at least one rpcsec_gss
+	  mechanism.
+	  Note: You should always select this option if you wish to use
+	  NFSv4.
+
+config RPCSEC_GSS_KRB5
+	tristate "Kerberos V mechanism for RPCSEC_GSS (EXPERIMENTAL)"
+	depends on SUNRPC_GSS && CRYPTO_DES && CRYPTO_MD5
+	default SUNRPC_GSS if NFS_V4=y
+	help
+	  Provides a gss-api mechanism based on Kerberos V5 (this is
+	  mandatory for RFC3010-compliant NFSv4 implementations).
+	  Requires a userspace daemon;
+		see http://www.citi.umich.edu/projects/nfsv4/.
+
+	  Note: If you select this option, please ensure that you also
+	  enable the MD5 and DES crypto ciphers.
+
 config SMB_FS
 	tristate "SMB file system support (to mount Windows shares etc.)"
 	depends on INET
@@ -1460,6 +1489,8 @@
 	  will be called ncpfs.  Say N unless you are connected to a Novell
 	  network.
 
+source "fs/ncpfs/Kconfig"
+
 config CODA_FS
 	tristate "Coda file system support (advanced network fs)"
 	depends on INET
@@ -1496,37 +1527,6 @@
 	  If you say Y or M your kernel or module will provide InterMezzo
 	  support.  You will also need a file server daemon, which you can get
 	  from <http://www.inter-mezzo.org/>.
-
-config SUNRPC
-	tristate
-	default m if NFS_FS!=y && NFSD!=y && (NFS_FS=m || NFSD=m)
-	default y if NFS_FS=y || NFSD=y
-
-config SUNRPC_GSS
-	tristate "Provide RPCSEC_GSS authentication (EXPERIMENTAL)"
-	depends on SUNRPC && EXPERIMENTAL
-	default SUNRPC if NFS_V4=y
-	help
-	  Provides cryptographic authentication for NFS rpc requests.  To
-	  make this useful, you must also select at least one rpcsec_gss
-	  mechanism.
-	  Note: You should always select this option if you wish to use
-	  NFSv4.
-
-config RPCSEC_GSS_KRB5
-	tristate "Kerberos V mechanism for RPCSEC_GSS (EXPERIMENTAL)"
-	depends on SUNRPC_GSS && CRYPTO_DES && CRYPTO_MD5
-	default SUNRPC_GSS if NFS_V4=y
-	help
-	  Provides a gss-api mechanism based on Kerberos V5 (this is
-	  mandatory for RFC3010-compliant NFSv4 implementations).
-	  Requires a userspace daemon;
-		see http://www.citi.umich.edu/projects/nfsv4/.
-
-	  Note: If you select this option, please ensure that you also
-	  enable the MD5 and DES crypto ciphers.
-
-source "fs/ncpfs/Kconfig"
 
 config AFS_FS
 # for fs/nls/Config.in
diff -Nru a/fs/affs/super.c b/fs/affs/super.c
--- a/fs/affs/super.c	Mon Mar 17 07:57:43 2003
+++ b/fs/affs/super.c	Tue Mar 18 05:15:12 2003
@@ -298,8 +298,7 @@
 	if (!sbi)
 		return -ENOMEM;
 	sb->s_fs_info = sbi;
-	memset(sbi, 0, sizeof(struct affs_sb_info));
-
+	memset(sbi, 0, sizeof(*sbi));
 	init_MUTEX(&sbi->s_bmlock);
 
 	if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block,
diff -Nru a/fs/attr.c b/fs/attr.c
--- a/fs/attr.c	Mon Dec  2 12:31:03 2002
+++ b/fs/attr.c	Sun Mar 16 00:39:53 2003
@@ -68,16 +68,10 @@
 	int error = 0;
 
 	if (ia_valid & ATTR_SIZE) {
-		if (attr->ia_size == inode->i_size) {
-			if (ia_valid == ATTR_SIZE)
-				goto out;	/* we can skip lock_kernel() */
-		} else {
-			lock_kernel();
+		if (attr->ia_size != inode->i_size)
 			error = vmtruncate(inode, attr->ia_size);
-			unlock_kernel();
-			if (error)
-				goto out;
-		}
+		if (error || (ia_valid == ATTR_SIZE))
+			goto out;
 	}
 
 	lock_kernel();
diff -Nru a/fs/autofs/inode.c b/fs/autofs/inode.c
--- a/fs/autofs/inode.c	Sun Nov 17 11:53:57 2002
+++ b/fs/autofs/inode.c	Thu Mar 13 16:52:26 2003
@@ -16,7 +16,6 @@
 #include <linux/file.h>
 #include <asm/bitops.h>
 #include "autofs_i.h"
-#define __NO_VERSION__
 #include <linux/module.h>
 
 static void autofs_put_super(struct super_block *sb)
diff -Nru a/fs/autofs4/inode.c b/fs/autofs4/inode.c
--- a/fs/autofs4/inode.c	Mon Oct  7 10:27:57 2002
+++ b/fs/autofs4/inode.c	Thu Mar 13 16:52:26 2003
@@ -16,7 +16,6 @@
 #include <linux/pagemap.h>
 #include <asm/bitops.h>
 #include "autofs_i.h"
-#define __NO_VERSION__
 #include <linux/module.h>
 
 static void ino_lnkfree(struct autofs_info *ino)
diff -Nru a/fs/befs/debug.c b/fs/befs/debug.c
--- a/fs/befs/debug.c	Tue Oct 22 07:39:38 2002
+++ b/fs/befs/debug.c	Thu Mar 20 10:47:37 2003
@@ -80,7 +80,7 @@
 
 	befs_block_run tmp_run;
 
-	befs_debug(sb, "befs_inode infomation");
+	befs_debug(sb, "befs_inode information");
 
 	befs_debug(sb, "  magic1 %08x", fs32_to_cpu(sb, inode->magic1));
 
diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c
--- a/fs/binfmt_elf.c	Sat Mar  8 14:50:42 2003
+++ b/fs/binfmt_elf.c	Mon Mar 17 21:31:50 2003
@@ -452,6 +452,7 @@
 	unsigned int size;
 	unsigned long elf_entry, interp_load_addr = 0;
 	unsigned long start_code, end_code, start_data, end_data;
+	unsigned long reloc_func_desc = 0;
 	struct elfhdr elf_ex;
 	struct elfhdr interp_elf_ex;
   	struct exec interp_ex;
@@ -695,6 +696,7 @@
 				load_bias += error -
 				             ELF_PAGESTART(load_bias + vaddr);
 				load_addr += load_bias;
+				reloc_func_desc = load_addr;
 			}
 		}
 		k = elf_ppnt->p_vaddr;
@@ -742,6 +744,7 @@
 			retval = -ENOEXEC; /* Nobody gets to see this, but.. */
 			goto out;
 		}
+		reloc_func_desc = interp_load_addr;
 	} else {
 		elf_entry = elf_ex.e_entry;
 	}
@@ -789,10 +792,14 @@
 	/*
 	 * The ABI may specify that certain registers be set up in special
 	 * ways (on i386 %edx is the address of a DT_FINI function, for
-	 * example.  This macro performs whatever initialization to
-	 * the regs structure is required.
+	 * example.  In addition, it may also specify (eg, PowerPC64 ELF)
+	 * that the e_entry field is the address of the function descriptor
+	 * for the startup routine, rather than the address of the startup
+	 * routine itself.  This macro performs whatever initialization to
+	 * the regs structure is required as well as any relocations to the
+	 * function descriptor entries when executing dynamically links apps.
 	 */
-	ELF_PLAT_INIT(regs);
+	ELF_PLAT_INIT(regs, reloc_func_desc);
 #endif
 
 	start_thread(regs, elf_entry, bprm->p);
diff -Nru a/fs/bio.c b/fs/bio.c
--- a/fs/bio.c	Tue Feb 25 09:18:00 2003
+++ b/fs/bio.c	Sun Mar 23 01:40:11 2003
@@ -7,7 +7,6 @@
  *
  * 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.
  *
@@ -17,6 +16,7 @@
  *
  */
 #include <linux/mm.h>
+#include <linux/swap.h>
 #include <linux/bio.h>
 #include <linux/blk.h>
 #include <linux/slab.h>
diff -Nru a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c	Sun Mar  2 18:13:32 2003
+++ b/fs/buffer.c	Sat Mar 22 22:14:13 2003
@@ -155,8 +155,10 @@
 
 static void buffer_io_error(struct buffer_head *bh)
 {
+	char b[BDEVNAME_SIZE];
+
 	printk(KERN_ERR "Buffer I/O error on device %s, logical block %Lu\n",
-			bdevname(bh->b_bdev),
+			bdevname(bh->b_bdev, b),
 			(unsigned long long)bh->b_blocknr);
 }
 
@@ -532,7 +534,7 @@
  * Completion handler for block_write_full_page() - pages which are unlocked
  * during I/O, and which have PageWriteback cleared upon I/O completion.
  */
-static void end_buffer_async_write(struct buffer_head *bh, int uptodate)
+void end_buffer_async_write(struct buffer_head *bh, int uptodate)
 {
 	static spinlock_t page_uptodate_lock = SPIN_LOCK_UNLOCKED;
 	unsigned long flags;
diff -Nru a/fs/char_dev.c b/fs/char_dev.c
--- a/fs/char_dev.c	Mon Mar 10 12:22:35 2003
+++ b/fs/char_dev.c	Sat Mar 22 22:14:19 2003
@@ -19,217 +19,183 @@
 
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
-#include <linux/tty.h>
-
-/* serial module kmod load support */
-struct tty_driver *get_tty_driver(kdev_t device);
-#define isa_tty_dev(ma)	(ma == TTY_MAJOR || ma == TTYAUX_MAJOR)
-#define need_serial(ma,mi) (get_tty_driver(mk_kdev(ma,mi)) == NULL)
 #endif
 
-#define HASH_BITS	6
-#define HASH_SIZE	(1UL << HASH_BITS)
-#define HASH_MASK	(HASH_SIZE-1)
-static struct list_head cdev_hashtable[HASH_SIZE];
-static spinlock_t cdev_lock = SPIN_LOCK_UNLOCKED;
-static kmem_cache_t * cdev_cachep;
+#define MAX_PROBE_HASH 255	/* random */
+
+static rwlock_t chrdevs_lock = RW_LOCK_UNLOCKED;
 
-#define alloc_cdev() \
-	 ((struct char_device *) kmem_cache_alloc(cdev_cachep, SLAB_KERNEL))
-#define destroy_cdev(cdev) kmem_cache_free(cdev_cachep, (cdev))
+static struct char_device_struct {
+	struct char_device_struct *next;
+	unsigned int major;
+	unsigned int baseminor;
+	int minorct;
+	const char *name;
+	struct file_operations *fops;
+} *chrdevs[MAX_PROBE_HASH];
 
-static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
+/* index in the above */
+static inline int major_to_index(int major)
 {
-	struct char_device *cdev = (struct char_device *) foo;
-
-	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
-	    SLAB_CTOR_CONSTRUCTOR)
-		memset(cdev, 0, sizeof(*cdev));
+	return major % MAX_PROBE_HASH;
 }
 
-void __init cdev_cache_init(void)
+/* get char device names in somewhat random order */
+int get_chrdev_list(char *page)
 {
-	int i;
-	struct list_head *head = cdev_hashtable;
+	struct char_device_struct *cd;
+	int i, len;
 
-	i = HASH_SIZE;
-	do {
-		INIT_LIST_HEAD(head);
-		head++;
-		i--;
-	} while (i);
-
-	cdev_cachep = kmem_cache_create("cdev_cache",
-					 sizeof(struct char_device),
-					 0, SLAB_HWCACHE_ALIGN, init_once,
-					 NULL);
-	if (!cdev_cachep)
-		panic("Cannot create cdev_cache SLAB cache");
-}
+	len = sprintf(page, "Character devices:\n");
 
-/*
- * Most likely _very_ bad one - but then it's hardly critical for small
- * /dev and can be fixed when somebody will need really large one.
- */
-static inline unsigned long hash(dev_t dev)
-{
-	unsigned long tmp = dev;
-	tmp = tmp + (tmp >> HASH_BITS) + (tmp >> HASH_BITS*2);
-	return tmp & HASH_MASK;
-}
-
-static struct char_device *cdfind(dev_t dev, struct list_head *head)
-{
-	struct list_head *p;
-	struct char_device *cdev;
-	list_for_each(p, head) {
-		cdev = list_entry(p, struct char_device, hash);
-		if (cdev->dev != dev)
-			continue;
-		atomic_inc(&cdev->count);
-		return cdev;
-	}
-	return NULL;
-}
-
-struct char_device *cdget(dev_t dev)
-{
-	struct list_head * head = cdev_hashtable + hash(dev);
-	struct char_device *cdev, *new_cdev;
-	spin_lock(&cdev_lock);
-	cdev = cdfind(dev, head);
-	spin_unlock(&cdev_lock);
-	if (cdev)
-		return cdev;
-	new_cdev = alloc_cdev();
-	if (!new_cdev)
-		return NULL;
-	atomic_set(&new_cdev->count,1);
-	new_cdev->dev = dev;
-	spin_lock(&cdev_lock);
-	cdev = cdfind(dev, head);
-	if (!cdev) {
-		list_add(&new_cdev->hash, head);
-		spin_unlock(&cdev_lock);
-		return new_cdev;
+	read_lock(&chrdevs_lock);
+	for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) {
+		for (cd = chrdevs[i]; cd; cd = cd->next)
+			len += sprintf(page+len, "%3d %s\n",
+				       cd->major, cd->name);
 	}
-	spin_unlock(&cdev_lock);
-	destroy_cdev(new_cdev);
-	return cdev;
-}
+	read_unlock(&chrdevs_lock);
 
-void cdput(struct char_device *cdev)
-{
-	if (atomic_dec_and_lock(&cdev->count, &cdev_lock)) {
-		list_del(&cdev->hash);
-		spin_unlock(&cdev_lock);
-		destroy_cdev(cdev);
-	}
+	return len;
 }
 
-struct device_struct {
-	const char * name;
-	struct file_operations * fops;
-};
-
-static rwlock_t chrdevs_lock = RW_LOCK_UNLOCKED;
-static struct device_struct chrdevs[MAX_CHRDEV];
-
-int get_chrdev_list(char *page)
+/*
+ * Return the function table of a device, if present.
+ * Increment the reference count of module in question.
+ */
+static struct file_operations *
+lookup_chrfops(unsigned int major, unsigned int minor)
 {
+	struct char_device_struct *cd;
+	struct file_operations *ret = NULL;
 	int i;
-	int len;
 
-	len = sprintf(page, "Character devices:\n");
+	i = major_to_index(major);
+
 	read_lock(&chrdevs_lock);
-	for (i = 0; i < MAX_CHRDEV ; i++) {
-		if (chrdevs[i].fops) {
-			len += sprintf(page+len, "%3d %s\n", i, chrdevs[i].name);
+	for (cd = chrdevs[i]; cd; cd = cd->next) {
+		if (major == cd->major &&
+		    minor - cd->baseminor < cd->minorct) {
+			ret = fops_get(cd->fops);
+			break;
 		}
 	}
 	read_unlock(&chrdevs_lock);
-	return len;
+
+	return ret;
 }
 
 /*
-	Return the function table of a device.
-	Load the driver if needed.
-	Increment the reference count of module in question.
-*/
-static struct file_operations * get_chrfops(unsigned int major, unsigned int minor)
+ * Return the function table of a device, if present.
+ * Load the driver if needed.
+ * Increment the reference count of module in question.
+ */
+static struct file_operations *
+get_chrfops(unsigned int major, unsigned int minor)
 {
 	struct file_operations *ret = NULL;
 
-	if (!major || major >= MAX_CHRDEV)
+	if (!major)
 		return NULL;
 
-	read_lock(&chrdevs_lock);
-	ret = fops_get(chrdevs[major].fops);
-	read_unlock(&chrdevs_lock);
+	ret = lookup_chrfops(major, minor);
+
 #ifdef CONFIG_KMOD
-	if (ret && isa_tty_dev(major)) {
-		lock_kernel();
-		if (need_serial(major,minor)) {
-			/* Force request_module anyway, but what for? */
-			fops_put(ret);
-			ret = NULL;
-		}
-		unlock_kernel();
-	}
 	if (!ret) {
-		char name[20];
+		char name[32];
 		sprintf(name, "char-major-%d", major);
 		request_module(name);
 
 		read_lock(&chrdevs_lock);
-		ret = fops_get(chrdevs[major].fops);
+		ret = lookup_chrfops(major, minor);
 		read_unlock(&chrdevs_lock);
 	}
 #endif
 	return ret;
 }
 
-int register_chrdev(unsigned int major, const char * name, struct file_operations *fops)
+/*
+ * Register a single major with a specified minor range
+ */
+int register_chrdev_region(unsigned int major, unsigned int baseminor,
+			   int minorct, const char *name,
+			   struct file_operations *fops)
 {
+	struct char_device_struct *cd, **cp;
+	int ret = 0;
+	int i;
+
+	/* temporary */
 	if (major == 0) {
-		write_lock(&chrdevs_lock);
-		for (major = MAX_CHRDEV-1; major > 0; major--) {
-			if (chrdevs[major].fops == NULL) {
-				chrdevs[major].name = name;
-				chrdevs[major].fops = fops;
-				write_unlock(&chrdevs_lock);
-				return major;
-			}
-		}
-		write_unlock(&chrdevs_lock);
-		return -EBUSY;
-	}
-	if (major >= MAX_CHRDEV)
-		return -EINVAL;
+		read_lock(&chrdevs_lock);
+		for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--)
+			if (chrdevs[i] == NULL)
+				break;
+		read_unlock(&chrdevs_lock);
+
+		if (i == 0)
+			return -EBUSY;
+		ret = major = i;
+	}
+
+	cd = kmalloc(sizeof(struct char_device_struct), GFP_KERNEL);
+	if (cd == NULL)
+		return -ENOMEM;
+
+	cd->major = major;
+	cd->baseminor = baseminor;
+	cd->minorct = minorct;
+	cd->name = name;
+	cd->fops = fops;
+
+	i = major_to_index(major);
+
 	write_lock(&chrdevs_lock);
-	if (chrdevs[major].fops && chrdevs[major].fops != fops) {
-		write_unlock(&chrdevs_lock);
-		return -EBUSY;
+	for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
+		if ((*cp)->major > major ||
+		    ((*cp)->major == major && (*cp)->baseminor >= baseminor))
+			break;
+	if (*cp && (*cp)->major == major &&
+	    (*cp)->baseminor < baseminor + minorct) {
+		ret = -EBUSY;
+	} else {
+		cd->next = *cp;
+		*cp = cd;
 	}
-	chrdevs[major].name = name;
-	chrdevs[major].fops = fops;
 	write_unlock(&chrdevs_lock);
-	return 0;
+
+	return ret;
 }
 
+int register_chrdev(unsigned int major, const char *name,
+		    struct file_operations *fops)
+{
+	return register_chrdev_region(major, 0, 256, name, fops);
+}
+
+/* todo: make void - error printk here */
 int unregister_chrdev(unsigned int major, const char * name)
 {
-	if (major >= MAX_CHRDEV)
-		return -EINVAL;
+	struct char_device_struct *cd, **cp;
+	int ret = 0;
+	int i;
+
+	i = major_to_index(major);
+
 	write_lock(&chrdevs_lock);
-	if (!chrdevs[major].fops || strcmp(chrdevs[major].name, name)) {
-		write_unlock(&chrdevs_lock);
-		return -EINVAL;
+	for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
+		if ((*cp)->major == major)
+			break;
+	if (!*cp || strcmp((*cp)->name, name))
+		ret = -EINVAL;
+	else {
+		cd = *cp;
+		*cp = cd->next;
+		kfree(cd);
 	}
-	chrdevs[major].name = NULL;
-	chrdevs[major].fops = NULL;
 	write_unlock(&chrdevs_lock);
-	return 0;
+
+	return ret;
 }
 
 /*
@@ -260,13 +226,23 @@
 	.open = chrdev_open,
 };
 
-const char * cdevname(kdev_t dev)
+const char *cdevname(kdev_t dev)
 {
-	static char buffer[32];
-	const char * name = chrdevs[major(dev)].name;
+	static char buffer[40];
+	const char *name = "unknown-char";
+	unsigned int major = major(dev);
+	unsigned int minor = minor(dev);
+	int i = major_to_index(major);
+	struct char_device_struct *cd;
+
+	read_lock(&chrdevs_lock);
+	for (cd = chrdevs[i]; cd; cd = cd->next)
+		if (cd->major == major)
+			break;
+	if (cd)
+		name = cd->name;
+	sprintf(buffer, "%s(%d,%d)", name, major, minor);
+	read_unlock(&chrdevs_lock);
 
-	if (!name)
-		name = "unknown-char";
-	sprintf(buffer, "%s(%d,%d)", name, major(dev), minor(dev));
 	return buffer;
 }
diff -Nru a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
--- a/fs/cifs/cifs_debug.c	Fri Mar  7 15:01:07 2003
+++ b/fs/cifs/cifs_debug.c	Tue Mar 18 09:07:42 2003
@@ -22,7 +22,6 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <asm/uaccess.h>
diff -Nru a/fs/compat.c b/fs/compat.c
--- a/fs/compat.c	Sun Mar  9 01:34:45 2003
+++ b/fs/compat.c	Tue Mar 11 22:56:59 2003
@@ -191,7 +191,7 @@
 	case F_GETLK:
 	case F_SETLK:
 	case F_SETLKW:
-		ret = get_compat_flock(&f, (struct compat_flock *)arg);
+		ret = get_compat_flock(&f, compat_ptr(arg));
 		if (ret != 0)
 			break;
 		old_fs = get_fs();
@@ -203,15 +203,14 @@
 			    ((f.l_start + f.l_len) >= COMPAT_OFF_T_MAX))
 				ret = -EOVERFLOW;
 			if (ret == 0)
-				ret = put_compat_flock(&f,
-						(struct compat_flock *)arg);
+				ret = put_compat_flock(&f, compat_ptr(arg));
 		}
 		break;
 
 	case F_GETLK64:
 	case F_SETLK64:
 	case F_SETLKW64:
-		ret = get_compat_flock64(&f, (struct compat_flock64 *)arg);
+		ret = get_compat_flock64(&f, compat_ptr(arg));
 		if (ret != 0)
 			break;
 		old_fs = get_fs();
@@ -226,8 +225,7 @@
 			    ((f.l_start + f.l_len) >= COMPAT_LOFF_T_MAX))
 				ret = -EOVERFLOW;
 			if (ret == 0)
-				ret = put_compat_flock64(&f,
-						(struct compat_flock64 *)arg);
+				ret = put_compat_flock64(&f, compat_ptr(arg));
 		}
 		break;
 
diff -Nru a/fs/dcache.c b/fs/dcache.c
--- a/fs/dcache.c	Mon Mar 10 10:49:26 2003
+++ b/fs/dcache.c	Fri Mar 21 20:05:21 2003
@@ -24,6 +24,7 @@
 #include <linux/cache.h>
 #include <linux/module.h>
 #include <linux/mount.h>
+#include <linux/file.h>
 #include <asm/uaccess.h>
 #include <linux/security.h>
 
@@ -1562,7 +1563,6 @@
 EXPORT_SYMBOL(d_genocide);
 
 extern void bdev_cache_init(void);
-extern void cdev_cache_init(void);
 
 void __init vfs_caches_init(unsigned long mempages)
 {
@@ -1574,7 +1574,7 @@
 
 	filp_cachep = kmem_cache_create("filp", 
 			sizeof(struct file), 0,
-			SLAB_HWCACHE_ALIGN, NULL, NULL);
+			SLAB_HWCACHE_ALIGN, filp_ctor, filp_dtor);
 	if(!filp_cachep)
 		panic("Cannot create filp SLAB cache");
 
@@ -1583,5 +1583,4 @@
 	files_init(mempages); 
 	mnt_init(mempages);
 	bdev_cache_init();
-	cdev_cache_init();
 }
diff -Nru a/fs/dcookies.c b/fs/dcookies.c
--- a/fs/dcookies.c	Thu Oct 31 19:38:53 2002
+++ b/fs/dcookies.c	Sat Mar 22 22:14:57 2003
@@ -142,7 +142,7 @@
 /* And here is where the userspace process can look up the cookie value
  * to retrieve the path.
  */
-asmlinkage int sys_lookup_dcookie(u64 cookie64, char * buf, size_t len)
+asmlinkage long sys_lookup_dcookie(u64 cookie64, char * buf, size_t len)
 {
 	unsigned long cookie = (unsigned long)cookie64;
 	int err = -EINVAL;
diff -Nru a/fs/devfs/base.c b/fs/devfs/base.c
--- a/fs/devfs/base.c	Sun Mar 16 22:33:08 2003
+++ b/fs/devfs/base.c	Sat Mar 22 07:38:04 2003
@@ -758,7 +758,6 @@
     rwlock_t lock;                   /*  Lock for searching(R)/updating(W)   */
     struct devfs_entry *first;
     struct devfs_entry *last;
-    unsigned short num_removable;    /*  Lock for writing but not reading    */
     unsigned char no_more_additions:1;
 };
 
@@ -766,7 +765,6 @@
 {
     struct block_device_operations *ops;
     dev_t dev;
-    unsigned char removable:1;
 };
 
 struct cdev_type
@@ -916,7 +914,7 @@
  *	@de:  The handle to the devfs entry.
  */
 
-void devfs_put (devfs_handle_t de)
+static void devfs_put (devfs_handle_t de)
 {
     if (!de) return;
     VERIFY_ENTRY (de);
@@ -1017,7 +1015,6 @@
  *	_devfs_append_entry - Append a devfs entry to a directory's child list.
  *	@dir:  The directory to add to.
  *	@de:  The devfs entry to append.
- *	@removable: If TRUE, increment the count of removable devices for %dir.
  *	@old_de: If an existing entry exists, it will be written here. This may
  *		 be %NULL. An implicit devfs_get() is performed on this entry.
  *
@@ -1028,7 +1025,7 @@
  */
 
 static int _devfs_append_entry (devfs_handle_t dir, devfs_handle_t de,
-				int removable, devfs_handle_t *old_de)
+				devfs_handle_t *old_de)
 {
     int retval;
 
@@ -1056,7 +1053,6 @@
 	    if (dir->u.dir.first == NULL) dir->u.dir.first = de;
 	    else dir->u.dir.last->next = de;
 	    dir->u.dir.last = de;
-	    if (removable) ++dir->u.dir.num_removable;
 	    retval = 0;
 	}
 	else retval = -EEXIST;
@@ -1095,13 +1091,13 @@
 	 == NULL ) return NULL;
     new->u.cdev.dev = devfs_alloc_devnum (S_IFCHR |S_IRUSR |S_IWUSR);
     new->u.cdev.ops = &devfsd_fops;
-    _devfs_append_entry (root_entry, new, FALSE, NULL);
+    _devfs_append_entry (root_entry, new, NULL);
 #ifdef CONFIG_DEVFS_DEBUG
     if ( ( new = _devfs_alloc_entry (".stat", 0, S_IFCHR | S_IRUGO | S_IWUGO) )
 	 == NULL ) return NULL;
     new->u.cdev.dev = devfs_alloc_devnum (S_IFCHR | S_IRUGO | S_IWUGO);
     new->u.cdev.ops = &stat_fops;
-    _devfs_append_entry (root_entry, new, FALSE, NULL);
+    _devfs_append_entry (root_entry, new, NULL);
 #endif
     return root_entry;
 }   /*  End Function _devfs_get_root_entry  */
@@ -1164,7 +1160,7 @@
 	{
 	    de = _devfs_alloc_entry (name, next_pos, MODE_DIR);
 	    devfs_get (de);
-	    if ( !de || _devfs_append_entry (dir, de, FALSE, &old) )
+	    if ( !de || _devfs_append_entry (dir, de, &old) )
 	    {
 		devfs_put (de);
 		if ( !old || !S_ISDIR (old->mode) )
@@ -1498,7 +1494,6 @@
 	de->u.bdev.dev = dev;
 	de->u.cdev.autogen = devnum != 0;
 	de->u.bdev.ops = ops;
-	if (flags & DEVFS_FL_REMOVABLE) de->u.bdev.removable = TRUE;
     } else {
 	PRINTK ("(%s): illegal mode: %x\n", name, mode);
 	devfs_put (de);
@@ -1516,7 +1511,7 @@
 	de->inode.uid = 0;
 	de->inode.gid = 0;
     }
-    err = _devfs_append_entry(dir, de, flags & DEVFS_FL_REMOVABLE, NULL);
+    err = _devfs_append_entry(dir, de, NULL);
     if (err)
     {
 	PRINTK ("(%s): could not append to parent, err: %d\n", name, err);
@@ -1553,8 +1548,6 @@
     else de->next->prev = de->prev;
     de->prev = de;          /*  Indicate we're unhooked                      */
     de->next = NULL;        /*  Force early termination for <devfs_readdir>  */
-    if (S_ISBLK (de->mode) && de->u.bdev.removable )
-	--parent->u.dir.num_removable;
     return TRUE;
 }   /*  End Function _devfs_unhook  */
 
@@ -1614,8 +1607,7 @@
 }   /*  End Function devfs_unregister  */
 
 static int devfs_do_symlink (devfs_handle_t dir, const char *name,
-			     unsigned int flags, const char *link,
-			     devfs_handle_t *handle, void *info)
+			     const char *link, devfs_handle_t *handle)
 {
     int err;
     unsigned int linklength;
@@ -1645,10 +1637,10 @@
 	kfree (newlink);
 	return -ENOTDIR;
     }
-    de->info = info;
+    de->info = NULL;
     de->u.symlink.linkname = newlink;
     de->u.symlink.length = linklength;
-    if ( ( err = _devfs_append_entry (dir, de, FALSE, NULL) ) != 0 )
+    if ( ( err = _devfs_append_entry (dir, de, NULL) ) != 0 )
     {
 	PRINTK ("(%s): could not append to parent, err: %d\n", name, err);
 	devfs_put (dir);
@@ -1667,40 +1659,31 @@
 
 /**
  *	devfs_mk_symlink Create a symbolic link in the devfs namespace.
- *	@dir: The handle to the parent devfs directory entry. If this is %NULL the
- *		new name is relative to the root of the devfs.
- *	@name: The name of the entry.
- *	@flags: A set of bitwise-ORed flags (DEVFS_FL_*).
- *	@link: The destination name.
- *	@handle: The handle to the symlink entry is written here. This may be %NULL.
- *	@info: An arbitrary pointer which will be associated with the entry.
+ *	@from: The name of the entry.
+ *	@to: Name of the destination
  *
  *	Returns 0 on success, else a negative error code is returned.
  */
 
-int devfs_mk_symlink (devfs_handle_t dir, const char *name, unsigned int flags,
-		      const char *link, devfs_handle_t *handle, void *info)
+int devfs_mk_symlink(const char *from, const char *to)
 {
-    int err;
-    devfs_handle_t de;
+	devfs_handle_t de;
+	int err;
 
-    if (handle != NULL) *handle = NULL;
-    DPRINTK (DEBUG_REGISTER, "(%s)\n", name);
-    err = devfs_do_symlink (dir, name, flags, link, &de, info);
-    if (err) return err;
-    if (handle == NULL) de->vfs_deletable = TRUE;
-    else *handle = de;
-    devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, flags & DEVFS_FL_WAIT);
-    return 0;
-}   /*  End Function devfs_mk_symlink  */
+	err = devfs_do_symlink(NULL, from, to, &de);
+	if (!err) {
+		de->vfs_deletable = TRUE;
+		devfsd_notify(de, DEVFSD_NOTIFY_REGISTERED, 0);
+	}
+
+	return err;
+}
 
 
 /**
  *	devfs_mk_dir - Create a directory in the devfs namespace.
- *	@dir: The handle to the parent devfs directory entry. If this is %NULL the
  *		new name is relative to the root of the devfs.
- *	@name: The name of the entry.
- *	@info: An arbitrary pointer which will be associated with the entry.
+ *	@fmt: The name of the entry.
  *
  *	Use of this function is optional. The devfs_register() function
  *	will automatically create intermediate directories as needed. This function
@@ -1709,36 +1692,42 @@
  *	On failure %NULL is returned.
  */
 
-devfs_handle_t devfs_mk_dir (devfs_handle_t dir, const char *name, void *info)
+devfs_handle_t devfs_mk_dir(const char *fmt, ...)
 {
-    int err;
-    struct devfs_entry *de, *old;
+	struct devfs_entry *dir = NULL, *de = NULL, *old;
+	char buf[64];
+	va_list args;
+	int n;
 
-    if (name == NULL)
-    {
-	PRINTK ("(): NULL name pointer\n");
-	return NULL;
-    }
-    if ( ( de = _devfs_prepare_leaf (&dir, name, MODE_DIR) ) == NULL )
-    {
-	PRINTK ("(%s): could not prepare leaf\n", name);
-	return NULL;
-    }
-    de->info = info;
-    if ( ( err = _devfs_append_entry (dir, de, FALSE, &old) ) != 0 )
-    {
-	PRINTK ("(%s): could not append to dir: %p \"%s\", err: %d\n",
-		name, dir, dir->name, err);
-	devfs_put (old);
-	devfs_put (dir);
-	return NULL;
-    }
-    DPRINTK (DEBUG_REGISTER, "(%s): de: %p dir: %p \"%s\"\n",
-	     name, de, dir, dir->name);
-    devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, 0);
-    devfs_put (dir);
-    return de;
-}   /*  End Function devfs_mk_dir  */
+	va_start(args, fmt);
+	n = vsnprintf(buf, 64, fmt, args);
+	if (n >= 64 || !buf[0]) {
+		printk(KERN_WARNING "%s: invalid argument.", __FUNCTION__);
+		return NULL;
+	}
+
+	de = _devfs_prepare_leaf(&dir, buf, MODE_DIR);
+	if (!de) {
+		PRINTK("(%s): could not prepare leaf\n", buf);
+		return NULL;
+	}
+
+	de->info = NULL;
+	if (_devfs_append_entry(dir, de, &old)) {
+		PRINTK("(%s): could not append to dir: %p \"%s\"\n",
+				buf, dir, dir->name);
+		devfs_put(old);
+		goto out_put;
+	}
+	
+	DPRINTK(DEBUG_REGISTER, "(%s): de: %p dir: %p \"%s\"\n",
+			buf, de, dir, dir->name);
+	devfsd_notify(de, DEVFSD_NOTIFY_REGISTERED, 0);
+
+ out_put:
+	devfs_put(dir);
+	return de;
+}
 
 
 void devfs_remove(const char *fmt, ...)
@@ -1924,102 +1913,6 @@
 }   /*  End Function try_modload  */
 
 
-/**
- *	check_disc_changed - Check if a removable disc was changed.
- *	@de: The device.
- *
- *	Returns 1 if the media was changed, else 0.
- *
- *	This function may block, and may indirectly cause the parent directory
- *	contents to be changed due to partition re-reading.
- */
-
-static int check_disc_changed (struct devfs_entry *de)
-{
-	int tmp;
-	int retval = 0;
-	dev_t dev = de->u.bdev.dev;
-	extern int warn_no_part;
-
-	if (!S_ISBLK(de->mode))
-		return 0;
-	/* Ugly hack to disable messages about unable to read partition table */
-	tmp = warn_no_part;
-	warn_no_part = 0;
-	retval = __check_disk_change(dev);
-	warn_no_part = tmp;
-	return retval;
-}   /*  End Function check_disc_changed  */
-
-/**
- *	scan_dir_for_removable - Scan a directory for removable media devices and check media.
- *	@dir: The directory.
- *
- *	This function may block, and may indirectly cause the directory
- *	contents to be changed due to partition re-reading. The directory will
- *	be locked for reading.
- */
-
-static void scan_dir_for_removable (struct devfs_entry *dir)
-{
-    struct devfs_entry *de;
-
-    read_lock (&dir->u.dir.lock);
-    if (dir->u.dir.num_removable < 1) de = NULL;
-    else
-    {
-	for (de = dir->u.dir.first; de != NULL; de = de->next)
-	{
-	    if (S_ISBLK (de->mode) && de->u.bdev.removable) break;
-	}
-	devfs_get (de);
-    }
-    read_unlock (&dir->u.dir.lock);
-    if (de) check_disc_changed (de);
-    devfs_put (de);
-}   /*  End Function scan_dir_for_removable  */
-
-/**
- *	get_removable_partition - Get removable media partition.
- *	@dir: The parent directory.
- *	@name: The name of the entry.
- *	@namelen: The number of characters in <<name>>.
- *
- *	Returns 1 if the media was changed, else 0.
- *
- *	This function may block, and may indirectly cause the directory
- *	contents to be changed due to partition re-reading. The directory must
- *	be locked for reading upon entry, and will be unlocked upon exit.
- */
-
-static int get_removable_partition (struct devfs_entry *dir, const char *name,
-				    unsigned int namelen)
-{
-    int retval;
-    struct devfs_entry *de;
-
-    if (dir->u.dir.num_removable < 1)
-    {
-	read_unlock (&dir->u.dir.lock);
-	return 0;
-    }
-    for (de = dir->u.dir.first; de != NULL; de = de->next)
-    {
-	if (!S_ISBLK (de->mode) || !de->u.bdev.removable) continue;
-	if (strcmp (de->name, "disc") == 0) break;
-	/*  Support for names where the partition is appended to the disc name
-	 */
-	if (de->namelen >= namelen) continue;
-	if (strncmp (de->name, name, de->namelen) == 0) break;
-    }
-    devfs_get (de);
-    read_unlock (&dir->u.dir.lock);
-    retval = de ? check_disc_changed (de) : 0;
-    devfs_put (de);
-    return retval;
-}   /*  End Function get_removable_partition  */
-
-
 /*  Superblock operations follow  */
 
 static struct inode_operations devfs_iops;
@@ -2119,7 +2012,6 @@
     if ( S_ISCHR (de->mode) )
     {
 	inode->i_rdev = to_kdev_t(de->u.cdev.dev);
-	inode->i_cdev = cdget(de->u.cdev.dev);
     }
     else if ( S_ISBLK (de->mode) )
     {
@@ -2169,7 +2061,6 @@
     switch ( (long) file->f_pos )
     {
       case 0:
-	scan_dir_for_removable (parent);
 	err = (*filldir) (dirent, "..", 2, file->f_pos,
 			  parent_ino (file->f_dentry), DT_DIR);
 	if (err == -EINVAL) break;
@@ -2336,6 +2227,8 @@
     wait_queue_head_t wait_queue;
 };
 
+/* XXX: this doesn't handle the case where we got a negative dentry
+        but a devfs entry has been registered in the meanwhile */
 static int devfs_d_revalidate_wait (struct dentry *dentry, int flags)
 {
     struct inode *dir = dentry->d_parent->d_inode;
@@ -2380,6 +2273,7 @@
 	add_wait_queue (&lookup_info->wait_queue, &wait);
 	read_unlock (&parent->u.dir.lock);
 	schedule ();
+	remove_wait_queue (&lookup_info->wait_queue, &wait);
     }
     else read_unlock (&parent->u.dir.lock);
     return 1;
@@ -2407,18 +2301,7 @@
     if (parent == NULL) return ERR_PTR (-ENOENT);
     read_lock (&parent->u.dir.lock);
     de = _devfs_search_dir (parent, dentry->d_name.name, dentry->d_name.len);
-    if (de) read_unlock (&parent->u.dir.lock);
-    else
-    {   /*  Try re-reading the partition (media may have changed)  */
-	if ( get_removable_partition (parent, dentry->d_name.name,
-				      dentry->d_name.len) )  /*  Unlocks  */
-	{   /*  Media did change  */
-	    read_lock (&parent->u.dir.lock);
-	    de = _devfs_search_dir (parent, dentry->d_name.name,
-				    dentry->d_name.len);
-	    read_unlock (&parent->u.dir.lock);
-	}
-    }
+    read_unlock (&parent->u.dir.lock);
     lookup_info.de = de;
     init_waitqueue_head (&lookup_info.wait_queue);
     dentry->d_fsdata = &lookup_info;
@@ -2510,8 +2393,7 @@
     /*  First try to get the devfs entry for this directory  */
     parent = get_devfs_entry_from_vfs_inode (dir);
     if (parent == NULL) return -ENOENT;
-    err = devfs_do_symlink (parent, dentry->d_name.name, DEVFS_FL_NONE,
-			    symname, &de, NULL);
+    err = devfs_do_symlink (parent, dentry->d_name.name, symname, &de);
     DPRINTK (DEBUG_DISABLED, "(%s): errcode from <devfs_do_symlink>: %d\n",
 	     dentry->d_name.name, err);
     if (err < 0) return err;
@@ -2545,7 +2427,7 @@
     de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode);
     if (!de) return -ENOMEM;
     de->vfs_deletable = TRUE;
-    if ( ( err = _devfs_append_entry (parent, de, FALSE, NULL) ) != 0 )
+    if ( ( err = _devfs_append_entry (parent, de, NULL) ) != 0 )
 	return err;
     de->inode.uid = current->euid;
     de->inode.gid = current->egid;
@@ -2613,7 +2495,7 @@
 	de->u.cdev.dev = rdev;
     else if (S_ISBLK (mode))
 	de->u.bdev.dev = rdev;
-    if ( ( err = _devfs_append_entry (parent, de, FALSE, NULL) ) != 0 )
+    if ( ( err = _devfs_append_entry (parent, de, NULL) ) != 0 )
 	return err;
     de->inode.uid = current->euid;
     de->inode.gid = current->egid;
diff -Nru a/fs/devfs/util.c b/fs/devfs/util.c
--- a/fs/devfs/util.c	Wed Jan 15 12:57:36 2003
+++ b/fs/devfs/util.c	Sat Mar 22 07:37:12 2003
@@ -87,7 +87,6 @@
 int devfs_register_tape (devfs_handle_t de)
 {
     int pos;
-    devfs_handle_t slave;
     char name[32], dest[64];
     static unsigned int tape_counter;
     int n = tape_counter++;
@@ -96,7 +95,7 @@
     if (pos < 0) return -1;
     strncpy (dest + pos, "../", 3);
     sprintf (name, "tapes/tape%u", n);
-    devfs_mk_symlink (NULL, name, DEVFS_FL_DEFAULT, dest + pos, &slave, NULL);
+    devfs_mk_symlink (name, dest + pos);
     return n;
 }   /*  End Function devfs_register_tape  */
 EXPORT_SYMBOL(devfs_register_tape);
diff -Nru a/fs/exec.c b/fs/exec.c
--- a/fs/exec.c	Mon Feb 24 09:40:34 2003
+++ b/fs/exec.c	Mon Mar 17 21:32:01 2003
@@ -633,7 +633,7 @@
 		count = 1;
 	while (atomic_read(&oldsig->count) > count) {
 		oldsig->group_exit_task = current;
-		current->state = TASK_UNINTERRUPTIBLE;
+		__set_current_state(TASK_UNINTERRUPTIBLE);
 		spin_unlock_irq(lock);
 		schedule();
 		spin_lock_irq(lock);
diff -Nru a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
--- a/fs/exportfs/expfs.c	Wed Jan 15 05:40:50 2003
+++ b/fs/exportfs/expfs.c	Thu Mar 20 10:47:27 2003
@@ -447,7 +447,7 @@
  * @dentry:  the dentry to encode
  * @fh:      where to store the file handle fragment
  * @max_len: maximum length to store there
- * @connectable: whether to store parent infomation
+ * @connectable: whether to store parent information
  *
  * This default encode_fh function assumes that the 32 inode number
  * is suitable for locating an inode, and that the generation number
diff -Nru a/fs/ext2/dir.c b/fs/ext2/dir.c
--- a/fs/ext2/dir.c	Mon Mar 10 22:34:32 2003
+++ b/fs/ext2/dir.c	Sat Mar 22 22:14:09 2003
@@ -259,8 +259,6 @@
 	int need_revalidate = (filp->f_version != inode->i_version);
 	int ret = 0;
 
-	lock_kernel();
-
 	if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
 		goto done;
 
@@ -313,7 +311,6 @@
 	filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
 	filp->f_version = inode->i_version;
 	UPDATE_ATIME(inode);
-	unlock_kernel();
 	return 0;
 }
 
@@ -660,6 +657,7 @@
 }
 
 struct file_operations ext2_dir_operations = {
+	.llseek		= generic_file_llseek,
 	.read		= generic_read_dir,
 	.readdir	= ext2_readdir,
 	.ioctl		= ext2_ioctl,
diff -Nru a/fs/ext2/super.c b/fs/ext2/super.c
--- a/fs/ext2/super.c	Sat Mar  8 14:50:40 2003
+++ b/fs/ext2/super.c	Sun Mar 16 22:22:33 2003
@@ -598,6 +598,7 @@
 	es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
 	sbi->s_es = es;
 	sb->s_magic = le16_to_cpu(es->s_magic);
+	sb->s_flags |= MS_ONE_SECOND;
 	if (sb->s_magic != EXT2_SUPER_MAGIC) {
 		if (!silent)
 			printk ("VFS: Can't find ext2 filesystem on dev %s.\n",
diff -Nru a/fs/ext2/xattr.c b/fs/ext2/xattr.c
--- a/fs/ext2/xattr.c	Sat Mar  8 14:50:42 2003
+++ b/fs/ext2/xattr.c	Sat Mar 22 22:14:13 2003
@@ -82,8 +82,9 @@
 		printk("\n"); \
 	} while (0)
 # define ea_bdebug(bh, f...) do { \
+		char b[BDEVNAME_SIZE]; \
 		printk(KERN_DEBUG "block %s:%ld: ", \
-			bdevname(bh->b_bdev), bh->b_blocknr); \
+			bdevname(bh->b_bdev, b), bh->b_blocknr); \
 		printk(f); \
 		printk("\n"); \
 	} while (0)
diff -Nru a/fs/ext3/acl.c b/fs/ext3/acl.c
--- a/fs/ext3/acl.c	Tue Feb 25 08:21:08 2003
+++ b/fs/ext3/acl.c	Sat Mar 22 22:14:52 2003
@@ -420,7 +420,7 @@
 			return PTR_ERR(handle);
 		}
 		error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, clone);
-		ext3_journal_stop(handle, inode);
+		ext3_journal_stop(handle);
 	}
 	posix_acl_release(clone);
 	return error;
@@ -522,7 +522,7 @@
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 	error = ext3_set_acl(handle, inode, type, acl);
-	ext3_journal_stop(handle, inode);
+	ext3_journal_stop(handle);
 
 release_and_out:
 	posix_acl_release(acl);
diff -Nru a/fs/ext3/dir.c b/fs/ext3/dir.c
--- a/fs/ext3/dir.c	Tue Mar  4 08:34:07 2003
+++ b/fs/ext3/dir.c	Sat Mar 22 22:14:09 2003
@@ -37,10 +37,11 @@
 				struct file * filp);
 
 struct file_operations ext3_dir_operations = {
+	.llseek		= generic_file_llseek,
 	.read		= generic_read_dir,
 	.readdir	= ext3_readdir,		/* we take BKL. needed?*/
 	.ioctl		= ext3_ioctl,		/* BKL held */
-	.fsync		= ext3_sync_file,		/* BKL held */
+	.fsync		= ext3_sync_file,	/* BKL held */
 #ifdef CONFIG_EXT3_INDEX
 	.release	= ext3_release_dir,
 #endif
@@ -98,16 +99,15 @@
 	struct super_block * sb;
 	int err;
 	struct inode *inode = filp->f_dentry->d_inode;
-
-	lock_kernel();
+	int ret = 0;
 
 	sb = inode->i_sb;
 
 	if (is_dx(inode)) {
 		err = ext3_dx_readdir(filp, dirent, filldir);
 		if (err != ERR_BAD_DX_DIR) {
-			unlock_kernel();
-			return err;
+			ret = err;
+			goto out;
 		}
 		/*
 		 * We don't set the inode dirty flag since it's not
@@ -186,8 +186,8 @@
 				filp->f_pos = (filp->f_pos |
 						(sb->s_blocksize - 1)) + 1;
 				brelse (bh);
-				unlock_kernel();
-				return stored;
+				ret = stored;
+				goto out;
 			}
 			offset += le16_to_cpu(de->rec_len);
 			if (le32_to_cpu(de->inode)) {
@@ -217,8 +217,8 @@
 		brelse (bh);
 	}
 	UPDATE_ATIME(inode);
-	unlock_kernel();
-	return 0;
+out:
+	return ret;
 }
 
 #ifdef CONFIG_EXT3_INDEX
diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
--- a/fs/ext3/inode.c	Sun Mar 16 22:33:16 2003
+++ b/fs/ext3/inode.c	Sat Mar 22 22:14:52 2003
@@ -235,7 +235,7 @@
 		clear_inode(inode);
 	else
 		ext3_free_inode(handle, inode);
-	ext3_journal_stop(handle, inode);
+	ext3_journal_stop(handle);
 	unlock_kernel();
 	return;
 no_delete:
@@ -1107,7 +1107,7 @@
 	}
 prepare_write_failed:
 	if (ret)
-		ext3_journal_stop(handle, inode);
+		ext3_journal_stop(handle);
 out:
 	unlock_kernel();
 	return ret;
@@ -1176,7 +1176,7 @@
 		if (!ret) 
 			ret = ret2;
 	}
-	ret2 = ext3_journal_stop(handle, inode);
+	ret2 = ext3_journal_stop(handle);
 	unlock_kernel();
 	if (!ret)
 		ret = ret2;
@@ -1374,7 +1374,7 @@
 				PAGE_CACHE_SIZE, NULL, bput_one);
 	}
 
-	err = ext3_journal_stop(handle, inode);
+	err = ext3_journal_stop(handle);
 	if (!ret)
 		ret = err;
 	unlock_kernel();
@@ -1479,7 +1479,7 @@
 					ret = err;
 			}
 		}
-		err = ext3_journal_stop(handle, inode);
+		err = ext3_journal_stop(handle);
 		if (ret == 0)
 			ret = err;
 		unlock_kernel();
@@ -2140,7 +2140,7 @@
 	if (inode->i_nlink)
 		ext3_orphan_del(handle, inode);
 
-	ext3_journal_stop(handle, inode);
+	ext3_journal_stop(handle);
 	unlock_kernel();
 }
 
@@ -2560,7 +2560,7 @@
 		rc = ext3_mark_inode_dirty(handle, inode);
 		if (!error)
 			error = rc;
-		ext3_journal_stop(handle, inode);
+		ext3_journal_stop(handle);
 	}
 	
 	rc = inode_setattr(inode, attr);
@@ -2737,7 +2737,7 @@
 				current_handle);
 		ext3_mark_inode_dirty(handle, inode);
 	}
-	ext3_journal_stop(handle, inode);
+	ext3_journal_stop(handle);
 out:
 	unlock_kernel();
 }
@@ -2818,7 +2818,7 @@
 
 	err = ext3_mark_inode_dirty(handle, inode);
 	handle->h_sync = 1;
-	ext3_journal_stop(handle, inode);
+	ext3_journal_stop(handle);
 	ext3_std_error(inode->i_sb, err);
 	
 	return err;
diff -Nru a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
--- a/fs/ext3/ioctl.c	Sun Mar 16 22:33:16 2003
+++ b/fs/ext3/ioctl.c	Sat Mar 22 22:14:52 2003
@@ -90,7 +90,7 @@
 
 		err = ext3_mark_iloc_dirty(handle, inode, &iloc);
 flags_err:
-		ext3_journal_stop(handle, inode);
+		ext3_journal_stop(handle);
 		if (err)
 			return err;
 		
@@ -126,7 +126,7 @@
 		inode->i_generation = generation;
 
 		err = ext3_mark_iloc_dirty(handle, inode, &iloc);
-		ext3_journal_stop(handle, inode);
+		ext3_journal_stop(handle);
 		return err;
 	}
 #ifdef CONFIG_JBD_DEBUG
diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
--- a/fs/ext3/namei.c	Fri Feb 28 12:13:20 2003
+++ b/fs/ext3/namei.c	Sat Mar 22 22:14:52 2003
@@ -1615,7 +1615,7 @@
 			inode->i_mapping->a_ops = &ext3_aops;
 		err = ext3_add_nondir(handle, dentry, inode);
 	}
-	ext3_journal_stop(handle, dir);
+	ext3_journal_stop(handle);
 	unlock_kernel();
 	return err;
 }
@@ -1647,7 +1647,7 @@
 #endif
 		err = ext3_add_nondir(handle, dentry, inode);
 	}
-	ext3_journal_stop(handle, dir);
+	ext3_journal_stop(handle);
 	unlock_kernel();
 	return err;
 }
@@ -1721,7 +1721,7 @@
 	ext3_mark_inode_dirty(handle, dir);
 	d_instantiate(dentry, inode);
 out_stop:
-	ext3_journal_stop(handle, dir);
+	ext3_journal_stop(handle);
 	unlock_kernel();
 	return err;
 }
@@ -1994,7 +1994,7 @@
 	ext3_mark_inode_dirty(handle, dir);
 
 end_rmdir:
-	ext3_journal_stop(handle, dir);
+	ext3_journal_stop(handle);
 	brelse (bh);
 	unlock_kernel();
 	return retval;
@@ -2050,7 +2050,7 @@
 	retval = 0;
 
 end_unlink:
-	ext3_journal_stop(handle, dir);
+	ext3_journal_stop(handle);
 	unlock_kernel();
 	brelse (bh);
 	return retval;
@@ -2109,7 +2109,7 @@
 	EXT3_I(inode)->i_disksize = inode->i_size;
 	err = ext3_add_nondir(handle, dentry, inode);
 out_stop:
-	ext3_journal_stop(handle, dir);
+	ext3_journal_stop(handle);
 	unlock_kernel();
 	return err;
 }
@@ -2142,7 +2142,7 @@
 	atomic_inc(&inode->i_count);
 
 	err = ext3_add_nondir(handle, dentry, inode);
-	ext3_journal_stop(handle, dir);
+	ext3_journal_stop(handle);
 	unlock_kernel();
 	return err;
 }
@@ -2299,7 +2299,7 @@
 	brelse (dir_bh);
 	brelse (old_bh);
 	brelse (new_bh);
-	ext3_journal_stop(handle, old_dir);
+	ext3_journal_stop(handle);
 	unlock_kernel();
 	return retval;
 }
diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c
--- a/fs/ext3/super.c	Mon Mar 10 22:34:32 2003
+++ b/fs/ext3/super.c	Sat Mar 22 22:14:52 2003
@@ -60,9 +60,11 @@
 
 static void make_rdonly(struct block_device *bdev, int *no_write)
 {
+	char b[BDEVNAME_SIZE];
+
 	if (bdev) {
 		printk(KERN_WARNING "Turning device %s read-only\n", 
-		       bdevname(bdev));
+		       bdevname(bdev, b));
 		*no_write = 0xdead0000 + bdev->bd_dev;
 	}
 }
@@ -106,6 +108,72 @@
 #define clear_ro_after(sb)	do {} while (0)
 #endif
 
+/* 
+ * Wrappers for journal_start/end.
+ *
+ * The only special thing we need to do here is to make sure that all
+ * journal_end calls result in the superblock being marked dirty, so
+ * that sync() will call the filesystem's write_super callback if
+ * appropriate. 
+ */
+handle_t *ext3_journal_start(struct inode *inode, int nblocks)
+{
+	journal_t *journal;
+	
+	if (inode->i_sb->s_flags & MS_RDONLY)
+		return ERR_PTR(-EROFS);
+
+	/* Special case here: if the journal has aborted behind our
+	 * backs (eg. EIO in the commit thread), then we still need to
+	 * take the FS itself readonly cleanly. */
+	journal = EXT3_JOURNAL(inode);
+	if (is_journal_aborted(journal)) {
+		ext3_abort(inode->i_sb, __FUNCTION__,
+			   "Detected aborted journal");
+		return ERR_PTR(-EROFS);
+	}
+	
+	return journal_start(journal, nblocks);
+}
+
+/* 
+ * The only special thing we need to do here is to make sure that all
+ * journal_stop calls result in the superblock being marked dirty, so
+ * that sync() will call the filesystem's write_super callback if
+ * appropriate. 
+ */
+int __ext3_journal_stop(const char *where, handle_t *handle)
+{
+	struct super_block *sb;
+	int err;
+	int rc;
+
+	sb = handle->h_transaction->t_journal->j_private;
+	err = handle->h_err;
+	rc = journal_stop(handle);
+
+	if (!err)
+		err = rc;
+	if (err)
+		__ext3_std_error(sb, where, err);
+	return err;
+}
+
+void ext3_journal_abort_handle(const char *caller, const char *err_fn,
+		struct buffer_head *bh, handle_t *handle, int err)
+{
+	char nbuf[16];
+	const char *errstr = ext3_decode_error(NULL, err, nbuf);
+	
+	printk(KERN_ERR "%s: aborting transaction: %s in %s", 
+	       caller, errstr, err_fn);
+
+	if (bh)
+		BUFFER_TRACE(bh, "abort");
+	journal_abort_handle(handle);
+	if (!handle->h_err)
+		handle->h_err = err;
+}
 
 static char error_buf[1024];
 
@@ -317,6 +385,7 @@
 {
 	struct block_device *bdev;
 	int err = -ENODEV;
+	char b[BDEVNAME_SIZE];
 
 	bdev = bdget(dev);
 	if (bdev == NULL)
@@ -328,7 +397,7 @@
 
 fail:
 	printk(KERN_ERR "EXT3: failed to open journal device %s: %d\n",
-			__bdevname(dev), err);
+			__bdevname(dev, b), err);
 	return NULL;
 }
 
@@ -812,8 +881,10 @@
 	printk(KERN_INFO "EXT3 FS " EXT3FS_VERSION ", " EXT3FS_DATE " on %s, ",
 				sb->s_id);
 	if (EXT3_SB(sb)->s_journal->j_inode == NULL) {
+		char b[BDEVNAME_SIZE];
+
 		printk("external journal on %s\n",
-		    bdevname(EXT3_SB(sb)->s_journal->j_dev));
+			bdevname(EXT3_SB(sb)->s_journal->j_dev, b));
 	} else {
 		printk("internal journal\n");
 	}
@@ -1097,6 +1168,7 @@
 	if (!parse_options ((char *) data, sbi, &journal_inum, 0))
 		goto failed_mount;
 
+	sb->s_flags |= MS_ONE_SECOND;
 	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
 		((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
 
@@ -1425,6 +1497,7 @@
 		printk(KERN_ERR "EXT3-fs: Could not load journal inode\n");
 		iput(journal_inode);
 	}
+	journal->j_private = sb;
 	ext3_init_journal_params(EXT3_SB(sb), journal);
 	return journal;
 }
@@ -1489,6 +1562,7 @@
 		printk(KERN_ERR "EXT3-fs: failed to create device journal\n");
 		goto out_bdev;
 	}
+	journal->j_private = sb;
 	ll_rw_block(READ, 1, &journal->j_sb_buffer);
 	wait_on_buffer(journal->j_sb_buffer);
 	if (!buffer_uptodate(journal->j_sb_buffer)) {
@@ -1555,7 +1629,6 @@
 		if (!(journal = ext3_get_dev_journal(sb, journal_dev)))
 			return -EINVAL;
 	}
-	
 
 	if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) {
 		err = journal_update_format(journal);
diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c
--- a/fs/ext3/xattr.c	Sat Mar  8 14:50:42 2003
+++ b/fs/ext3/xattr.c	Sat Mar 22 22:14:52 2003
@@ -78,8 +78,9 @@
 		printk("\n"); \
 	} while (0)
 # define ea_bdebug(bh, f...) do { \
+		char b[BDEVNAME_SIZE]; \
 		printk(KERN_DEBUG "block %s:%ld: ", \
-			bdevname(bh->b_bdev), bh->b_blocknr); \
+			bdevname(bh->b_bdev, b), bh->b_blocknr); \
 		printk(f); \
 		printk("\n"); \
 	} while (0)
@@ -854,7 +855,7 @@
 	else
 		error = ext3_xattr_set_handle(handle, inode, name_index, name,
 					      value, value_len, flags);
-	error2 = ext3_journal_stop(handle, inode);
+	error2 = ext3_journal_stop(handle);
 	unlock_kernel();
 
 	return error ? error : error2;
diff -Nru a/fs/fat/inode.c b/fs/fat/inode.c
--- a/fs/fat/inode.c	Tue Dec 31 17:28:22 2002
+++ b/fs/fat/inode.c	Thu Mar  6 15:43:48 2003
@@ -939,7 +939,8 @@
 		error = first;
 		goto out_fail;
 	}
-	if (FAT_FIRST_ENT(sb, media) != first) {
+	if (FAT_FIRST_ENT(sb, media) != first
+	    && (media != 0xf8 || FAT_FIRST_ENT(sb, 0xfe) != first)) {
 		if (!silent) {
 			printk(KERN_ERR "FAT: invalid first entry of FAT "
 			       "(0x%x != 0x%x)\n",
diff -Nru a/fs/file_table.c b/fs/file_table.c
--- a/fs/file_table.c	Mon Mar 10 10:49:27 2003
+++ b/fs/file_table.c	Mon Mar 17 21:32:08 2003
@@ -22,72 +22,81 @@
 	.max_files = NR_FILE
 };
 
-/* Here the new files go */
-static LIST_HEAD(anon_list);
-/* And here the free ones sit */
-static LIST_HEAD(free_list);
 /* public *and* exported. Not pretty! */
-spinlock_t files_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+spinlock_t __cacheline_aligned_in_smp files_lock = SPIN_LOCK_UNLOCKED;
+
+static spinlock_t filp_count_lock = SPIN_LOCK_UNLOCKED;
+
+/* slab constructors and destructors are called from arbitrary
+ * context and must be fully threaded - use a local spinlock
+ * to protect files_stat.nr_files
+ */
+void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags)
+{
+	if ((cflags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR) {
+		unsigned long flags;
+		spin_lock_irqsave(&filp_count_lock, flags);
+		files_stat.nr_files++;
+		spin_unlock_irqrestore(&filp_count_lock, flags);
+	}
+}
+
+void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&filp_count_lock, flags);
+	files_stat.nr_files--;
+	spin_unlock_irqrestore(&filp_count_lock, flags);
+}
+
+static inline void file_free(struct file *f)
+{
+	kmem_cache_free(filp_cachep, f);
+}
 
 /* Find an unused file structure and return a pointer to it.
  * Returns NULL, if there are no more free file structures or
  * we run out of memory.
- *
- * SMP-safe.
  */
-struct file * get_empty_filp(void)
+struct file *get_empty_filp(void)
 {
-	static int old_max = 0;
+static int old_max = 0;
 	struct file * f;
 
-	file_list_lock();
-	if (files_stat.nr_free_files > NR_RESERVED_FILES) {
-	used_one:
-		f = list_entry(free_list.next, struct file, f_list);
-		list_del(&f->f_list);
-		files_stat.nr_free_files--;
-	new_one:
-		memset(f, 0, sizeof(*f));
-		if (security_file_alloc(f)) {
-			list_add(&f->f_list, &free_list);
-			files_stat.nr_free_files++;
-			file_list_unlock();
-			return NULL;
-		}
-		eventpoll_init_file(f);
-		atomic_set(&f->f_count,1);
-		f->f_version = 0;
-		f->f_uid = current->fsuid;
-		f->f_gid = current->fsgid;
-		f->f_owner.lock = RW_LOCK_UNLOCKED;
-		list_add(&f->f_list, &anon_list);
-		file_list_unlock();
-		return f;
-	}
-	/*
-	 * Use a reserved one if we're the superuser
-	 */
-	if (files_stat.nr_free_files && !current->euid)
-		goto used_one;
 	/*
-	 * Allocate a new one if we're below the limit.
+	 * Privileged users can go above max_files
 	 */
-	if (files_stat.nr_files < files_stat.max_files) {
-		file_list_unlock();
-		f = kmem_cache_alloc(filp_cachep, SLAB_KERNEL);
-		file_list_lock();
+	if (files_stat.nr_files < files_stat.max_files ||
+				capable(CAP_SYS_ADMIN)) {
+		f = kmem_cache_alloc(filp_cachep, GFP_KERNEL);
 		if (f) {
-			files_stat.nr_files++;
-			goto new_one;
+			memset(f, 0, sizeof(*f));
+			if (security_file_alloc(f)) {
+				file_free(f);
+				goto fail;
+			}
+			eventpoll_init_file(f);
+			atomic_set(&f->f_count, 1);
+			f->f_uid = current->fsuid;
+			f->f_gid = current->fsgid;
+			f->f_owner.lock = RW_LOCK_UNLOCKED;
+			/* f->f_version: 0 */
+			INIT_LIST_HEAD(&f->f_list);
+			return f;
 		}
-		/* Big problems... */
-		printk(KERN_WARNING "VFS: filp allocation failed\n");
+	}
 
-	} else if (files_stat.max_files > old_max) {
-		printk(KERN_INFO "VFS: file-max limit %d reached\n", files_stat.max_files);
+	/* Ran out of filps - report that */
+	if (files_stat.max_files >= old_max) {
+		printk(KERN_INFO "VFS: file-max limit %d reached\n",
+					files_stat.max_files);
 		old_max = files_stat.max_files;
+	} else {
+		/* Big problems... */
+		printk(KERN_WARNING "VFS: filp allocation failed\n");
 	}
-	file_list_unlock();
+fail:
 	return NULL;
 }
 
@@ -108,6 +117,7 @@
 	filp->f_uid    = current->fsuid;
 	filp->f_gid    = current->fsgid;
 	filp->f_op     = dentry->d_inode->i_fop;
+	INIT_LIST_HEAD(&filp->f_list);
 	error = security_file_alloc(filp);
 	if (!error)
 		if (filp->f_op && filp->f_op->open) {
@@ -140,11 +150,11 @@
 /* __fput is called from task context when aio completion releases the last
  * last use of a struct file *.  Do not use otherwise.
  */
-void __fput(struct file * file)
+void __fput(struct file *file)
 {
-	struct dentry * dentry = file->f_dentry;
-	struct vfsmount * mnt = file->f_vfsmnt;
-	struct inode * inode = dentry->d_inode;
+	struct dentry *dentry = file->f_dentry;
+	struct vfsmount *mnt = file->f_vfsmnt;
+	struct inode *inode = dentry->d_inode;
 
 	/*
 	 * The function eventpoll_release() should be the first called
@@ -159,20 +169,17 @@
 	fops_put(file->f_op);
 	if (file->f_mode & FMODE_WRITE)
 		put_write_access(inode);
-	file_list_lock();
 	file->f_dentry = NULL;
 	file->f_vfsmnt = NULL;
-	list_del(&file->f_list);
-	list_add(&file->f_list, &free_list);
-	files_stat.nr_free_files++;
-	file_list_unlock();
+	file_kill(file);
+	file_free(file);
 	dput(dentry);
 	mntput(mnt);
 }
 
-struct file * fget(unsigned int fd)
+struct file *fget(unsigned int fd)
 {
-	struct file * file;
+	struct file *file;
 	struct files_struct *files = current->files;
 
 	read_lock(&files->file_lock);
@@ -183,17 +190,12 @@
 	return file;
 }
 
-/* Here. put_filp() is SMP-safe now. */
-
 void put_filp(struct file *file)
 {
-	if(atomic_dec_and_test(&file->f_count)) {
+	if (atomic_dec_and_test(&file->f_count)) {
 		security_file_free(file);
-		file_list_lock();
-		list_del(&file->f_list);
-		list_add(&file->f_list, &free_list);
-		files_stat.nr_free_files++;
-		file_list_unlock();
+		file_kill(file);
+		file_free(file);
 	}
 }
 
@@ -202,16 +204,17 @@
 	if (!list)
 		return;
 	file_list_lock();
-	list_del(&file->f_list);
-	list_add(&file->f_list, list);
+	list_move(&file->f_list, list);
 	file_list_unlock();
 }
 
 void file_kill(struct file *file)
 {
-	file_list_lock();
-	list_del_init(&file->f_list);
-	file_list_unlock();
+	if (!list_empty(&file->f_list)) {
+		file_list_lock();
+		list_del_init(&file->f_list);
+		file_list_unlock();
+	}
 }
 
 int fs_may_remount_ro(struct super_block *sb)
@@ -228,7 +231,7 @@
 		if (inode->i_nlink == 0)
 			goto too_bad;
 
-		/* Writable file? */
+		/* Writeable file? */
 		if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE))
 			goto too_bad;
 	}
diff -Nru a/fs/inode.c b/fs/inode.c
--- a/fs/inode.c	Sun Mar 16 22:33:19 2003
+++ b/fs/inode.c	Sat Mar 22 22:14:19 2003
@@ -128,7 +128,6 @@
 		memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
 		inode->i_pipe = NULL;
 		inode->i_bdev = NULL;
-		inode->i_cdev = NULL;
 		inode->i_rdev = to_kdev_t(0);
 		inode->i_security = NULL;
 		if (security_inode_alloc(inode)) {
@@ -146,7 +145,7 @@
 		mapping->assoc_mapping = NULL;
 		mapping->backing_dev_info = &default_backing_dev_info;
 		if (sb->s_bdev)
-			inode->i_data.backing_dev_info = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
+			mapping->backing_dev_info = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
 		memset(&inode->u, 0, sizeof(inode->u));
 		inode->i_mapping = mapping;
 	}
@@ -242,10 +241,6 @@
 		inode->i_sb->s_op->clear_inode(inode);
 	if (inode->i_bdev)
 		bd_forget(inode);
-	else if (inode->i_cdev) {
-		cdput(inode->i_cdev);
-		inode->i_cdev = NULL;
-	}
 	inode->i_state = I_CLEAR;
 }
 
@@ -1078,6 +1073,19 @@
 	return res;
 }
 
+/*
+ * Return true if the filesystem which backs this inode considers the two
+ * passed timespecs to be sufficiently different to warrant flushing the
+ * altered time out to disk.
+ */
+static int inode_times_differ(struct inode *inode,
+			struct timespec *old, struct timespec *new)
+{
+	if (IS_ONE_SECOND(inode))
+		return old->tv_sec != new->tv_sec;
+	return !timespec_equal(old, new);
+}
+
 /**
  *	update_atime	-	update the access time
  *	@inode: inode accessed
@@ -1089,19 +1097,23 @@
  
 void update_atime(struct inode *inode)
 {
-	struct timespec now = CURRENT_TIME; 
+	struct timespec now;
 
-	/* Can later do this more lazily with a per superblock interval */
-	if (timespec_equal(&inode->i_atime, &now))
-		return;
 	if (IS_NOATIME(inode))
 		return;
 	if (IS_NODIRATIME(inode) && S_ISDIR(inode->i_mode))
 		return;
 	if (IS_RDONLY(inode))
 		return;
-	inode->i_atime = now;
-	mark_inode_dirty_sync(inode);
+
+	now = current_kernel_time();
+	if (inode_times_differ(inode, &inode->i_atime, &now)) {
+		inode->i_atime = now;
+		mark_inode_dirty_sync(inode);
+	} else {
+		if (!timespec_equal(&inode->i_atime, &now))
+			inode->i_atime = now;
+	}
 }
 
 /**
@@ -1110,20 +1122,25 @@
  *	@ctime_too: update ctime too
  *
  *	Update the mtime time on an inode and mark it for writeback.
- *	This function automatically handles read only file systems and media.
  *	When ctime_too is specified update the ctime too.
  */
 
 void inode_update_time(struct inode *inode, int ctime_too)
 {
-	struct timespec now = CURRENT_TIME; 
-	if (timespec_equal(&inode->i_mtime, &now) &&
-	    !(ctime_too && !timespec_equal(&inode->i_ctime, &now)))
-		return;
+	struct timespec now = current_kernel_time();
+	int sync_it = 0;
+
+	if (inode_times_differ(inode, &inode->i_mtime, &now))
+		sync_it = 1;
 	inode->i_mtime = now;
-	if (ctime_too) 
+
+	if (ctime_too) {
+		if (inode_times_differ(inode, &inode->i_ctime, &now))
+			sync_it = 1;
 		inode->i_ctime = now;
-	mark_inode_dirty_sync(inode);
+	}
+	if (sync_it)
+		mark_inode_dirty_sync(inode);
 }
 EXPORT_SYMBOL(inode_update_time);
 
@@ -1214,7 +1231,7 @@
 		goto repeat;
 	}
 	remove_wait_queue(wq, &wait);
-	current->state = TASK_RUNNING;
+	__set_current_state(TASK_RUNNING);
 }
 
 void wake_up_inode(struct inode *inode)
@@ -1293,7 +1310,6 @@
 	if (S_ISCHR(mode)) {
 		inode->i_fop = &def_chr_fops;
 		inode->i_rdev = to_kdev_t(rdev);
-		inode->i_cdev = cdget(rdev);
 	} else if (S_ISBLK(mode)) {
 		inode->i_fop = &def_blk_fops;
 		inode->i_rdev = to_kdev_t(rdev);
@@ -1302,5 +1318,6 @@
 	else if (S_ISSOCK(mode))
 		inode->i_fop = &bad_sock_fops;
 	else
-		printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o)\n", mode);
+		printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o)\n",
+		       mode);
 }
diff -Nru a/fs/intermezzo/cache.c b/fs/intermezzo/cache.c
--- a/fs/intermezzo/cache.c	Sun Feb 16 16:14:54 2003
+++ b/fs/intermezzo/cache.c	Tue Mar 18 09:08:01 2003
@@ -20,7 +20,6 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
diff -Nru a/fs/intermezzo/dcache.c b/fs/intermezzo/dcache.c
--- a/fs/intermezzo/dcache.c	Fri Dec 13 17:27:18 2002
+++ b/fs/intermezzo/dcache.c	Thu Mar 13 16:52:26 2003
@@ -31,7 +31,6 @@
  * with heavy changes by Linus Torvalds
  */
 
-#define __NO_VERSION__
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
diff -Nru a/fs/intermezzo/dir.c b/fs/intermezzo/dir.c
--- a/fs/intermezzo/dir.c	Sun Feb 16 16:14:54 2003
+++ b/fs/intermezzo/dir.c	Tue Mar 18 09:08:01 2003
@@ -40,7 +40,6 @@
 #include <linux/smp_lock.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 
 #include "intermezzo_fs.h"
diff -Nru a/fs/intermezzo/ext_attr.c b/fs/intermezzo/ext_attr.c
--- a/fs/intermezzo/ext_attr.c	Fri Dec 13 17:27:18 2002
+++ b/fs/intermezzo/ext_attr.c	Thu Mar 13 16:52:26 2003
@@ -22,7 +22,6 @@
  * Extended attribute handling for presto.
  */
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
diff -Nru a/fs/intermezzo/file.c b/fs/intermezzo/file.c
--- a/fs/intermezzo/file.c	Sun Feb 16 16:14:54 2003
+++ b/fs/intermezzo/file.c	Tue Mar 18 09:08:01 2003
@@ -45,7 +45,6 @@
 #include <linux/blkdev.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 
 #include <linux/fsfilter.h>
diff -Nru a/fs/intermezzo/inode.c b/fs/intermezzo/inode.c
--- a/fs/intermezzo/inode.c	Fri Dec 13 17:27:18 2002
+++ b/fs/intermezzo/inode.c	Thu Mar 13 16:52:26 2003
@@ -24,7 +24,6 @@
  * Super block/filesystem wide operations
  */
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
diff -Nru a/fs/intermezzo/kml.c b/fs/intermezzo/kml.c
--- a/fs/intermezzo/kml.c	Fri Dec 13 17:27:19 2002
+++ b/fs/intermezzo/kml.c	Thu Mar 13 16:52:26 2003
@@ -1,7 +1,6 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <asm/uaccess.h>
 
diff -Nru a/fs/intermezzo/kml_decode.c b/fs/intermezzo/kml_decode.c
--- a/fs/intermezzo/kml_decode.c	Fri Dec 13 17:27:19 2002
+++ b/fs/intermezzo/kml_decode.c	Thu Mar 13 16:52:26 2003
@@ -5,7 +5,6 @@
  *
  * Copyright (C) 2001 Mountainview Data, Inc.
  */
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
diff -Nru a/fs/intermezzo/kml_reint.c b/fs/intermezzo/kml_reint.c
--- a/fs/intermezzo/kml_reint.c	Fri Dec 13 17:27:19 2002
+++ b/fs/intermezzo/kml_reint.c	Thu Mar 13 16:52:26 2003
@@ -22,7 +22,6 @@
  *
  */
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
diff -Nru a/fs/intermezzo/kml_setup.c b/fs/intermezzo/kml_setup.c
--- a/fs/intermezzo/kml_setup.c	Fri Dec 13 17:27:19 2002
+++ b/fs/intermezzo/kml_setup.c	Thu Mar 13 16:52:26 2003
@@ -1,7 +1,6 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <asm/uaccess.h>
 
diff -Nru a/fs/intermezzo/methods.c b/fs/intermezzo/methods.c
--- a/fs/intermezzo/methods.c	Sun Feb 16 16:14:54 2003
+++ b/fs/intermezzo/methods.c	Tue Mar 18 09:08:23 2003
@@ -40,7 +40,6 @@
 #include <linux/smp_lock.h>
 #include <linux/blkdev.h>
 #include <linux/init.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 
 #include <linux/fsfilter.h>
diff -Nru a/fs/intermezzo/replicator.c b/fs/intermezzo/replicator.c
--- a/fs/intermezzo/replicator.c	Sun Feb 16 16:14:54 2003
+++ b/fs/intermezzo/replicator.c	Tue Mar 18 09:08:23 2003
@@ -23,7 +23,6 @@
  *
  */
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <asm/uaccess.h>
 
diff -Nru a/fs/intermezzo/super.c b/fs/intermezzo/super.c
--- a/fs/intermezzo/super.c	Thu Mar  6 09:33:04 2003
+++ b/fs/intermezzo/super.c	Tue Mar 18 09:08:23 2003
@@ -42,7 +42,6 @@
 #include <linux/blkdev.h>
 #include <linux/init.h>
 #include <linux/devfs_fs_kernel.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 
 #include "intermezzo_fs.h"
diff -Nru a/fs/intermezzo/sysctl.c b/fs/intermezzo/sysctl.c
--- a/fs/intermezzo/sysctl.c	Fri Dec 13 17:27:19 2002
+++ b/fs/intermezzo/sysctl.c	Thu Mar 13 16:52:26 2003
@@ -21,7 +21,6 @@
  *  Sysctrl entries for Intermezzo!
  */
 
-#define __NO_VERSION__
 #include <linux/config.h> /* for CONFIG_PROC_FS */
 #include <linux/module.h>
 #include <linux/sched.h>
diff -Nru a/fs/intermezzo/vfs.c b/fs/intermezzo/vfs.c
--- a/fs/intermezzo/vfs.c	Wed Jan 15 12:19:48 2003
+++ b/fs/intermezzo/vfs.c	Sat Mar 22 22:14:13 2003
@@ -183,10 +183,11 @@
         int minor = presto_f2m(fset);
         int errorval = izo_channels[minor].uc_errorval;
 	struct block_device *bdev = fset->fset_dentry->d_inode->i_sb->s_bdev;
+	char b[BDEVNAME_SIZE];
 
         if (errorval && errorval == (long)value && !bdev_read_only(bdev)) {
                 CDEBUG(D_SUPER, "setting device %s read only\n",
-				bdevname(bdev));
+				bdevname(bdev, b));
                 BLKDEV_FAIL(bdev, 1);
                 izo_channels[minor].uc_errorval = -bdev->bd_dev;
         }
diff -Nru a/fs/jbd/journal.c b/fs/jbd/journal.c
--- a/fs/jbd/journal.c	Tue Feb 11 14:57:53 2003
+++ b/fs/jbd/journal.c	Sat Mar 22 22:14:13 2003
@@ -637,11 +637,13 @@
 		if (ret)
 			*retp = ret;
 		else {
+			char b[BDEVNAME_SIZE];
+
 			printk(KERN_ALERT "%s: journal block not found "
 					"at offset %lu on %s\n",
 				__FUNCTION__,
 				blocknr,
-				bdevname(journal->j_dev));
+				bdevname(journal->j_dev, b));
 			err = -EIO;
 			__journal_abort_soft(journal, err);
 		}
@@ -1398,7 +1400,7 @@
  * device this journal is present.
  */
 
-const char * journal_dev_name(journal_t *journal)
+const char *journal_dev_name(journal_t *journal, char *buffer)
 {
 	struct block_device *bdev;
 
@@ -1407,7 +1409,7 @@
 	else
 		bdev = journal->j_dev;
 
-	return bdevname(bdev);
+	return bdevname(bdev, buffer);
 }
 
 /*
@@ -1424,12 +1426,13 @@
 void __journal_abort_hard (journal_t *journal)
 {
 	transaction_t *transaction;
+	char b[BDEVNAME_SIZE];
 
 	if (journal->j_flags & JFS_ABORT)
 		return;
 
 	printk (KERN_ERR "Aborting journal on device %s.\n",
-		journal_dev_name(journal));
+		journal_dev_name(journal, b));
 
 	journal->j_flags |= JFS_ABORT;
 	transaction = journal->j_running_transaction;
diff -Nru a/fs/jffs/intrep.c b/fs/jffs/intrep.c
--- a/fs/jffs/intrep.c	Thu Feb 13 09:34:46 2003
+++ b/fs/jffs/intrep.c	Thu Mar 13 16:52:26 2003
@@ -55,7 +55,6 @@
  *
  */
 
-#define __NO_VERSION__
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/slab.h>
diff -Nru a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c
--- a/fs/jffs/jffs_fm.c	Tue Jun 11 02:59:10 2002
+++ b/fs/jffs/jffs_fm.c	Thu Mar 13 16:52:26 2003
@@ -16,7 +16,6 @@
  * Copyright (C) 2000  Alexander Larsson (alex@cendio.se), Cendio Systems AB
  *
  */
-#define __NO_VERSION__
 #include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/jffs.h>
diff -Nru a/fs/lockd/lockd_syms.c b/fs/lockd/lockd_syms.c
--- a/fs/lockd/lockd_syms.c	Tue Sep 10 18:28:27 2002
+++ b/fs/lockd/lockd_syms.c	Thu Mar 13 16:52:26 2003
@@ -8,7 +8,6 @@
  * Copyright (C) 1997 Olaf Kirch <okir@monad.swb.de>
  */
 
-#define __NO_VERSION__
 #include <linux/config.h>
 #include <linux/module.h>
 
diff -Nru a/fs/locks.c b/fs/locks.c
--- a/fs/locks.c	Mon Mar 10 12:09:00 2003
+++ b/fs/locks.c	Mon Mar 17 21:32:01 2003
@@ -565,7 +565,7 @@
 	int result = 0;
 	DECLARE_WAITQUEUE(wait, current);
 
-	current->state = TASK_INTERRUPTIBLE;
+	__set_current_state(TASK_INTERRUPTIBLE);
 	add_wait_queue(fl_wait, &wait);
 	if (timeout == 0)
 		schedule();
@@ -574,7 +574,7 @@
 	if (signal_pending(current))
 		result = -ERESTARTSYS;
 	remove_wait_queue(fl_wait, &wait);
-	current->state = TASK_RUNNING;
+	__set_current_state(TASK_RUNNING);
 	return result;
 }
 
diff -Nru a/fs/nfs/inode.c b/fs/nfs/inode.c
--- a/fs/nfs/inode.c	Thu Feb 13 04:57:46 2003
+++ b/fs/nfs/inode.c	Mon Mar 17 21:32:11 2003
@@ -1231,6 +1231,7 @@
 
 	if (root->size > sizeof(root->data)) {
 		printk("nfs_get_sb: invalid root filehandle\n");
+		kfree(server);
 		return ERR_PTR(-EINVAL);
 	}
 	/* We now require that the mount process passes the remote address */
diff -Nru a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
--- a/fs/nfsd/vfs.c	Sat Mar 15 20:55:43 2003
+++ b/fs/nfsd/vfs.c	Mon Mar 17 21:33:23 2003
@@ -1203,7 +1203,9 @@
 				iap->ia_mode = (iap->ia_mode&S_IALLUGO)
 					| S_IFLNK;
 				err = notify_change(dnew, iap);
-				if (!err && EX_ISSYNC(fhp->fh_export))
+				if (err)
+					err = nfserrno(err);
+				else if (EX_ISSYNC(fhp->fh_export))
 					write_inode_now(dentry->d_inode, 1);
 		       }
 		}
diff -Nru a/fs/partitions/Kconfig b/fs/partitions/Kconfig
--- a/fs/partitions/Kconfig	Tue Oct 29 17:16:55 2002
+++ b/fs/partitions/Kconfig	Thu Mar  6 15:43:48 2003
@@ -177,6 +177,13 @@
 
 	  If unsure, say N.
 
+config NEC98_PARTITION
+	bool "NEC PC-9800 partition table support" if PARTITION_ADVANCED
+	default y if !PARTITION_ADVANCED && X86_PC9800
+	help
+	  Say Y here if you would like to be able to read the hard disk
+	  partition table format used by NEC PC-9800 machines.
+
 config SGI_PARTITION
 	bool "SGI partition support" if PARTITION_ADVANCED
 	default y if !PARTITION_ADVANCED && (SGI_IP22 || SGI_IP27)
diff -Nru a/fs/partitions/Makefile b/fs/partitions/Makefile
--- a/fs/partitions/Makefile	Mon Feb  3 14:19:38 2003
+++ b/fs/partitions/Makefile	Thu Mar  6 15:43:48 2003
@@ -16,3 +16,4 @@
 obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o
 obj-$(CONFIG_IBM_PARTITION) += ibm.o
 obj-$(CONFIG_EFI_PARTITION) += efi.o
+obj-$(CONFIG_NEC98_PARTITION) += nec98.o msdos.o
diff -Nru a/fs/partitions/amiga.c b/fs/partitions/amiga.c
--- a/fs/partitions/amiga.c	Sat Jul 20 11:03:57 2002
+++ b/fs/partitions/amiga.c	Sat Mar 22 22:14:13 2003
@@ -32,6 +32,7 @@
 	struct PartitionBlock *pb;
 	int start_sect, nr_sects, blk, part, res = 0;
 	int slot = 1;
+	char b[BDEVNAME_SIZE];
 
 	for (blk = 0; ; blk++, put_dev_sector(sect)) {
 		if (blk == RDB_ALLOCATION_LIMIT)
@@ -40,7 +41,7 @@
 		if (!data) {
 			if (warn_no_part)
 				printk("Dev %s: unable to read RDB block %d\n",
-				       bdevname(bdev), blk);
+				       bdevname(bdev, b), blk);
 			goto rdb_done;
 		}
 		if (*(u32 *)data != cpu_to_be32(IDNAME_RIGIDDISK))
@@ -61,7 +62,7 @@
 		}
 
 		printk("Dev %s: RDB in block %d has bad checksum\n",
-			       bdevname(bdev),blk);
+			       bdevname(bdev, b), blk);
 	}
 
 	printk(" RDSK");
@@ -72,7 +73,7 @@
 		if (!data) {
 			if (warn_no_part)
 				printk("Dev %s: unable to read partition block %d\n",
-				       bdevname(bdev),blk);
+				       bdevname(bdev, b), blk);
 			goto rdb_done;
 		}
 		pb  = (struct PartitionBlock *)data;
diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c
--- a/fs/partitions/check.c	Sat Mar  8 14:50:30 2003
+++ b/fs/partitions/check.c	Sat Mar 22 07:38:05 2003
@@ -28,6 +28,7 @@
 #include "ldm.h"
 #include "mac.h"
 #include "msdos.h"
+#include "nec98.h"
 #include "osf.h"
 #include "sgi.h"
 #include "sun.h"
@@ -51,6 +52,9 @@
 #ifdef CONFIG_LDM_PARTITION
 	ldm_partition,		/* this must come before msdos */
 #endif
+#ifdef CONFIG_NEC98_PARTITION
+	nec98_partition,	/* must be come before `msdos_partition' */
+#endif
 #ifdef CONFIG_MSDOS_PARTITION
 	msdos_partition,
 #endif
@@ -156,7 +160,6 @@
 {
 #ifdef CONFIG_DEVFS_FS
 	devfs_handle_t dir;
-	unsigned int devfs_flags = DEVFS_FL_DEFAULT;
 	struct hd_struct *p = dev->part;
 	char devname[16];
 
@@ -165,10 +168,8 @@
 	dir = dev->de;
 	if (!dir)
 		return;
-	if (dev->flags & GENHD_FL_REMOVABLE)
-		devfs_flags |= DEVFS_FL_REMOVABLE;
 	sprintf(devname, "part%d", part);
-	p[part-1].de = devfs_register (dir, devname, devfs_flags,
+	p[part-1].de = devfs_register (dir, devname, 0,
 				    dev->major, dev->first_minor + part,
 				    S_IFBLK | S_IRUSR | S_IWUSR,
 				    dev->fops, NULL);
@@ -184,12 +185,9 @@
 {
 #ifdef CONFIG_DEVFS_FS
 	int pos = 0;
-	devfs_handle_t dir, slave;
-	unsigned int devfs_flags = DEVFS_FL_DEFAULT;
+	devfs_handle_t dir;
 	char dirname[64], symlink[16];
 
-	if (dev->flags & GENHD_FL_REMOVABLE)
-		devfs_flags |= DEVFS_FL_REMOVABLE;
 	if (dev->flags & GENHD_FL_DEVFS) {
 		dir = dev->de;
 		if (!dir)  /*  Aware driver wants to block disc management  */
@@ -202,14 +200,13 @@
 		/*  Unaware driver: construct "real" directory  */
 		sprintf(dirname, "../%s/disc%d", dev->disk_name,
 			dev->first_minor >> dev->minor_shift);
-		dir = devfs_mk_dir(NULL, dirname + 3, NULL);
+		dir = devfs_mk_dir(dirname + 3);
 		dev->de = dir;
 	}
 	dev->number = devfs_alloc_unique_number (&disc_numspace);
 	sprintf(symlink, "discs/disc%d", dev->number);
-	devfs_mk_symlink(NULL, symlink, DEVFS_FL_DEFAULT,
-			  dirname + pos, &slave, NULL);
-	dev->disk_de = devfs_register(dir, "disc", devfs_flags,
+	devfs_mk_symlink(symlink, dirname + pos);
+	dev->disk_de = devfs_register(dir, "disc", 0,
 			    dev->major, dev->first_minor,
 			    S_IFBLK | S_IRUSR | S_IWUSR, dev->fops, NULL);
 #endif
@@ -224,7 +221,6 @@
 	sprintf(vname, "cdroms/cdrom%d", dev->number);
 	if (dev->de) {
 		int pos;
-		devfs_handle_t slave;
 		char rname[64];
 
 		dev->disk_de = devfs_register(dev->de, "cd", DEVFS_FL_DEFAULT,
@@ -235,8 +231,7 @@
 		pos = devfs_generate_path(dev->disk_de, rname+3, sizeof(rname)-3);
 		if (pos >= 0) {
 			strncpy(rname + pos, "../", 3);
-			devfs_mk_symlink(NULL, vname, DEVFS_FL_DEFAULT,
-					 rname + pos, &slave, NULL);
+			devfs_mk_symlink(vname, rname + pos);
 		}
 	} else {
 		dev->disk_de = devfs_register (NULL, vname, DEVFS_FL_DEFAULT,
diff -Nru a/fs/partitions/nec98.c b/fs/partitions/nec98.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/partitions/nec98.c	Thu Mar  6 15:43:48 2003
@@ -0,0 +1,197 @@
+/*
+ *  NEC PC-9800 series partition supports
+ *
+ *  Copyright (C) 1999	Kyoto University Microcomputer Club
+ */
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/kernel.h>
+#include <linux/blk.h>
+#include <linux/hdreg.h>
+
+#include "check.h"
+#include "nec98.h"
+
+struct nec98_partition {
+	__u8	mid;		/* 0x80 - active */
+	__u8	sid;		/* 0x80 - bootable */
+	__u16	pad1;		/* dummy for padding */
+	__u8	ipl_sector;	/* IPL sector	*/
+	__u8	ipl_head;	/* IPL head	*/
+	__u16	ipl_cyl;	/* IPL cylinder	*/
+	__u8	sector;		/* starting sector	*/
+	__u8	head;		/* starting head	*/
+	__u16	cyl;		/* starting cylinder	*/
+	__u8	end_sector;	/* end sector	*/
+	__u8	end_head;	/* end head	*/
+	__u16	end_cyl;	/* end cylinder	*/
+	unsigned char name[16];
+} __attribute__((__packed__));
+
+#define NEC98_BSD_PARTITION_MID 0x14
+#define NEC98_BSD_PARTITION_SID 0x44
+#define MID_SID_16(mid, sid)	(((mid) & 0xFF) | (((sid) & 0xFF) << 8))
+#define NEC98_BSD_PARTITION_MID_SID	\
+	MID_SID_16(NEC98_BSD_PARTITION_MID, NEC98_BSD_PARTITION_SID)
+#define NEC98_VALID_PTABLE_ENTRY(P) \
+	(!(P)->pad1 && (P)->cyl <= (P)->end_cyl)
+
+extern int pc98_bios_param(struct block_device *bdev, int *ip);
+
+static inline int
+is_valid_nec98_partition_table(const struct nec98_partition *ptable,
+				__u8 nsectors, __u8 nheads)
+{
+	int i;
+	int valid = 0;
+
+	for (i = 0; i < 16; i++) {
+		if (!*(__u16 *)&ptable[i])
+			continue;	/* empty slot */
+		if (ptable[i].pad1	/* `pad1' contains junk */
+		    || ptable[i].ipl_sector	>= nsectors
+		    || ptable[i].sector		>= nsectors
+		    || ptable[i].end_sector	>= nsectors
+		    || ptable[i].ipl_head	>= nheads
+		    || ptable[i].head		>= nheads
+		    || ptable[i].end_head	>= nheads
+		    || ptable[i].cyl > ptable[i].end_cyl)
+			return 0;
+		valid = 1;	/* We have a valid partition.  */
+	}
+	/* If no valid PC-9800-style partitions found,
+	   the disk may have other type of partition table.  */
+	return valid;
+}
+
+#ifdef CONFIG_BSD_DISKLABEL
+extern void parse_bsd(struct parsed_partitions *state,
+			struct block_device *bdev,
+			u32 offset, u32 size, int origin, char *flavour,
+			int max_partitions);
+#endif
+
+int nec98_partition(struct parsed_partitions *state, struct block_device *bdev)
+{
+	unsigned int nr;
+	struct hd_geometry geo;
+	Sector sect;
+	const struct nec98_partition *part;
+	unsigned char *data;
+	int sector_size = bdev_hardsect_size(bdev);
+	int major = MAJOR(bdev->bd_dev);
+
+	if (ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)&geo) != 0) {
+		printk(" unsupported disk (major = %u)\n", major);
+		return 0;
+	}
+
+#ifdef NEC98_PARTITION_DEBUG
+	printk("ioctl_by_bdev head=%d sect=%d\n", geo.heads, geo.sectors);
+#endif
+	data = read_dev_sector(bdev, 0, &sect);
+	if (!data) {
+		if (warn_no_part)
+			printk(" unable to read partition table\n");
+		return -1;
+	}
+
+	/* magic(?) check */
+	if (*(__u16 *)(data + sector_size - 2) != NEC98_PTABLE_MAGIC) {
+		put_dev_sector(sect);
+		return 0;
+	}
+
+	put_dev_sector(sect);
+	data = read_dev_sector(bdev, 1, &sect);
+	if (!data) {
+		if (warn_no_part)
+			printk(" unable to read partition table\n");
+		return -1;
+	}
+
+	if (!is_valid_nec98_partition_table((struct nec98_partition *)data,
+					     geo.sectors, geo.heads)) {
+#ifdef NEC98_PARTITION_DEBUG
+		if (warn_no_part)
+			printk(" partition table consistency check failed"
+				" (not PC-9800 disk?)\n");
+#endif
+		put_dev_sector(sect);
+		return 0;
+	}
+
+	part = (const struct nec98_partition *)data;
+	for (nr = 0; nr < 16; nr++, part++) {
+		unsigned int start_sect, end_sect;
+
+		if (part->mid == 0 || part->sid == 0)
+			continue;
+
+		if (nr)
+			printk("     ");
+
+		{	/* Print partition name. Fdisk98 might put NUL
+			   characters in partition name... */
+
+			int j;
+			unsigned char *p;
+			unsigned char buf[sizeof (part->name) * 2 + 1];
+
+			for (p = buf, j = 0; j < sizeof (part->name); j++, p++)
+				if ((*p = part->name[j]) < ' ') {
+					*p++ = '^';
+					*p = part->name[j] + '@';
+				}
+
+			*p = 0;
+			printk(" <%s>", buf);
+		}
+		start_sect = (part->cyl * geo.heads + part->head) * geo.sectors
+			+ part->sector;
+		end_sect = (part->end_cyl + 1) * geo.heads * geo.sectors;
+		if (end_sect <= start_sect) {
+			printk(" (invalid partition info)\n");
+			continue;
+		}
+
+		put_partition(state, nr + 1, start_sect, end_sect - start_sect);
+#ifdef CONFIG_BSD_DISKLABEL
+		if ((*(__u16 *)&part->mid & 0x7F7F)
+		    == NEC98_BSD_PARTITION_MID_SID) {
+			printk("!");
+			/* NEC98_BSD_PARTITION_MID_SID is not valid SYSIND for
+			   IBM PC's MS-DOS partition table, so we simply pass
+			   it to bsd_disklabel_partition;
+			   it will just print `<bsd: ... >'. */
+			parse_bsd(state, bdev, start_sect,
+					end_sect - start_sect, nr + 1,
+					"bsd98", BSD_MAXPARTITIONS);
+		}
+#endif
+		{	/* Pretty size printing. */
+			/* XXX sector size? */
+			unsigned int psize = (end_sect - start_sect) / 2;
+			int unit_char = 'K';
+
+			if (psize > 99999) {
+				psize >>= 10;
+				unit_char = 'M';
+			}
+			printk(" %5d%cB (%5d-%5d)\n", 
+			       psize, unit_char, part->cyl, part->end_cyl);
+		}
+	}
+
+	put_dev_sector(sect);
+
+	return nr ? 1 : 0;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -Nru a/fs/partitions/nec98.h b/fs/partitions/nec98.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/partitions/nec98.h	Thu Mar  6 15:43:48 2003
@@ -0,0 +1,10 @@
+/*
+ *  NEC PC-9800 series partition supports
+ *
+ *  Copyright (C) 1998-2000	Kyoto University Microcomputer Club
+ */
+
+#define NEC98_PTABLE_MAGIC	0xAA55
+
+extern int nec98_partition(struct parsed_partitions *state,
+				struct block_device *bdev);
diff -Nru a/fs/partitions/sgi.c b/fs/partitions/sgi.c
--- a/fs/partitions/sgi.c	Thu Jan 16 09:38:15 2003
+++ b/fs/partitions/sgi.c	Sat Mar 22 22:14:13 2003
@@ -35,6 +35,7 @@
 	Sector sect;
 	struct sgi_disklabel *label;
 	struct sgi_partition *p;
+	char b[BDEVNAME_SIZE];
 
 	label = (struct sgi_disklabel *) read_dev_sector(bdev, 0, &sect);
 	if (!label)
@@ -43,7 +44,7 @@
 	magic = label->magic_mushroom;
 	if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) {
 		/*printk("Dev %s SGI disklabel: bad magic %08x\n",
-		       bdevname(bdev), magic);*/
+		       bdevname(bdev, b), magic);*/
 		put_dev_sector(sect);
 		return 0;
 	}
@@ -54,7 +55,7 @@
 	}
 	if(csum) {
 		printk(KERN_WARNING "Dev %s SGI disklabel: csum bad, label corrupted\n",
-		       bdevname(bdev));
+		       bdevname(bdev, b));
 		put_dev_sector(sect);
 		return 0;
 	}
diff -Nru a/fs/partitions/sun.c b/fs/partitions/sun.c
--- a/fs/partitions/sun.c	Mon Jan 27 10:31:49 2003
+++ b/fs/partitions/sun.c	Sat Mar 22 22:14:13 2003
@@ -45,6 +45,7 @@
 	} * label;		
 	struct sun_partition *p;
 	unsigned long spc;
+	char b[BDEVNAME_SIZE];
 
 	label = (struct sun_disklabel *)read_dev_sector(bdev, 0, &sect);
 	if (!label)
@@ -53,7 +54,7 @@
 	p = label->partitions;
 	if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
 /*		printk(KERN_INFO "Dev %s Sun disklabel: bad magic %04x\n",
-		       bdevname(bdev), be16_to_cpu(label->magic)); */
+		       bdevname(bdev, b), be16_to_cpu(label->magic)); */
 		put_dev_sector(sect);
 		return 0;
 	}
@@ -63,7 +64,7 @@
 		csum ^= *ush--;
 	if (csum) {
 		printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",
-		       bdevname(bdev));
+		       bdevname(bdev, b));
 		put_dev_sector(sect);
 		return 0;
 	}
diff -Nru a/fs/proc/inode.c b/fs/proc/inode.c
--- a/fs/proc/inode.c	Mon Jan 13 23:56:39 2003
+++ b/fs/proc/inode.c	Thu Mar 13 16:52:26 2003
@@ -13,7 +13,6 @@
 #include <linux/file.h>
 #include <linux/limits.h>
 #include <linux/init.h>
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
--- a/fs/proc/proc_misc.c	Sat Mar  8 14:50:46 2003
+++ b/fs/proc/proc_misc.c	Sat Mar 22 22:14:49 2003
@@ -42,6 +42,7 @@
 #include <linux/blkdev.h>
 #include <linux/hugetlb.h>
 #include <linux/jiffies.h>
+#include <linux/sysrq.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
@@ -133,8 +134,6 @@
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
-extern atomic_t vm_committed_space;
-
 static int meminfo_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
 {
@@ -183,7 +182,7 @@
 		K(i.totalram),
 		K(i.freeram),
 		K(i.bufferram),
-		K(ps.nr_pagecache-total_swapcache_pages-i.bufferram),
+		K(get_page_cache_size()-total_swapcache_pages-i.bufferram),
 		K(total_swapcache_pages),
 		K(active),
 		K(inactive),
@@ -521,6 +520,28 @@
 	.write		= write_profile,
 };
 
+#ifdef CONFIG_MAGIC_SYSRQ
+/*
+ * writing 'C' to /proc/sysrq-trigger is like sysrq-C
+ */
+static ssize_t write_sysrq_trigger(struct file *file, const char *buf,
+				     size_t count, loff_t *ppos)
+{
+	if (count) {
+		char c;
+
+		if (get_user(c, buf))
+			return -EFAULT;
+		handle_sysrq(c, NULL, NULL);
+	}
+	return count;
+}
+
+static struct file_operations proc_sysrq_trigger_operations = {
+	.write		= write_sysrq_trigger,
+};
+#endif
+
 struct proc_dir_entry *proc_root_kcore;
 
 static void create_seq_entry(char *name, mode_t mode, struct file_operations *f)
@@ -592,6 +613,11 @@
 			entry->size = (1+prof_len) * sizeof(unsigned int);
 		}
 	}
+#ifdef CONFIG_MAGIC_SYSRQ
+	entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL);
+	if (entry)
+		entry->proc_fops = &proc_sysrq_trigger_operations;
+#endif
 #ifdef CONFIG_PPC32
 	{
 		extern struct file_operations ppc_htab_operations;
diff -Nru a/fs/readdir.c b/fs/readdir.c
--- a/fs/readdir.c	Sat Mar  8 14:50:39 2003
+++ b/fs/readdir.c	Sat Mar 22 22:14:57 2003
@@ -85,7 +85,7 @@
 	return 0;
 }
 
-asmlinkage int old_readdir(unsigned int fd, void * dirent, unsigned int count)
+asmlinkage long old_readdir(unsigned int fd, void * dirent, unsigned int count)
 {
 	int error;
 	struct file * file;
diff -Nru a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
--- a/fs/reiserfs/journal.c	Fri Mar 14 08:16:39 2003
+++ b/fs/reiserfs/journal.c	Sat Mar 22 22:14:13 2003
@@ -867,9 +867,11 @@
 }
 
 static void reiserfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate) {
+    char b[BDEVNAME_SIZE];
+
     if (buffer_journaled(bh)) {
         reiserfs_warning("clm-2084: pinned buffer %lu:%s sent to disk\n",
-	                 bh->b_blocknr, bdevname(bh->b_bdev)) ;
+	                 bh->b_blocknr, bdevname(bh->b_bdev, b)) ;
     }
     if (uptodate)
     	set_buffer_uptodate(bh) ;
@@ -1652,10 +1654,12 @@
   int replay_count = 0 ;
   int continue_replay = 1 ;
   int ret ;
+  char b[BDEVNAME_SIZE];
 
   cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
   printk("reiserfs: checking transaction log (%s) for (%s)\n",
-	 bdevname(SB_JOURNAL(p_s_sb)->j_dev_bd), reiserfs_bdevname(p_s_sb));
+	 bdevname(SB_JOURNAL(p_s_sb)->j_dev_bd, b),
+	 reiserfs_bdevname(p_s_sb));
   start = get_seconds() ;
 
   /* step 1, read in the journal header block.  Check the transaction it says 
@@ -1893,6 +1897,7 @@
 	int result;
 	dev_t jdev;
 	int blkdev_mode = FMODE_READ | FMODE_WRITE;
+	char b[BDEVNAME_SIZE];
 
 	result = 0;
 
@@ -1915,7 +1920,7 @@
 			result = -ENOMEM;
 		if( result != 0 )
 			printk( "sh-458: journal_init_dev: cannot init journal device\n '%s': %i", 
-				bdevname(journal->j_dev_bd), result );
+				bdevname(journal->j_dev_bd, b), result );
 
 		else if (jdev != super->s_dev) {
 			set_blocksize(journal->j_dev_bd, super->s_blocksize);
@@ -1948,7 +1953,8 @@
 	if( result != 0 ) {
 		release_journal_dev( super, journal );
 	}
-	printk( "journal_init_dev: journal device: %s\n", bdevname(journal->j_dev_bd));
+	printk( "journal_init_dev: journal device: %s\n",
+		bdevname(journal->j_dev_bd, b));
 	return result;
 }
 
@@ -1961,6 +1967,7 @@
     struct reiserfs_super_block * rs;
     struct reiserfs_journal_header *jh;
     struct reiserfs_journal *journal;
+    char b[BDEVNAME_SIZE];
 
     if (sizeof(struct reiserfs_journal_commit) != 4096 ||
       sizeof(struct reiserfs_journal_desc) != 4096) {
@@ -2007,7 +2014,8 @@
      if (is_reiserfs_jr(rs) && (jh->jh_journal.jp_journal_magic != sb_jp_journal_magic(rs))) {
 	 printk("sh-460: journal header magic %x (device %s) does not match "
 		"to magic found in super block %x (device %s)\n",
-		jh->jh_journal.jp_journal_magic, bdevname( SB_JOURNAL(p_s_sb)->j_dev_bd ),
+		jh->jh_journal.jp_journal_magic,
+		bdevname( SB_JOURNAL(p_s_sb)->j_dev_bd, b),
 		sb_jp_journal_magic(rs), reiserfs_bdevname (p_s_sb));
 	 brelse (bhjh);
 	 goto free_and_return;
@@ -2058,7 +2066,7 @@
   printk ("Reiserfs journal params: device %s, size %u, "
 	  "journal first block %u, max trans len %u, max batch %u, "
 	  "max commit age %u, max trans age %u\n",
-	  bdevname( SB_JOURNAL(p_s_sb)->j_dev_bd ),
+	  bdevname( SB_JOURNAL(p_s_sb)->j_dev_bd, b),
 	  SB_ONDISK_JOURNAL_SIZE(p_s_sb),
 	  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb),
 	  SB_JOURNAL_TRANS_MAX(p_s_sb),
diff -Nru a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c
--- a/fs/reiserfs/prints.c	Tue Oct  8 11:40:46 2002
+++ b/fs/reiserfs/prints.c	Sat Mar 22 22:14:13 2003
@@ -139,8 +139,11 @@
 
 static void sprintf_buffer_head (char * buf, struct buffer_head * bh) 
 {
+  char b[BDEVNAME_SIZE];
+
   sprintf (buf, "dev %s, size %d, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
-	   bdevname (bh->b_bdev), bh->b_size, (unsigned long long)bh->b_blocknr,
+	   bdevname (bh->b_bdev, b), bh->b_size,
+	   (unsigned long long)bh->b_blocknr,
 	   atomic_read (&(bh->b_count)),
 	   bh->b_state, bh->b_page,
 	   buffer_uptodate (bh) ? "UPTODATE" : "!UPTODATE",
@@ -497,7 +500,7 @@
     struct reiserfs_super_block * rs = (struct reiserfs_super_block *)(bh->b_data);
     int skipped, data_blocks;
     char *version;
-    
+    char b[BDEVNAME_SIZE];
 
     if (is_reiserfs_3_5(rs)) {
         version = "3.5";
@@ -510,7 +513,7 @@
 	return 1;
     }
 
-    printk ("%s\'s super block is in block %llu\n", bdevname (bh->b_bdev), 
+    printk ("%s\'s super block is in block %llu\n", bdevname (bh->b_bdev, b),
             (unsigned long long)bh->b_blocknr);
     printk ("Reiserfs version %s\n", version );
     printk ("Block count %u\n", sb_block_count(rs));
diff -Nru a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
--- a/fs/reiserfs/procfs.c	Sat Dec  7 03:13:42 2002
+++ b/fs/reiserfs/procfs.c	Sat Mar 22 22:14:13 2003
@@ -460,6 +460,7 @@
 	struct reiserfs_super_block *rs;
 	struct journal_params *jp;	
 	int len = 0;
+	char b[BDEVNAME_SIZE];
     
 	sb = procinfo_prologue((int)data);
 	if( sb == NULL )
@@ -516,7 +517,7 @@
 			"prepare_retry: \t%12lu\n",
 
                         DJP( jp_journal_1st_block ),
-                        bdevname(SB_JOURNAL(sb)->j_dev_bd),
+                        bdevname(SB_JOURNAL(sb)->j_dev_bd, b),
                         DJP( jp_journal_dev ),
                         DJP( jp_journal_size ),
                         DJP( jp_journal_trans_max ),
diff -Nru a/fs/select.c b/fs/select.c
--- a/fs/select.c	Thu Dec 26 10:57:24 2002
+++ b/fs/select.c	Mon Mar 17 21:32:01 2003
@@ -235,7 +235,7 @@
 		}
 		__timeout = schedule_timeout(__timeout);
 	}
-	current->state = TASK_RUNNING;
+	__set_current_state(TASK_RUNNING);
 
 	poll_freewait(&table);
 
@@ -425,7 +425,7 @@
 			break;
 		timeout = schedule_timeout(timeout);
 	}
-	current->state = TASK_RUNNING;
+	__set_current_state(TASK_RUNNING);
 	return count;
 }
 
diff -Nru a/fs/super.c b/fs/super.c
--- a/fs/super.c	Mon Mar 10 10:49:27 2003
+++ b/fs/super.c	Thu Mar 20 18:25:40 2003
@@ -303,11 +303,25 @@
 /*
  * Call the ->sync_fs super_op against all filesytems which are r/w and
  * which implement it.
+ *
+ * This operation is careful to avoid the livelock which could easily happen
+ * if two or more filesystems are being continuously dirtied.  s_need_sync_fs
+ * is used only here.  We set it against all filesystems and then clear it as
+ * we sync them.  So redirtied filesystems are skipped.
+ *
+ * But if process A is currently running sync_filesytems and then process B
+ * calls sync_filesystems as well, process B will set all the s_need_sync_fs
+ * flags again, which will cause process A to resync everything.  Fix that with
+ * a local mutex.
+ *
+ * FIXME: If wait==0, we only really need to call ->sync_fs if s_dirt is true.
  */
 void sync_filesystems(int wait)
 {
-	struct super_block * sb;
+	struct super_block *sb;
+	static DECLARE_MUTEX(mutex);
 
+	down(&mutex);		/* Could be down_interruptible */
 	spin_lock(&sb_lock);
 	for (sb = sb_entry(super_blocks.next); sb != sb_entry(&super_blocks);
 			sb = sb_entry(sb->s_list.next)) {
@@ -337,6 +351,7 @@
 		goto restart;
 	}
 	spin_unlock(&sb_lock);
+	up(&mutex);
 }
 
 /**
@@ -526,8 +541,10 @@
 		}
 		goto out;
 	} else {
+		char b[BDEVNAME_SIZE];
+
 		s->s_flags = flags;
-		strncpy(s->s_id, bdevname(bdev), sizeof(s->s_id));
+		strncpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
 		s->s_old_blocksize = block_size(bdev);
 		sb_set_blocksize(s, s->s_old_blocksize);
 		error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
diff -Nru a/fs/sysfs/file.c b/fs/sysfs/file.c
--- a/fs/sysfs/file.c	Thu Jan 30 15:10:06 2003
+++ b/fs/sysfs/file.c	Tue Mar 18 12:52:42 2003
@@ -80,7 +80,7 @@
 	struct kobject * kobj = file->f_dentry->d_parent->d_fsdata;
 	struct sysfs_ops * ops = buffer->ops;
 	int ret = 0;
-	size_t count;
+	ssize_t count;
 
 	if (!buffer->page)
 		buffer->page = (char *) __get_free_page(GFP_KERNEL);
diff -Nru a/fs/ufs/util.c b/fs/ufs/util.c
--- a/fs/ufs/util.c	Thu May 23 06:19:01 2002
+++ b/fs/ufs/util.c	Mon Mar 17 21:32:11 2003
@@ -48,6 +48,7 @@
 failed:
 	for (j = 0; j < i; j++)
 		brelse (ubh->bh[j]);
+	kfree(ubh);
 	return NULL;
 }
 
diff -Nru a/fs/xfs/linux/xfs_aops.c b/fs/xfs/linux/xfs_aops.c
--- a/fs/xfs/linux/xfs_aops.c	Wed Feb 19 09:13:40 2003
+++ b/fs/xfs/linux/xfs_aops.c	Mon Mar 17 14:05:46 2003
@@ -31,11 +31,55 @@
  */
 
 #include <xfs.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
 #include <linux/mpage.h>
 
+STATIC void convert_page(struct inode *, struct page *,
+			page_buf_bmap_t *, void *, int, int);
 
+void
+linvfs_unwritten_done(
+	struct buffer_head	*bh,
+	int			uptodate)
+{
+	page_buf_t		*pb = (page_buf_t *)bh->b_private;
+
+	ASSERT(buffer_unwritten(bh));
+	bh->b_end_io = NULL;
+	clear_buffer_unwritten(bh);
+	if (!uptodate)
+		pagebuf_ioerror(pb, -EIO);
+	if (atomic_dec_and_test(&pb->pb_io_remaining) == 1)
+		pagebuf_iodone(pb, 1, 1);
+	end_buffer_async_write(bh, uptodate);
+}
+
+/*
+ * Issue transactions to convert a buffer range from unwritten
+ * to written extents.
+ */
+STATIC void
+xfs_unwritten_conv(
+	xfs_buf_t		*bp)
+{
+	bhv_desc_t		*bdp = XFS_BUF_FSPRIVATE(bp, bhv_desc_t *);
+	xfs_mount_t		*mp;
+	xfs_inode_t		*ip;
+
+	ip = XFS_BHVTOI(bdp);
+	mp = ip->i_mount;
+
+	if (XFS_TEST_ERROR(XFS_BUF_GETERROR(bp), mp,
+			   XFS_ERRTAG_STRATCMPL_IOERR,
+			   XFS_RANDOM_STRATCMPL_IOERR)) {
+		xfs_ioerror_alert(__FUNCTION__, mp, bp, XFS_BUF_ADDR(bp));
+	}
+
+	XFS_IOMAP_WRITE_UNWRITTEN(mp, &ip->i_iocore,
+				  XFS_BUF_OFFSET(bp), XFS_BUF_SIZE(bp));
+	XFS_BUF_SET_FSPRIVATE(bp, NULL);
+	XFS_BUF_CLR_IODONE_FUNC(bp);
+	xfs_biodone(bp);
+}
 
 STATIC int
 map_blocks(
@@ -128,6 +172,58 @@
 }
 
 /*
+ * Look for a page at index which is unlocked and contains our
+ * unwritten extent flagged buffers at its head.  Returns page
+ * locked and with an extra reference count, and length of the
+ * unwritten extent component on this page that we can write,
+ * in units of filesystem blocks.
+ */
+STATIC struct page *
+probe_unwritten_page(
+	struct address_space	*mapping,
+	unsigned long		index,
+	page_buf_bmap_t		*mp,
+	page_buf_t		*pb,
+	unsigned long		max_offset,
+	unsigned long		*fsbs)
+{
+	struct page		*page;
+
+	page = find_trylock_page(mapping, index);
+	if (!page)
+		return 0;
+	if (PageWriteback(page))
+		goto out;
+
+	if (page->mapping && page_has_buffers(page)) {
+		struct buffer_head	*bh, *head;
+		unsigned long		p_offset = 0;
+
+		*fsbs = 0;
+		bh = head = page_buffers(page);
+		do {
+			if (!buffer_unwritten(bh))
+				break;
+			if (!match_offset_to_mapping(page, mp, p_offset))
+				break;
+			if (p_offset >= max_offset)
+				break;
+			set_buffer_unwritten_io(bh);
+			bh->b_private = pb;
+			p_offset += bh->b_size;
+			(*fsbs)++;
+		} while ((bh = bh->b_this_page) != head);
+
+		if (p_offset)
+			return page;
+	}
+
+out:
+	unlock_page(page);
+	return NULL;
+}
+
+/*
  * Look for a page at index which is unlocked and not mapped
  * yet - clustering for mmap write case.
  */
@@ -149,6 +245,7 @@
 	if (page->mapping && PageDirty(page)) {
 		if (page_has_buffers(page)) {
 			struct buffer_head	*bh, *head;
+
 			bh = head = page_buffers(page);
 			do {
 				if (buffer_mapped(bh) || !buffer_uptodate(bh))
@@ -189,6 +286,8 @@
 	 */
 	if (bh == head) {
 		tlast = inode->i_size >> PAGE_CACHE_SHIFT;
+		/* Prune this back to avoid pathological behavior */
+		tlast = min(tlast, startpage->index + 64);
 		for (tindex = startpage->index + 1; tindex < tlast; tindex++) {
 			len = probe_unmapped_page(mapping, tindex,
 							PAGE_CACHE_SIZE);
@@ -206,11 +305,12 @@
 }
 
 /*
- * Probe for a given page (index) in the inode & test if it is delayed.
- * Returns page locked and with an extra reference count.
+ * Probe for a given page (index) in the inode and test if it is delayed
+ * and without unwritten buffers.  Returns page locked and with an extra
+ * reference count.
  */
 STATIC struct page *
-probe_page(
+probe_delalloc_page(
 	struct inode		*inode,
 	unsigned long		index)
 {
@@ -224,12 +324,20 @@
 
 	if (page->mapping && page_has_buffers(page)) {
 		struct buffer_head	*bh, *head;
+		int			acceptable = 0;
 
 		bh = head = page_buffers(page);
 		do {
-			if (buffer_delay(bh))
-				return page;
+			if (buffer_unwritten(bh)) {
+				acceptable = 0;
+				break;
+			} else if (buffer_delay(bh)) {
+				acceptable = 1;
+			}
 		} while ((bh = bh->b_this_page) != head);
+
+		if (acceptable)
+			return page;
 	}
 
 out:
@@ -237,6 +345,103 @@
 	return NULL;
 }
 
+STATIC int
+map_unwritten(
+	struct inode		*inode,
+	struct page		*start_page,
+	struct buffer_head	*head,
+	struct buffer_head	*curr,
+	unsigned long		p_offset,
+	int			block_bits,
+	page_buf_bmap_t		*mp,
+	int			all_bh)
+{
+	struct buffer_head	*bh = curr;
+	page_buf_bmap_t		*tmp;
+	page_buf_t		*pb;
+	loff_t			offset, size;
+	unsigned long		nblocks = 0;
+
+	offset = start_page->index;
+	offset <<= PAGE_CACHE_SHIFT;
+	offset += p_offset;
+
+	pb = pagebuf_lookup(mp->pbm_target,
+			    mp->pbm_offset, mp->pbm_bsize, _PBF_LOCKABLE);
+	if (!pb)
+		return -ENOMEM;
+
+	/* Set the count to 1 initially, this will stop an I/O
+	 * completion callout which happens before we have started
+	 * all the I/O from calling pagebuf_iodone too early.
+	 */
+	atomic_set(&pb->pb_io_remaining, 1);
+
+	/* First map forwards in the page consecutive buffers
+	 * covering this unwritten extent
+	 */
+	do {
+		if (!buffer_unwritten(bh))
+			break;
+		tmp = match_offset_to_mapping(start_page, mp, p_offset);
+		if (!tmp)
+			break;
+		BUG_ON(!(tmp->pbm_flags & PBMF_UNWRITTEN));
+		map_buffer_at_offset(start_page, bh, p_offset, block_bits, mp);
+		set_buffer_unwritten_io(bh);
+		bh->b_private = pb;
+		p_offset += bh->b_size;
+		nblocks++;
+	} while ((bh = bh->b_this_page) != head);
+
+	atomic_add(nblocks, &pb->pb_io_remaining);
+
+	/* If we reached the end of the page, map forwards in any
+	 * following pages which are also covered by this extent.
+	 */
+	if (bh == head) {
+		struct address_space	*mapping = inode->i_mapping;
+		unsigned long		tindex, tlast, bs;
+		struct page		*page;
+
+		tlast = inode->i_size >> PAGE_CACHE_SHIFT;
+		tlast = min(tlast, start_page->index + pb->pb_page_count - 1);
+		for (tindex = start_page->index + 1; tindex < tlast; tindex++) {
+			page = probe_unwritten_page(mapping, tindex, mp, pb,
+					PAGE_CACHE_SIZE, &bs);
+			if (!page)
+				break;
+			nblocks += bs;
+			atomic_add(bs, &pb->pb_io_remaining);
+			convert_page(inode, page, mp, pb, 1, all_bh);
+		}
+
+		if ((tindex == tlast) && (inode->i_size & ~PAGE_CACHE_MASK)) {
+			page = probe_unwritten_page(mapping, tindex, mp, pb,
+					inode->i_size & ~PAGE_CACHE_MASK, &bs);
+			if (page) {
+				nblocks += bs;
+				atomic_add(bs, &pb->pb_io_remaining);
+				convert_page(inode, page,
+							mp, pb, 1, all_bh);
+			}
+		}
+	}
+
+	size = nblocks;		/* NB: using 64bit number here */
+	size <<= block_bits;	/* convert fsb's to byte range */
+
+	XFS_BUF_SET_SIZE(pb, size);
+	XFS_BUF_SET_OFFSET(pb, offset);
+	XFS_BUF_SET_FSPRIVATE(pb, LINVFS_GET_VP(inode)->v_fbhv);
+	XFS_BUF_SET_IODONE_FUNC(pb, xfs_unwritten_conv);
+
+	if (atomic_dec_and_test(&pb->pb_io_remaining) == 1)
+		pagebuf_iodone(pb, 1, 1);
+
+	return 0;
+}
+
 STATIC void
 submit_page(
 	struct page		*page,
@@ -255,6 +460,8 @@
 		for (i = 0; i < cnt; i++) {
 			bh = bh_arr[i];
 			mark_buffer_async_write(bh);
+			if (buffer_unwritten(bh))
+				set_buffer_unwritten_io(bh);
 			set_buffer_uptodate(bh);
 			clear_buffer_dirty(bh);
 		}
@@ -268,14 +475,15 @@
 /*
  * Allocate & map buffers for page given the extent map. Write it out.
  * except for the original page of a writepage, this is called on
- * delalloc pages only, for the original page it is possible that
- * the page has no mapping at all.
+ * delalloc/unwritten pages only, for the original page it is possible
+ * that the page has no mapping at all.
  */
 STATIC void
 convert_page(
 	struct inode		*inode,
 	struct page		*page,
 	page_buf_bmap_t		*maps,
+	void			*private,
 	int			startio,
 	int			all_bh)
 {
@@ -308,7 +516,23 @@
 			continue;
 		ASSERT(!(tmp->pbm_flags & PBMF_HOLE));
 		ASSERT(!(tmp->pbm_flags & PBMF_DELAY));
-		map_buffer_at_offset(page, bh, offset, bbits, tmp);
+
+		/* If this is a new unwritten extent buffer (i.e. one
+		 * that we haven't passed in private data for, we must
+		 * now map this buffer too.
+		 */
+		if (buffer_unwritten(bh) && !bh->b_end_io) {
+			ASSERT(tmp->pbm_flags & PBMF_UNWRITTEN);
+			map_unwritten(inode, page, head, bh,
+						offset, bbits, tmp, all_bh);
+		} else {
+			map_buffer_at_offset(page, bh, offset, bbits, tmp);
+			if (buffer_unwritten(bh)) {
+				set_buffer_unwritten_io(bh);
+				bh->b_private = private;
+				ASSERT(private);
+			}
+		}
 		if (startio && (offset < end)) {
 			bh_arr[index++] = bh;
 		} else {
@@ -341,10 +565,10 @@
 
 	tlast = (mp->pbm_offset + mp->pbm_bsize) >> PAGE_CACHE_SHIFT;
 	for (; tindex < tlast; tindex++) {
-		page = probe_page(inode, tindex);
+		page = probe_delalloc_page(inode, tindex);
 		if (!page)
 			break;
-		convert_page(inode, page, mp, startio, all_bh);
+		convert_page(inode, page, mp, NULL, startio, all_bh);
 	}
 }
 
@@ -368,7 +592,7 @@
  */
 
 STATIC int
-delalloc_convert(
+page_state_convert(
 	struct page	*page,
 	int		startio,
 	int		unmapped) /* also implies page uptodate */
@@ -411,10 +635,42 @@
 		}
 
 		/*
-		 * First case, allocate space for delalloc buffer head
-		 * we can return EAGAIN here in the release page case.
+		 * First case, map an unwritten extent and prepare for
+		 * extent state conversion transaction on completion.
 		 */
-		if (buffer_delay(bh)) {
+		if (buffer_unwritten(bh)) {
+			if (!mp) {
+				err = map_blocks(inode, offset, len, &map,
+						PBF_FILE_UNWRITTEN);
+				if (err) {
+					goto error;
+				}
+				mp = match_offset_to_mapping(page, &map,
+								p_offset);
+			}
+			if (mp) {
+				if (!bh->b_end_io) {
+					err = map_unwritten(inode, page,
+							head, bh, p_offset,
+							inode->i_blkbits,
+							mp, unmapped);
+					if (err) {
+						goto error;
+					}
+				}
+				if (startio) {
+					bh_arr[cnt++] = bh;
+				} else {
+					set_buffer_dirty(bh);
+					unlock_buffer(bh);
+				}
+				page_dirty = 0;
+			}
+		/*
+		 * Second case, allocate space for a delalloc buffer.
+		 * We can return EAGAIN here in the release page case.
+		 */
+		} else if (buffer_delay(bh)) {
 			if (!mp) {
 				err = map_blocks(inode, offset, len, &map,
 					PBF_FILE_ALLOCATE | flags);
@@ -574,6 +830,12 @@
 			bh_result->b_bdev = pbmap.pbm_target->pbr_bdev;
 			set_buffer_mapped(bh_result);
 		}
+		if (pbmap.pbm_flags & PBMF_UNWRITTEN) {
+			if (create)
+				set_buffer_mapped(bh_result);
+			set_buffer_unwritten(bh_result);
+			set_buffer_delay(bh_result);
+		}
 	}
 
 	/* If we previously allocated a block out beyond eof and
@@ -695,21 +957,23 @@
 	return mpage_readpages(mapping, pages, nr_pages, linvfs_get_block);
 }
 
-
 STATIC void
 count_page_state(
 	struct page		*page,
 	int			*delalloc,
-	int			*unmapped)
+	int			*unmapped,
+	int			*unwritten)
 {
 	struct buffer_head	*bh, *head;
 
-	*delalloc = *unmapped = 0;
+	*delalloc = *unmapped = *unwritten = 0;
 
 	bh = head = page_buffers(page);
 	do {
 		if (buffer_uptodate(bh) && !buffer_mapped(bh))
 			(*unmapped) = 1;
+		else if (buffer_unwritten(bh))
+			(*unwritten) = 1;
 		else if (buffer_delay(bh))
 			(*delalloc) = 1;
 	} while ((bh = bh->b_this_page) != head);
@@ -736,6 +1000,7 @@
  * is off, we need to fail the writepage and redirty the page.
  * We also need to set PF_NOIO ourselves.
  */
+
 STATIC int
 linvfs_writepage(
 	struct page		*page,
@@ -743,7 +1008,7 @@
 {
 	int			error;
 	int			need_trans;
-	int			delalloc, unmapped;
+	int			delalloc, unmapped, unwritten;
 	struct inode		*inode = page->mapping->host;
 
 	/*
@@ -751,15 +1016,16 @@
 	 *  1. There are delalloc buffers on the page
 	 *  2. The page is upto date and we have unmapped buffers
 	 *  3. The page is upto date and we have no buffers
+	 *  4. There are unwritten buffers on the page
 	 */
 	if (!page_has_buffers(page)) {
 		unmapped = 1;
 		need_trans = 1;
 	} else {
-		count_page_state(page, &delalloc, &unmapped);
+		count_page_state(page, &delalloc, &unmapped, &unwritten);
 		if (!PageUptodate(page))
 			unmapped = 0;
-		need_trans = delalloc + unmapped;
+		need_trans = delalloc + unmapped + unwritten;
 	}
 
 	/*
@@ -775,15 +1041,14 @@
 	 * Delay hooking up buffer heads until we have
 	 * made our go/no-go decision.
 	 */
-	if (!page_has_buffers(page)) {
+	if (!page_has_buffers(page))
 		create_empty_buffers(page, 1 << inode->i_blkbits, 0);
-	}
 
 	/*
-	 * Convert delalloc or unmapped space to real space and flush out
-	 * to disk.
+	 * Convert delayed allocate, unwritten or unmapped space
+	 * to real space and flush out to disk.
 	 */
-	error = delalloc_convert(page, 1, unmapped);
+	error = page_state_convert(page, 1, unmapped);
 	if (error == -EAGAIN)
 		goto out_fail;
 	if (unlikely(error < 0))
@@ -824,10 +1089,10 @@
 	struct page		*page,
 	int			gfp_mask)
 {
-	int			delalloc, unmapped;
+	int			delalloc, unmapped, unwritten;
 
-	count_page_state(page, &delalloc, &unmapped);
-	if (!delalloc)
+	count_page_state(page, &delalloc, &unmapped, &unwritten);
+	if (!delalloc && !unwritten)
 		goto free_buffers;
 
 	if (!(gfp_mask & __GFP_FS))
@@ -839,7 +1104,7 @@
 	 * Never need to allocate space here - we will always
 	 * come back to writepage in that case.
 	 */
-	if (delalloc_convert(page, 0, 0) == 0)
+	if (page_state_convert(page, 0, 0) == 0)
 		goto free_buffers;
 	return 0;
 
diff -Nru a/fs/xfs/linux/xfs_behavior.c b/fs/xfs/linux/xfs_behavior.c
--- a/fs/xfs/linux/xfs_behavior.c	Wed Sep 11 11:12:02 2002
+++ b/fs/xfs/linux/xfs_behavior.c	Mon Mar 17 13:24:32 2003
@@ -121,9 +121,7 @@
 {
 	bhv_desc_t	*bdp;
 
-	BHV_READ_LOCK(bhp);
 	bdp = bhv_lookup(bhp, ops);
-	BHV_READ_UNLOCK(bhp);
 
 	return bdp;
 }
@@ -140,18 +138,12 @@
 {
 	bhv_desc_t	*curdesc;
 
-	BHV_READ_LOCK(bhp);
 	for (curdesc = bhp->bh_first;
 	     curdesc != NULL;
 	     curdesc = curdesc->bd_next) {
-
-		if (curdesc->bd_next == NULL) {
-			BHV_READ_UNLOCK(bhp);
+		if (curdesc->bd_next == NULL)
 			return curdesc;
-		}
 	}
-
-	BHV_READ_UNLOCK(bhp);
 	return NULL;
 }
 
diff -Nru a/fs/xfs/linux/xfs_behavior.h b/fs/xfs/linux/xfs_behavior.h
--- a/fs/xfs/linux/xfs_behavior.h	Wed Sep 11 11:12:02 2002
+++ b/fs/xfs/linux/xfs_behavior.h	Mon Mar 17 13:24:32 2003
@@ -152,13 +152,6 @@
 #define BHV_IDENTITY(bdp)	((bhv_identity_t *)(bdp)->bd_ops)
 #define BHV_POSITION(bdp)	(BHV_IDENTITY(bdp)->bi_position)
 
-
-#define BHV_READ_LOCK(bhp)
-#define BHV_READ_UNLOCK(bhp)
-#define BHV_NOT_READ_LOCKED(bhp)	1
-#define BHV_IS_WRITE_LOCKED(bhp)	1
-#define BHV_NOT_WRITE_LOCKED(bhp)	1
-
 extern void bhv_head_init(bhv_head_t *, char *);
 extern void bhv_head_destroy(bhv_head_t *);
 extern void bhv_head_reinit(bhv_head_t *);
@@ -179,8 +172,6 @@
 	(bdp)->bd_ops = ops;				\
 	(bdp)->bd_next = NULL;				\
  }
-
-#define BHV_DESC_INIT(so,A,B)	bhv_desc_init(&(so->so_bhv),so,A,B)
 
 /*
  * Remove a behavior descriptor from a behavior chain.
diff -Nru a/fs/xfs/linux/xfs_file.c b/fs/xfs/linux/xfs_file.c
--- a/fs/xfs/linux/xfs_file.c	Mon Nov 25 13:53:29 2002
+++ b/fs/xfs/linux/xfs_file.c	Mon Mar 17 14:05:46 2003
@@ -32,8 +32,6 @@
 
 #include <xfs.h>
 #include <linux/dcache.h>
-#include <linux/pagemap.h>
-#include <linux/slab.h>
 #include <linux/mman.h> /* for PROT_WRITE */
 
 static struct vm_operations_struct linvfs_file_vm_ops;
@@ -227,8 +225,8 @@
 	int		eof = 0;
 	caddr_t		read_buf;
 	int		namelen, size = 0;
-	size_t		rlen = PAGE_CACHE_SIZE << 2;
-	xfs_off_t	start_offset;
+	size_t		rlen = PAGE_CACHE_SIZE;
+	xfs_off_t	start_offset, curr_offset;
 	xfs_dirent_t	*dbp = NULL;
 
 	vp = LINVFS_GET_VP(filp->f_dentry->d_inode);
@@ -247,7 +245,7 @@
 	uio.uio_iov = &iov;
 	uio.uio_fmode = filp->f_mode;
 	uio.uio_segflg = UIO_SYSSPACE;
-	uio.uio_offset = filp->f_pos;
+	curr_offset = uio.uio_offset = filp->f_pos;
 
 	while (!eof) {
 		uio.uio_resid = iov.iov_len = rlen;
@@ -268,21 +266,22 @@
 			namelen = strlen(dbp->d_name);
 
 			if (filldir(dirent, dbp->d_name, namelen,
-					(loff_t) dbp->d_off,
+					(loff_t) curr_offset,
 					(ino_t) dbp->d_ino,
 					DT_UNKNOWN)) {
 				goto done;
 			}
 			size -= dbp->d_reclen;
+			curr_offset = (loff_t)dbp->d_off & 0x7fffffff;
 			dbp = nextdp(dbp);
 		}
 	}
 done:
 	if (!error) {
 		if (size == 0)
-			filp->f_pos = uio.uio_offset;
+			filp->f_pos = uio.uio_offset & 0x7fffffff;
 		else if (dbp)
-			filp->f_pos = dbp->d_off;
+			filp->f_pos = curr_offset;
 	}
 
 	kfree(read_buf);
@@ -308,7 +307,6 @@
 	vma->vm_ops = &linvfs_file_vm_ops;
 
 	VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error);
-	UPDATE_ATIME(ip);
 	return 0;
 }
 
diff -Nru a/fs/xfs/linux/xfs_fs_subr.c b/fs/xfs/linux/xfs_fs_subr.c
--- a/fs/xfs/linux/xfs_fs_subr.c	Mon Oct 14 13:48:53 2002
+++ b/fs/xfs/linux/xfs_fs_subr.c	Mon Mar 17 12:16:07 2003
@@ -33,48 +33,6 @@
 #include <xfs.h>
 
 /*
- * Implementation for VFS_DOUNMOUNT.
- */
-int
-fs_dounmount(
-	bhv_desc_t	*bdp,
-	int		flags,
-	vnode_t		*rootvp,
-	cred_t		*cr)
-{
-	struct vfs	*vfsp = bhvtovfs(bdp);
-	bhv_desc_t	*fbdp = vfsp->vfs_fbhv;
-	int		error;
-
-	/*
-	 * Wait for sync to finish and lock vfsp.  This also sets the
-	 * VFS_OFFLINE flag.  Once we do this we can give up reference
-	 * the root vnode which we hold to avoid the another unmount
-	 * ripping the vfs out from under us before we get to lock it.
-	 * The VFS_DOUNMOUNT calling convention is that the reference
-	 * on the rot vnode is released whether the call succeeds or
-	 * fails.
-	 */
-	if (rootvp)
-		VN_RELE(rootvp);
-
-	/*
-	 * Now invoke SYNC and UNMOUNT ops, using the PVFS versions is
-	 * OK since we already have a behavior lock as a result of
-	 * being in VFS_DOUNMOUNT.  It is necessary to do things this
-	 * way since using the VFS versions would cause us to get the
-	 * behavior lock twice which can cause deadlock as well as
-	 * making the coding of vfs relocation unnecessarilty difficult
-	 * by making relocations invoked by unmount occur in a different
-	 * environment than those invoked by mount-update.
-	 */
-	PVFS_SYNC(fbdp, SYNC_ATTR|SYNC_DELWRI, cr, error);
-	if (error == 0)
-		PVFS_UNMOUNT(fbdp, flags, cr, error);
-	return error;
-}
-
-/*
  * Stub for no-op vnode operations that return error status.
  */
 int
diff -Nru a/fs/xfs/linux/xfs_fs_subr.h b/fs/xfs/linux/xfs_fs_subr.h
--- a/fs/xfs/linux/xfs_fs_subr.h	Wed Sep 11 11:12:04 2002
+++ b/fs/xfs/linux/xfs_fs_subr.h	Mon Mar 17 12:16:07 2003
@@ -42,7 +42,6 @@
 extern int	fs_nosys(void);
 extern int	fs_nodev(void);
 extern void	fs_noval(void);
-extern int	fs_dounmount(bhv_desc_t *, int, vnode_t *, struct cred *);
 extern void	fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
 extern void	fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
 extern int	fs_flush_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int);
diff -Nru a/fs/xfs/linux/xfs_globals.c b/fs/xfs/linux/xfs_globals.c
--- a/fs/xfs/linux/xfs_globals.c	Tue Feb 25 08:09:57 2003
+++ b/fs/xfs/linux/xfs_globals.c	Mon Mar 17 12:19:19 2003
@@ -46,7 +46,7 @@
  * Tunable XFS parameters.  xfs_params is required even when CONFIG_SYSCTL=n,
  * other XFS code uses these values.
  */
-xfs_param_t xfs_params = { 0, 1, 0, 0, 0 };
+xfs_param_t xfs_params = { 0, 1, 0, 0, 0, 3 };
 
 /*
  * Used to serialize atomicIncWithWrap.
diff -Nru a/fs/xfs/linux/xfs_ioctl.c b/fs/xfs/linux/xfs_ioctl.c
--- a/fs/xfs/linux/xfs_ioctl.c	Tue Dec  3 13:35:55 2002
+++ b/fs/xfs/linux/xfs_ioctl.c	Mon Mar 17 14:08:02 2003
@@ -130,7 +130,6 @@
 		int		lock_mode;
 
 		/* need to get access to the xfs_inode to read the generation */
-		VN_BHV_READ_LOCK(&(vp)->v_bh);
 		bhv = VNODE_TO_FIRST_BHV(vp);
 		ASSERT(bhv);
 		ip = XFS_BHVTOI(bhv);
@@ -145,7 +144,6 @@
 		handle.ha_fid.xfs_fid_ino = ip->i_ino;
 
 		xfs_iunlock_map_shared(ip, lock_mode);
-		VN_BHV_READ_UNLOCK(&(vp)->v_bh);
 
 		hsize = XFS_HSIZE(handle);
 	}
@@ -585,6 +583,14 @@
 	case XFS_IOC_FREESP64:
 	case XFS_IOC_RESVSP64:
 	case XFS_IOC_UNRESVSP64:
+		/* 
+		 * Only allow the sys admin to reserve space unless
+		 * unwritten extents are enabled.
+		 */
+		if (!XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb) &&
+		    !capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
 		return xfs_ioc_space(bdp, vp, filp, cmd, arg);
 
 	case XFS_IOC_DIOINFO: {
@@ -685,11 +691,7 @@
 		xfs_fsop_resblks_t inout;
 		__uint64_t	   in;
 
-		/* Only allow the sys admin to reserve space unless
-		 * unwritten extents are enabled.
-		 */
-		if (!XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb) &&
-		    !capable(CAP_SYS_ADMIN))
+		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 
 		if (copy_from_user(&inout, (char *)arg, sizeof(inout)))
@@ -810,9 +812,6 @@
 	int			attr_flags = 0;
 	int			error;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -XFS_ERROR(EPERM);
-
 	if (filp->f_flags & O_RDONLY)
 		return -XFS_ERROR(EBADF);
 
@@ -847,10 +846,7 @@
 	/* done = 1 if there are more stats to get and if bulkstat */
 	/* should be called again (unused here, but used in dmapi) */
 
-	/* Do not allow space reservation if this is not the admin and
-	 * unwritten extents are turned off.
-	 */
-	if (!XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb) && !capable(CAP_SYS_ADMIN))
+	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	if (XFS_FORCED_SHUTDOWN(mp))
diff -Nru a/fs/xfs/linux/xfs_iomap.c b/fs/xfs/linux/xfs_iomap.c
--- a/fs/xfs/linux/xfs_iomap.c	Wed Feb 19 09:13:41 2003
+++ b/fs/xfs/linux/xfs_iomap.c	Mon Mar 17 12:19:19 2003
@@ -530,6 +530,7 @@
 	xfs_trans_t	*tp;
 	int		i, nimaps, committed;
 	int		error = 0;
+	int		nres;
 
 	*retmap = 0;
 
@@ -562,9 +563,19 @@
 		nimaps = 0;
 		while (nimaps == 0) {
 			tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE);
-			error = xfs_trans_reserve(tp, 0, XFS_WRITE_LOG_RES(mp),
+			nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
+			error = xfs_trans_reserve(tp, nres,
+					XFS_WRITE_LOG_RES(mp),
 					0, XFS_TRANS_PERM_LOG_RES,
 					XFS_WRITE_LOG_COUNT);
+
+			if (error == ENOSPC) {
+				error = xfs_trans_reserve(tp, 0,
+						XFS_WRITE_LOG_RES(mp),
+						0,
+						XFS_TRANS_PERM_LOG_RES,
+						XFS_WRITE_LOG_COUNT);
+			}
 			if (error) {
 				xfs_trans_cancel(tp, 0);
 				return XFS_ERROR(error);
diff -Nru a/fs/xfs/linux/xfs_iops.c b/fs/xfs/linux/xfs_iops.c
--- a/fs/xfs/linux/xfs_iops.c	Tue Feb 25 08:21:08 2003
+++ b/fs/xfs/linux/xfs_iops.c	Mon Mar 17 13:54:08 2003
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -45,7 +45,7 @@
 	vattr_t		va;
 	int		error;
 
-	va.va_mask = XFS_AT_NLINK|XFS_AT_SIZE;
+	va.va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS;
 	VOP_GETATTR(vp, &va, ATTR_LAZY, NULL, error);
 	ip->i_nlink = va.va_nlink;
 	ip->i_size = va.va_size;
@@ -154,20 +154,18 @@
 	return linvfs_mknod(dir, dentry, mode|S_IFDIR, 0);
 }
 
-
 STATIC struct dentry *
 linvfs_lookup(
 	struct inode	*dir,
 	struct dentry	*dentry)
 {
-	int		error;
-	vnode_t		*vp, *cvp;
 	struct inode	*ip = NULL;
+	vnode_t		*vp, *cvp = NULL;
+	int		error;
 
 	if (dentry->d_name.len >= MAXNAMELEN)
 		return ERR_PTR(-ENAMETOOLONG);
 
-	cvp = NULL;
 	vp = LINVFS_GET_VP(dir);
 	VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error);
 	if (!error) {
@@ -189,10 +187,10 @@
 	struct inode	*dir,
 	struct dentry	*dentry)
 {
-	int		error;
-	vnode_t		*tdvp;	/* Target directory for new name/link */
-	vnode_t		*vp;	/* vp of name being linked */
 	struct inode	*ip;	/* inode of guy being linked to */
+	vnode_t		*tdvp;	/* target directory for new name/link */
+	vnode_t		*vp;	/* vp of name being linked */
+	int		error;
 
 	ip = old_dentry->d_inode;	/* inode being linked to */
 	if (S_ISDIR(ip->i_mode))
@@ -201,7 +199,6 @@
 	tdvp = LINVFS_GET_VP(dir);
 	vp = LINVFS_GET_VP(ip);
 
-	error = 0;
 	VOP_LINK(tdvp, vp, dentry, NULL, error);
 	if (!error) {
 		VMODIFY(tdvp);
@@ -218,16 +215,14 @@
 	struct inode	*dir,
 	struct dentry	*dentry)
 {
-	int		error = 0;
 	struct inode	*inode;
 	vnode_t		*dvp;	/* directory containing name to remove */
+	int		error;
 
 	inode = dentry->d_inode;
-
 	dvp = LINVFS_GET_VP(dir);
 
 	VOP_REMOVE(dvp, dentry, NULL, error);
-
 	if (!error) {
 		validate_fields(dir);	/* For size only */
 		validate_fields(inode);
@@ -244,13 +239,14 @@
 	struct dentry	*dentry,
 	const char	*symname)
 {
-	int		error;
+	struct inode	*ip;
+	vattr_t		va;
 	vnode_t		*dvp;	/* directory containing name to remove */
 	vnode_t		*cvp;	/* used to lookup symlink to put in dentry */
-	vattr_t		va;
-	struct inode	*ip = NULL;
+	int		error;
 
 	dvp = LINVFS_GET_VP(dir);
+	cvp = NULL;
 
 	memset(&va, 0, sizeof(va));
 	va.va_type = VLNK;
@@ -259,20 +255,14 @@
 
 	error = 0;
 	VOP_SYMLINK(dvp, dentry, &va, (char *)symname, &cvp, NULL, error);
-	if (!error) {
-		ASSERT(cvp);
+	if (!error && cvp) {
 		ASSERT(cvp->v_type == VLNK);
 		ip = LINVFS_GET_IP(cvp);
-		if (!ip) {
-			error = ENOMEM;
-			VN_RELE(cvp);
-		} else {
-			d_instantiate(dentry, ip);
-			validate_fields(dir);
-			validate_fields(ip); /* size needs update */
-			mark_inode_dirty_sync(ip);
-			mark_inode_dirty_sync(dir);
-		}
+		d_instantiate(dentry, ip);
+		validate_fields(dir);
+		validate_fields(ip); /* size needs update */
+		mark_inode_dirty_sync(ip);
+		mark_inode_dirty_sync(dir);
 	}
 	return -error;
 }
@@ -303,23 +293,20 @@
 	struct inode	*ndir,
 	struct dentry	*ndentry)
 {
-	int		error;
+	struct inode	*new_inode = ndentry->d_inode;
 	vnode_t		*fvp;	/* from directory */
 	vnode_t		*tvp;	/* target directory */
-	struct inode	*new_inode = NULL;
+	int		error;
 
 	fvp = LINVFS_GET_VP(odir);
 	tvp = LINVFS_GET_VP(ndir);
 
-	new_inode = ndentry->d_inode;
-
 	VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error);
 	if (error)
 		return -error;
 
-	if (new_inode) {
+	if (new_inode)
 		validate_fields(new_inode);
-	}
 
 	validate_fields(odir);
 	if (ndir != odir)
@@ -334,13 +321,11 @@
 	char		*buf,
 	int		size)
 {
-	vnode_t		*vp;
+	vnode_t		*vp = LINVFS_GET_VP(dentry->d_inode);
 	uio_t		uio;
 	iovec_t		iov;
 	int		error;
 
-	vp = LINVFS_GET_VP(dentry->d_inode);
-
 	iov.iov_base = buf;
 	iov.iov_len = size;
 
@@ -348,6 +333,7 @@
 	uio.uio_offset = 0;
 	uio.uio_segflg = UIO_USERSPACE;
 	uio.uio_resid = size;
+	uio.uio_iovcnt = 1;
 
 	VOP_READLINK(vp, &uio, NULL, error);
 	if (error)
@@ -395,6 +381,7 @@
 	uio->uio_segflg = UIO_SYSSPACE;
 	uio->uio_resid = MAXNAMELEN;
 	uio->uio_fmode = 0;
+	uio->uio_iovcnt = 1;
 
 	VOP_READLINK(vp, uio, NULL, error);
 	if (error) {
@@ -425,11 +412,6 @@
 	return -error;
 }
 
-/* Brute force approach for now - copy data into linux inode
- * from the results of a getattr. This gets called out of things
- * like stat.
- */
-
 STATIC int
 linvfs_getattr(
 	struct vfsmount	*mnt,
@@ -440,9 +422,8 @@
 	vnode_t		*vp = LINVFS_GET_VP(inode);
 	int		error = 0;
 
-	if (unlikely(vp->v_flag & VMODIFIED)) {
+	if (unlikely(vp->v_flag & VMODIFIED))
 		error = vn_revalidate(vp);
-	}
 	if (!error)
 		generic_fillattr(inode, stat);
 	return 0;
@@ -454,11 +435,11 @@
 	struct iattr	*attr)
 {
 	struct inode	*inode = dentry->d_inode;
+	unsigned int	ia_valid = attr->ia_valid;
 	vnode_t		*vp = LINVFS_GET_VP(inode);
 	vattr_t		vattr;
-	unsigned int	ia_valid = attr->ia_valid;
-	int		error;
 	int		flags = 0;
+	int		error;
 
 	memset(&vattr, 0, sizeof(vattr_t));
 	if (ia_valid & ATTR_UID) {
@@ -511,7 +492,7 @@
 
 STATIC void
 linvfs_truncate(
-	struct inode		*inode)
+	struct inode	*inode)
 {
 	block_truncate_page(inode->i_mapping, inode->i_size, linvfs_get_block);
 }
@@ -579,11 +560,11 @@
 	size_t		size,
 	int		flags)
 {
-	int		error;
-	int		xflags = 0;
-	char		*p = (char *)name;
 	struct inode	*inode = dentry->d_inode;
 	vnode_t		*vp = LINVFS_GET_VP(inode);
+	char		*p = (char *)name;
+	int		xflags = 0;
+	int		error;
 
 	if (strncmp(name, xfs_namespaces[SYSTEM_NAMES].name,
 			xfs_namespaces[SYSTEM_NAMES].namelen) == 0) {
@@ -592,20 +573,16 @@
 			 return error;
 		error = -EOPNOTSUPP;
 		p += xfs_namespaces[SYSTEM_NAMES].namelen;
-		if (strcmp(p, POSIXACL_ACCESS) == 0) {
+		if (strcmp(p, POSIXACL_ACCESS) == 0)
 			error = xfs_acl_vset(vp, (void *) data, size,
 						_ACL_TYPE_ACCESS);
-		}
-		else if (strcmp(p, POSIXACL_DEFAULT) == 0) {
+		else if (strcmp(p, POSIXACL_DEFAULT) == 0)
 			error = xfs_acl_vset(vp, (void *) data, size,
 						_ACL_TYPE_DEFAULT);
-		}
-		else if (strcmp(p, POSIXCAP) == 0) {
+		else if (strcmp(p, POSIXCAP) == 0)
 			error = xfs_cap_vset(vp, (void *) data, size);
-		}
-		if (!error) {
+		if (!error)
 			error = vn_revalidate(vp);
-		}
 		return error;
 	}
 
@@ -642,25 +619,22 @@
 	void		*data,
 	size_t		size)
 {
-	ssize_t		error;
-	int		xflags = 0;
-	char		*p = (char *)name;
 	struct inode	*inode = dentry->d_inode;
 	vnode_t		*vp = LINVFS_GET_VP(inode);
+	char		*p = (char *)name;
+	int		xflags = 0;
+	ssize_t		error;
 
 	if (strncmp(name, xfs_namespaces[SYSTEM_NAMES].name,
 			xfs_namespaces[SYSTEM_NAMES].namelen) == 0) {
 		error = -EOPNOTSUPP;
 		p += xfs_namespaces[SYSTEM_NAMES].namelen;
-		if (strcmp(p, POSIXACL_ACCESS) == 0) {
+		if (strcmp(p, POSIXACL_ACCESS) == 0)
 			error = xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
-		}
-		else if (strcmp(p, POSIXACL_DEFAULT) == 0) {
+		else if (strcmp(p, POSIXACL_DEFAULT) == 0)
 			error = xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
-		}
-		else if (strcmp(p, POSIXCAP) == 0) {
+		else if (strcmp(p, POSIXCAP) == 0)
 			error = xfs_cap_vget(vp, data, size);
-		}
 		return error;
 	}
 
@@ -699,15 +673,13 @@
 	char			*data,
 	size_t			size)
 {
-	ssize_t			error;
-	int			result = 0;
-	int			xflags = ATTR_KERNAMELS;
-	char			*k = data;
 	attrlist_cursor_kern_t	cursor;
 	xattr_namespace_t	*sys;
-	vnode_t			*vp;
-
-	vp = LINVFS_GET_VP(dentry->d_inode);
+	vnode_t			*vp = LINVFS_GET_VP(dentry->d_inode);
+	char			*k = data;
+	int			xflags = ATTR_KERNAMELS;
+	int			result = 0;
+	ssize_t			error;
 
 	if (!size)
 		xflags |= ATTR_KERNOVAL;
@@ -743,11 +715,11 @@
 	struct dentry	*dentry,
 	const char	*name)
 {
-	int		error;
-	int		xflags = 0;
-	char		*p = (char *)name;
 	struct inode	*inode = dentry->d_inode;
 	vnode_t		*vp = LINVFS_GET_VP(inode);
+	char		*p = (char *)name;
+	int		xflags = 0;
+	int		error;
 
 	if (strncmp(name, xfs_namespaces[SYSTEM_NAMES].name,
 			xfs_namespaces[SYSTEM_NAMES].namelen) == 0) {
@@ -786,8 +758,8 @@
 struct inode_operations linvfs_file_inode_operations =
 {
 	.permission		= linvfs_permission,
-	.getattr		= linvfs_getattr,
 	.truncate		= linvfs_truncate,
+	.getattr		= linvfs_getattr,
 	.setattr		= linvfs_setattr,
 	.setxattr		= linvfs_setxattr,
 	.getxattr		= linvfs_getxattr,
diff -Nru a/fs/xfs/linux/xfs_iops.h b/fs/xfs/linux/xfs_iops.h
--- a/fs/xfs/linux/xfs_iops.h	Mon Oct 14 13:40:26 2002
+++ b/fs/xfs/linux/xfs_iops.h	Mon Mar 17 13:38:13 2003
@@ -66,5 +66,6 @@
 extern struct address_space_operations linvfs_aops;
 
 extern int linvfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
+extern void linvfs_unwritten_done(struct buffer_head *, int);
 
 #endif /* __XFS_IOPS_H__ */
diff -Nru a/fs/xfs/linux/xfs_linux.h b/fs/xfs/linux/xfs_linux.h
--- a/fs/xfs/linux/xfs_linux.h	Tue Jan 14 09:23:52 2003
+++ b/fs/xfs/linux/xfs_linux.h	Mon Mar 17 13:50:56 2003
@@ -69,22 +69,25 @@
 #define STATIC static
 #endif
 
+/*
+ * State flag for unwritten extent buffers.
+ *
+ * We need to be able to distinguish between these and delayed
+ * allocate buffers within XFS.  The generic IO path code does
+ * not need to distinguish - we use the BH_Delay flag for both
+ * delalloc and these ondisk-uninitialised buffers.
+ */
+BUFFER_FNS(PrivateStart, unwritten);
+static inline void set_buffer_unwritten_io(struct buffer_head *bh)
+{
+	bh->b_end_io = linvfs_unwritten_done;
+}
+
 #define restricted_chown	xfs_params.restrict_chown
 #define irix_sgid_inherit	xfs_params.sgid_inherit
 #define irix_symlink_mode	xfs_params.symlink_mode
 #define xfs_panic_mask		xfs_params.panic_mask
-
-typedef struct xfs_dirent {		/* data from readdir() */
-	xfs_ino_t	d_ino;		/* inode number of entry */
-	xfs_off_t	d_off;		/* offset of disk directory entry */
-	unsigned short	d_reclen;	/* length of this record */
-	char		d_name[1];	/* name of file */
-} xfs_dirent_t;
-
-#define DIRENTBASESIZE		(((xfs_dirent_t *)0)->d_name - (char *)0)
-#define DIRENTSIZE(namelen)	\
-	((DIRENTBASESIZE + (namelen) + \
-		sizeof(xfs_off_t)) & ~(sizeof(xfs_off_t) - 1))
+#define xfs_error_level		xfs_params.error_level
 
 #define NBPP		PAGE_SIZE
 #define DPPSHFT		(PAGE_SHIFT - 9)
diff -Nru a/fs/xfs/linux/xfs_lrw.c b/fs/xfs/linux/xfs_lrw.c
--- a/fs/xfs/linux/xfs_lrw.c	Tue Jan 14 09:38:38 2003
+++ b/fs/xfs/linux/xfs_lrw.c	Mon Mar 17 14:05:46 2003
@@ -35,7 +35,6 @@
  */
 
 #include <xfs.h>
-#include <linux/pagemap.h>
 #include <linux/capability.h>
 
 
diff -Nru a/fs/xfs/linux/xfs_lrw.h b/fs/xfs/linux/xfs_lrw.h
--- a/fs/xfs/linux/xfs_lrw.h	Fri Dec 20 11:49:56 2002
+++ b/fs/xfs/linux/xfs_lrw.h	Mon Mar 17 14:05:46 2003
@@ -47,36 +47,36 @@
  */
 #define XFS_MAX_RW_NBMAPS	4
 
-extern int xfs_bmap (struct bhv_desc *, xfs_off_t, ssize_t, int,
+extern int xfs_bmap(struct bhv_desc *, xfs_off_t, ssize_t, int,
 			struct page_buf_bmap_s *, int *);
-extern int xfsbdstrat (struct xfs_mount *, struct page_buf_s *);
-extern int xfs_bdstrat_cb (struct page_buf_s *);
+extern int xfsbdstrat(struct xfs_mount *, struct page_buf_s *);
+extern int xfs_bdstrat_cb(struct page_buf_s *);
 
-extern int xfs_zero_eof (struct vnode *, struct xfs_iocore *, xfs_off_t,
+extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t,
 				xfs_fsize_t, xfs_fsize_t);
-extern ssize_t xfs_read (struct bhv_desc *, struct file *,
+extern ssize_t xfs_read(struct bhv_desc *, struct file *,
 				const struct iovec *, unsigned long,
 				loff_t *, struct cred *);
-extern ssize_t xfs_write (struct bhv_desc *, struct file *,
+extern ssize_t xfs_write(struct bhv_desc *, struct file *,
 				const struct iovec *, unsigned long,
 				loff_t *, struct cred *);
-extern ssize_t xfs_sendfile (struct bhv_desc *, struct file *,
+extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *,
 				loff_t *, size_t, read_actor_t,
 				void *, struct cred *);
 
-extern int xfs_iomap (struct xfs_iocore *, xfs_off_t, ssize_t, int,
+extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int,
 				struct page_buf_bmap_s *, int *);
-extern int xfs_iomap_write_direct (struct xfs_inode *, loff_t, size_t,
+extern int xfs_iomap_write_direct(struct xfs_inode *, loff_t, size_t,
 				int, struct xfs_bmbt_irec *, int *, int);
-extern int xfs_iomap_write_delay (struct xfs_inode *, loff_t, size_t,
+extern int xfs_iomap_write_delay(struct xfs_inode *, loff_t, size_t,
 				int, struct xfs_bmbt_irec *, int *);
-extern int xfs_iomap_write_allocate (struct xfs_inode *,
+extern int xfs_iomap_write_allocate(struct xfs_inode *,
 				struct xfs_bmbt_irec *, int *);
-extern int xfs_iomap_write_unwritten (struct xfs_inode *, loff_t, size_t);
+extern int xfs_iomap_write_unwritten(struct xfs_inode *, loff_t, size_t);
 
-extern int xfs_dev_is_read_only (struct xfs_mount *, char *);
+extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
 
-extern void XFS_log_write_unmount_ro (struct bhv_desc *);
+extern void XFS_log_write_unmount_ro(struct bhv_desc *);
 
 #define XFS_FSB_TO_DB_IO(io,fsb) \
 		(((io)->io_flags & XFS_IOCORE_RT) ? \
diff -Nru a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c
--- a/fs/xfs/linux/xfs_super.c	Wed Feb 19 09:33:29 2003
+++ b/fs/xfs/linux/xfs_super.c	Sat Mar 22 22:14:13 2003
@@ -323,6 +323,7 @@
 	};
 	struct proc_xfs_info	*xfs_infop;
 	struct xfs_mount	*mp = XFS_BHVTOM(vfsp->vfs_fbhv);
+	char b[BDEVNAME_SIZE];
 
 	for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
 		if (mp->m_flags & xfs_infop->flag)
@@ -352,12 +353,12 @@
 
 	if (mp->m_ddev_targp->pbr_dev != mp->m_logdev_targp->pbr_dev)
 		seq_printf(m, "," MNTOPT_LOGDEV "=%s",
-				bdevname(mp->m_logdev_targp->pbr_bdev));
+				bdevname(mp->m_logdev_targp->pbr_bdev, b));
 
 	if (mp->m_rtdev_targp &&
 	    mp->m_ddev_targp->pbr_dev != mp->m_rtdev_targp->pbr_dev)
 		seq_printf(m, "," MNTOPT_RTDEV "=%s",
-				bdevname(mp->m_rtdev_targp->pbr_bdev));
+				bdevname(mp->m_rtdev_targp->pbr_bdev, b));
 
 	if (mp->m_dalign > 0)
 		seq_printf(m, "," MNTOPT_SUNIT "=%d",
@@ -766,7 +767,9 @@
 	vfs_t			*vfsp = LINVFS_GET_VFS(sb);
 	int			error;
 
-	VFS_DOUNMOUNT(vfsp, 0, NULL, NULL, error);
+	VFS_SYNC(vfsp, SYNC_ATTR|SYNC_DELWRI, NULL, error);
+	if (error == 0)
+		VFS_UNMOUNT(vfsp, 0, NULL, error);
 	if (error) {
 		printk("XFS unmount got error %d\n", error);
 		printk("%s: vfsp/0x%p left dangling!\n", __FUNCTION__, vfsp);
diff -Nru a/fs/xfs/linux/xfs_sysctl.c b/fs/xfs/linux/xfs_sysctl.c
--- a/fs/xfs/linux/xfs_sysctl.c	Tue Feb 25 08:09:57 2003
+++ b/fs/xfs/linux/xfs_sysctl.c	Mon Mar 17 12:25:09 2003
@@ -35,8 +35,8 @@
 #include <linux/proc_fs.h>
 
 
-STATIC ulong xfs_min[XFS_PARAM] = { 0, 0, 0, 0, 0 };
-STATIC ulong xfs_max[XFS_PARAM] = { 1, 1, 1, 1, 127 };
+STATIC ulong xfs_min[XFS_PARAM] = { 0, 0, 0, 0, 0,   0 };
+STATIC ulong xfs_max[XFS_PARAM] = { 1, 1, 1, 1, 127, 3 };
 
 static struct ctl_table_header *xfs_table_header;
 
@@ -69,23 +69,27 @@
 STATIC ctl_table xfs_table[] = {
 	{XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear,
 	sizeof(ulong), 0644, NULL, &xfs_stats_clear_proc_handler,
-	&sysctl_intvec, NULL, &xfs_min[2], &xfs_max[2]},
+	&sysctl_intvec, NULL, &xfs_min[0], &xfs_max[0]},
 
 	{XFS_RESTRICT_CHOWN, "restrict_chown", &xfs_params.restrict_chown,
 	sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
-	&sysctl_intvec, NULL, &xfs_min[3], &xfs_max[3]},
+	&sysctl_intvec, NULL, &xfs_min[1], &xfs_max[1]},
 
 	{XFS_SGID_INHERIT, "irix_sgid_inherit", &xfs_params.sgid_inherit,
 	sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
-	&sysctl_intvec, NULL, &xfs_min[4], &xfs_max[4]},
+	&sysctl_intvec, NULL, &xfs_min[2], &xfs_max[2]},
 
 	{XFS_SYMLINK_MODE, "irix_symlink_mode", &xfs_params.symlink_mode,
 	sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
-	&sysctl_intvec, NULL, &xfs_min[5], &xfs_max[5]},
+	&sysctl_intvec, NULL, &xfs_min[3], &xfs_max[3]},
 
 	{XFS_PANIC_MASK, "panic_mask", &xfs_params.panic_mask,
 	sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
-	&sysctl_intvec, NULL, &xfs_min[6], &xfs_max[6]},
+	&sysctl_intvec, NULL, &xfs_min[4], &xfs_max[4]},
+
+	{XFS_ERRLEVEL, "error_level", &xfs_params.error_level,
+	sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax,
+	&sysctl_intvec, NULL, &xfs_min[5], &xfs_max[5]},
 
 	{0}
 };
diff -Nru a/fs/xfs/linux/xfs_sysctl.h b/fs/xfs/linux/xfs_sysctl.h
--- a/fs/xfs/linux/xfs_sysctl.h	Tue Feb 25 08:09:57 2003
+++ b/fs/xfs/linux/xfs_sysctl.h	Mon Mar 17 12:19:19 2003
@@ -48,14 +48,31 @@
 				/*  not a member of the parent dir GID.  */
 	ulong	symlink_mode;	/* Symlink creat mode affected by umask. */
 	ulong	panic_mask;	/* bitmask to specify panics on errors.  */
+	ulong	error_level;	/* Degree of reporting for internal probs*/
 } xfs_param_t;
 
+/*
+ * xfs_error_level:
+ *
+ * How much error reporting will be done when internal problems are
+ * encountered.  These problems normally return an EFSCORRUPTED to their
+ * caller, with no other information reported.
+ *
+ * 0	No error reports
+ * 1	Report EFSCORRUPTED errors that will cause a filesystem shutdown
+ * 5	Report all EFSCORRUPTED errors (all of the above errors, plus any
+ *	additional errors that are known to not cause shutdowns)
+ *
+ * xfs_panic_mask bit 0x8 turns the error reports into panics
+ */
+
 enum {
 	XFS_STATS_CLEAR = 1,
 	XFS_RESTRICT_CHOWN = 2,
 	XFS_SGID_INHERIT = 3,
 	XFS_SYMLINK_MODE = 4,
 	XFS_PANIC_MASK = 5,
+	XFS_ERRLEVEL = 6,
 };
 
 extern xfs_param_t	xfs_params;
diff -Nru a/fs/xfs/linux/xfs_vfs.h b/fs/xfs/linux/xfs_vfs.h
--- a/fs/xfs/linux/xfs_vfs.h	Mon Oct 14 13:40:27 2002
+++ b/fs/xfs/linux/xfs_vfs.h	Mon Mar 17 13:24:32 2003
@@ -75,9 +75,6 @@
 	int	(*vfs_mount)(struct vfs *, struct xfs_mount_args *,
 					struct cred *);
 					/* mount file system */
-	int	(*vfs_dounmount)(bhv_desc_t *, int, struct vnode *,
-				 struct cred *);
-					/* preparation and unmount */
 	int	(*vfs_unmount)(bhv_desc_t *, int, struct cred *);
 					/* unmount file system */
 	int	(*vfs_root)(bhv_desc_t *, struct vnode **);
@@ -98,48 +95,30 @@
 					int, char *, int);
 } vfsops_t;
 
-#define VFS_DOUNMOUNT(vfsp,f,vp,cr, rv) \
-{	\
-	BHV_READ_LOCK(&(vfsp)->vfs_bh); \
-	rv = (*(VFS_FOPS(vfsp)->vfs_dounmount))((vfsp)->vfs_fbhv, f, vp, cr);	\
-	BHV_READ_UNLOCK(&(vfsp)->vfs_bh); \
-}
 #define VFS_UNMOUNT(vfsp,f,cr, rv)	\
 {	\
-	BHV_READ_LOCK(&(vfsp)->vfs_bh); \
-	rv = (*(VFS_FOPS(vfsp)->vfs_unmount))((vfsp)->vfs_fbhv, f, cr);		\
-	BHV_READ_UNLOCK(&(vfsp)->vfs_bh); \
+	rv = (*(VFS_FOPS(vfsp)->vfs_unmount))((vfsp)->vfs_fbhv, f, cr);	\
 }
 #define VFS_ROOT(vfsp, vpp, rv)		\
 {	\
-	BHV_READ_LOCK(&(vfsp)->vfs_bh); \
 	rv = (*(VFS_FOPS(vfsp)->vfs_root))((vfsp)->vfs_fbhv, vpp);	\
-	BHV_READ_UNLOCK(&(vfsp)->vfs_bh); \
 }
 #define VFS_STATVFS(vfsp, sp, vp, rv)	\
 {	\
-	BHV_READ_LOCK(&(vfsp)->vfs_bh); \
-	rv = (*(VFS_FOPS(vfsp)->vfs_statvfs))((vfsp)->vfs_fbhv, sp, vp);	\
-	BHV_READ_UNLOCK(&(vfsp)->vfs_bh); \
+	rv = (*(VFS_FOPS(vfsp)->vfs_statvfs))((vfsp)->vfs_fbhv, sp, vp);\
 }
 #define VFS_SYNC(vfsp, flag, cr, rv) \
 {	\
-	BHV_READ_LOCK(&(vfsp)->vfs_bh); \
 	rv = (*(VFS_FOPS(vfsp)->vfs_sync))((vfsp)->vfs_fbhv, flag, cr); \
-	BHV_READ_UNLOCK(&(vfsp)->vfs_bh); \
 }
 #define VFS_VGET(vfsp, vpp, fidp, rv) \
 {	\
-	BHV_READ_LOCK(&(vfsp)->vfs_bh); \
 	rv = (*(VFS_FOPS(vfsp)->vfs_vget))((vfsp)->vfs_fbhv, vpp, fidp);  \
-	BHV_READ_UNLOCK(&(vfsp)->vfs_bh); \
 }
 
 #define VFS_INIT_VNODE(vfsp, vp, bhv, unlock) \
 {	\
-	BHV_READ_LOCK(&(vfsp)->vfs_bh); \
 	(*(VFS_FOPS(vfsp)->vfs_init_vnode))((vfsp)->vfs_fbhv, vp, bhv, unlock);\
-	BHV_READ_UNLOCK(&(vfsp)->vfs_bh); \
 }
 
 /* No behavior lock here */
@@ -148,9 +127,7 @@
 
 #define VFS_DMAPI_FSYS_VECTOR(vfsp, df, rv) \
 {	\
-	BHV_READ_LOCK(&(vfsp)->vfs_bh); \
 	rv = (*(VFS_FOPS(vfsp)->vfs_dmapi_fsys_vector))((vfsp)->vfs_fbhv, df);	      \
-	BHV_READ_UNLOCK(&(vfsp)->vfs_bh); \
 }
 
 
diff -Nru a/fs/xfs/linux/xfs_vnode.c b/fs/xfs/linux/xfs_vnode.c
--- a/fs/xfs/linux/xfs_vnode.c	Tue Dec  3 13:18:12 2002
+++ b/fs/xfs/linux/xfs_vnode.c	Mon Mar 17 12:11:38 2003
@@ -137,6 +137,7 @@
 	struct vnode	*vp = LINVFS_GET_VP(inode);
 
 	XFS_STATS_INC(xfsstats.vn_active);
+	XFS_STATS_INC(xfsstats.vn_alloc);
 
 	vp->v_flag = VMODIFIED;
 	spinlock_init(&vp->v_lock, "v_lock");
diff -Nru a/fs/xfs/linux/xfs_vnode.h b/fs/xfs/linux/xfs_vnode.h
--- a/fs/xfs/linux/xfs_vnode.h	Tue Jan 14 09:09:34 2003
+++ b/fs/xfs/linux/xfs_vnode.h	Mon Mar 17 13:24:32 2003
@@ -98,11 +98,6 @@
 
 #define VNODE_TO_FIRST_BHV(vp)		(BHV_HEAD_FIRST(&(vp)->v_bh))
 #define VN_BHV_HEAD(vp)			((bhv_head_t *)(&((vp)->v_bh)))
-#define VN_BHV_READ_LOCK(bhp)		BHV_READ_LOCK(bhp)
-#define VN_BHV_READ_UNLOCK(bhp)		BHV_READ_UNLOCK(bhp)
-#define VN_BHV_WRITE_LOCK(bhp)		BHV_WRITE_LOCK(bhp)
-#define VN_BHV_NOT_READ_LOCKED(bhp)	BHV_NOT_READ_LOCKED(bhp)
-#define VN_BHV_NOT_WRITE_LOCKED(bhp)	BHV_NOT_WRITE_LOCKED(bhp)
 #define vn_bhv_head_init(bhp,name)	bhv_head_init(bhp,name)
 #define vn_bhv_remove(bhp,bdp)		bhv_remove(bhp,bdp)
 #define vn_bhv_lookup(bhp,ops)		bhv_lookup(bhp,ops)
@@ -274,187 +269,130 @@
 
 #define VOP_READ(vp,file,iov,segs,offset,cr,rv)				\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,cr); \
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_WRITE(vp,file,iov,segs,offset,cr,rv)			\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,cr);\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_SENDFILE(vp,f,of,cnt,act,targ,cr,rv)			\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,of,cnt,act,targ,cr);\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_BMAP(vp,of,sz,rw,b,n,rv)					\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n);		\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_OPEN(vp, cr, rv)						\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_open, vp)((vp)->v_fbhv, cr);			\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_GETATTR(vp, vap, f, cr, rv)					\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_getattr, vp)((vp)->v_fbhv, vap, f, cr);		\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_SETATTR(vp, vap, f, cr, rv)					\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_setattr, vp)((vp)->v_fbhv, vap, f, cr);		\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_ACCESS(vp, mode, cr, rv)					\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_access, vp)((vp)->v_fbhv, mode, cr);		\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_LOOKUP(vp,d,vpp,f,rdir,cr,rv)				\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_lookup, vp)((vp)->v_fbhv,d,vpp,f,rdir,cr);	\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_CREATE(dvp,d,vap,vpp,cr,rv)					\
 {									\
-	VN_BHV_READ_LOCK(&(dvp)->v_bh);					\
 	rv = _VOP_(vop_create, dvp)((dvp)->v_fbhv,d,vap,vpp,cr);	\
-	VN_BHV_READ_UNLOCK(&(dvp)->v_bh);				\
 }
 #define VOP_REMOVE(dvp,d,cr,rv)						\
 {									\
-	VN_BHV_READ_LOCK(&(dvp)->v_bh);					\
 	rv = _VOP_(vop_remove, dvp)((dvp)->v_fbhv,d,cr);		\
-	VN_BHV_READ_UNLOCK(&(dvp)->v_bh);				\
 }
 #define VOP_LINK(tdvp,fvp,d,cr,rv)					\
 {									\
-	VN_BHV_READ_LOCK(&(tdvp)->v_bh);				\
 	rv = _VOP_(vop_link, tdvp)((tdvp)->v_fbhv,fvp,d,cr);		\
-	VN_BHV_READ_UNLOCK(&(tdvp)->v_bh);				\
 }
 #define VOP_RENAME(fvp,fnm,tdvp,tnm,cr,rv)				\
 {									\
-	VN_BHV_READ_LOCK(&(fvp)->v_bh);					\
 	rv = _VOP_(vop_rename, fvp)((fvp)->v_fbhv,fnm,tdvp,tnm,cr);	\
-	VN_BHV_READ_UNLOCK(&(fvp)->v_bh);				\
 }
 #define VOP_MKDIR(dp,d,vap,vpp,cr,rv)					\
 {									\
-	VN_BHV_READ_LOCK(&(dp)->v_bh);					\
 	rv = _VOP_(vop_mkdir, dp)((dp)->v_fbhv,d,vap,vpp,cr);		\
-	VN_BHV_READ_UNLOCK(&(dp)->v_bh);				\
 }
 #define	VOP_RMDIR(dp,d,cr,rv)	 					\
 {									\
-	VN_BHV_READ_LOCK(&(dp)->v_bh);					\
 	rv = _VOP_(vop_rmdir, dp)((dp)->v_fbhv,d,cr);			\
-	VN_BHV_READ_UNLOCK(&(dp)->v_bh);				\
 }
 #define VOP_READDIR(vp,uiop,cr,eofp,rv)					\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_readdir, vp)((vp)->v_fbhv,uiop,cr,eofp);		\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_SYMLINK(dvp,d,vap,tnm,vpp,cr,rv)				\
 {									\
-	VN_BHV_READ_LOCK(&(dvp)->v_bh);					\
-	rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr); \
-	VN_BHV_READ_UNLOCK(&(dvp)->v_bh);				\
+	rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr);	\
 }
 #define VOP_READLINK(vp,uiop,cr,rv)					\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,cr);		\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_FSYNC(vp,f,cr,b,e,rv)					\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_fsync, vp)((vp)->v_fbhv,f,cr,b,e);		\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_INACTIVE(vp, cr, rv)					\
-{	/* vnode not reference-able, so no need to lock chain */	\
+{									\
 	rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr);			\
 }
 #define VOP_RELEASE(vp, rv)						\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_release, vp)((vp)->v_fbhv);			\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_FID2(vp, fidp, rv)						\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp);			\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_RWLOCK(vp,i)						\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	(void)_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i);			\
-	/* "allow" is done by rwunlock */				\
 }
 #define VOP_RWLOCK_TRY(vp,i)						\
 	_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
 
 #define VOP_RWUNLOCK(vp,i)						\
-{	/* "prevent" was done by rwlock */				\
+{									\
 	(void)_VOP_(vop_rwunlock, vp)((vp)->v_fbhv, i);			\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_RECLAIM(vp, rv)						\
-{	/* vnode not reference-able, so no need to lock chain */	\
+{									\
 	rv = _VOP_(vop_reclaim, vp)((vp)->v_fbhv);			\
 }
 #define VOP_ATTR_GET(vp, name, val, vallenp, fl, cred, rv)		\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_attr_get, vp)((vp)->v_fbhv,name,val,vallenp,fl,cred); \
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_ATTR_SET(vp, name, val, vallen, fl, cred, rv)		\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_attr_set, vp)((vp)->v_fbhv,name,val,vallen,fl,cred); \
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_ATTR_REMOVE(vp, name, flags, cred, rv)			\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_attr_remove, vp)((vp)->v_fbhv,name,flags,cred);	\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_ATTR_LIST(vp, buf, buflen, fl, cursor, cred, rv)		\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_attr_list, vp)((vp)->v_fbhv,buf,buflen,fl,cursor,cred);\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_LINK_REMOVED(vp, dvp, linkzero)				\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	(void)_VOP_(vop_link_removed, vp)((vp)->v_fbhv, dvp, linkzero); \
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_VNODE_CHANGE(vp, cmd, val)					\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	(void)_VOP_(vop_vnode_change, vp)((vp)->v_fbhv,cmd,val);	\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 /*
  * These are page cache functions that now go thru VOPs.
@@ -462,39 +400,29 @@
  */
 #define VOP_TOSS_PAGES(vp, first, last, fiopt)				\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	_VOP_(vop_tosspages, vp)((vp)->v_fbhv,first, last, fiopt);	\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 /*
  * 'last' parameter is unused and left in for IRIX compatibility
  */
 #define VOP_FLUSHINVAL_PAGES(vp, first, last, fiopt)			\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	_VOP_(vop_flushinval_pages, vp)((vp)->v_fbhv,first,last,fiopt); \
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 /*
  * 'last' parameter is unused and left in for IRIX compatibility
  */
 #define VOP_FLUSH_PAGES(vp, first, last, flags, fiopt, rv)		\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_flush_pages, vp)((vp)->v_fbhv,first,last,flags,fiopt);\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_IOCTL(vp, inode, filp, cmd, arg, rv)			\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_ioctl, vp)((vp)->v_fbhv,inode,filp,cmd,arg);	\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 #define VOP_IFLUSH(vp, flags, rv)					\
 {									\
-	VN_BHV_READ_LOCK(&(vp)->v_bh);					\
 	rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags);		\
-	VN_BHV_READ_UNLOCK(&(vp)->v_bh);				\
 }
 
 /*
diff -Nru a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c
--- a/fs/xfs/pagebuf/page_buf.c	Tue Feb 25 08:05:54 2003
+++ b/fs/xfs/pagebuf/page_buf.c	Mon Mar 17 13:38:13 2003
@@ -121,7 +121,8 @@
 STATIC kmem_cache_t *pagebuf_cache;
 STATIC void pagebuf_daemon_wakeup(int);
 STATIC void pagebuf_delwri_queue(page_buf_t *, int);
-STATIC struct workqueue_struct *pagebuf_workqueue;
+STATIC struct workqueue_struct *pagebuf_logio_workqueue;
+STATIC struct workqueue_struct *pagebuf_dataio_workqueue;
 
 /*
  * Pagebuf module configuration parameters, exported via
@@ -786,6 +787,25 @@
 }
 
 /*
+ * Create a skeletal pagebuf (no pages associated with it).
+ */
+page_buf_t *
+pagebuf_lookup(
+	struct pb_target	*target,
+	loff_t			ioff,
+	size_t			isize,
+	page_buf_flags_t	flags)
+{
+	page_buf_t		*pb;
+
+	pb = pagebuf_allocate(flags);
+	if (pb) {
+		_pagebuf_initialize(pb, target, ioff, isize, flags);
+	}
+	return pb;
+}
+
+/*
  * If we are not low on memory then do the readahead in a deadlock
  * safe manner.
  */
@@ -1131,6 +1151,7 @@
 void
 pagebuf_iodone(
 	page_buf_t		*pb,
+	int			dataio,
 	int			schedule)
 {
 	pb->pb_flags &= ~(PBF_READ | PBF_WRITE);
@@ -1143,7 +1164,8 @@
 	if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) {
 		if (schedule) {
 			INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb);
-			queue_work(pagebuf_workqueue, &pb->pb_iodone_work);
+			queue_work(dataio ? pagebuf_dataio_workqueue :
+				pagebuf_logio_workqueue, &pb->pb_iodone_work);
 		} else {
 			pagebuf_iodone_work(pb);
 		}
@@ -1268,7 +1290,7 @@
 
 	if (atomic_dec_and_test(&pb->pb_io_remaining) == 1) {
 		pb->pb_locked = 0;
-		pagebuf_iodone(pb, 1);
+		pagebuf_iodone(pb, 0, 1);
 	}
 
 	bio_put(bio);
@@ -1412,7 +1434,7 @@
 
 	if (atomic_dec_and_test(&pb->pb_io_remaining) == 1) {
 		pb->pb_locked = 0;
-		pagebuf_iodone(pb, 0);
+		pagebuf_iodone(pb, 0, 0);
 	}
 
 	return 0;
@@ -1734,13 +1756,21 @@
 {
 	int		rval;
 
-	pagebuf_workqueue = create_workqueue("pagebuf");
-	if (!pagebuf_workqueue)
+	pagebuf_logio_workqueue = create_workqueue("xfslogd");
+	if (!pagebuf_logio_workqueue)
 		return -ENOMEM;
 
+	pagebuf_dataio_workqueue = create_workqueue("xfsdatad");
+	if (!pagebuf_dataio_workqueue) {
+		destroy_workqueue(pagebuf_logio_workqueue);
+		return -ENOMEM;
+	}
+
 	rval = kernel_thread(pagebuf_daemon, NULL, CLONE_FS|CLONE_FILES);
-	if (rval < 0)
-		destroy_workqueue(pagebuf_workqueue);
+	if (rval < 0) {
+		destroy_workqueue(pagebuf_logio_workqueue);
+		destroy_workqueue(pagebuf_dataio_workqueue);
+	}
 
 	return rval;
 }
@@ -1756,7 +1786,8 @@
 	pbd_active = 0;
 	wake_up_interruptible(&pbd_waitq);
 	wait_event_interruptible(pbd_waitq, pbd_active);
-	destroy_workqueue(pagebuf_workqueue);
+	destroy_workqueue(pagebuf_logio_workqueue);
+	destroy_workqueue(pagebuf_dataio_workqueue);
 }
 
 
diff -Nru a/fs/xfs/pagebuf/page_buf.h b/fs/xfs/pagebuf/page_buf.h
--- a/fs/xfs/pagebuf/page_buf.h	Tue Feb 25 08:05:54 2003
+++ b/fs/xfs/pagebuf/page_buf.h	Mon Mar 17 13:38:13 2003
@@ -169,8 +169,8 @@
  * This buffer structure is used by the page cache buffer management routines
  * to refer to an assembly of pages forming a logical buffer.  The actual
  * I/O is performed with buffer_head or bio structures, as required by drivers,
- * for drivers which do not understand this structure. The buffer structure is
- * used on temporary basis only, and discarded when released.  
+ * for drivers which do not understand this structure.	The buffer structure is
+ * used on temporary basis only, and discarded when released.
  *
  * The real data storage is recorded in the page cache.	 Metadata is
  * hashed to the inode for the block device on which the file system resides.
@@ -245,6 +245,13 @@
 		page_buf_flags_t);	/* PBF_LOCK, PBF_READ,		*/
 					/* PBF_ASYNC			*/	
 
+extern page_buf_t *pagebuf_lookup(
+		struct pb_target *,
+		loff_t,			/* starting offset of range	*/
+		size_t,			/* length of range		*/
+		page_buf_flags_t);	/* PBF_READ, PBF_WRITE,		*/
+					/* PBF_FORCEIO, _PBF_LOCKABLE	*/
+
 extern page_buf_t *pagebuf_get_empty(	/* allocate pagebuf struct with */
 					/*  no memory or disk address	*/
 		struct pb_target *);	/* mount point "fake" inode	*/
@@ -300,6 +307,7 @@
 
 extern void pagebuf_iodone(		/* mark buffer I/O complete	*/
 		page_buf_t *,		/* buffer to mark		*/
+		int,			/* use data/log helper thread.	*/
 		int);			/* run completion locally, or in
 					 * a helper thread. 		*/
 
diff -Nru a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
--- a/fs/xfs/support/debug.c	Tue Feb 25 08:07:49 2003
+++ b/fs/xfs/support/debug.c	Mon Mar 17 13:18:00 2003
@@ -55,7 +55,7 @@
     BUG();
 }
 
-#ifdef DEBUG
+#if (defined(DEBUG) || defined(INDUCE_IO_ERRROR))
 
 unsigned long
 random(void)
@@ -85,8 +85,8 @@
 cmn_err(register int level, char *fmt, ...)
 {
 	char	*fp = fmt;
-	ulong	flags;
 	int	len;
+	ulong	flags;
 	va_list	ap;
 
 	level &= XFS_ERR_MASK;
diff -Nru a/fs/xfs/support/kmem.c b/fs/xfs/support/kmem.c
--- a/fs/xfs/support/kmem.c	Wed Sep 11 11:12:12 2002
+++ b/fs/xfs/support/kmem.c	Mon Mar 17 12:02:53 2003
@@ -139,7 +139,7 @@
 	}
 
 	rval = __vmalloc(size, flag_convert(flags), PAGE_KERNEL);
-	if (!rval && !(flags & KM_SLEEP))
+	if (!rval && (flags & KM_SLEEP))
 		panic("kmem_alloc: NULL memory on KM_SLEEP request!");
 
 	return rval;
@@ -176,7 +176,9 @@
 
 	new = kmem_alloc(newsize, flags);
 	if (ptr) {
-		memcpy(new, ptr, ((oldsize < newsize) ? oldsize : newsize));
+		if (new)
+			memcpy(new, ptr,
+				((oldsize < newsize) ? oldsize : newsize));
 		kmem_free(ptr, oldsize);
 	}
 
diff -Nru a/fs/xfs/support/time.h b/fs/xfs/support/time.h
--- a/fs/xfs/support/time.h	Mon Nov 25 13:44:16 2002
+++ b/fs/xfs/support/time.h	Mon Mar 17 13:50:56 2003
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -34,6 +34,8 @@
 
 #include <linux/sched.h>
 #include <linux/time.h>
+
+typedef struct timespec timespec_t;
 
 static inline void delay(long ticks)
 {
diff -Nru a/fs/xfs/support/uuid.h b/fs/xfs/support/uuid.h
--- a/fs/xfs/support/uuid.h	Mon Nov 25 13:44:16 2002
+++ b/fs/xfs/support/uuid.h	Mon Mar 17 13:50:56 2003
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -31,6 +31,10 @@
  */
 #ifndef __XFS_SUPPORT_UUID_H__
 #define __XFS_SUPPORT_UUID_H__
+
+typedef struct {
+	unsigned char	__u_bits[16];
+} uuid_t;
 
 void uuid_create_nil(uuid_t *uuid);
 int uuid_is_nil(uuid_t *uuid);
diff -Nru a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
--- a/fs/xfs/xfs_alloc.c	Tue Dec  3 13:14:52 2002
+++ b/fs/xfs/xfs_alloc.c	Mon Mar 17 12:19:19 2003
@@ -2183,34 +2183,11 @@
 		INT_GET(agf->agf_flfirst, ARCH_CONVERT) < XFS_AGFL_SIZE(mp) &&
 		INT_GET(agf->agf_fllast,  ARCH_CONVERT) < XFS_AGFL_SIZE(mp) &&
 		INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE(mp);
-	if (XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF,
-			XFS_RANDOM_ALLOC_READ_AGF)) {
+	if (unlikely(XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF,
+			XFS_RANDOM_ALLOC_READ_AGF))) {
+		XFS_CORRUPTION_ERROR("xfs_alloc_read_agf",
+				     XFS_ERRLEVEL_LOW, mp, agf);
 		xfs_trans_brelse(tp, bp);
-#ifdef __KERNEL__	/* additional, temporary, debugging code */
-		cmn_err(CE_NOTE,
-			"xfs_alloc_read_agf: error in <%s> AG %d",
-			mp->m_fsname, agno);
-		if (INT_GET(agf->agf_magicnum, ARCH_CONVERT) != XFS_AGF_MAGIC)
-			cmn_err(CE_NOTE, "bad agf_magicnum 0x%x",
-				INT_GET(agf->agf_magicnum, ARCH_CONVERT));
-		if (!XFS_AGF_GOOD_VERSION(INT_GET(agf->agf_versionnum, ARCH_CONVERT)))
-			cmn_err(CE_NOTE, "Bad version number 0x%x",
-				INT_GET(agf->agf_versionnum, ARCH_CONVERT));
-		if (!(INT_GET(agf->agf_freeblks, ARCH_CONVERT) <=
-				INT_GET(agf->agf_length, ARCH_CONVERT)))
-			cmn_err(CE_NOTE, "Bad freeblks %d %d",
-				INT_GET(agf->agf_freeblks, ARCH_CONVERT),
-				INT_GET(agf->agf_length, ARCH_CONVERT));
-		if (!(INT_GET(agf->agf_flfirst, ARCH_CONVERT) < XFS_AGFL_SIZE(mp)))
-			cmn_err(CE_NOTE, "Bad flfirst %d",
-				INT_GET(agf->agf_flfirst, ARCH_CONVERT));
-		if (!(INT_GET(agf->agf_fllast, ARCH_CONVERT) < XFS_AGFL_SIZE(mp)))
-			cmn_err(CE_NOTE, "Bad fllast %d",
-				INT_GET(agf->agf_fllast, ARCH_CONVERT));
-		if (!(INT_GET(agf->agf_flcount, ARCH_CONVERT) <= XFS_AGFL_SIZE(mp)))
-			cmn_err(CE_NOTE, "Bad flcount %d",
-				INT_GET(agf->agf_flcount, ARCH_CONVERT));
-#endif
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 	pag = &mp->m_perag[agno];
diff -Nru a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
--- a/fs/xfs/xfs_attr.c	Wed Nov  6 11:04:34 2002
+++ b/fs/xfs/xfs_attr.c	Mon Mar 17 12:19:19 2003
@@ -1125,8 +1125,10 @@
 		return(error);
 	ASSERT(bp != NULL);
 	leaf = bp->data;
-	if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)
-						!= XFS_ATTR_LEAF_MAGIC) {
+	if (unlikely(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)
+						!= XFS_ATTR_LEAF_MAGIC)) {
+		XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW,
+				     context->dp->i_mount, leaf);
 		xfs_da_brelse(NULL, bp);
 		return(XFS_ERROR(EFSCORRUPTED));
 	}
@@ -1806,14 +1808,22 @@
 						      XFS_ATTR_FORK);
 			if (error)
 				return(error);
-			if (bp == NULL)
+			if (unlikely(bp == NULL)) {
+				XFS_ERROR_REPORT("xfs_attr_node_list(2)",
+						 XFS_ERRLEVEL_LOW,
+						 context->dp->i_mount);
 				return(XFS_ERROR(EFSCORRUPTED));
+			}
 			node = bp->data;
 			if (INT_GET(node->hdr.info.magic, ARCH_CONVERT)
 							== XFS_ATTR_LEAF_MAGIC)
 				break;
-			if (INT_GET(node->hdr.info.magic, ARCH_CONVERT)
-							!= XFS_DA_NODE_MAGIC) {
+			if (unlikely(INT_GET(node->hdr.info.magic, ARCH_CONVERT)
+							!= XFS_DA_NODE_MAGIC)) {
+				XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)",
+						     XFS_ERRLEVEL_LOW,
+						     context->dp->i_mount,
+						     node);
 				xfs_da_brelse(NULL, bp);
 				return(XFS_ERROR(EFSCORRUPTED));
 			}
@@ -1846,8 +1856,11 @@
 	 */
 	for (;;) {
 		leaf = bp->data;
-		if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)
-						!= XFS_ATTR_LEAF_MAGIC) {
+		if (unlikely(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)
+						!= XFS_ATTR_LEAF_MAGIC)) {
+			XFS_CORRUPTION_ERROR("xfs_attr_node_list(4)",
+					     XFS_ERRLEVEL_LOW,
+					     context->dp->i_mount, leaf);
 			xfs_da_brelse(NULL, bp);
 			return(XFS_ERROR(EFSCORRUPTED));
 		}
@@ -1860,8 +1873,12 @@
 					      &bp, XFS_ATTR_FORK);
 		if (error)
 			return(error);
-		if (bp == NULL)
+		if (unlikely((bp == NULL))) {
+			XFS_ERROR_REPORT("xfs_attr_node_list(5)",
+					 XFS_ERRLEVEL_LOW,
+					 context->dp->i_mount);
 			return(XFS_ERROR(EFSCORRUPTED));
+		}
 	}
 	xfs_da_brelse(NULL, bp);
 	return(0);
diff -Nru a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
--- a/fs/xfs/xfs_attr_leaf.c	Tue Feb 25 02:47:45 2003
+++ b/fs/xfs/xfs_attr_leaf.c	Mon Mar 17 12:19:19 2003
@@ -455,9 +455,13 @@
 	nsbuf = 0;
 	for (i = 0, sfe = &sf->list[0];
 			i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) {
-		if (((char *)sfe < (char *)sf) ||
+		if (unlikely(
+		    ((char *)sfe < (char *)sf) ||
 		    ((char *)sfe >= ((char *)sf + dp->i_afp->if_bytes)) ||
-		    (sfe->namelen >= MAXNAMELEN)) {
+		    (sfe->namelen >= MAXNAMELEN))) {
+			XFS_CORRUPTION_ERROR("xfs_attr_shortform_list",
+					     XFS_ERRLEVEL_LOW,
+					     context->dp->i_mount, sfe);
 			xfs_attr_trace_l_c("sf corrupted", context);
 			kmem_free(sbuf, sbsize);
 			return XFS_ERROR(EFSCORRUPTED);
diff -Nru a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
--- a/fs/xfs/xfs_bmap.c	Thu Feb  6 07:33:47 2003
+++ b/fs/xfs/xfs_bmap.c	Mon Mar 17 12:19:19 2003
@@ -160,8 +160,7 @@
 	xfs_inode_t		*ip,	/* incore inode pointer */
 	xfs_btree_cur_t		*cur,	/* btree cursor */
 	int			*logflagsp, /* inode logging flags */
-	int			whichfork,  /* data or attr fork */
-	int			async);	    /* xaction can be async */
+	int			whichfork); /* data or attr fork */
 
 #ifdef XFSDEBUG
 /*
@@ -187,7 +186,6 @@
 	xfs_bmap_free_t		*flist, /* list of extents to be freed */
 	xfs_btree_cur_t		*cur,	/* if null, not a btree */
 	xfs_bmbt_irec_t		*new,	/* new data to put in extent list */
-	int			iflags, /* input flags (meta-data or not) */
 	int			*logflagsp,/* inode logging flags */
 	int			whichfork, /* data or attr fork */
 	int			rsvd);	 /* OK to allocate reserved blocks */
@@ -811,7 +809,7 @@
 					RIGHT.br_blockcount, &i)))
 				goto done;
 			ASSERT(i == 1);
-			if ((error = xfs_bmbt_delete(cur, 0, &i)))
+			if ((error = xfs_bmbt_delete(cur, &i)))
 				goto done;
 			ASSERT(i == 1);
 			if ((error = xfs_bmbt_decrement(cur, 0, &i)))
@@ -1349,13 +1347,13 @@
 					RIGHT.br_blockcount, &i)))
 				goto done;
 			ASSERT(i == 1);
-			if ((error = xfs_bmbt_delete(cur, 0, &i)))
+			if ((error = xfs_bmbt_delete(cur, &i)))
 				goto done;
 			ASSERT(i == 1);
 			if ((error = xfs_bmbt_decrement(cur, 0, &i)))
 				goto done;
 			ASSERT(i == 1);
-			if ((error = xfs_bmbt_delete(cur, 0, &i)))
+			if ((error = xfs_bmbt_delete(cur, &i)))
 				goto done;
 			ASSERT(i == 1);
 			if ((error = xfs_bmbt_decrement(cur, 0, &i)))
@@ -1394,7 +1392,7 @@
 					&i)))
 				goto done;
 			ASSERT(i == 1);
-			if ((error = xfs_bmbt_delete(cur, 0, &i)))
+			if ((error = xfs_bmbt_delete(cur, &i)))
 				goto done;
 			ASSERT(i == 1);
 			if ((error = xfs_bmbt_decrement(cur, 0, &i)))
@@ -1434,7 +1432,7 @@
 					RIGHT.br_blockcount, &i)))
 				goto done;
 			ASSERT(i == 1);
-			if ((error = xfs_bmbt_delete(cur, 0, &i)))
+			if ((error = xfs_bmbt_delete(cur, &i)))
 				goto done;
 			ASSERT(i == 1);
 			if ((error = xfs_bmbt_decrement(cur, 0, &i)))
@@ -2010,7 +2008,7 @@
 				right.br_startblock, right.br_blockcount, &i)))
 			return error;
 		ASSERT(i == 1);
-		if ((error = xfs_bmbt_delete(cur, 0, &i)))
+		if ((error = xfs_bmbt_delete(cur, &i)))
 			return error;
 		ASSERT(i == 1);
 		if ((error = xfs_bmbt_decrement(cur, 0, &i)))
@@ -2722,8 +2720,7 @@
 	xfs_inode_t		*ip,	/* incore inode pointer */
 	xfs_btree_cur_t		*cur,	/* btree cursor */
 	int			*logflagsp, /* inode logging flags */
-	int			whichfork,  /* data or attr fork */
-	int			async)	    /* xaction can be async */
+	int			whichfork)  /* data or attr fork */
 {
 	/* REFERENCED */
 	xfs_bmbt_block_t	*cblock;/* child btree block */
@@ -2757,8 +2754,6 @@
 	if ((error = xfs_btree_check_lblock(cur, cblock, 0, cbp)))
 		return error;
 	xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp);
-	if (!async)
-		xfs_trans_set_sync(tp);
 	ip->i_d.di_nblocks--;
 	if (XFS_IS_QUOTA_ON(mp) &&
 	    ip->i_ino != mp->m_sb.sb_uquotino &&
@@ -2787,7 +2782,6 @@
 	xfs_bmap_free_t		*flist, /* list of extents to be freed */
 	xfs_btree_cur_t		*cur,	/* if null, not a btree */
 	xfs_bmbt_irec_t		*del,	/* data to remove from extent list */
-	int			iflags, /* input flags */
 	int			*logflagsp, /* inode logging flags */
 	int			whichfork, /* data or attr fork */
 	int			rsvd)	/* OK to allocate reserved blocks */
@@ -2916,7 +2910,7 @@
 			flags |= XFS_ILOG_FEXT(whichfork);
 			break;
 		}
-		if ((error = xfs_bmbt_delete(cur, iflags & XFS_BMAPI_ASYNC, &i)))
+		if ((error = xfs_bmbt_delete(cur, &i)))
 			goto done;
 		ASSERT(i == 1);
 		break;
@@ -4396,12 +4390,14 @@
 
 
 		num_recs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
-		if (i + num_recs > room) {
+		if (unlikely(i + num_recs > room)) {
 			ASSERT(i + num_recs <= room);
 			xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-				"corrupt dinode %Lu, (btree extents).  "
-				"Unmount and run xfs_repair.",
+				"corrupt dinode %Lu, (btree extents).  Unmount and run xfs_repair.",
 				(unsigned long long) ip->i_ino);
+			XFS_ERROR_REPORT("xfs_bmap_read_extents(1)",
+					 XFS_ERRLEVEL_LOW,
+					ip->i_mount);
 			goto error0;
 		}
 		XFS_WANT_CORRUPTED_GOTO(
@@ -4429,7 +4425,10 @@
 			 * any "older" data bmap btree records for a
 			 * set bit in the "extent flag" position.
 			 */
-			if (xfs_check_nostate_extents(temp, num_recs)) {
+			if (unlikely(xfs_check_nostate_extents(temp, num_recs))) {
+				XFS_ERROR_REPORT("xfs_bmap_read_extents(2)",
+						 XFS_ERRLEVEL_LOW,
+						 ip->i_mount);
 				goto error0;
 			}
 		}
@@ -4606,12 +4605,15 @@
 	ASSERT(*nmap <= XFS_BMAP_MAX_NMAP || !(flags & XFS_BMAPI_WRITE));
 	whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
 		XFS_ATTR_FORK : XFS_DATA_FORK;
-	if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
-	    XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
-	    XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL) {
+	mp = ip->i_mount;
+	if (unlikely(XFS_TEST_ERROR(
+	    (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
+	     XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
+	     XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL),
+	     mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) {
+		XFS_ERROR_REPORT("xfs_bmapi", XFS_ERRLEVEL_LOW, mp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
-	mp = ip->i_mount;
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return XFS_ERROR(EIO);
 	ifp = XFS_IFORK_PTR(ip, whichfork);
@@ -5027,7 +5029,7 @@
 	    XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) {
 		ASSERT(wr && cur);
 		error = xfs_bmap_btree_to_extents(tp, ip, cur,
-			&tmp_logflags, whichfork, 0);
+			&tmp_logflags, whichfork);
 		logflags |= tmp_logflags;
 		if (error)
 			goto error0;
@@ -5102,8 +5104,11 @@
 	xfs_bmbt_irec_t prev;		/* previous extent list record */
 
 	ifp = XFS_IFORK_PTR(ip, whichfork);
-	if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
-	    XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) {
+	if (unlikely(
+	    XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
+	    XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)) {
+	       XFS_ERROR_REPORT("xfs_bmapi_single", XFS_ERRLEVEL_LOW,
+				ip->i_mount);
 	       return XFS_ERROR(EFSCORRUPTED);
 	}
 	if (XFS_FORCED_SHUTDOWN(ip->i_mount))
@@ -5148,7 +5153,6 @@
 	xfs_bmap_free_t		*flist,		/* i/o: list extents to free */
 	int			*done)		/* set if not done yet */
 {
-	int			async;		/* xactions can be async */
 	xfs_btree_cur_t		*cur;		/* bmap btree cursor */
 	xfs_bmbt_irec_t		del;		/* extent being deleted */
 	int			eof;		/* is deleting at eof */
@@ -5175,14 +5179,16 @@
 	whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
 		XFS_ATTR_FORK : XFS_DATA_FORK;
 	ifp = XFS_IFORK_PTR(ip, whichfork);
-	if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
-	    XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE) {
+	if (unlikely(
+	    XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
+	    XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
+		XFS_ERROR_REPORT("xfs_bunmapi", XFS_ERRLEVEL_LOW,
+				 ip->i_mount);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 	mp = ip->i_mount;
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return XFS_ERROR(EIO);
-	async = flags & XFS_BMAPI_ASYNC;
 	rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0;
 	ASSERT(len > 0);
 	ASSERT(nexts >= 0);
@@ -5409,7 +5415,7 @@
 			goto error0;
 		}
 		error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del,
-			flags, &tmp_logflags, whichfork, rsvd);
+			&tmp_logflags, whichfork, rsvd);
 		logflags |= tmp_logflags;
 		if (error)
 			goto error0;
@@ -5455,7 +5461,7 @@
 		 XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) {
 		ASSERT(cur != NULL);
 		error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags,
-			whichfork, async);
+			whichfork);
 		logflags |= tmp_logflags;
 		if (error)
 			goto error0;
@@ -5562,11 +5568,11 @@
 			    ip->i_d.di_aformat != XFS_DINODE_FMT_BTREE &&
 			    ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)
 				return XFS_ERROR(EINVAL);
-		} else if (ip->i_d.di_aformat != 0 &&
-			   ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) {
-			cmn_err(CE_NOTE,
-				"EFSCORRUPTED returned from file %s line %d",
-				__FILE__, __LINE__);
+		} else if (unlikely(
+		           ip->i_d.di_aformat != 0 &&
+			   ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS)) {
+			XFS_ERROR_REPORT("xfs_getbmap", XFS_ERRLEVEL_LOW,
+					 ip->i_mount);
 			return XFS_ERROR(EFSCORRUPTED);
 		}
 	} else if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
@@ -6114,12 +6120,11 @@
 	mp = ip->i_mount;
 	ifp = XFS_IFORK_PTR(ip, whichfork);
 	if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) {
-		if (xfs_bmap_count_leaves(ifp->if_u1.if_extents,
+		if (unlikely(xfs_bmap_count_leaves(ifp->if_u1.if_extents,
 			ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t),
-			count) < 0) {
-				cmn_err(CE_NOTE,
-					"EFSCORRUPTED returned from file %s line %d",
-					__FILE__, __LINE__);
+			count) < 0)) {
+			XFS_ERROR_REPORT("xfs_bmap_count_blocks(1)",
+					 XFS_ERRLEVEL_LOW, mp);
 			return XFS_ERROR(EFSCORRUPTED);
 		}
 		return 0;
@@ -6137,10 +6142,9 @@
 	ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
 	bno = INT_GET(*pp, ARCH_CONVERT);
 
-	if (xfs_bmap_count_tree(mp, tp, bno, level, count) < 0) {
-		cmn_err(CE_NOTE,
-			"EFSCORRUPTED returned from file %s line %d",
-			__FILE__, __LINE__);
+	if (unlikely(xfs_bmap_count_tree(mp, tp, bno, level, count) < 0)) {
+		XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
+				 mp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 
@@ -6191,12 +6195,11 @@
 		pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
 			xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]);
 		bno = INT_GET(*pp, ARCH_CONVERT);
-		if ((error =
-		     xfs_bmap_count_tree(mp, tp, bno, level, count)) < 0) {
+		if (unlikely((error =
+		     xfs_bmap_count_tree(mp, tp, bno, level, count)) < 0)) {
 			xfs_trans_brelse(tp, bp);
-			cmn_err(CE_NOTE,
-				"EFSCORRUPTED returned from file %s line %d",
-				__FILE__, __LINE__);
+			XFS_ERROR_REPORT("xfs_bmap_count_tree(1)",
+					 XFS_ERRLEVEL_LOW, mp);
 			return XFS_ERROR(EFSCORRUPTED);
 		}
 		xfs_trans_brelse(tp, bp);
@@ -6207,11 +6210,10 @@
 			numrecs = INT_GET(block->bb_numrecs, ARCH_CONVERT);
 			frp = XFS_BTREE_REC_ADDR(mp->m_sb.sb_blocksize,
 				xfs_bmbt, block, 1, mp->m_bmap_dmxr[0]);
-			if (xfs_bmap_count_leaves(frp, numrecs, count) < 0) {
+			if (unlikely(xfs_bmap_count_leaves(frp, numrecs, count) < 0)) {
 				xfs_trans_brelse(tp, bp);
-				cmn_err(CE_NOTE,
-					"EFSCORRUPTED returned from file %s line %d",
-					__FILE__, __LINE__);
+				XFS_ERROR_REPORT("xfs_bmap_count_tree(2)",
+						 XFS_ERRLEVEL_LOW, mp);
 				return XFS_ERROR(EFSCORRUPTED);
 			}
 			xfs_trans_brelse(tp, bp);
diff -Nru a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
--- a/fs/xfs/xfs_bmap_btree.c	Wed Nov  6 11:33:06 2002
+++ b/fs/xfs/xfs_bmap_btree.c	Mon Mar 17 12:00:45 2003
@@ -41,7 +41,7 @@
  */
 
 
-STATIC int xfs_bmbt_killroot(xfs_btree_cur_t *, int);
+STATIC int xfs_bmbt_killroot(xfs_btree_cur_t *);
 STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
 STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
 STATIC int xfs_bmbt_lshift(xfs_btree_cur_t *, int, int *);
@@ -304,7 +304,6 @@
 xfs_bmbt_delrec(
 	xfs_btree_cur_t		*cur,
 	int			level,
-	int			async,		/* deletion can be async */
 	int			*stat)		/* success/failure */
 {
 	xfs_bmbt_block_t	*block;		/* bmap btree block */
@@ -408,7 +407,7 @@
 	if (level == cur->bc_nlevels - 1) {
 		xfs_iroot_realloc(cur->bc_private.b.ip, -1,
 			cur->bc_private.b.whichfork);
-		if ((error = xfs_bmbt_killroot(cur, async))) {
+		if ((error = xfs_bmbt_killroot(cur))) {
 			XFS_BMBT_TRACE_CURSOR(cur, ERROR);
 			goto error0;
 		}
@@ -442,7 +441,7 @@
 	 */
 	if (lbno == NULLFSBLOCK && rbno == NULLFSBLOCK &&
 	    level == cur->bc_nlevels - 2) {
-		if ((error = xfs_bmbt_killroot(cur, async))) {
+		if ((error = xfs_bmbt_killroot(cur))) {
 			XFS_BMBT_TRACE_CURSOR(cur, ERROR);
 			goto error0;
 		}
@@ -645,8 +644,6 @@
 	}
 	xfs_bmap_add_free(XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(rbp)), 1,
 		cur->bc_private.b.flist, mp);
-	if (!async)
-		xfs_trans_set_sync(cur->bc_tp);
 	cur->bc_private.b.ip->i_d.di_nblocks--;
 	xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
 	if (XFS_IS_QUOTA_ON(mp) &&
@@ -911,8 +908,7 @@
 
 STATIC int
 xfs_bmbt_killroot(
-	xfs_btree_cur_t		*cur,
-	int			async)
+	xfs_btree_cur_t		*cur)
 {
 	xfs_bmbt_block_t	*block;
 	xfs_bmbt_block_t	*cblock;
@@ -991,8 +987,6 @@
 	memcpy(pp, cpp, INT_GET(block->bb_numrecs, ARCH_CONVERT) * sizeof(*pp));
 	xfs_bmap_add_free(XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(cbp)), 1,
 		cur->bc_private.b.flist, cur->bc_mp);
-	if (!async)
-		xfs_trans_set_sync(cur->bc_tp);
 	ip->i_d.di_nblocks--;
 	if (XFS_IS_QUOTA_ON(cur->bc_mp) &&
 	    ip->i_ino != cur->bc_mp->m_sb.sb_uquotino &&
@@ -1834,7 +1828,6 @@
 int					/* error */
 xfs_bmbt_delete(
 	xfs_btree_cur_t *cur,
-	int		async,		/* deletion can be async */
 	int		*stat)		/* success/failure */
 {
 	int		error;		/* error return value */
@@ -1846,7 +1839,7 @@
 
 	XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
 	for (level = 0, i = 2; i == 2; level++) {
-		if ((error = xfs_bmbt_delrec(cur, level, async, &i))) {
+		if ((error = xfs_bmbt_delrec(cur, level, &i))) {
 			XFS_BMBT_TRACE_CURSOR(cur, ERROR);
 			return error;
 		}
diff -Nru a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
--- a/fs/xfs/xfs_bmap_btree.h	Tue Dec  3 13:11:27 2002
+++ b/fs/xfs/xfs_bmap_btree.h	Mon Mar 17 12:00:45 2003
@@ -479,7 +479,6 @@
 int
 xfs_bmbt_delete(
 	struct xfs_btree_cur *,
-	int,
 	int *);
 
 void
diff -Nru a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
--- a/fs/xfs/xfs_btree.c	Mon Oct 14 14:15:58 2002
+++ b/fs/xfs/xfs_btree.c	Mon Mar 17 12:19:19 2003
@@ -190,15 +190,12 @@
 		!INT_ISZERO(block->bb_rightsib, ARCH_CONVERT) &&
 		(INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLDFSBNO ||
 		 XFS_FSB_SANITY_CHECK(mp, INT_GET(block->bb_rightsib, ARCH_CONVERT)));
-	if (XFS_TEST_ERROR(!lblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK,
-			XFS_RANDOM_BTREE_CHECK_LBLOCK)) {
+	if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK,
+			XFS_RANDOM_BTREE_CHECK_LBLOCK))) {
 		if (bp)
 			xfs_buftrace("LBTREE ERROR", bp);
-#ifdef __KERNEL__	/* additional, temporary, debugging code */
-		cmn_err(CE_NOTE,
-			"EFSCORRUPTED returned from file %s line %d",
-			__FILE__, __LINE__);
-#endif
+		XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW,
+				 mp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 	return 0;
@@ -312,22 +309,13 @@
 		(INT_GET(block->bb_rightsib, ARCH_CONVERT) == NULLAGBLOCK ||
 		 INT_GET(block->bb_rightsib, ARCH_CONVERT) < agflen) &&
 		!INT_ISZERO(block->bb_rightsib, ARCH_CONVERT);
-	if (XFS_TEST_ERROR(!sblock_ok, cur->bc_mp,
+	if (unlikely(XFS_TEST_ERROR(!sblock_ok, cur->bc_mp,
 			XFS_ERRTAG_BTREE_CHECK_SBLOCK,
-			XFS_RANDOM_BTREE_CHECK_SBLOCK)) {
+			XFS_RANDOM_BTREE_CHECK_SBLOCK))) {
 		if (bp)
 			xfs_buftrace("SBTREE ERROR", bp);
-#ifdef __KERNEL__	/* additional, temporary, debugging code */
-		cmn_err(CE_NOTE,
-			"xfs_btree_check_sblock: Not OK:");
-		cmn_err(CE_NOTE,
-			"magic 0x%x level %d numrecs %d leftsib %d rightsib %d",
-			INT_GET(block->bb_magic, ARCH_CONVERT),
-			INT_GET(block->bb_level, ARCH_CONVERT),
-			INT_GET(block->bb_numrecs, ARCH_CONVERT),
-			INT_GET(block->bb_leftsib, ARCH_CONVERT),
-			INT_GET(block->bb_rightsib, ARCH_CONVERT));
-#endif
+		XFS_ERROR_REPORT("xfs_btree_check_sblock", XFS_ERRLEVEL_LOW,
+				 cur->bc_mp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 	return 0;
diff -Nru a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
--- a/fs/xfs/xfs_btree.h	Wed Sep 11 11:12:25 2002
+++ b/fs/xfs/xfs_btree.h	Mon Mar 17 12:19:19 2003
@@ -570,7 +570,9 @@
 	{ \
 		int fs_is_ok = (x); \
 		ASSERT(fs_is_ok); \
-		if (!fs_is_ok) { \
+		if (unlikely(!fs_is_ok)) { \
+			XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_GOTO", \
+					 XFS_ERRLEVEL_LOW, NULL); \
 			error = XFS_ERROR(EFSCORRUPTED); \
 			goto l; \
 		} \
@@ -580,8 +582,11 @@
 	{ \
 		int fs_is_ok = (x); \
 		ASSERT(fs_is_ok); \
-		if (!fs_is_ok) \
+		if (unlikely(!fs_is_ok)) { \
+			XFS_ERROR_REPORT("XFS_WANT_CORRUPTED_RETURN", \
+					 XFS_ERRLEVEL_LOW, NULL); \
 			return XFS_ERROR(EFSCORRUPTED); \
+		} \
 	}
 
 #endif	/* __XFS_BTREE_H__ */
diff -Nru a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
--- a/fs/xfs/xfs_buf.h	Tue Feb 25 07:59:20 2003
+++ b/fs/xfs/xfs_buf.h	Mon Mar 17 13:38:13 2003
@@ -163,15 +163,17 @@
 #define XFS_BUF_SET_PTR(bp, val, count)		\
 				pagebuf_associate_memory(bp, val, count)
 #define XFS_BUF_ADDR(bp)	((bp)->pb_bn)
-#define XFS_BUF_OFFSET(bp)	((bp)->pb_file_offset >> 9)
 #define XFS_BUF_SET_ADDR(bp, blk)		\
 			((bp)->pb_bn = (page_buf_daddr_t)(blk))
+#define XFS_BUF_OFFSET(bp)	((bp)->pb_file_offset)
+#define XFS_BUF_SET_OFFSET(bp, off)		\
+			((bp)->pb_file_offset = (off))
 #define XFS_BUF_COUNT(bp)	((bp)->pb_count_desired)
 #define XFS_BUF_SET_COUNT(bp, cnt)		\
-			((bp)->pb_count_desired = cnt)
+			((bp)->pb_count_desired = (cnt))
 #define XFS_BUF_SIZE(bp)	((bp)->pb_buffer_length)
 #define XFS_BUF_SET_SIZE(bp, cnt)		\
-			((bp)->pb_buffer_length = cnt)
+			((bp)->pb_buffer_length = (cnt))
 #define XFS_BUF_SET_VTYPE_REF(bp, type, ref)
 #define XFS_BUF_SET_VTYPE(bp, type)
 #define XFS_BUF_SET_REF(bp, ref)
@@ -242,7 +244,7 @@
 
 
 #define xfs_biodone(pb)		    \
-	    pagebuf_iodone(pb, 0)
+	    pagebuf_iodone(pb, 0, 0)
 
 #define xfs_incore(buftarg,blkno,len,lockit) \
 	    pagebuf_find(buftarg, blkno ,len, lockit)
diff -Nru a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
--- a/fs/xfs/xfs_buf_item.c	Tue Feb 25 10:47:24 2003
+++ b/fs/xfs/xfs_buf_item.c	Mon Mar 17 13:43:53 2003
@@ -991,7 +991,7 @@
 	xfs_buf_t	*bp)
 {
 	xfs_log_item_t	*lip;
-	static time_t	lasttime;
+	static ulong	lasttime;
 	static dev_t	lastdev;
 	xfs_mount_t	*mp;
 
diff -Nru a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
--- a/fs/xfs/xfs_da_btree.c	Tue Feb 25 02:47:48 2003
+++ b/fs/xfs/xfs_da_btree.c	Mon Mar 17 12:19:19 2003
@@ -1791,8 +1791,11 @@
 		error = xfs_bmap_last_offset(tp, ip, &lastoff, w);
 	if (error)
 		return error;
-	if (lastoff == 0)
+	if (unlikely(lastoff == 0)) {
+		XFS_ERROR_REPORT("xfs_da_swap_lastblock(1)", XFS_ERRLEVEL_LOW,
+				 mp);
 		return XFS_ERROR(EFSCORRUPTED);
+	}
 	/*
 	 * Read the last block in the btree space.
 	 */
@@ -1833,8 +1836,11 @@
 		if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w)))
 			goto done;
 		sib_info = sib_buf->data;
-		if (INT_GET(sib_info->forw, ARCH_CONVERT) != last_blkno ||
-		    INT_GET(sib_info->magic, ARCH_CONVERT) != INT_GET(dead_info->magic, ARCH_CONVERT)) {
+		if (unlikely(
+		    INT_GET(sib_info->forw, ARCH_CONVERT) != last_blkno ||
+		    INT_GET(sib_info->magic, ARCH_CONVERT) != INT_GET(dead_info->magic, ARCH_CONVERT))) {
+			XFS_ERROR_REPORT("xfs_da_swap_lastblock(2)",
+					 XFS_ERRLEVEL_LOW, mp);
 			error = XFS_ERROR(EFSCORRUPTED);
 			goto done;
 		}
@@ -1852,9 +1858,12 @@
 		if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w)))
 			goto done;
 		sib_info = sib_buf->data;
-		if (   INT_GET(sib_info->back, ARCH_CONVERT) != last_blkno
+		if (unlikely(
+		       INT_GET(sib_info->back, ARCH_CONVERT) != last_blkno
 		    || INT_GET(sib_info->magic, ARCH_CONVERT)
-				!= INT_GET(dead_info->magic, ARCH_CONVERT)) {
+				!= INT_GET(dead_info->magic, ARCH_CONVERT))) {
+			XFS_ERROR_REPORT("xfs_da_swap_lastblock(3)",
+					 XFS_ERRLEVEL_LOW, mp);
 			error = XFS_ERROR(EFSCORRUPTED);
 			goto done;
 		}
@@ -1874,8 +1883,11 @@
 		if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w)))
 			goto done;
 		par_node = par_buf->data;
-		if (INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC ||
-		    (level >= 0 && level != INT_GET(par_node->hdr.level, ARCH_CONVERT) + 1)) {
+		if (unlikely(
+		    INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC ||
+		    (level >= 0 && level != INT_GET(par_node->hdr.level, ARCH_CONVERT) + 1))) {
+			XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)",
+					 XFS_ERRLEVEL_LOW, mp);
 			error = XFS_ERROR(EFSCORRUPTED);
 			goto done;
 		}
@@ -1885,7 +1897,9 @@
 		     INT_GET(par_node->btree[entno].hashval, ARCH_CONVERT) < dead_hash;
 		     entno++)
 			continue;
-		if (entno == INT_GET(par_node->hdr.count, ARCH_CONVERT)) {
+		if (unlikely(entno == INT_GET(par_node->hdr.count, ARCH_CONVERT))) {
+			XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)",
+					 XFS_ERRLEVEL_LOW, mp);
 			error = XFS_ERROR(EFSCORRUPTED);
 			goto done;
 		}
@@ -1910,15 +1924,20 @@
 		par_blkno = INT_GET(par_node->hdr.info.forw, ARCH_CONVERT);
 		xfs_da_brelse(tp, par_buf);
 		par_buf = NULL;
-		if (par_blkno == 0) {
+		if (unlikely(par_blkno == 0)) {
+			XFS_ERROR_REPORT("xfs_da_swap_lastblock(6)",
+					 XFS_ERRLEVEL_LOW, mp);
 			error = XFS_ERROR(EFSCORRUPTED);
 			goto done;
 		}
 		if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w)))
 			goto done;
 		par_node = par_buf->data;
-		if (INT_GET(par_node->hdr.level, ARCH_CONVERT) != level ||
-		    INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC) {
+		if (unlikely(
+		    INT_GET(par_node->hdr.level, ARCH_CONVERT) != level ||
+		    INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC)) {
+			XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)",
+					 XFS_ERRLEVEL_LOW, mp);
 			error = XFS_ERROR(EFSCORRUPTED);
 			goto done;
 		}
@@ -2111,6 +2130,26 @@
 	}
 	if (!xfs_da_map_covers_blocks(nmap, mapp, bno, nfsb)) {
 		error = mappedbno == -2 ? 0 : XFS_ERROR(EFSCORRUPTED);
+		if (unlikely(error == EFSCORRUPTED)) {
+			if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
+				int	i;
+				cmn_err(CE_ALERT, "xfs_da_do_buf: bno %lld\n",
+					bno);
+				cmn_err(CE_ALERT, "dir: inode %lld\n",
+					dp->i_ino);
+				for (i = 0; i < nmap; i++) {
+					cmn_err(CE_ALERT,
+						"[%02d] br_startoff %lld br_startblock %lld br_blockcount %lld br_state %d\n",
+						i,
+						mapp[i].br_startoff,
+						mapp[i].br_startblock,
+						mapp[i].br_blockcount,
+						mapp[i].br_state);
+				}
+			}
+			XFS_ERROR_REPORT("xfs_da_do_buf(1)",
+					 XFS_ERRLEVEL_LOW, mp);
+		}
 		goto exit0;
 	}
 	if (caller != 3 && nmap > 1) {
@@ -2193,7 +2232,8 @@
 		free = rbp->data;
 		magic = INT_GET(info->magic, ARCH_CONVERT);
 		magic1 = INT_GET(data->hdr.magic, ARCH_CONVERT);
-		if (XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
+		if (unlikely(
+		    XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
 				   (magic != XFS_DIR_LEAF_MAGIC) &&
 				   (magic != XFS_ATTR_LEAF_MAGIC) &&
 				   (magic != XFS_DIR2_LEAF1_MAGIC) &&
@@ -2202,8 +2242,10 @@
 				   (magic1 != XFS_DIR2_DATA_MAGIC) &&
 				   (INT_GET(free->hdr.magic, ARCH_CONVERT) != XFS_DIR2_FREE_MAGIC),
 				mp, XFS_ERRTAG_DA_READ_BUF,
-				XFS_RANDOM_DA_READ_BUF)) {
+				XFS_RANDOM_DA_READ_BUF))) {
 			xfs_buftrace("DA READ ERROR", rbp->bps[0]);
+			XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)",
+					     XFS_ERRLEVEL_LOW, mp, info);
 			error = XFS_ERROR(EFSCORRUPTED);
 			xfs_da_brelse(trans, rbp);
 			nbplist = 0;
diff -Nru a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
--- a/fs/xfs/xfs_dfrag.c	Wed Sep 11 11:12:28 2002
+++ b/fs/xfs/xfs_dfrag.c	Mon Mar 17 13:24:32 2003
@@ -69,15 +69,12 @@
 	}
 
 	bhp = VN_BHV_HEAD(vp);
-	VN_BHV_READ_LOCK(bhp);
 	bdp = vn_bhv_lookup(bhp, &xfs_vnodeops);
 	if (bdp == NULL) {
-		VN_BHV_READ_UNLOCK(bhp);
 		error = XFS_ERROR(EBADF);
 		goto error0;
 	} else {
 		ip = XFS_BHVTOI(bdp);
-		VN_BHV_READ_UNLOCK(bhp);
 	}
 
 	if (((tfp = fget((int)sx.sx_fdtmp)) == NULL) ||
@@ -87,15 +84,12 @@
 	}
 
 	tbhp = VN_BHV_HEAD(tvp);
-	VN_BHV_READ_LOCK(tbhp);
 	tbdp = vn_bhv_lookup(tbhp, &xfs_vnodeops);
 	if (tbdp == NULL) {
-		VN_BHV_READ_UNLOCK(tbhp);
 		error = XFS_ERROR(EBADF);
 		goto error0;
 	} else {
 		tip = XFS_BHVTOI(tbdp);
-		VN_BHV_READ_UNLOCK(tbhp);
 	}
 
 	if (ip->i_ino == tip->i_ino) {
diff -Nru a/fs/xfs/xfs_dir.c b/fs/xfs/xfs_dir.c
--- a/fs/xfs/xfs_dir.c	Tue Jan 14 09:23:52 2003
+++ b/fs/xfs/xfs_dir.c	Mon Mar 17 12:30:23 2003
@@ -887,7 +887,7 @@
 	 * hashval, then we run with it.
 	 */
 	if (bno > 0) {
-		error = xfs_da_read_buf(trans, dp, bno, -1, &bp, XFS_DATA_FORK);
+		error = xfs_da_read_buf(trans, dp, bno, -2, &bp, XFS_DATA_FORK);
 		if ((error != 0) && (error != EFSCORRUPTED))
 			return(error);
 		if (bp)
@@ -962,9 +962,11 @@
 	 */
 	for (;;) {
 		leaf = bp->data;
-		if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC) {
+		if (unlikely(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC)) {
 			xfs_dir_trace_g_dul("node: not a leaf", dp, uio, leaf);
 			xfs_da_brelse(trans, bp);
+			XFS_CORRUPTION_ERROR("xfs_dir_node_getdents(1)",
+					     XFS_ERRLEVEL_LOW, mp, leaf);
 			return XFS_ERROR(EFSCORRUPTED);
 		}
 		xfs_dir_trace_g_dul("node: leaf detail", dp, uio, leaf);
@@ -988,8 +990,11 @@
 					XFS_DATA_FORK);
 		if (error)
 			return(error);
-		if (bp == NULL)
+		if (unlikely(bp == NULL)) {
+			XFS_ERROR_REPORT("xfs_dir_node_getdents(2)",
+					 XFS_ERRLEVEL_LOW, mp);
 			return(XFS_ERROR(EFSCORRUPTED));
+		}
 	}
 	*eofp = 1;
 	xfs_dir_trace_g_du("node: E-O-F", dp, uio);
diff -Nru a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
--- a/fs/xfs/xfs_dir2_block.c	Mon Oct 14 14:06:33 2002
+++ b/fs/xfs/xfs_dir2_block.c	Mon Mar 17 12:19:19 2003
@@ -98,7 +98,10 @@
 	/*
 	 * Check the magic number, corrupted if wrong.
 	 */
-	if (INT_GET(block->hdr.magic, ARCH_CONVERT) != XFS_DIR2_BLOCK_MAGIC) {
+	if (unlikely(INT_GET(block->hdr.magic, ARCH_CONVERT)
+						!= XFS_DIR2_BLOCK_MAGIC)) {
+		XFS_CORRUPTION_ERROR("xfs_dir2_block_addname",
+				     XFS_ERRLEVEL_LOW, mp, block);
 		xfs_da_brelse(tp, bp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
@@ -437,7 +440,6 @@
 	xfs_mount_t		*mp;		/* filesystem mount point */
 	xfs_dir2_put_args_t	p;		/* arg package for put rtn */
 	char			*ptr;		/* current data entry */
-	char			*savptr;	/* saved data entry */
 	int			wantoff;	/* starting block offset */
 
 	mp = dp->i_mount;
@@ -488,8 +490,6 @@
 
 		dep = (xfs_dir2_data_entry_t *)ptr;
 
-		savptr = ptr;		/* In case we need it.. */
-
 		/*
 		 * Bump pointer for the next iteration.
 		 */
@@ -504,14 +504,8 @@
 		 */
 		p.namelen = dep->namelen;
 
-		/*
-		 * NOTE! Linux "filldir" semantics require that the
-		 *	 offset "cookie" be for this entry, not the
-		 *	 next; all the actual shuffling to make it
-		 *	 "look right" to the user is done in filldir.
-		 */
 		p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
-						    savptr - (char *)block);
+						    ptr - (char *)block);
 #if XFS_BIG_FILESYSTEMS
 		p.ino = INT_GET(dep->inumber, ARCH_CONVERT) + mp->m_inoadd;
 #else
diff -Nru a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
--- a/fs/xfs/xfs_dir2_leaf.c	Mon Oct 14 14:06:33 2002
+++ b/fs/xfs/xfs_dir2_leaf.c	Mon Mar 17 12:54:20 2003
@@ -1059,6 +1059,9 @@
 					XFS_DIR2_DB_OFF_TO_BYTE(mp,
 					    XFS_DIR2_BYTE_TO_DB(mp, curoff),
 					    (char *)ptr - (char *)data);
+				if (ptr >= (char *)data + mp->m_dirblksize) {
+					continue;
+				}
 			}
 		}
 		/*
@@ -1086,13 +1089,7 @@
 
 		length = XFS_DIR2_DATA_ENTSIZE(p.namelen);
 
-		/*
-		 * NOTE! Linux "filldir" semantics require that the
-		 *	 offset "cookie" be for this entry, not the
-		 *	 next; all the actual shuffling to make it
-		 *	 "look right" to the user is done in filldir.
-		 */
-		p.cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff);
+		p.cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length);
 
 #if XFS_BIG_FILESYSTEMS
 		p.ino = INT_GET(dep->inumber, ARCH_CONVERT) + mp->m_inoadd;
diff -Nru a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
--- a/fs/xfs/xfs_dir2_node.c	Wed Nov  6 11:04:34 2002
+++ b/fs/xfs/xfs_dir2_node.c	Mon Mar 17 12:43:41 2003
@@ -511,7 +511,9 @@
 				/*
 				 * If it has room, return it.
 				 */
-				if (INT_GET(free->bests[fi], ARCH_CONVERT) == NULLDATAOFF) {
+				if (unlikely(INT_GET(free->bests[fi], ARCH_CONVERT) == NULLDATAOFF)) {
+					XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
+							 XFS_ERRLEVEL_LOW, mp);
 					return XFS_ERROR(EFSCORRUPTED);
 				}
 				if (INT_GET(free->bests[fi], ARCH_CONVERT) >= length) {
@@ -1346,6 +1348,7 @@
 	int			findex;		/* freespace entry index */
 	xfs_dir2_db_t		foundbno=0;	/* found freespace block no */
 	int			foundindex=0;	/* found freespace entry idx */
+	int			foundhole;	/* found hole in freespace */
 	xfs_dir2_free_t		*free=NULL;	/* freespace block structure */
 	xfs_dir2_db_t		ifbno;		/* initial freespace block no */
 	xfs_dir2_db_t		lastfbno=0;	/* highest freespace block no */
@@ -1354,6 +1357,7 @@
 	xfs_mount_t		*mp;		/* filesystem mount point */
 	int			needlog;	/* need to log data header */
 	int			needscan;	/* need to rescan data frees */
+	int			needfreesp;	/* need to allocate freesp blk */
 	xfs_dir2_data_off_t	*tagp;		/* data entry tag pointer */
 	xfs_trans_t		*tp;		/* transaction pointer */
 
@@ -1361,6 +1365,7 @@
 	mp = dp->i_mount;
 	tp = args->trans;
 	length = XFS_DIR2_DATA_ENTSIZE(args->namelen);
+	foundhole = 0;
 	/*
 	 * If we came in with a freespace block that means that lookup
 	 * found an entry with our hash value.	This is the freespace
@@ -1450,11 +1455,12 @@
 			 * to avoid it.
 			 */
 			if ((error = xfs_da_read_buf(tp, dp,
-					XFS_DIR2_DB_TO_DA(mp, fbno), -1, &fbp,
+					XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp,
 					XFS_DATA_FORK))) {
 				return error;
 			}
-			if (fbp == NULL) {
+			if (unlikely(fbp == NULL)) {
+				foundhole = 1;
 				continue;
 			}
 			free = fbp->data;
@@ -1473,7 +1479,7 @@
 			 * one is empty, remember this slot.
 			 */
 			if (foundindex == -1 &&
-			    INT_GET(free->bests[findex], ARCH_CONVERT) == NULLDATAOFF) {
+			    INT_GET(free->bests[findex], ARCH_CONVERT) == NULLDATAOFF && !foundhole) {
 				foundindex = findex;
 				foundbno = fbno;
 			}
@@ -1487,7 +1493,8 @@
 				 * remember this slot.
 				 */
 				if (foundindex == -1 &&
-				    findex < XFS_DIR2_MAX_FREE_BESTS(mp)) {
+				    findex < XFS_DIR2_MAX_FREE_BESTS(mp) &&
+				    !foundhole) {
 					foundindex = findex;
 					foundbno = fbno;
 				}
@@ -1502,68 +1509,10 @@
 		}
 	}
 	/*
-	 * If we don't have a data block, and there's no free slot in a
-	 * freeblock, we need to add a new freeblock.
-	 */
-	if (dbno == -1 && foundindex == -1) {
-		/*
-		 * Not allowed to allocate, so return failure.
-		 */
-		if (args->justcheck || args->total == 0) {
-			return XFS_ERROR(ENOSPC);
-		}
-		/*
-		 * Add the new freeblock.
-		 */
-		if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE,
-				&fbno))) {
-			return error;
-		}
-		/*
-		 * Get a buffer for the new block.
-		 */
-		if ((error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fbno),
-				-1, &fbp, XFS_DATA_FORK))) {
-			return error;
-		}
-		ASSERT(fbp != NULL);
-		/*
-		 * Initialize the new block to be empty, and remember
-		 * its first slot as our empty slot.
-		 */
-		free = fbp->data;
-		INT_SET(free->hdr.magic, ARCH_CONVERT, XFS_DIR2_FREE_MAGIC);
-		INT_SET(free->hdr.firstdb, ARCH_CONVERT, (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) *
-			XFS_DIR2_MAX_FREE_BESTS(mp));
-		INT_ZERO(free->hdr.nused, ARCH_CONVERT);
-		INT_ZERO(free->hdr.nvalid, ARCH_CONVERT);
-		foundindex = 0;
-		foundbno = fbno;
-	}
-	/*
-	 * If we don't have a data block, and we don't have a freeblock buffer
-	 * in hand (we dropped the one with the free slot in it),
-	 * go read the freeblock again.
-	 */
-	if (dbno == -1 && fbp == NULL) {
-		/*
-		 * We're going to use the empty slot we found before.
-		 */
-		findex = foundindex;
-		fbno = foundbno;
-		if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fbno),
-				-1, &fbp, XFS_DATA_FORK))) {
-			return error;
-		}
-		ASSERT(fbp != NULL);
-		free = fbp->data;
-		ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
-	}
-	/*
 	 * If we don't have a data block, we need to allocate one and make
 	 * the freespace entries refer to it.
 	 */
-	if (dbno == -1) {
+	if (unlikely(dbno == -1)) {
 		/*
 		 * Not allowed to allocate, return failure.
 		 */
@@ -1572,7 +1521,7 @@
 			 * Drop the freespace buffer unless it came from our
 			 * caller.
 			 */
-			if (fblk == NULL || fblk->bp == NULL)
+			if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
 				xfs_da_buf_done(fbp);
 			return XFS_ERROR(ENOSPC);
 		}
@@ -1586,7 +1535,7 @@
 			 * Drop the freespace buffer unless it came from our
 			 * caller.
 			 */
-			if (fblk == NULL || fblk->bp == NULL)
+			if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
 				xfs_da_buf_done(fbp);
 			return error;
 		}
@@ -1595,21 +1544,80 @@
 		 * freespace block we have in hand, drop the one we have
 		 * and get the right one.
 		 */
-		if (XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno) {
-			xfs_da_brelse(tp, fbp);
+		needfreesp = 0;
+		if (XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno || fbp == NULL) {
+			if (fbp)
+				xfs_da_brelse(tp, fbp);
 			if (fblk && fblk->bp)
 				fblk->bp = NULL;
 			fbno = XFS_DIR2_DB_TO_FDB(mp, dbno);
 			if ((error = xfs_da_read_buf(tp, dp,
-					XFS_DIR2_DB_TO_DA(mp, fbno), -1, &fbp,
+					XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp,
 					XFS_DATA_FORK))) {
 				xfs_da_buf_done(dbp);
 				return error;
 			}
+
+			/*
+			 * If there wasn't a freespace block, the read will
+			 * return a NULL fbp.  Allocate one later.
+			 */
+
+			if(unlikely( fbp == NULL )) {
+				needfreesp = 1;
+			} else {
+				free = fbp->data;
+				ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
+			}
+		}
+
+		/*
+		 * If we don't have a data block, and there's no free slot in a
+		 * freeblock, we need to add a new freeblock.
+		 */
+		if (unlikely(needfreesp || foundindex == -1)) {
+			/*
+			 * Add the new freeblock.
+			 */
+			if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE,
+							&fbno))) {
+				return error;
+			}
+
+			if (XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno) {
+				cmn_err(CE_ALERT,
+		"xfs_dir2_node_addname_int: needed block %lld, got %lld\n",
+					XFS_DIR2_DB_TO_FDB(mp, dbno), fbno);
+				XFS_ERROR_REPORT("xfs_dir2_node_addname_int",
+						 XFS_ERRLEVEL_LOW, mp);
+				return XFS_ERROR(EFSCORRUPTED);
+			}
+
+			/*
+			 * Get a buffer for the new block.
+			 */
+			if ((error = xfs_da_get_buf(tp, dp,
+						   XFS_DIR2_DB_TO_DA(mp, fbno),
+						   -1, &fbp, XFS_DATA_FORK))) {
+				return error;
+			}
 			ASSERT(fbp != NULL);
+
+			/*
+			 * Initialize the new block to be empty, and remember
+			 * its first slot as our empty slot.
+			 */
 			free = fbp->data;
-			ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
+			INT_SET(free->hdr.magic, ARCH_CONVERT, XFS_DIR2_FREE_MAGIC);
+			INT_SET(free->hdr.firstdb, ARCH_CONVERT,
+				(fbno - XFS_DIR2_FREE_FIRSTDB(mp)) *
+				XFS_DIR2_MAX_FREE_BESTS(mp));
+			INT_ZERO(free->hdr.nvalid, ARCH_CONVERT);
+			INT_ZERO(free->hdr.nused, ARCH_CONVERT);
+			foundindex = 0;
+			foundbno = fbno;
 		}
+
 		/*
 		 * Set the freespace block index from the data block number.
 		 */
@@ -1651,16 +1659,17 @@
 		 * If just checking, we succeeded.
 		 */
 		if (args->justcheck) {
-			if (fblk == NULL || fblk->bp == NULL)
+			if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
 				xfs_da_buf_done(fbp);
 			return 0;
 		}
 		/*
 		 * Read the data block in.
 		 */
-		if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, dbno),
+		if (unlikely(
+		    error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, dbno),
 				-1, &dbp, XFS_DATA_FORK))) {
-			if (fblk == NULL || fblk->bp == NULL)
+			if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
 				xfs_da_buf_done(fbp);
 			return error;
 		}
@@ -1715,7 +1724,7 @@
 	/*
 	 * If the caller didn't hand us the freespace block, drop it.
 	 */
-	if (fblk == NULL || fblk->bp == NULL)
+	if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL)
 		xfs_da_buf_done(fbp);
 	/*
 	 * Return the data block and offset in args, then drop the data block.
@@ -1943,9 +1952,17 @@
 	/*
 	 * Read the freespace block.
 	 */
-	if ((error = xfs_da_read_buf(tp, dp, (xfs_dablk_t)fo, -1, &bp,
+	if (unlikely(error = xfs_da_read_buf(tp, dp, (xfs_dablk_t)fo, -2, &bp,
 			XFS_DATA_FORK))) {
 		return error;
+	}
+
+	/*
+	 * There can be holes in freespace.  If fo is a hole, there's
+	 * nothing to do.
+	 */
+	if (bp == NULL) {
+		return 0;
 	}
 	free = bp->data;
 	ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
diff -Nru a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
--- a/fs/xfs/xfs_dir2_sf.c	Mon Oct 14 14:06:33 2002
+++ b/fs/xfs/xfs_dir2_sf.c	Mon Mar 17 11:46:09 2003
@@ -752,14 +752,8 @@
 	if (dir_offset <=
 		    XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
 					       XFS_DIR2_DATA_DOT_OFFSET)) {
-		/*
-		 * NOTE! Linux "filldir" semantics require that the
-		 *	 offset "cookie" be for this entry, not the
-		 *	 next; all the actual shuffling to make it
-		 *	 "look right" to the user is done in filldir.
-		 */
 		p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, 0,
-						XFS_DIR2_DATA_DOT_OFFSET);
+						XFS_DIR2_DATA_DOTDOT_OFFSET);
 #if XFS_BIG_FILESYSTEMS
 		p.ino = dp->i_ino + mp->m_inoadd;
 #else
@@ -784,14 +778,8 @@
 	if (dir_offset <=
 		    XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
 					       XFS_DIR2_DATA_DOTDOT_OFFSET)) {
-		/*
-		 * NOTE! Linux "filldir" semantics require that the
-		 *	 offset "cookie" be for this entry, not the
-		 *	 next; all the actual shuffling to make it
-		 *	 "look right" to the user is done in filldir.
-		 */
 		p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
-						XFS_DIR2_DATA_DOTDOT_OFFSET);
+						XFS_DIR2_DATA_FIRST_OFFSET);
 #if XFS_BIG_FILESYSTEMS
 		p.ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp, &sfp->hdr.parent, ARCH_CONVERT) +
 			mp->m_inoadd;
@@ -826,14 +814,9 @@
 
 		p.namelen = sfep->namelen;
 
-		/*
-		 * NOTE! Linux "filldir" semantics require that the
-		 *	 offset "cookie" be for this entry, not the
-		 *	 next; all the actual shuffling to make it
-		 *	 "look right" to the user is done in filldir.
-		 */
 		p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
-				XFS_DIR2_SF_GET_OFFSET_ARCH(sfep, ARCH_CONVERT));
+			XFS_DIR2_SF_GET_OFFSET_ARCH(sfep, ARCH_CONVERT) +
+			XFS_DIR2_DATA_ENTSIZE(p.namelen));
 
 #if XFS_BIG_FILESYSTEMS
 		p.ino = XFS_DIR2_SF_GET_INUMBER_ARCH(sfp,
diff -Nru a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c
--- a/fs/xfs/xfs_dir_leaf.c	Tue Feb 25 02:47:50 2003
+++ b/fs/xfs/xfs_dir_leaf.c	Mon Mar 17 12:19:19 2003
@@ -103,10 +103,11 @@
 		agblkno != 0 &&
 		ioff < (1 << mp->m_sb.sb_inopblog) &&
 		XFS_AGINO_TO_INO(mp, agno, agino) == ino;
-	if (XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,
-			XFS_RANDOM_DIR_INO_VALIDATE)) {
+	if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,
+			XFS_RANDOM_DIR_INO_VALIDATE))) {
 		xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx",
 				(unsigned long long) ino);
+		XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 	return 0;
@@ -455,10 +456,13 @@
 	for (i = 0, sfe = &sf->list[0];
 			i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) {
 
-		if (((char *)sfe < (char *)sf) ||
+		if (unlikely(
+		    ((char *)sfe < (char *)sf) ||
 		    ((char *)sfe >= ((char *)sf + dp->i_df.if_bytes)) ||
-		    (sfe->namelen >= MAXNAMELEN)) {
+		    (sfe->namelen >= MAXNAMELEN))) {
 			xfs_dir_trace_g_du("sf: corrupted", dp, uio);
+			XFS_CORRUPTION_ERROR("xfs_dir_shortform_getdents", 
+					     XFS_ERRLEVEL_LOW, mp, sfe);
 			kmem_free(sbuf, sbsize);
 			return XFS_ERROR(EFSCORRUPTED);
 		}
@@ -1970,9 +1974,12 @@
 		namest = XFS_DIR_LEAF_NAMESTRUCT(leaf,
 				    INT_GET(entry->nameidx, ARCH_CONVERT));
 
-		if (((char *)namest < (char *)leaf) ||
+		if (unlikely(
+		    ((char *)namest < (char *)leaf) ||
 		    ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)) ||
-		    (entry->namelen >= MAXNAMELEN)) {
+		    (entry->namelen >= MAXNAMELEN))) {
+			XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(1)", 
+					     XFS_ERRLEVEL_LOW, mp, leaf);
 			xfs_dir_trace_g_du("leaf: corrupted", dp, uio);
 			return XFS_ERROR(EFSCORRUPTED);
 		}
@@ -2031,9 +2038,12 @@
 		namest = XFS_DIR_LEAF_NAMESTRUCT(leaf,
 				    INT_GET(entry->nameidx, ARCH_CONVERT));
 
-		if (((char *)namest < (char *)leaf) ||
+		if (unlikely(
+		    ((char *)namest < (char *)leaf) ||
 		    ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)) ||
-		    (entry->namelen >= MAXNAMELEN)) {
+		    (entry->namelen >= MAXNAMELEN))) {
+			XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(2)",
+					     XFS_ERRLEVEL_LOW, mp, leaf);
 			xfs_dir_trace_g_du("leaf: corrupted", dp, uio);
 			return XFS_ERROR(EFSCORRUPTED);
 		}
@@ -2076,11 +2086,14 @@
 
 			leaf2 = bp2->data;
 
-			if (   (INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT)
+			if (unlikely(
+			       (INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT)
 						!= XFS_DIR_LEAF_MAGIC)
 			    || (INT_GET(leaf2->hdr.info.back, ARCH_CONVERT)
-						!= bno)) {	/* GROT */
-
+						!= bno))) {	/* GROT */
+				XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(3)",
+						     XFS_ERRLEVEL_LOW, mp,
+						     leaf2);
 				xfs_da_brelse(dp->i_transp, bp2);
 
 				return(XFS_ERROR(EFSCORRUPTED));
diff -Nru a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
--- a/fs/xfs/xfs_error.c	Tue Dec  3 13:21:48 2002
+++ b/fs/xfs/xfs_error.c	Mon Mar 17 13:08:03 2003
@@ -238,3 +238,79 @@
 	xfs_fs_vcmn_err(level, mp, fmt, ap);
 	va_end(ap);
 }
+
+void
+xfs_stack_trace(void)
+{
+	dump_stack();
+}
+
+void
+xfs_error_report(
+	char		*tag,
+	int		level,
+	xfs_mount_t	*mp,
+	char		*fname,
+	int		linenum,
+	inst_t		*ra)
+{
+	if (level <= xfs_error_level) {
+		if (mp != NULL) {
+			xfs_cmn_err(XFS_PTAG_ERROR_REPORT,
+				    CE_ALERT, mp,
+		"XFS internal error %s at line %d of file %s.  Caller 0x%x\n",
+				    tag, linenum, fname, ra);
+		} else {
+			cmn_err(CE_ALERT,
+		"XFS internal error %s at line %d of file %s.  Caller 0x%x\n",
+				tag, linenum, fname, ra);
+		}
+
+		xfs_stack_trace();
+	}
+}
+
+void
+xfs_hex_dump(void *p, int length)
+{
+	__uint8_t *uip = (__uint8_t*)p;
+	int	i;
+	char	sbuf[128], *s;
+	
+	s = sbuf;
+	*s = '\0';
+	for (i=0; i<length; i++, uip++) {
+		if ((i % 16) == 0) {
+			if (*s != '\0')
+				cmn_err(CE_ALERT, "%s\n", sbuf);
+			s = sbuf;
+			sprintf(s, "0x%x: ", i);
+			while( *s != '\0')
+				s++;
+		}
+		sprintf(s, "%02x ", *uip);
+
+		/*
+		 * the kernel sprintf is a void; user sprintf returns
+		 * the sprintf'ed string's length.  Find the new end-
+		 * of-string
+		 */
+		while( *s != '\0')
+			s++;
+	}
+	cmn_err(CE_ALERT, "%s\n", sbuf);
+}
+
+void
+xfs_corruption_error(
+	char		*tag,
+	int		level,
+	xfs_mount_t	*mp,
+	void		*p,
+	char		*fname,
+	int		linenum,
+	inst_t		*ra)
+{
+	xfs_hex_dump(p, 16);
+	xfs_error_report(tag, level, mp, fname, linenum, ra);
+}
diff -Nru a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
--- a/fs/xfs/xfs_error.h	Wed Feb 19 09:21:32 2003
+++ b/fs/xfs/xfs_error.h	Mon Mar 17 12:57:02 2003
@@ -52,6 +52,39 @@
 #define XFS_ERROR(e)	(e)
 #endif
 
+struct xfs_mount;
+
+extern void
+xfs_error_report(
+	char		*tag,
+	int		level,
+	struct xfs_mount *mp,
+	char		*fname,
+	int		linenum,
+	inst_t		*ra);
+
+extern void
+xfs_corruption_error(
+	char		*tag,
+	int		level,
+	struct xfs_mount *mp,
+	void		*p,
+	char		*fname,
+	int		linenum,
+	inst_t		*ra);
+
+extern void
+xfs_hex_dump(void *p, int length);
+
+#define	XFS_ERROR_REPORT(e, lvl, mp)	\
+	xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address)
+#define	XFS_CORRUPTION_ERROR(e, lvl, mp, mem)	\
+	xfs_corruption_error(e, lvl, mp, mem, \
+			     __FILE__, __LINE__, __return_address)
+
+#define XFS_ERRLEVEL_OFF	0
+#define XFS_ERRLEVEL_LOW	1
+#define XFS_ERRLEVEL_HIGH	5
 
 /*
  * error injection tags - the labels can be anything you want
@@ -79,7 +112,8 @@
 #define XFS_ERRTAG_STRATREAD_IOERR			18
 #define XFS_ERRTAG_STRATCMPL_IOERR			19
 #define XFS_ERRTAG_DIOWRITE_IOERR			20
-#define XFS_ERRTAG_MAX					21
+#define XFS_ERRTAG_BMAPIFORMAT				21
+#define XFS_ERRTAG_MAX					22
 
 /*
  * Random factors for above tags, 1 means always, 2 means 1/2 time, etc.
@@ -105,6 +139,7 @@
 #define XFS_RANDOM_STRATREAD_IOERR			(XFS_RANDOM_DEFAULT/10)
 #define XFS_RANDOM_STRATCMPL_IOERR			(XFS_RANDOM_DEFAULT/10)
 #define XFS_RANDOM_DIOWRITE_IOERR			(XFS_RANDOM_DEFAULT/10)
+#define	XFS_RANDOM_BMAPIFORMAT				XFS_RANDOM_DEFAULT
 
 #if (defined(DEBUG) || defined(INDUCE_IO_ERROR))
 extern int	xfs_error_test(int, int *, char *, int, char *, unsigned long);
@@ -146,7 +181,7 @@
 #define		XFS_PTAG_IFLUSH			0x0000000000000001LL
 #define		XFS_PTAG_LOGRES			0x0000000000000002LL
 #define		XFS_PTAG_AILDELETE		0x0000000000000004LL
-#define		XFS_PTAG_AVAILABLE		0x0000000000000008LL
+#define		XFS_PTAG_ERROR_REPORT		0x0000000000000008LL
 #define		XFS_PTAG_SHUTDOWN_CORRUPT	0x0000000000000010LL
 #define		XFS_PTAG_SHUTDOWN_IOERROR	0x0000000000000020LL
 #define		XFS_PTAG_SHUTDOWN_LOGERROR	0x0000000000000040LL
diff -Nru a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
--- a/fs/xfs/xfs_ialloc.c	Tue Dec  3 13:14:52 2002
+++ b/fs/xfs/xfs_ialloc.c	Mon Mar 17 12:19:20 2003
@@ -1303,14 +1303,11 @@
 		INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC &&
 		XFS_AGI_GOOD_VERSION(
 			INT_GET(agi->agi_versionnum, ARCH_CONVERT));
-	if (XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
-			XFS_RANDOM_IALLOC_READ_AGI)) {
+	if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
+			XFS_RANDOM_IALLOC_READ_AGI))) {
+		XFS_CORRUPTION_ERROR("xfs_ialloc_read_agi", XFS_ERRLEVEL_LOW,
+				     mp, agi);
 		xfs_trans_brelse(tp, bp);
-#ifdef __KERNEL__	/* additional, temporary, debugging code */
-		cmn_err(CE_NOTE,
-			"EFSCORRUPTED returned from file %s line %d",
-			__FILE__, __LINE__);
-#endif
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 	pag = &mp->m_perag[agno];
diff -Nru a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
--- a/fs/xfs/xfs_iget.c	Fri Dec 20 12:03:56 2002
+++ b/fs/xfs/xfs_iget.c	Mon Mar 17 12:11:38 2003
@@ -422,7 +422,6 @@
 		vp = LINVFS_GET_VP(inode);
 		if (inode->i_state & I_NEW) {
 inode_allocate:
-			XFS_STATS_INC(xfsstats.vn_alloc);
 			vn_initialize(inode);
 			error = xfs_iget_core(vp, mp, tp, ino,
 							lock_flags, ipp, bno);
diff -Nru a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
--- a/fs/xfs/xfs_inode.c	Tue Feb 25 10:47:18 2003
+++ b/fs/xfs/xfs_inode.c	Mon Mar 17 13:29:01 2003
@@ -31,6 +31,7 @@
  */
 
 #include <xfs.h>
+#include <asm/unaligned.h>	/* for get_unaligned, put_unaligned */
 
 
 kmem_zone_t *xfs_ifork_zone;
@@ -226,8 +227,9 @@
 	di_ok =
 		INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC &&
 		XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT));
-	if (XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
-			XFS_RANDOM_ITOBP_INOTOBP)) {
+	if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
+			XFS_RANDOM_ITOBP_INOTOBP))) {
+		XFS_CORRUPTION_ERROR("xfs_inotobp", XFS_ERRLEVEL_LOW, mp, dip);
 		xfs_trans_brelse(tp, bp);
 		cmn_err(CE_WARN,
 	"xfs_inotobp: XFS_TEST_ERROR()	returned an "
@@ -369,13 +371,15 @@
 					(i << mp->m_sb.sb_inodelog));
 		di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC &&
 			    XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT));
-		if (XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
-				 XFS_RANDOM_ITOBP_INOTOBP)) {
+		if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
+				 XFS_RANDOM_ITOBP_INOTOBP))) {
 #ifdef DEBUG
 			prdev("bad inode magic/vsn daddr 0x%llx #%d (magic=%x)",
 				mp->m_dev, (unsigned long long)imap.im_blkno, i,
 				INT_GET(dip->di_core.di_magic, ARCH_CONVERT));
 #endif
+			XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_LOW,
+					     mp, dip);
 			xfs_trans_brelse(tp, bp);
 			return XFS_ERROR(EFSCORRUPTED);
 		}
@@ -419,9 +423,10 @@
 		XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
 	error = 0;
 
-	if (INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) +
+	if (unlikely(
+	    INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) +
 		INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) >
-	    INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT)) {
+	    INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT))) {
 		xfs_fs_cmn_err(CE_WARN, ip->i_mount,
 			"corrupt dinode %Lu, extent total = %d, nblocks = %Lu."
 			"  Unmount and run xfs_repair.",
@@ -430,15 +435,19 @@
 			    + INT_GET(dip->di_core.di_anextents, ARCH_CONVERT)),
 			(unsigned long long)
 			INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT));
+		XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW,
+				     ip->i_mount, dip);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 
-	if (INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize) {
+	if (unlikely(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize)) {
 		xfs_fs_cmn_err(CE_WARN, ip->i_mount,
 			"corrupt dinode %Lu, forkoff = 0x%x."
 			"  Unmount and run xfs_repair.",
 			(unsigned long long)ip->i_ino,
 			(int)(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT)));
+		XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW,
+				     ip->i_mount, dip);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 
@@ -447,8 +456,11 @@
 	case IFCHR:
 	case IFBLK:
 	case IFSOCK:
-		if (INT_GET(dip->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_DEV)
+		if (unlikely(INT_GET(dip->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_DEV)) {
+			XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW,
+					      ip->i_mount, dip);
 			return XFS_ERROR(EFSCORRUPTED);
+		}
 		ip->i_d.di_size = 0;
 		ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT);
 		break;
@@ -461,24 +473,26 @@
 			/*
 			 * no local regular files yet
 			 */
-			if ((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & IFMT) == IFREG) {
+			if (unlikely((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & IFMT) == IFREG)) {
 				xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-					"corrupt inode "
-					"(local format for regular file) %Lu.  "
-					"Unmount and run xfs_repair.",
+					"corrupt inode (local format for regular file) %Lu.  Unmount and run xfs_repair.",
 					(unsigned long long) ip->i_ino);
+				XFS_CORRUPTION_ERROR("xfs_iformat(4)",
+						     XFS_ERRLEVEL_LOW,
+						     ip->i_mount, dip);
 				return XFS_ERROR(EFSCORRUPTED);
 			}
 
 			di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT);
-			if (di_size >
-			    XFS_DFORK_DSIZE_ARCH(dip, ip->i_mount, ARCH_CONVERT)) {
+			if (unlikely(di_size >
+			    XFS_DFORK_DSIZE_ARCH(dip, ip->i_mount, ARCH_CONVERT))) {
 				xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-					"corrupt inode %Lu "
-					"(bad size %Ld for local inode).  "
-					"Unmount and run xfs_repair.",
+					"corrupt inode %Lu (bad size %Ld for local inode).  Unmount and run xfs_repair.",
 					(unsigned long long) ip->i_ino,
 					(long long) di_size);
+				XFS_CORRUPTION_ERROR("xfs_iformat(5)",
+						     XFS_ERRLEVEL_LOW,
+						     ip->i_mount, dip);
 				return XFS_ERROR(EFSCORRUPTED);
 			}
 
@@ -492,11 +506,14 @@
 			error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
 			break;
 		default:
+			XFS_ERROR_REPORT("xfs_iformat(6)", XFS_ERRLEVEL_LOW,
+					 ip->i_mount);
 			return XFS_ERROR(EFSCORRUPTED);
 		}
 		break;
 
 	default:
+		XFS_ERROR_REPORT("xfs_iformat(7)", XFS_ERRLEVEL_LOW, ip->i_mount);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 	if (error) {
@@ -557,13 +574,13 @@
 	 * is wrong and we just bail out rather than crash in
 	 * kmem_alloc() or memcpy() below.
 	 */
-	if (size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT)) {
+	if (unlikely(size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT))) {
 		xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-			"corrupt inode %Lu "
-			"(bad size %d for local fork, size = %d).  "
-			"Unmount and run xfs_repair.",
+			"corrupt inode %Lu (bad size %d for local fork, size = %d).  Unmount and run xfs_repair.",
 			(unsigned long long) ip->i_ino, size,
 			XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT));
+		XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW,
+				     ip->i_mount, dip);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 	ifp = XFS_IFORK_PTR(ip, whichfork);
@@ -619,11 +636,12 @@
 	 * is wrong and we just bail out rather than crash in
 	 * kmem_alloc() or memcpy() below.
 	 */
-	if (size < 0 || size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT)) {
+	if (unlikely(size < 0 || size > XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT))) {
 		xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-			"corrupt inode %Lu ((a)extents = %d).  "
-			"Unmount and run xfs_repair.",
+			"corrupt inode %Lu ((a)extents = %d).  Unmount and run xfs_repair.",
 			(unsigned long long) ip->i_ino, nex);
+		XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW,
+				     ip->i_mount, dip);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 
@@ -647,8 +665,10 @@
 		ep = ifp->if_u1.if_extents;
 #if ARCH_CONVERT != ARCH_NOCONVERT
 		for (i = 0; i < nex; i++, ep++, dp++) {
-			ep->l0 = INT_GET(dp->l0, ARCH_CONVERT);
-			ep->l1 = INT_GET(dp->l1, ARCH_CONVERT);
+			ep->l0 = INT_GET(get_unaligned((u64*)&dp->l0),
+								ARCH_CONVERT);
+			ep->l1 = INT_GET(get_unaligned((u64*)&dp->l1),
+								ARCH_CONVERT);
 		}
 #else
 		memcpy(ep, dp, size);
@@ -657,9 +677,13 @@
 			whichfork);
 		if (whichfork != XFS_DATA_FORK ||
 			XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE)
-				if (xfs_check_nostate_extents(
-				    ifp->if_u1.if_extents, nex))
+				if (unlikely(xfs_check_nostate_extents(
+				    ifp->if_u1.if_extents, nex))) {
+					XFS_ERROR_REPORT("xfs_iformat_extents(2)",
+							 XFS_ERRLEVEL_LOW,
+							 ip->i_mount);
 					return XFS_ERROR(EFSCORRUPTED);
+				}
 	}
 	ifp->if_flags |= XFS_IFEXTENTS;
 	return 0;
@@ -697,14 +721,15 @@
 	 * or the number of extents is greater than the number of
 	 * blocks.
 	 */
-	if (XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max
+	if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max
 	    || XFS_BMDR_SPACE_CALC(nrecs) >
 			XFS_DFORK_SIZE_ARCH(dip, ip->i_mount, whichfork, ARCH_CONVERT)
-	    || XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks) {
+	    || XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) {
 		xfs_fs_cmn_err(CE_WARN, ip->i_mount,
-			"corrupt inode %Lu (btree).  "
-			"Unmount and run xfs_repair.",
+			"corrupt inode %Lu (btree).  Unmount and run xfs_repair.",
 			(unsigned long long) ip->i_ino);
+		XFS_ERROR_REPORT("xfs_iformat_btree", XFS_ERRLEVEL_LOW,
+				 ip->i_mount);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 
@@ -975,8 +1000,11 @@
 	xfs_ifork_t	*ifp;
 	size_t		size;
 
-	if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)
+	if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
+		XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW,
+				 ip->i_mount);
 		return XFS_ERROR(EFSCORRUPTED);
+	}
 	size = XFS_IFORK_NEXTENTS(ip, whichfork) * (uint)sizeof(xfs_bmbt_rec_t);
 	ifp = XFS_IFORK_PTR(ip, whichfork);
 	/*
@@ -1817,8 +1845,9 @@
 	agi_ok =
 		INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC &&
 		XFS_AGI_GOOD_VERSION(INT_GET(agi->agi_versionnum, ARCH_CONVERT));
-	if (XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK,
-			XFS_RANDOM_IUNLINK)) {
+	if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK,
+			XFS_RANDOM_IUNLINK))) {
+		XFS_CORRUPTION_ERROR("xfs_iunlink", XFS_ERRLEVEL_LOW, mp, agi);
 		xfs_trans_brelse(tp, agibp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
@@ -1919,8 +1948,10 @@
 	agi_ok =
 		INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC &&
 		XFS_AGI_GOOD_VERSION(INT_GET(agi->agi_versionnum, ARCH_CONVERT));
-	if (XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK_REMOVE,
-			XFS_RANDOM_IUNLINK_REMOVE)) {
+	if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK_REMOVE,
+			XFS_RANDOM_IUNLINK_REMOVE))) {
+		XFS_CORRUPTION_ERROR("xfs_iunlink_remove", XFS_ERRLEVEL_LOW,
+				     mp, agi);
 		xfs_trans_brelse(tp, agibp);
 		cmn_err(CE_WARN,
 			"xfs_iunlink_remove: XFS_TEST_ERROR()  returned an error on %s.	 Returning EFSCORRUPTED.",
@@ -2676,8 +2707,10 @@
 
 #if ARCH_CONVERT != ARCH_NOCONVERT
 		/* Translate to on disk format */
-		dest_ep->l0 = INT_GET(ep->l0, ARCH_CONVERT);
-		dest_ep->l1 = INT_GET(ep->l1, ARCH_CONVERT);
+		put_unaligned(INT_GET(ep->l0, ARCH_CONVERT),
+			      (u64*)&dest_ep->l0);
+		put_unaligned(INT_GET(ep->l1, ARCH_CONVERT),
+			      (u64*)&dest_ep->l1);
 #else
 		*dest_ep = *ep;
 #endif
@@ -2745,7 +2778,9 @@
 			memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
 		}
 		if (whichfork == XFS_DATA_FORK) {
-			if (XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip)) {
+			if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) {
+				XFS_ERROR_REPORT("xfs_iflush_fork",
+						 XFS_ERRLEVEL_LOW, mp);
 				return XFS_ERROR(EFSCORRUPTED);
 			}
 		}
diff -Nru a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
--- a/fs/xfs/xfs_log.c	Wed Feb 19 09:26:03 2003
+++ b/fs/xfs/xfs_log.c	Mon Mar 17 12:13:54 2003
@@ -62,10 +62,6 @@
 /* local state machine functions */
 STATIC void xlog_state_done_syncing(xlog_in_core_t *iclog, int);
 STATIC void xlog_state_do_callback(xlog_t *log,int aborted, xlog_in_core_t *iclog);
-static inline void xlog_state_finish_copy(xlog_t	*log,
-					xlog_in_core_t	*iclog,
-					int		first_write,
-					int		bytes);
 STATIC int  xlog_state_get_iclog_space(xlog_t		*log,
 				       int		len,
 				       xlog_in_core_t	**iclog,
@@ -876,7 +872,7 @@
  * We may be holding the log iclog lock upon entering this routine.
  */
 xfs_lsn_t
-xlog_assign_tail_lsn(xfs_mount_t *mp, xlog_in_core_t *iclog)
+xlog_assign_tail_lsn(xfs_mount_t *mp)
 {
 	xfs_lsn_t tail_lsn;
 	SPLDECL(s);
@@ -888,8 +884,6 @@
 		log->l_tail_lsn = tail_lsn;
 	else
 		tail_lsn = log->l_tail_lsn = log->l_last_sync_lsn;
-	if (iclog)
-		INT_SET(iclog->ic_header.h_tail_lsn, ARCH_CONVERT, tail_lsn);
 	GRANT_UNLOCK(log, s);
 
 	return tail_lsn;
@@ -1402,7 +1396,7 @@
 {
 	xfs_caddr_t	dptr;		/* pointer to byte sized element */
 	xfs_buf_t	*bp;
-	int		i;
+	int		i, ops;
 	uint		roundup;
 	uint		count;		/* byte count of bwrite */
 	int		split = 0;	/* split write into two regions */
@@ -1439,7 +1433,12 @@
 	log->l_roundoff += iclog->ic_roundoff;
 
 	xlog_pack_data(log, iclog);	  /* put cycle number in every block */
-	INT_SET(iclog->ic_header.h_len, ARCH_CONVERT, iclog->ic_offset);	/* real byte length */
+
+	/* real byte length */
+	INT_SET(iclog->ic_header.h_len, ARCH_CONVERT, iclog->ic_offset);
+	/* put ops count in correct order */
+	ops = iclog->ic_header.h_num_logops;
+	INT_SET(iclog->ic_header.h_num_logops, ARCH_CONVERT, ops);
 
 	bp	    = iclog->ic_bp;
 	ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long)1);
@@ -1596,6 +1595,28 @@
 	kmem_free(log, sizeof(xlog_t));
 }	/* xlog_unalloc_log */
 
+/*
+ * Update counters atomically now that memcpy is done.
+ */
+/* ARGSUSED */
+static inline void
+xlog_state_finish_copy(xlog_t		*log,
+		       xlog_in_core_t	*iclog,
+		       int		record_cnt,
+		       int		copy_bytes)
+{
+	SPLDECL(s);
+
+	s = LOG_LOCK(log);
+
+	iclog->ic_header.h_num_logops += record_cnt;
+	iclog->ic_offset += copy_bytes;
+
+	LOG_UNLOCK(log, s);
+}	/* xlog_state_finish_copy */
+
+
+
 
 /*
  * Write some region out to in-core log
@@ -1663,6 +1684,7 @@
     int		     contwr;	     /* continued write of in-core log? */
     int		     firstwr = 0;    /* first write of transaction */
     int		     error;
+    int		     record_cnt = 0, data_cnt = 0;
 
     partial_copy_len = partial_copy = 0;
 
@@ -1725,7 +1747,8 @@
 		logop_head->oh_flags	= XLOG_START_TRANS;
 		INT_ZERO(logop_head->oh_res2, ARCH_CONVERT);
 		ticket->t_flags		&= ~XLOG_TIC_INITED;	/* clear bit */
-		firstwr++;			  /* increment log ops below */
+		firstwr = 1;			  /* increment log ops below */
+		record_cnt++;
 
 		start_rec_copy = sizeof(xlog_op_header_t);
 		xlog_write_adv_cnt(ptr, len, log_offset, start_rec_copy);
@@ -1793,10 +1816,13 @@
 
 	    /* make copy_len total bytes copied, including headers */
 	    copy_len += start_rec_copy + sizeof(xlog_op_header_t);
-	    xlog_state_finish_copy(log, iclog, firstwr, (contwr? copy_len : 0));
+	    record_cnt++;
+	    data_cnt += contwr ? copy_len : 0;
 	    firstwr = 0;
 	    if (partial_copy) {			/* copied partial region */
 		    /* already marked WANT_SYNC by xlog_state_get_iclog_space */
+		    xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
+		    record_cnt = data_cnt = 0;
 		    if ((error = xlog_state_release_iclog(log, iclog)))
 			    return (error);
 		    break;			/* don't increment index */
@@ -1805,6 +1831,8 @@
 		partial_copy_len = partial_copy = 0;
 
 		if (iclog->ic_size - log_offset <= sizeof(xlog_op_header_t)) {
+		    xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
+		    record_cnt = data_cnt = 0;
 		    xlog_state_want_sync(log, iclog);
 		    if (commit_iclog) {
 			ASSERT(flags & XLOG_COMMIT_TRANS);
@@ -1821,6 +1849,7 @@
     } /* for (index = 0; index < nentries; ) */
     ASSERT(len == 0);
 
+    xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
     if (commit_iclog) {
 	ASSERT(flags & XLOG_COMMIT_TRANS);
 	*commit_iclog = iclog;
@@ -2208,30 +2237,6 @@
 
 
 /*
- * Update counters atomically now that memcpy is done.
- */
-/* ARGSUSED */
-static inline void
-xlog_state_finish_copy(xlog_t		*log,
-		       xlog_in_core_t	*iclog,
-		       int		first_write,
-		       int		copy_bytes)
-{
-	SPLDECL(s);
-
-	s = LOG_LOCK(log);
-
-	if (first_write)
-		INT_MOD(iclog->ic_header.h_num_logops, ARCH_CONVERT, +1);
-	INT_MOD(iclog->ic_header.h_num_logops, ARCH_CONVERT, +1);
-	iclog->ic_offset += copy_bytes;
-
-	LOG_UNLOCK(log, s);
-}	/* xlog_state_finish_copy */
-
-
-
-/*
  * If the head of the in-core log ring is not (ACTIVE or DIRTY), then we must
  * sleep.  The flush semaphore is set to the number of in-core buffers and
  * decremented around disk syncing.  Therefore, if all buffers are syncing,
@@ -2722,7 +2727,7 @@
 	SPLDECL(s);
 	int		sync = 0;	/* do we sync? */
 
-	xlog_assign_tail_lsn(log->l_mp, 0);
+	xlog_assign_tail_lsn(log->l_mp);
 
 	s = LOG_LOCK(log);
 
@@ -3594,7 +3599,10 @@
 
 	iclog = log->l_iclog;
 	do {
-		if (INT_GET(iclog->ic_header.h_num_logops, ARCH_CONVERT))
+		/* endianness does not matter here, zero is zero in
+		 * any language.
+		 */
+		if (iclog->ic_header.h_num_logops)
 			return(0);
 		iclog = iclog->ic_next;
 	} while (iclog != log->l_iclog);
diff -Nru a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
--- a/fs/xfs/xfs_log_priv.h	Tue Dec  3 13:37:29 2002
+++ b/fs/xfs/xfs_log_priv.h	Mon Mar 17 12:13:54 2003
@@ -536,8 +536,7 @@
 
 
 /* common routines */
-extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp,
-				      xlog_in_core_t *iclog);
+extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
 extern int	 xlog_find_head(xlog_t *log, xfs_daddr_t *head_blk);
 extern int	 xlog_find_tail(xlog_t	*log,
 				xfs_daddr_t *head_blk,
diff -Nru a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
--- a/fs/xfs/xfs_log_recover.c	Wed Feb 19 09:15:46 2003
+++ b/fs/xfs/xfs_log_recover.c	Mon Mar 17 13:48:29 2003
@@ -166,17 +166,21 @@
      * a dirty log created in IRIX.
      */
 
-    if (INT_GET(head->h_fmt, ARCH_CONVERT) != XLOG_FMT) {
+    if (unlikely(INT_GET(head->h_fmt, ARCH_CONVERT) != XLOG_FMT)) {
 	xlog_warn("XFS: dirty log written in incompatible format - can't recover");
 #ifdef DEBUG
 	xlog_header_check_dump(mp, head);
 #endif
+	XFS_ERROR_REPORT("xlog_header_check_recover(1)",
+			 XFS_ERRLEVEL_HIGH, mp);
 	return XFS_ERROR(EFSCORRUPTED);
-    } else if (!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid)) {
+    } else if (unlikely(!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid))) {
 	xlog_warn("XFS: dirty log entry has mismatched uuid - can't recover");
 #ifdef DEBUG
 	xlog_header_check_dump(mp, head);
 #endif
+	XFS_ERROR_REPORT("xlog_header_check_recover(2)",
+			 XFS_ERRLEVEL_HIGH, mp);
 	return XFS_ERROR(EFSCORRUPTED);
     }
 
@@ -202,11 +206,13 @@
 
 	xlog_warn("XFS: nil uuid in log - IRIX style log");
 
-    } else if (!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid)) {
+    } else if (unlikely(!uuid_equal(&mp->m_sb.sb_uuid, &head->h_fs_uuid))) {
 	xlog_warn("XFS: log has mismatched uuid - can't recover");
 #ifdef DEBUG
 	xlog_header_check_dump(mp, head);
 #endif
+	XFS_ERROR_REPORT("xlog_header_check_mount",
+			 XFS_ERRLEVEL_HIGH, mp);
 	return XFS_ERROR(EFSCORRUPTED);
     }
 
@@ -1113,8 +1119,11 @@
 		 * the distance from the beginning of the log to the
 		 * tail.
 		 */
-		if (head_block < tail_block || head_block >= log->l_logBBsize)
+		if (unlikely(head_block < tail_block || head_block >= log->l_logBBsize)) {
+			XFS_ERROR_REPORT("xlog_clear_stale_blocks(1)",
+					 XFS_ERRLEVEL_LOW, log->l_mp);
 			return XFS_ERROR(EFSCORRUPTED);
+		}
 		tail_distance = tail_block + (log->l_logBBsize - head_block);
 	} else {
 		/*
@@ -1122,8 +1131,11 @@
 		 * so the distance from the head to the tail is just
 		 * the tail block minus the head block.
 		 */
-		if (head_block >= tail_block || head_cycle != (tail_cycle + 1))
+		if (unlikely(head_block >= tail_block || head_cycle != (tail_cycle + 1))){
+			XFS_ERROR_REPORT("xlog_clear_stale_blocks(2)",
+					 XFS_ERRLEVEL_LOW, log->l_mp);
 			return XFS_ERROR(EFSCORRUPTED);
+		}
 		tail_distance = tail_block - head_block;
 	}
 
@@ -1732,10 +1744,12 @@
 		logged_nextp = (xfs_agino_t *)
 			       ((char *)(item->ri_buf[item_index].i_addr) +
 				(next_unlinked_offset - reg_buf_offset));
-		if (*logged_nextp == 0)	 {
+		if (unlikely(*logged_nextp == 0)) {
 			xfs_fs_cmn_err(CE_ALERT, mp,
 				"bad inode buffer log record (ptr = 0x%p, bp = 0x%p).  XFS trying to replay bad (0) inode di_next_unlinked field",
 				item, bp);
+			XFS_ERROR_REPORT("xlog_recover_do_inode_buf",
+					 XFS_ERRLEVEL_LOW, mp);
 			return XFS_ERROR(EFSCORRUPTED);
 		}
 
@@ -1933,6 +1947,8 @@
 		xfs_fs_cmn_err(CE_ALERT, log->l_mp,
 			"xfs_log_recover: unknown buffer type 0x%x, dev 0x%x",
 			buf_f->blf_type, log->l_dev);
+		XFS_ERROR_REPORT("xlog_recover_do_buffer_trans",
+				 XFS_ERRLEVEL_LOW, log->l_mp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 
@@ -2038,7 +2054,6 @@
 		imap.im_blkno = 0;
 		xfs_imap(log->l_mp, 0, ino, &imap, 0);
 	}
-
 	bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len,
 								XFS_BUF_LOCK);
 	if (XFS_BUF_ISERROR(bp)) {
@@ -2049,7 +2064,6 @@
 		return error;
 	}
 	error = 0;
-	xfs_inobp_check(mp, bp);
 	ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
 	dip = (xfs_dinode_t *)xfs_buf_offset(bp, imap.im_boffset);
 
@@ -2057,34 +2071,42 @@
 	 * Make sure the place we're flushing out to really looks
 	 * like an inode!
 	 */
-	if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) {
+	if (unlikely(INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC)) {
 		xfs_buf_relse(bp);
 		xfs_fs_cmn_err(CE_ALERT, mp,
 			"xfs_inode_recover: Bad inode magic number, dino ptr = 0x%p, dino bp = 0x%p, ino = %Ld",
 			dip, bp, ino);
+		XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)",
+				 XFS_ERRLEVEL_LOW, mp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 	dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr);
-	if (dicp->di_magic != XFS_DINODE_MAGIC) {
+	if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
 		xfs_buf_relse(bp);
 		xfs_fs_cmn_err(CE_ALERT, mp,
 			"xfs_inode_recover: Bad inode log record, rec ptr 0x%p, ino %Ld",
 			item, ino);
+		XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)",
+				 XFS_ERRLEVEL_LOW, mp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
-	if ((dicp->di_mode & IFMT) == IFREG) {
+	if (unlikely((dicp->di_mode & IFMT) == IFREG)) {
 		if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
 		    (dicp->di_format != XFS_DINODE_FMT_BTREE)) {
+			XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(3)",
+					 XFS_ERRLEVEL_LOW, mp, dicp);
 			xfs_buf_relse(bp);
 			xfs_fs_cmn_err(CE_ALERT, mp,
 				"xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
 				item, dip, bp, ino);
 			return XFS_ERROR(EFSCORRUPTED);
 		}
-	} else if ((dicp->di_mode & IFMT) == IFDIR) {
+	} else if (unlikely((dicp->di_mode & IFMT) == IFDIR)) {
 		if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
 		    (dicp->di_format != XFS_DINODE_FMT_BTREE) &&
 		    (dicp->di_format != XFS_DINODE_FMT_LOCAL)) {
+			XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(4)",
+					     XFS_ERRLEVEL_LOW, mp, dicp);
 			xfs_buf_relse(bp);
 			xfs_fs_cmn_err(CE_ALERT, mp,
 				"xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
@@ -2092,7 +2114,9 @@
 			return XFS_ERROR(EFSCORRUPTED);
 		}
 	}
-	if (dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks) {
+	if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){
+		XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(5)",
+				     XFS_ERRLEVEL_LOW, mp, dicp);
 		xfs_buf_relse(bp);
 		xfs_fs_cmn_err(CE_ALERT, mp,
 			"xfs_inode_recover: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld",
@@ -2101,14 +2125,18 @@
 			dicp->di_nblocks);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
-	if (dicp->di_forkoff > mp->m_sb.sb_inodesize) {
+	if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) {
+		XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)",
+				     XFS_ERRLEVEL_LOW, mp, dicp);
 		xfs_buf_relse(bp);
 		xfs_fs_cmn_err(CE_ALERT, mp,
 			"xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x",
 			item, dip, bp, ino, dicp->di_forkoff);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
-	if (item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t)) {
+	if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) {
+		XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)",
+				     XFS_ERRLEVEL_LOW, mp, dicp);
 		xfs_buf_relse(bp);
 		xfs_fs_cmn_err(CE_ALERT, mp,
 			"xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p",
@@ -2207,14 +2235,6 @@
 
 
 write_inode_buffer:
-#if 0
-	/*
-	 * Can't do this if the transaction didn't log the current
-	 * contents, e.g. rmdir.
-	 */
-	XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip);
-#endif
-	xfs_inobp_check(mp, bp);
 	if (ITEM_TYPE(item) == XFS_LI_INODE) {
 		ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL ||
 		       XFS_BUF_FSPRIVATE(bp, xfs_mount_t *) == mp);
@@ -3238,10 +3258,12 @@
 	    ASSERT(BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) <= INT_MAX));
 	    bblks = (int) BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT));	/* blocks in data section */
 
-	    if ((INT_GET(rhead->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) ||
+	    if (unlikely((INT_GET(rhead->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) ||
 		(BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) > INT_MAX)) ||
 		(bblks <= 0) ||
-		(blk_no > log->l_logBBsize)) {
+		(blk_no > log->l_logBBsize))) {
+		    XFS_ERROR_REPORT("xlog_do_recovery_pass(1)",
+				     XFS_ERRLEVEL_LOW, log->l_mp);
 		    error = EFSCORRUPTED;
 		    goto bread_err2;
 	    }
@@ -3307,9 +3329,11 @@
 	    ASSERT(bblks > 0);
 	    blk_no += hblks;			/* successfully read header */
 
-	    if ((INT_GET(rhead->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) ||
+	    if (unlikely((INT_GET(rhead->h_magicno, ARCH_CONVERT) != XLOG_HEADER_MAGIC_NUM) ||
 		(BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) > INT_MAX)) ||
-		(bblks <= 0)) {
+		(bblks <= 0))) {
+		    XFS_ERROR_REPORT("xlog_do_recovery_pass(2)",
+				     XFS_ERRLEVEL_LOW, log->l_mp);
 		    error = EFSCORRUPTED;
 		    goto bread_err2;
 	    }
@@ -3472,7 +3496,7 @@
 	 * or iunlinks they will have some entries in the AIL; so we look at
 	 * the AIL to determine how to set the tail_lsn.
 	 */
-	xlog_assign_tail_lsn(log->l_mp, NULL);
+	xlog_assign_tail_lsn(log->l_mp);
 
 	/*
 	 * Now that we've finished replaying all buffer and inode
diff -Nru a/fs/xfs/xfs_macros.h b/fs/xfs/xfs_macros.h
--- a/fs/xfs/xfs_macros.h	Wed Sep 11 11:12:47 2002
+++ b/fs/xfs/xfs_macros.h	Mon Mar 17 11:44:08 2003
@@ -33,13 +33,12 @@
 #define __XFS_MACROS_H__
 
 /*
- * Set for debug kernels and simulation, and 32-bit kernels,
- * but not for standalone.  These replacements save space.
+ * Set for debug kernels and simulation
+ * These replacements save space.
  * Used in xfs_macros.c.
  */
 #define XFS_WANT_SPACE_C	\
-	(!defined(_STANDALONE) && \
-	 (defined(DEBUG) || (defined(_KERNEL))))
+	(!defined(_STANDALONE) && defined(DEBUG))
 
 /*
  * Set for debug simulation and kernel builds, but not for standalone.
diff -Nru a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
--- a/fs/xfs/xfs_mount.c	Mon Feb 24 10:18:24 2003
+++ b/fs/xfs/xfs_mount.c	Mon Mar 17 13:48:29 2003
@@ -205,13 +205,17 @@
 		return XFS_ERROR(EWRONGFS);
 	}
 
-	if (sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp) {
+	if (unlikely(sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) {
 		cmn_err(CE_WARN, "XFS: filesystem is marked as having an external log; specify logdev on the\nmount command line.");
+		XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(1)",
+				     XFS_ERRLEVEL_HIGH, mp, sbp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 
-	if (sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp) {
+	if (unlikely(sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) {
 		cmn_err(CE_WARN, "XFS: filesystem is marked as having an internal log; don't specify logdev on\nthe mount command line.");
+		XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(2)",
+				     XFS_ERRLEVEL_HIGH, mp, sbp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 
@@ -219,7 +223,8 @@
 	 * More sanity checking. These were stolen directly from
 	 * xfs_repair.
 	 */
-	if (sbp->sb_agcount <= 0					||
+	if (unlikely(
+	    sbp->sb_agcount <= 0					||
 	    sbp->sb_sectsize < XFS_MIN_SECTORSIZE			||
 	    sbp->sb_sectsize > XFS_MAX_SECTORSIZE			||
 	    sbp->sb_sectlog < XFS_MIN_SECTORSIZE_LOG			||
@@ -232,20 +237,25 @@
 	    sbp->sb_inodesize > XFS_DINODE_MAX_SIZE			||
 	    (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE)	||
 	    (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE)	||
-	    sbp->sb_imax_pct > 100) {
+	    sbp->sb_imax_pct > 100)) {
 		cmn_err(CE_WARN, "XFS: SB sanity check 1 failed");
+		XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(3)",
+				     XFS_ERRLEVEL_LOW, mp, sbp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 
 	/*
 	 * Sanity check AG count, size fields against data size field
 	 */
-	if (sbp->sb_dblocks == 0 ||
+	if (unlikely(
+	    sbp->sb_dblocks == 0 ||
 	    sbp->sb_dblocks >
 	     (xfs_drfsbno_t)sbp->sb_agcount * sbp->sb_agblocks ||
 	    sbp->sb_dblocks < (xfs_drfsbno_t)(sbp->sb_agcount - 1) *
-			      sbp->sb_agblocks + XFS_MIN_AG_BLOCKS) {
+			      sbp->sb_agblocks + XFS_MIN_AG_BLOCKS)) {
 		cmn_err(CE_WARN, "XFS: SB sanity check 2 failed");
+		XFS_ERROR_REPORT("xfs_mount_validate_sb(4)",
+				 XFS_ERRLEVEL_LOW, mp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 
@@ -257,8 +267,10 @@
 	}
 #endif
 
-	if (sbp->sb_inprogress) {
+	if (unlikely(sbp->sb_inprogress)) {
 		cmn_err(CE_WARN, "XFS: file system busy");
+		XFS_ERROR_REPORT("xfs_mount_validate_sb(5)",
+				 XFS_ERRLEVEL_LOW, mp);
 		return XFS_ERROR(EFSCORRUPTED);
 	}
 
@@ -636,7 +648,6 @@
 				error = XFS_ERROR(EINVAL);
 				goto error1;
 			}
-			mp->m_dalign = mp->m_swidth = 0;
 		} else {
 			/*
 			 * Convert the stripe unit and width to FSBs.
@@ -915,7 +926,7 @@
 	/*
 	 * log's mount-time initialization. Perform 1st part recovery if needed
 	 */
-	if (sbp->sb_logblocks > 0) {		/* check for volume case */
+	if (likely(sbp->sb_logblocks > 0)) {	/* check for volume case */
 		error = xfs_log_mount(mp, mp->m_logdev_targp->pbr_dev,
 				      XFS_FSB_TO_DADDR(mp, sbp->sb_logstart),
 				      XFS_FSB_TO_BB(mp, sbp->sb_logblocks));
@@ -925,6 +936,7 @@
 		}
 	} else {	/* No log has been defined */
 		cmn_err(CE_WARN, "XFS: no log defined");
+		XFS_ERROR_REPORT("xfs_mountfs_int(1)", XFS_ERRLEVEL_LOW, mp);
 		error = XFS_ERROR(EFSCORRUPTED);
 		goto error2;
 	}
@@ -941,7 +953,7 @@
 
 	ASSERT(rip != NULL);
 	rvp = XFS_ITOV(rip);
-	if ((rip->i_d.di_mode & IFMT) != IFDIR) {
+	if (unlikely((rip->i_d.di_mode & IFMT) != IFDIR)) {
 		cmn_err(CE_WARN, "XFS: corrupted root inode");
 		VMAP(rvp, vmap);
 		prdev("Root inode %llu is not a directory",
@@ -949,6 +961,8 @@
 		xfs_iunlock(rip, XFS_ILOCK_EXCL);
 		VN_RELE(rvp);
 		vn_purge(rvp, &vmap);
+		XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
+				 mp);
 		error = XFS_ERROR(EFSCORRUPTED);
 		goto error3;
 	}
diff -Nru a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
--- a/fs/xfs/xfs_qm.c	Mon Nov 25 13:27:06 2002
+++ b/fs/xfs/xfs_qm.c	Mon Mar 17 12:19:20 2003
@@ -444,16 +444,22 @@
 			xfs_iflock(uqp);
 			error = xfs_iflush(uqp, XFS_IFLUSH_SYNC);
 			xfs_iunlock(uqp, XFS_ILOCK_EXCL);
-			if (error == EFSCORRUPTED)
+			if (unlikely(error == EFSCORRUPTED)) {
+				XFS_ERROR_REPORT("xfs_qm_unmount_quotas(1)",
+						 XFS_ERRLEVEL_LOW, mp);
 				goto out;
+			}
 		}
 		if ((gqp = mp->m_quotainfo->qi_gquotaip) != NULL) {
 			xfs_ilock(gqp, XFS_ILOCK_EXCL);
 			xfs_iflock(gqp);
 			error = xfs_iflush(gqp, XFS_IFLUSH_SYNC);
 			xfs_iunlock(gqp, XFS_ILOCK_EXCL);
-			if (error == EFSCORRUPTED)
+			if (unlikely(error == EFSCORRUPTED)) {
+				XFS_ERROR_REPORT("xfs_qm_unmount_quotas(2)",
+						 XFS_ERRLEVEL_LOW, mp);
 				goto out;
+			}
 		}
 	}
 	if (uqp) {
diff -Nru a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
--- a/fs/xfs/xfs_rename.c	Tue Jan 14 09:25:41 2003
+++ b/fs/xfs/xfs_rename.c	Mon Mar 17 12:35:53 2003
@@ -467,9 +467,6 @@
 		}
 		target_ip_dropped = 1;
 
-		/* Do this test while we still hold the locks */
-		target_link_zero = (target_ip)->i_d.di_nlink==0;
-
 		if (src_is_directory) {
 			/*
 			 * Drop the link from the old "." entry.
@@ -480,6 +477,9 @@
 				goto abort_return;
 			}
 		}
+
+		/* Do this test while we still hold the locks */
+		target_link_zero = (target_ip)->i_d.di_nlink==0;
 
 	} /* target_ip != NULL */
 
diff -Nru a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
--- a/fs/xfs/xfs_types.h	Mon Nov 25 13:44:16 2002
+++ b/fs/xfs/xfs_types.h	Mon Mar 17 13:50:56 2003
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -34,8 +34,6 @@
 
 #ifdef __KERNEL__
 
-#include <linux/types.h>
-
 /*
  * POSIX Extensions
  */
@@ -56,9 +54,7 @@
 typedef signed long long int	__int64_t;
 typedef unsigned long long int	__uint64_t;
 
-typedef enum { B_FALSE, B_TRUE } boolean_t;
-
-
+typedef enum { B_FALSE,B_TRUE }	boolean_t;
 typedef __int64_t		prid_t;		/* project ID */
 typedef __uint32_t		inst_t;		/* an instruction */
 
@@ -68,12 +64,6 @@
 typedef char *			xfs_caddr_t;	/* <core address> type */
 typedef __u32			xfs_dev_t;
 
-typedef struct timespec		timespec_t;
-
-typedef struct {
-	unsigned char	__u_bits[16];
-} uuid_t;
-
 /* __psint_t is the same size as a pointer */
 #if (BITS_PER_LONG == 32)
 typedef __int32_t __psint_t;
@@ -184,6 +174,18 @@
  * the longest permissible file (component) name.
  */
 #define MAXNAMELEN	256
+
+typedef struct xfs_dirent {		/* data from readdir() */
+	xfs_ino_t	d_ino;		/* inode number of entry */
+	xfs_off_t	d_off;		/* offset of disk directory entry */
+	unsigned short	d_reclen;	/* length of this record */
+	char		d_name[1];	/* name of file */
+} xfs_dirent_t;
+
+#define DIRENTBASESIZE		(((xfs_dirent_t *)0)->d_name - (char *)0)
+#define DIRENTSIZE(namelen)	\
+	((DIRENTBASESIZE + (namelen) + \
+		sizeof(xfs_off_t)) & ~(sizeof(xfs_off_t) - 1))
 
 typedef enum {
 	XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi
diff -Nru a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
--- a/fs/xfs/xfs_vfsops.c	Mon Feb  3 10:21:32 2003
+++ b/fs/xfs/xfs_vfsops.c	Mon Mar 17 12:16:07 2003
@@ -1582,7 +1582,6 @@
 
 vfsops_t xfs_vfsops = {
 	.vfs_mount		= xfs_mount,
-	.vfs_dounmount		= fs_dounmount,
 	.vfs_unmount		= xfs_unmount,
 	.vfs_root		= xfs_root,
 	.vfs_statvfs		= xfs_statvfs,
diff -Nru a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
--- a/fs/xfs/xfs_vnodeops.c	Tue Jan 14 09:40:21 2003
+++ b/fs/xfs/xfs_vnodeops.c	Mon Mar 17 12:59:12 2003
@@ -72,7 +72,8 @@
 	 */
 	if (vp->v_type == VDIR && ip->i_d.di_nextents > 0) {
 		mode = xfs_ilock_map_shared(ip);
-		(void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK);
+		if (ip->i_d.di_nextents > 0)
+			(void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK);
 		xfs_iunlock(ip, mode);
 	}
 	return 0;
@@ -125,7 +126,8 @@
 	 * Quick exit for non-stat callers
 	 */
 	if ((vap->va_mask &
-	    ~(XFS_AT_SIZE|XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK)) == 0) {
+	    ~(XFS_AT_SIZE|XFS_AT_FSID|XFS_AT_NODEID|
+	      XFS_AT_NLINK|XFS_AT_BLKSIZE)) == 0) {
 		if (!(flags & ATTR_LAZY))
 			xfs_iunlock(ip, XFS_ILOCK_SHARED);
 		return 0;
@@ -1919,6 +1921,7 @@
 	xfs_bmap_free_t		free_list;
 	xfs_fsblock_t		first_block;
 	boolean_t		dp_joined_to_trans;
+	int			dm_event_sent = 0;
 	uint			cancel_flags;
 	int			committed;
 	xfs_prid_t		prid;
@@ -1943,15 +1946,16 @@
 				dm_di_mode, 0, 0);
 		if (error)
 			return error;
+		dm_event_sent = 1;
 	}
 
-	/* Return through std_return after this point. */
-
 	mp = dp->i_mount;
 
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return XFS_ERROR(EIO);
 
+	/* Return through std_return after this point. */
+
 	udqp = gdqp = NULL;
 	if (vap->va_mask & XFS_AT_PROJID)
 		prid = (xfs_prid_t)vap->va_projid;
@@ -2111,12 +2115,12 @@
 	/* Fallthrough to std_return with error = 0  */
 
 std_return:
-	if ((error != 0) &&
+	if ( (*vpp || (error != 0 && dm_event_sent != 0)) &&
 			DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
 							DM_EVENT_POSTCREATE)) {
 		(void) dm_send_namesp_event(DM_EVENT_POSTCREATE,
 			dir_bdp, DM_RIGHT_NULL,
-			vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops),
+			*vpp ? vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops):NULL,
 			DM_RIGHT_NULL, name, NULL,
 			dm_di_mode, error, 0);
 	}
@@ -2838,6 +2842,7 @@
 	vnode_t			*dir_vp;
 	boolean_t		dp_joined_to_trans;
 	boolean_t		created = B_FALSE;
+	int			dm_event_sent = 0;
 	xfs_prid_t		prid;
 	xfs_dquot_t		*udqp, *gdqp;
 	uint			resblks;
@@ -2864,6 +2869,7 @@
 					dm_di_mode, 0, 0);
 		if (error)
 			return error;
+		dm_event_sent = 1;
 	}
 
 	/* Return through std_return after this point. */
@@ -3026,7 +3032,7 @@
 	 * xfs_trans_commit. */
 
 std_return:
-	if ( (created || (error != 0)) &&
+	if ( (created || (error != 0 && dm_event_sent != 0)) &&
 			DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
 						DM_EVENT_POSTCREATE)) {
 		(void) dm_send_namesp_event(DM_EVENT_POSTCREATE,
diff -Nru a/fs/xfs/xfsidbg.c b/fs/xfs/xfsidbg.c
--- a/fs/xfs/xfsidbg.c	Wed Feb 19 12:23:53 2003
+++ b/fs/xfs/xfsidbg.c	Mon Mar 17 13:24:32 2003
@@ -4162,8 +4162,6 @@
 			}
 			if (!(ip->i_flags & XFS_IQUIESCE)) {
 				kdb_printf("ip 0x%p not quiesced\n", ip);
-			} else if (!BHV_IS_WRITE_LOCKED(VN_BHV_HEAD(XFS_ITOV(ip)))) {
-				kdb_printf("ip 0x%p not write locked\n", ip);
 			}
 			ip = ip->i_mnext;
 		} while (ip != mp->m_inodes);
diff -Nru a/include/asm-alpha/core_cia.h b/include/asm-alpha/core_cia.h
--- a/include/asm-alpha/core_cia.h	Sun Feb 16 16:35:48 2003
+++ b/include/asm-alpha/core_cia.h	Tue Mar 18 09:09:27 2003
@@ -293,7 +293,8 @@
 #ifdef __KERNEL__
 
 #ifndef __EXTERN_INLINE
-#define __EXTERN_INLINE static inline
+/* Do not touch, this should *NOT* be static inline */
+#define __EXTERN_INLINE extern inline
 #define __IO_EXTERN_INLINE
 #endif
 
diff -Nru a/include/asm-alpha/elf.h b/include/asm-alpha/elf.h
--- a/include/asm-alpha/elf.h	Mon Jan 20 01:01:48 2003
+++ b/include/asm-alpha/elf.h	Mon Mar 17 21:31:50 2003
@@ -50,7 +50,7 @@
    we start programs with a value of 0 to indicate that there is no
    such function.  */
 
-#define ELF_PLAT_INIT(_r)       _r->r0 = 0
+#define ELF_PLAT_INIT(_r, load_addr)	_r->r0 = 0
 
 /* The registers are layed out in pt_regs for PAL and syscall
    convenience.  Re-order them for the linear elf_gregset_t.  */
diff -Nru a/include/asm-alpha/linux_logo.h b/include/asm-alpha/linux_logo.h
--- a/include/asm-alpha/linux_logo.h	Mon Feb  4 23:41:04 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,27 +0,0 @@
-/* $Id: linux_logo.h,v 1.6 1998/07/30 16:30:20 jj Exp $
- * include/asm-alpha/linux_logo.h: This is a linux logo
- *                                 to be displayed on boot.
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * image size has to be 80x80
- * values have to start from 0x20
- * (i.e. RGB(linux_logo_red[0],
- *	     linux_logo_green[0],
- *	     linux_logo_blue[0]) is color 0x20)
- * BW image has to be 80x80 as well, with MS bit
- * on the left
- * Serial_console ascii image can be any size,
- * but should contain %s to display the version
- */
- 
-#include <linux/init.h>
-#include <linux/version.h>
-
-#define linux_logo_banner "Linux/AXP version " UTS_RELEASE
-
-#include <linux/linux_logo.h>
-
diff -Nru a/include/asm-arm/arch-cl7500/io.h b/include/asm-arm/arch-cl7500/io.h
--- a/include/asm-arm/arch-cl7500/io.h	Sun Dec 29 02:02:03 2002
+++ b/include/asm-arm/arch-cl7500/io.h	Tue Mar 18 15:19:45 2003
@@ -239,4 +239,15 @@
 /* the following macro is deprecated */
 #define ioaddr(port)			__ioaddr((port))
 
+#define insb(p,d,l)	__raw_readsb(__ioaddr(p),d,l)
+#define insw(p,d,l)	__raw_readsw(__ioaddr(p),d,l)
+
+#define outsb(p,d,l)	__raw_writesb(__ioaddr(p),d,l)
+#define outsw(p,d,l)	__raw_writesw(__ioaddr(p),d,l)
+
+/*
+ * 1:1 mapping for ioremapped regions.
+ */
+#define __mem_pci(x)	(x)
+
 #endif
diff -Nru a/include/asm-arm/arch-pxa/time.h b/include/asm-arm/arch-pxa/time.h
--- a/include/asm-arm/arch-pxa/time.h	Mon Feb 17 14:15:21 2003
+++ b/include/asm-arm/arch-pxa/time.h	Tue Mar 18 13:59:49 2003
@@ -49,7 +49,6 @@
 
 static void pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	long flags;
 	int next_match;
 
 	do_profile(regs);
@@ -63,11 +62,9 @@
 	do {
 		do_leds();
 		do_set_rtc();
-		local_irq_save( flags );
 		do_timer(regs);
 		OSSR = OSSR_M0;  /* Clear match on timer 0 */
 		next_match = (OSMR0 += LATCH);
-		local_irq_restore( flags );
 	} while( (signed long)(next_match - OSCR) <= 0 );
 }
 
diff -Nru a/include/asm-arm/cache.h b/include/asm-arm/cache.h
--- a/include/asm-arm/cache.h	Sun Sep 29 14:20:36 2002
+++ b/include/asm-arm/cache.h	Wed Mar 19 05:21:27 2003
@@ -4,18 +4,12 @@
 #ifndef __ASMARM_CACHE_H
 #define __ASMARM_CACHE_H
 
-#define        L1_CACHE_BYTES  32
-#define        L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
-#define        SMP_CACHE_BYTES L1_CACHE_BYTES
+#define L1_CACHE_SHIFT		5
+#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
-#ifdef MODULE
-#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
-#else
-#define __cacheline_aligned					\
-  __attribute__((__aligned__(L1_CACHE_BYTES),			\
-		 __section__(".data.cacheline_aligned")))
-#endif
-
-#define L1_CACHE_SHIFT_MAX 5	/* largest L1 which this arch supports */
+/*
+ * largest L1 which this arch supports
+ */
+#define L1_CACHE_SHIFT_MAX	5
 
 #endif
diff -Nru a/include/asm-arm/elf.h b/include/asm-arm/elf.h
--- a/include/asm-arm/elf.h	Tue Aug 20 17:33:33 2002
+++ b/include/asm-arm/elf.h	Mon Mar 17 21:31:50 2003
@@ -48,7 +48,7 @@
 /* When the program starts, a1 contains a pointer to a function to be 
    registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
    have no such handler.  */
-#define ELF_PLAT_INIT(_r)	(_r)->ARM_r0 = 0
+#define ELF_PLAT_INIT(_r, load_addr)	(_r)->ARM_r0 = 0
 
 /* This yields a mask that user programs can use to figure out what
    instruction set this cpu supports. */
diff -Nru a/include/asm-arm/hardware/ssp.h b/include/asm-arm/hardware/ssp.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-arm/hardware/ssp.h	Tue Mar 18 15:34:21 2003
@@ -0,0 +1,28 @@
+/*
+ *  ssp.h
+ *
+ *  Copyright (C) 2003 Russell King, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef SSP_H
+#define SSP_H
+
+struct ssp_state {
+	unsigned int	cr0;
+	unsigned int	cr1;
+};
+
+int ssp_write_word(u16 data);
+int ssp_read_word(void);
+void ssp_flush(void);
+void ssp_enable(void);
+void ssp_disable(void);
+void ssp_save_state(struct ssp_state *ssp);
+void ssp_restore_state(struct ssp_state *ssp);
+int ssp_init(void);
+void ssp_exit(void);
+
+#endif
diff -Nru a/include/asm-arm/linux_logo.h b/include/asm-arm/linux_logo.h
--- a/include/asm-arm/linux_logo.h	Mon Feb  4 23:41:04 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,19 +0,0 @@
-/*
- *  linux/include/asm-arm/linux_logo.h
- *
- *  Copyright (C) 1998 Russell King
- *
- * 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.
- *
- *  Linux console driver logo definitions for ARM
- */
-
-#include <linux/init.h>
-#include <linux/version.h>
-
-#define linux_logo_banner "ARM Linux version " UTS_RELEASE
-
-#include <linux/linux_logo.h>
-
diff -Nru a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h
--- a/include/asm-arm/mach/arch.h	Wed May 29 16:16:37 2002
+++ b/include/asm-arm/mach/arch.h	Tue Mar 18 15:19:45 2003
@@ -17,6 +17,7 @@
 #ifndef __ASSEMBLY__
 
 struct tag;
+struct meminfo;
 
 struct machine_desc {
 	/*
diff -Nru a/include/asm-arm/mach/dma.h b/include/asm-arm/mach/dma.h
--- a/include/asm-arm/mach/dma.h	Tue Feb  5 09:39:52 2002
+++ b/include/asm-arm/mach/dma.h	Tue Mar 18 15:19:45 2003
@@ -40,7 +40,6 @@
 
 	unsigned int	dma_base;	/* Controller base address	*/
 	int		dma_irq;	/* Controller IRQ		*/
-	int		state;		/* Controller state		*/
 	struct scatterlist cur_sg;	/* Current controller buffer	*/
 
 	struct dma_ops	*d_ops;
diff -Nru a/include/asm-arm/mach/pci.h b/include/asm-arm/mach/pci.h
--- a/include/asm-arm/mach/pci.h	Tue May 14 02:42:09 2002
+++ b/include/asm-arm/mach/pci.h	Tue Mar 18 13:42:00 2003
@@ -12,6 +12,7 @@
 struct pci_bus;
 
 struct hw_pci {
+	struct list_head buses;
 	int		nr_controllers;
 	int		(*setup)(int nr, struct pci_sys_data *);
 	struct pci_bus *(*scan)(int nr, struct pci_sys_data *);
@@ -25,6 +26,7 @@
  * Per-controller structure
  */
 struct pci_sys_data {
+	struct list_head node;
 	int		busnr;		/* primary bus number			*/
 	unsigned long	mem_offset;	/* bus->cpu memory mapping offset	*/
 	unsigned long	io_offset;	/* bus->cpu IO mapping offset		*/
diff -Nru a/include/asm-arm/proc-armv/system.h b/include/asm-arm/proc-armv/system.h
--- a/include/asm-arm/proc-armv/system.h	Mon Feb  3 03:16:30 2003
+++ b/include/asm-arm/proc-armv/system.h	Tue Mar 18 15:04:46 2003
@@ -63,6 +63,7 @@
 #define local_irq_save(x)					\
 	({							\
 		unsigned long temp;				\
+		(void) (&temp == &x);				\
 	__asm__ __volatile__(					\
 	"mrs	%0, cpsr		@ local_irq_save\n"	\
 "	orr	%1, %0, #128\n"					\
diff -Nru a/include/asm-cris/elf.h b/include/asm-cris/elf.h
--- a/include/asm-cris/elf.h	Tue Feb  5 07:24:38 2002
+++ b/include/asm-cris/elf.h	Mon Mar 17 21:31:50 2003
@@ -39,7 +39,7 @@
 	   A value of 0 tells we have no such handler.  */
 	
 	/* Explicitly set registers to 0 to increase determinism.  */
-#define ELF_PLAT_INIT(_r)	do { \
+#define ELF_PLAT_INIT(_r, load_addr)	do { \
 	(_r)->r13 = 0; (_r)->r12 = 0; (_r)->r11 = 0; (_r)->r10 = 0; \
 	(_r)->r9 = 0;  (_r)->r8 = 0;  (_r)->r7 = 0;  (_r)->r6 = 0;  \
 	(_r)->r5 = 0;  (_r)->r4 = 0;  (_r)->r3 = 0;  (_r)->r2 = 0;  \
diff -Nru a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
--- a/include/asm-generic/tlb.h	Wed Jan  8 12:37:27 2003
+++ b/include/asm-generic/tlb.h	Sun Mar 23 22:31:25 2003
@@ -14,6 +14,7 @@
 #define _ASM_GENERIC__TLB_H
 
 #include <linux/config.h>
+#include <linux/swap.h>
 #include <asm/tlbflush.h>
 
 /*
diff -Nru a/include/asm-i386/elf.h b/include/asm-i386/elf.h
--- a/include/asm-i386/elf.h	Thu Jan  2 07:22:48 2003
+++ b/include/asm-i386/elf.h	Mon Mar 17 21:31:50 2003
@@ -43,7 +43,7 @@
    We might as well make sure everything else is cleared too (except for %esp),
    just to make things more deterministic.
  */
-#define ELF_PLAT_INIT(_r)	do { \
+#define ELF_PLAT_INIT(_r, load_addr)	do { \
 	_r->ebx = 0; _r->ecx = 0; _r->edx = 0; \
 	_r->esi = 0; _r->edi = 0; _r->ebp = 0; \
 	_r->eax = 0; \
diff -Nru a/include/asm-i386/hardirq.h b/include/asm-i386/hardirq.h
--- a/include/asm-i386/hardirq.h	Fri Nov  8 22:31:03 2002
+++ b/include/asm-i386/hardirq.h	Sun Mar 23 16:56:04 2003
@@ -79,7 +79,7 @@
 #define nmi_enter()		(irq_enter())
 #define nmi_exit()		(preempt_count() -= HARDIRQ_OFFSET)
 
-#if CONFIG_PREEMPT
+#ifdef CONFIG_PREEMPT
 # define in_atomic()	((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
 # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
 #else
diff -Nru a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h
--- a/include/asm-i386/hw_irq.h	Tue Feb 18 18:59:01 2003
+++ b/include/asm-i386/hw_irq.h	Mon Mar 17 21:31:45 2003
@@ -56,6 +56,7 @@
 extern void print_IO_APIC(void);
 extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
 extern void send_IPI(int dest, int vector);
+extern void setup_ioapic_dest(unsigned long mask);
 
 extern unsigned long io_apic_irqs;
 
diff -Nru a/include/asm-i386/linux_logo.h b/include/asm-i386/linux_logo.h
--- a/include/asm-i386/linux_logo.h	Mon Feb  4 23:41:04 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,27 +0,0 @@
-/* $Id: linux_logo.h,v 1.8 1998/07/30 16:30:24 jj Exp $
- * include/asm-i386/linux_logo.h: This is a linux logo
- *                                to be displayed on boot.
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * image size has to be 80x80
- * values have to start from 0x20
- * (i.e. RGB(linux_logo_red[0],
- *	     linux_logo_green[0],
- *	     linux_logo_blue[0]) is color 0x20)
- * BW image has to be 80x80 as well, with MS bit
- * on the left
- * Serial_console ascii image can be any size,
- * but should contain %s to display the version
- */
- 
-#include <linux/init.h>
-#include <linux/version.h>
-
-#define linux_logo_banner "Linux/ia32 version " UTS_RELEASE
-
-#include <linux/linux_logo.h>
-
diff -Nru a/include/asm-i386/mach-default/mach_reboot.h b/include/asm-i386/mach-default/mach_reboot.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/mach-default/mach_reboot.h	Fri Feb 14 14:59:20 2003
@@ -0,0 +1,30 @@
+/*
+ *  arch/i386/mach-generic/mach_reboot.h
+ *
+ *  Machine specific reboot functions for generic.
+ *  Split out from reboot.c by Osamu Tomita <tomita@cinet.co.jp>
+ */
+#ifndef _MACH_REBOOT_H
+#define _MACH_REBOOT_H
+
+static inline void kb_wait(void)
+{
+	int i;
+
+	for (i = 0; i < 0x10000; i++)
+		if ((inb_p(0x64) & 0x02) == 0)
+			break;
+}
+
+static inline void mach_reboot(void)
+{
+	int i;
+	for (i = 0; i < 100; i++) {
+		kb_wait();
+		udelay(50);
+		outb(0xfe, 0x64);         /* pulse reset low */
+		udelay(50);
+	}
+}
+
+#endif /* !_MACH_REBOOT_H */
diff -Nru a/include/asm-i386/mach-default/pci-functions.h b/include/asm-i386/mach-default/pci-functions.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/mach-default/pci-functions.h	Fri Feb 14 14:54:22 2003
@@ -0,0 +1,19 @@
+/*
+ *	PCI BIOS function numbering for conventional PCI BIOS 
+ *	systems
+ */
+
+#define PCIBIOS_PCI_FUNCTION_ID 	0xb1XX
+#define PCIBIOS_PCI_BIOS_PRESENT 	0xb101
+#define PCIBIOS_FIND_PCI_DEVICE		0xb102
+#define PCIBIOS_FIND_PCI_CLASS_CODE	0xb103
+#define PCIBIOS_GENERATE_SPECIAL_CYCLE	0xb106
+#define PCIBIOS_READ_CONFIG_BYTE	0xb108
+#define PCIBIOS_READ_CONFIG_WORD	0xb109
+#define PCIBIOS_READ_CONFIG_DWORD	0xb10a
+#define PCIBIOS_WRITE_CONFIG_BYTE	0xb10b
+#define PCIBIOS_WRITE_CONFIG_WORD	0xb10c
+#define PCIBIOS_WRITE_CONFIG_DWORD	0xb10d
+#define PCIBIOS_GET_ROUTING_OPTIONS	0xb10e
+#define PCIBIOS_SET_PCI_HW_INT		0xb10f
+
diff -Nru a/include/asm-i386/mach-pc9800/mach_reboot.h b/include/asm-i386/mach-pc9800/mach_reboot.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/mach-pc9800/mach_reboot.h	Fri Feb 14 14:59:47 2003
@@ -0,0 +1,21 @@
+/*
+ *  arch/i386/mach-pc9800/mach_reboot.h
+ *
+ *  Machine specific reboot functions for PC-9800.
+ *  Written by Osamu Tomita <tomita@cinet.co.jp>
+ */
+#ifndef _MACH_REBOOT_H
+#define _MACH_REBOOT_H
+
+#ifdef CMOS_WRITE
+#undef CMOS_WRITE
+#define CMOS_WRITE(a,b)	do{}while(0)
+#endif
+
+static inline void mach_reboot(void)
+{
+	outb(0, 0xf0);		/* signal CPU reset */
+	mdelay(1);
+}
+
+#endif /* !_MACH_REBOOT_H */
diff -Nru a/include/asm-i386/mach-pc9800/pci-functions.h b/include/asm-i386/mach-pc9800/pci-functions.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/mach-pc9800/pci-functions.h	Fri Feb 14 15:00:56 2003
@@ -0,0 +1,20 @@
+/*
+ *	PCI BIOS function codes for the PC9800. Different to
+ *	standard PC systems
+ */
+
+/* Note: PC-9800 confirms PCI 2.1 on only few models */
+
+#define PCIBIOS_PCI_FUNCTION_ID 	0xccXX
+#define PCIBIOS_PCI_BIOS_PRESENT 	0xcc81
+#define PCIBIOS_FIND_PCI_DEVICE		0xcc82
+#define PCIBIOS_FIND_PCI_CLASS_CODE	0xcc83
+/*      PCIBIOS_GENERATE_SPECIAL_CYCLE	0xcc86	(not supported by bios) */
+#define PCIBIOS_READ_CONFIG_BYTE	0xcc88
+#define PCIBIOS_READ_CONFIG_WORD	0xcc89
+#define PCIBIOS_READ_CONFIG_DWORD	0xcc8a
+#define PCIBIOS_WRITE_CONFIG_BYTE	0xcc8b
+#define PCIBIOS_WRITE_CONFIG_WORD	0xcc8c
+#define PCIBIOS_WRITE_CONFIG_DWORD	0xcc8d
+#define PCIBIOS_GET_ROUTING_OPTIONS	0xcc8e	/* PCI 2.1 only */
+#define PCIBIOS_SET_PCI_HW_INT		0xcc8f	/* PCI 2.1 only */
diff -Nru a/include/asm-i386/mach-pc9800/setup_arch_post.h b/include/asm-i386/mach-pc9800/setup_arch_post.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/mach-pc9800/setup_arch_post.h	Fri Feb 14 15:00:56 2003
@@ -0,0 +1,29 @@
+/**
+ * machine_specific_memory_setup - Hook for machine specific memory setup.
+ *
+ * Description:
+ *	This is included late in kernel/setup.c so that it can make
+ *	use of all of the static functions.
+ **/
+
+static inline char * __init machine_specific_memory_setup(void)
+{
+	char *who;
+	unsigned long low_mem_size, lower_high, higher_high;
+
+
+	who = "BIOS (common area)";
+
+	low_mem_size = ((*(unsigned char *)__va(PC9800SCA_BIOS_FLAG) & 7) + 1) << 17;
+	add_memory_region(0, low_mem_size, 1);
+	lower_high = (__u32) *(__u8 *) bus_to_virt(PC9800SCA_EXPMMSZ) << 17;
+	higher_high = (__u32) *(__u16 *) bus_to_virt(PC9800SCA_MMSZ16M) << 20;
+	if (lower_high != 0x00f00000UL) {
+		add_memory_region(HIGH_MEMORY, lower_high, 1);
+		add_memory_region(0x01000000UL, higher_high, 1);
+	}
+	else
+		add_memory_region(HIGH_MEMORY, lower_high + higher_high, 1);
+
+	return who;
+}
diff -Nru a/include/asm-i386/mach-pc9800/setup_arch_pre.h b/include/asm-i386/mach-pc9800/setup_arch_pre.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/mach-pc9800/setup_arch_pre.h	Thu Mar 13 17:21:57 2003
@@ -0,0 +1,36 @@
+/* Hook to call BIOS initialisation function */
+
+/* no action for generic */
+
+#define ARCH_SETUP arch_setup_pc9800();
+
+#include <linux/timex.h>
+#include <asm/io.h>
+#include <asm/pc9800.h>
+#include <asm/pc9800_sca.h>
+
+int CLOCK_TICK_RATE;
+extern unsigned long tick_usec;	/* ACTHZ          period (usec) */
+extern unsigned long tick_nsec;	/* USER_HZ period (nsec) */
+unsigned char pc9800_misc_flags;
+/* (bit 0) 1:High Address Video ram exists 0:otherwise */
+
+#ifdef CONFIG_SMP
+#define MPC_TABLE_SIZE 512
+#define MPC_TABLE ((char *) (PARAM+0x400))
+char mpc_table[MPC_TABLE_SIZE];
+#endif
+
+static  inline void arch_setup_pc9800(void)
+{
+	CLOCK_TICK_RATE = PC9800_8MHz_P() ? 1996800 : 2457600;
+	printk(KERN_DEBUG "CLOCK_TICK_RATE = %d\n", CLOCK_TICK_RATE);
+	tick_usec = TICK_USEC; 		/* ACTHZ          period (usec) */
+	tick_nsec = TICK_NSEC(TICK_USEC);	/* USER_HZ period (nsec) */
+
+	pc9800_misc_flags = PC9800_MISC_FLAGS;
+#ifdef CONFIG_SMP
+	if ((*(u32 *)(MPC_TABLE)) == 0x504d4350)
+		memcpy(mpc_table, MPC_TABLE, *(u16 *)(MPC_TABLE + 4));
+#endif /* CONFIG_SMP */
+}
diff -Nru a/include/asm-i386/pc9800_sca.h b/include/asm-i386/pc9800_sca.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/pc9800_sca.h	Fri Feb 14 15:29:24 2003
@@ -0,0 +1,25 @@
+/*
+ *  System-common area definitions for NEC PC-9800 series
+ *
+ *  Copyright (C) 1999	TAKAI Kousuke <tak@kmc.kyoto-u.ac.jp>,
+ *			Kyoto University Microcomputer Club.
+ */
+
+#ifndef _ASM_I386_PC9800SCA_H_
+#define _ASM_I386_PC9800SCA_H_
+
+#define PC9800SCA_EXPMMSZ		(0x0401)	/* B */
+#define PC9800SCA_SCSI_PARAMS		(0x0460)	/* 8 * 4B */
+#define PC9800SCA_DISK_EQUIPS		(0x0482)	/* B */
+#define PC9800SCA_XROM_ID		(0x04C0)	/* 52B */
+#define PC9800SCA_BIOS_FLAG		(0x0501)	/* B */
+#define PC9800SCA_MMSZ16M		(0x0594)	/* W */
+
+/* PC-9821 have additional system common area in their BIOS-ROM segment. */
+
+#define PC9821SCA__BASE			(0xF8E8 << 4)
+#define PC9821SCA_ROM_ID		(PC9821SCA__BASE + 0x00)
+#define PC9821SCA_ROM_FLAG4		(PC9821SCA__BASE + 0x05)
+#define PC9821SCA_RSFLAGS		(PC9821SCA__BASE + 0x11)	/* B */
+
+#endif /* !_ASM_I386_PC9800SCA_H_ */
diff -Nru a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h
--- a/include/asm-i386/pgtable-2level.h	Tue Feb 25 01:39:10 2003
+++ b/include/asm-i386/pgtable-2level.h	Sat Mar 22 22:06:03 2003
@@ -63,4 +63,16 @@
 #define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 #define pfn_pmd(pfn, prot)	__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 
+/*
+ * Bits 0, 6 and 7 are taken, split up the 29 bits of offset
+ * into this range:
+ */
+#define PTE_FILE_MAX_BITS	29
+
+#define pte_to_pgoff(pte) \
+	((((pte).pte_low >> 1) & 0x1f ) + (((pte).pte_low >> 8) << 5 ))
+
+#define pgoff_to_pte(off) \
+	((pte_t) { (((off) & 0x1f) << 1) + (((off) >> 5) << 8) + _PAGE_FILE })
+
 #endif /* _I386_PGTABLE_2LEVEL_H */
diff -Nru a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h
--- a/include/asm-i386/pgtable-3level.h	Thu Mar  6 08:19:07 2003
+++ b/include/asm-i386/pgtable-3level.h	Sat Mar 22 22:06:03 2003
@@ -115,4 +115,12 @@
 	return __pmd(((unsigned long long)page_nr << PAGE_SHIFT) | pgprot_val(pgprot));
 }
 
+/*
+ * Bits 0, 6 and 7 are taken in the low part of the pte,
+ * put the 32 bits of offset into the high part.
+ */
+#define pte_to_pgoff(pte) ((pte).pte_high)
+#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) })
+#define PTE_FILE_MAX_BITS       32
+
 #endif /* _I386_PGTABLE_3LEVEL_H */
diff -Nru a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
--- a/include/asm-i386/pgtable.h	Thu Mar  6 17:44:46 2003
+++ b/include/asm-i386/pgtable.h	Sat Mar 22 22:06:03 2003
@@ -110,6 +110,7 @@
 #define _PAGE_PSE	0x080	/* 4 MB (or 2MB) page, Pentium+, if present.. */
 #define _PAGE_GLOBAL	0x100	/* Global TLB entry PPro+ */
 
+#define _PAGE_FILE	0x040	/* pagecache or swap? */
 #define _PAGE_PROTNONE	0x080	/* If not present */
 
 #define _PAGE_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
@@ -187,6 +188,7 @@
 static inline int pte_dirty(pte_t pte)		{ return (pte).pte_low & _PAGE_DIRTY; }
 static inline int pte_young(pte_t pte)		{ return (pte).pte_low & _PAGE_ACCESSED; }
 static inline int pte_write(pte_t pte)		{ return (pte).pte_low & _PAGE_RW; }
+static inline int pte_file(pte_t pte)		{ return (pte).pte_low & _PAGE_FILE; }
 
 static inline pte_t pte_rdprotect(pte_t pte)	{ (pte).pte_low &= ~_PAGE_USER; return pte; }
 static inline pte_t pte_exprotect(pte_t pte)	{ (pte).pte_low &= ~_PAGE_USER; return pte; }
@@ -231,18 +233,41 @@
 #define pmd_large(pmd) \
 	((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
 
-/* to find an entry in a page-table-directory. */
+/*
+ * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
+ *
+ * this macro returns the index of the entry in the pgd page which would
+ * control the given virtual address
+ */
 #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
 
+/*
+ * pgd_offset() returns a (pgd_t *)
+ * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
+ */
 #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
 
-/* to find an entry in a kernel page-table-directory */
+/*
+ * a shortcut which implies the use of the kernel's pgd, instead
+ * of a process's
+ */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
+/*
+ * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
+ *
+ * this macro returns the index of the entry in the pmd page which would
+ * control the given virtual address
+ */
 #define pmd_index(address) \
 		(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
 
-/* Find an entry in the third-level page table.. */
+/*
+ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
+ *
+ * this macro returns the index of the entry in the pte page which would
+ * control the given virtual address
+ */
 #define pte_index(address) \
 		(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
 #define pte_offset_kernel(dir, address) \
@@ -282,7 +307,7 @@
 #define update_mmu_cache(vma,address,pte) do { } while (0)
 
 /* Encode and de-code a swap entry */
-#define __swp_type(x)			(((x).val >> 1) & 0x3f)
+#define __swp_type(x)			(((x).val >> 1) & 0x1f)
 #define __swp_offset(x)			((x).val >> 8)
 #define __swp_entry(type, offset)	((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
 #define __pte_to_swp_entry(pte)		((swp_entry_t) { (pte).pte_low })
diff -Nru a/include/asm-i386/processor.h b/include/asm-i386/processor.h
--- a/include/asm-i386/processor.h	Mon Mar 10 14:41:23 2003
+++ b/include/asm-i386/processor.h	Thu Mar 20 21:43:55 2003
@@ -371,6 +371,10 @@
 	 * pads the TSS to be cacheline-aligned (size is 0x100)
 	 */
 	unsigned long __cacheline_filler[5];
+	/*
+	 * .. and then another 0x100 bytes for emergency kernel stack
+	 */
+	unsigned long stack[64];
 };
 
 struct thread_struct {
diff -Nru a/include/asm-i386/system.h b/include/asm-i386/system.h
--- a/include/asm-i386/system.h	Thu Feb 20 20:33:52 2003
+++ b/include/asm-i386/system.h	Thu Mar 20 10:12:10 2003
@@ -407,5 +407,6 @@
 
 #define BROKEN_ACPI_Sx		0x0001
 #define BROKEN_INIT_AFTER_S1	0x0002
+#define BROKEN_PNP_BIOS		0x0004
 
 #endif
diff -Nru a/include/asm-i386/timex.h b/include/asm-i386/timex.h
--- a/include/asm-i386/timex.h	Sun Mar 31 05:27:31 2002
+++ b/include/asm-i386/timex.h	Thu Mar 13 17:17:16 2003
@@ -9,10 +9,14 @@
 #include <linux/config.h>
 #include <asm/msr.h>
 
+#ifdef CONFIG_X86_PC9800
+   extern int CLOCK_TICK_RATE;
+#else
 #ifdef CONFIG_MELAN
 #  define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */
 #else
 #  define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
+#endif
 #endif
 
 #define CLOCK_TICK_FACTOR	20	/* Factor of both 1000000 and CLOCK_TICK_RATE */
diff -Nru a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h
--- a/include/asm-i386/uaccess.h	Tue Feb 25 10:12:03 2003
+++ b/include/asm-i386/uaccess.h	Sat Mar  1 05:55:41 2003
@@ -47,7 +47,13 @@
 #define __addr_ok(addr) ((unsigned long)(addr) < (current_thread_info()->addr_limit.seg))
 
 /*
- * Uhhuh, this needs 33-bit arithmetic. We have a carry..
+ * Test whether a block of memory is a valid user space address.
+ * Returns 0 if the range is valid, nonzero otherwise.
+ *
+ * This is equivalent to the following test:
+ * (u33)addr + (u33)size >= (u33)current->addr_limit.seg
+ *
+ * This needs 33-bit arithmetic. We have a carry...
  */
 #define __range_ok(addr,size) ({ \
 	unsigned long flag,sum; \
@@ -58,6 +64,25 @@
 
 #ifdef CONFIG_X86_WP_WORKS_OK
 
+/**
+ * access_ok: - Checks if a user space pointer is valid
+ * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that
+ *        %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
+ *        to write to a block, it is always safe to read from it.
+ * @addr: User space pointer to start of block to check
+ * @size: Size of block to check
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Checks if a pointer to a block of memory in user space is valid.
+ *
+ * Returns true (nonzero) if the memory block may be valid, false (zero)
+ * if it is definitely invalid.
+ *
+ * Note that, depending on architecture, this function probably just
+ * checks that the pointer is in the user space range - after calling
+ * this function, memory access functions may still return -EFAULT.
+ */
 #define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
 
 #else
@@ -68,6 +93,23 @@
 
 #endif
 
+/**
+ * verify_area: - Obsolete, use access_ok()
+ * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE
+ * @addr: User space pointer to start of block to check
+ * @size: Size of block to check
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This function has been replaced by access_ok().
+ *
+ * Checks if a pointer to a block of memory in user space is valid.
+ *
+ * Returns zero if the memory block may be valid, -EFAULT
+ * if it is definitely invalid.
+ *
+ * See access_ok() for more details.
+ */
 static inline int verify_area(int type, const void * addr, unsigned long size)
 {
 	return access_ok(type,addr,size) ? 0 : -EFAULT;
@@ -118,7 +160,25 @@
 		:"=a" (ret),"=d" (x) \
 		:"0" (ptr))
 
+
 /* Careful: we have to cast the result to the type of the pointer for sign reasons */
+/**
+ * get_user: - Get a simple variable from user space.
+ * @x:   Variable to store result.
+ * @ptr: Source address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple variable from user space to kernel
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and the result of
+ * dereferencing @ptr must be assignable to @x without a cast.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
 #define get_user(x,ptr)							\
 ({	int __ret_gu,__val_gu;						\
 	switch(sizeof (*(ptr))) {					\
@@ -138,11 +198,70 @@
 
 extern void __put_user_bad(void);
 
+
+/**
+ * put_user: - Write a simple value into user space.
+ * @x:   Value to copy to user space.
+ * @ptr: Destination address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple value from kernel space to user
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
+ * to the result of dereferencing @ptr.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
 #define put_user(x,ptr)							\
   __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
 
+
+/**
+ * __get_user: - Get a simple variable from user space, with less checking.
+ * @x:   Variable to store result.
+ * @ptr: Source address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple variable from user space to kernel
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and the result of
+ * dereferencing @ptr must be assignable to @x without a cast.
+ *
+ * Caller must check the pointer with access_ok() before calling this
+ * function.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
 #define __get_user(x,ptr) \
   __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+
+
+/**
+ * __put_user: - Write a simple value into user space, with less checking.
+ * @x:   Value to copy to user space.
+ * @ptr: Destination address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple value from kernel space to user
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
+ * to the result of dereferencing @ptr.
+ *
+ * Caller must check the pointer with access_ok() before calling this
+ * function.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
 #define __put_user(x,ptr) \
   __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
 
@@ -263,6 +382,21 @@
  * If a store crosses a page boundary and gets a fault, the x86 will not write
  * anything, so this is accurate.
  */
+
+/**
+ * __copy_to_user: - Copy a block of data into user space, with less checking.
+ * @to:   Destination address, in user space.
+ * @from: Source address, in kernel space.
+ * @n:    Number of bytes to copy.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Copy data from kernel space to user space.  Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ */
 static inline unsigned long
 __copy_to_user(void *to, const void *from, unsigned long n)
 {
@@ -284,6 +418,23 @@
 	return __copy_to_user_ll(to, from, n);
 }
 
+/**
+ * __copy_from_user: - Copy a block of data from user space, with less checking.
+ * @to:   Destination address, in kernel space.
+ * @from: Source address, in user space.
+ * @n:    Number of bytes to copy.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Copy data from user space to kernel space.  Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ *
+ * If some data could not be copied, this function will pad the copied
+ * data to the requested size using zero bytes.
+ */
 static inline unsigned long
 __copy_from_user(void *to, const void *from, unsigned long n)
 {
@@ -305,6 +456,19 @@
 	return __copy_from_user_ll(to, from, n);
 }
 
+/**
+ * copy_to_user: - Copy a block of data into user space.
+ * @to:   Destination address, in user space.
+ * @from: Source address, in kernel space.
+ * @n:    Number of bytes to copy.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Copy data from kernel space to user space.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ */
 static inline unsigned long
 copy_to_user(void *to, const void *from, unsigned long n)
 {
@@ -313,6 +477,22 @@
 	return n;
 }
 
+/**
+ * copy_from_user: - Copy a block of data from user space.
+ * @to:   Destination address, in kernel space.
+ * @from: Source address, in user space.
+ * @n:    Number of bytes to copy.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Copy data from user space to kernel space.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ *
+ * If some data could not be copied, this function will pad the copied
+ * data to the requested size using zero bytes.
+ */
 static inline unsigned long
 copy_from_user(void *to, const void *from, unsigned long n)
 {
@@ -323,7 +503,23 @@
 
 long strncpy_from_user(char *dst, const char *src, long count);
 long __strncpy_from_user(char *dst, const char *src, long count);
+
+/**
+ * strlen_user: - Get the size of a string in user space.
+ * @str: The string to measure.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Get the size of a NULL-terminated string in user space.
+ *
+ * Returns the size of the string INCLUDING the terminating NULL.
+ * On exception, returns 0.
+ *
+ * If there is a limit on the length of a valid string, you may wish to
+ * consider using strnlen_user() instead.
+ */
 #define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+
 long strnlen_user(const char *str, long n);
 unsigned long clear_user(void *mem, unsigned long len);
 unsigned long __clear_user(void *mem, unsigned long len);
diff -Nru a/include/asm-i386/upd4990a.h b/include/asm-i386/upd4990a.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/upd4990a.h	Thu Feb 20 08:30:58 2003
@@ -0,0 +1,52 @@
+/*
+ *  Architecture dependent definitions
+ *  for NEC uPD4990A serial I/O real-time clock.
+ *
+ *  Copyright 2001  TAKAI Kousuke <tak@kmc.kyoto-u.ac.jp>
+ *		    Kyoto University Microcomputer Club (KMC).
+ *
+ *  References:
+ *	uPD4990A serial I/O real-time clock users' manual (Japanese)
+ *	No. S12828JJ4V0UM00 (4th revision), NEC Corporation, 1999.
+ */
+
+#ifndef _ASM_I386_uPD4990A_H
+#define _ASM_I386_uPD4990A_H
+
+#include <asm/io.h>
+
+#define UPD4990A_IO		(0x0020)
+#define UPD4990A_IO_DATAOUT	(0x0033)
+
+#define UPD4990A_OUTPUT_DATA_CLK(data, clk)		\
+	outb((((data) & 1) << 5) | (((clk) & 1) << 4)	\
+	      | UPD4990A_PAR_SERIAL_MODE, UPD4990A_IO)
+
+#define UPD4990A_OUTPUT_CLK(clk)	UPD4990A_OUTPUT_DATA_CLK(0, (clk))
+
+#define UPD4990A_OUTPUT_STROBE(stb) \
+	outb(((stb) << 3) | UPD4990A_PAR_SERIAL_MODE, UPD4990A_IO)
+
+/*
+ * Note: udelay() is *not* usable for UPD4990A_DELAY because
+ *	 the Linux kernel reads uPD4990A to set up system clock
+ *	 before calibrating delay...
+ */
+#define UPD4990A_DELAY(usec)						\
+	do {								\
+		if (__builtin_constant_p((usec)) && (usec) < 5)	\
+			__asm__ (".rept %c1\n\toutb %%al,%0\n\t.endr"	\
+				 : : "N" (0x5F),			\
+				     "i" (((usec) * 10 + 5) / 6));	\
+		else {							\
+			int _count = ((usec) * 10 + 5) / 6;		\
+			__asm__ volatile ("1: outb %%al,%1\n\tloop 1b"	\
+					  : "=c" (_count)		\
+					  : "N" (0x5F), "0" (_count));	\
+		}							\
+	} while (0)
+
+/* Caller should ignore all bits except bit0 */
+#define UPD4990A_READ_DATA()	inb(UPD4990A_IO_DATAOUT)
+
+#endif
diff -Nru a/include/asm-ia64/elf.h b/include/asm-ia64/elf.h
--- a/include/asm-ia64/elf.h	Wed Jan 29 14:36:09 2003
+++ b/include/asm-ia64/elf.h	Mon Mar 17 21:31:50 2003
@@ -50,7 +50,7 @@
  * talk to him...
  */
 extern void ia64_init_addr_space (void);
-#define ELF_PLAT_INIT(_r)	ia64_init_addr_space()
+#define ELF_PLAT_INIT(_r, load_addr)	ia64_init_addr_space()
 
 /* ELF register definitions.  This is needed for core dump support.  */
 
diff -Nru a/include/asm-ia64/ia32.h b/include/asm-ia64/ia32.h
--- a/include/asm-ia64/ia32.h	Sun Jan 12 16:07:06 2003
+++ b/include/asm-ia64/ia32.h	Mon Mar 17 21:31:50 2003
@@ -306,7 +306,7 @@
 #define ELF_ET_DYN_BASE		(IA32_PAGE_OFFSET/3 + 0x1000000)
 
 void ia64_elf32_init(struct pt_regs *regs);
-#define ELF_PLAT_INIT(_r)	ia64_elf32_init(_r)
+#define ELF_PLAT_INIT(_r, load_addr)	ia64_elf32_init(_r)
 
 #define elf_addr_t	u32
 
diff -Nru a/include/asm-ia64/linux_logo.h b/include/asm-ia64/linux_logo.h
--- a/include/asm-ia64/linux_logo.h	Mon Feb  4 23:41:04 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,28 +0,0 @@
-/* $Id: linux_logo.h,v 1.6 1998/07/30 16:30:20 jj Exp $
- * include/asm-ia64/linux_logo.h: This is a linux logo
- *                                to be displayed on boot.
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 1998 David Mosberger (davidm@hpl.hp.com)
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * image size has to be 80x80
- * values have to start from 0x20
- * (i.e. RGB(linux_logo_red[0],
- *	     linux_logo_green[0],
- *	     linux_logo_blue[0]) is color 0x20)
- * BW image has to be 80x80 as well, with MS bit
- * on the left
- * Serial_console ascii image can be any size,
- * but should contain %s to display the version
- */
- 
-#include <linux/init.h>
-#include <linux/version.h>
-
-#define linux_logo_banner "Linux/ia64 version " UTS_RELEASE
-
-#include <linux/linux_logo.h>
-
diff -Nru a/include/asm-m68k/amigahw.h b/include/asm-m68k/amigahw.h
--- a/include/asm-m68k/amigahw.h	Mon Feb  4 23:41:04 2002
+++ b/include/asm-m68k/amigahw.h	Thu Mar 13 05:14:53 2003
@@ -324,7 +324,7 @@
 };
 #define TOD3000_CNTRL1_HOLD	0
 #define TOD3000_CNTRL1_FREE	9
-#define TOD_3000 ((struct tod3000 *)(zTwoBase+0xDC0000))
+#define tod_3000 ((*(volatile struct tod3000 *)(zTwoBase+0xDC0000)))
 
 struct tod2000 {
   unsigned int  :28, second2:4;	/* lower digit */
@@ -349,6 +349,6 @@
 #define TOD2000_CNTRL1_BUSY	(1<<1)
 #define TOD2000_CNTRL3_24HMODE	(1<<2)
 #define TOD2000_HOUR1_PM	(1<<2)
-#define TOD_2000 ((struct tod2000 *)(zTwoBase+0xDC0000))
+#define tod_2000 ((*(volatile struct tod2000 *)(zTwoBase+0xDC0000)))
 
 #endif /* _M68K_AMIGAHW_H */
diff -Nru a/include/asm-m68k/apollohw.h b/include/asm-m68k/apollohw.h
--- a/include/asm-m68k/apollohw.h	Tue Feb  5 09:39:47 2002
+++ b/include/asm-m68k/apollohw.h	Thu Feb 27 07:26:59 2003
@@ -101,9 +101,4 @@
 
 #define isaIO2mem(x) (((((x) & 0x3f8)  << 7) | (((x) & 0xfc00) >> 6) | ((x) & 0x7)) + 0x40000 + IO_BASE)
 
-#define inb(addr) (*((volatile unsigned char *)(addr)))
-#define outb(val,addr) (*((volatile unsigned char *)(addr)) = (val))
-#define inw(addr) (*((volatile unsigned short *)(addr)))
-#define outw(val,addr) (*((volatile unsigned short *)(addr)) = (val))
-
 #endif
diff -Nru a/include/asm-m68k/elf.h b/include/asm-m68k/elf.h
--- a/include/asm-m68k/elf.h	Tue Feb  5 09:39:46 2002
+++ b/include/asm-m68k/elf.h	Mon Mar 17 21:31:50 2003
@@ -31,7 +31,7 @@
 /* For SVR4/m68k the function pointer to be registered with `atexit' is
    passed in %a1.  Although my copy of the ABI has no such statement, it
    is actually used on ASV.  */
-#define ELF_PLAT_INIT(_r)	_r->a1 = 0
+#define ELF_PLAT_INIT(_r, load_addr)	_r->a1 = 0
 
 #define USE_ELF_CORE_DUMP
 #ifndef CONFIG_SUN3
diff -Nru a/include/asm-m68k/io.h b/include/asm-m68k/io.h
--- a/include/asm-m68k/io.h	Tue Feb 25 02:08:54 2003
+++ b/include/asm-m68k/io.h	Tue Feb 18 12:30:19 2003
@@ -162,7 +162,9 @@
 #ifdef CONFIG_GG2
     case GG2_ISA: return GG2_ISA_MEM_B(addr);
 #endif
-      /* FIXME: any ISA mem mapping for PCMCIA? */
+#ifdef CONFIG_AMIGA_PCMCIA
+    case AG_ISA: return addr;
+#endif
     default: return 0; /* avoid warnings, just in case */
     }
 }
@@ -176,6 +178,9 @@
 #ifdef CONFIG_GG2
     case GG2_ISA: return GG2_ISA_MEM_W(addr);
 #endif
+#ifdef CONFIG_AMIGA_PCMCIA
+    case AG_ISA: return addr;
+#endif
     default: return 0; /* avoid warnings, just in case */
     }
 }
@@ -187,9 +192,9 @@
 #define isa_outw(val,port) (ISA_SEX ? out_be16(isa_itw(port),(val)) : out_le16(isa_itw(port),(val)))
 
 #define isa_readb(p)       in_8(isa_mtb(p))
-#define isa_readw(p)       in_le16(isa_mtw(p))
+#define isa_readw(p)       (ISA_SEX ? in_be16(isa_mtw(p)) : in_le16(isa_mtw(p)))
 #define isa_writeb(val,p)  out_8(isa_mtb(p),(val))
-#define isa_writew(val,p)  out_le16(isa_mtw(p),(val))
+#define isa_writew(val,p)  (ISA_SEX ? out_be16(isa_mtw(p),(val)) : out_le16(isa_mtw(p),(val)))
 
 static inline void isa_delay(void)
 {
diff -Nru a/include/asm-m68k/kmap_types.h b/include/asm-m68k/kmap_types.h
--- a/include/asm-m68k/kmap_types.h	Mon Sep  2 01:25:11 2002
+++ b/include/asm-m68k/kmap_types.h	Tue Feb 11 06:14:43 2003
@@ -15,6 +15,8 @@
 	KM_PTE1,
 	KM_IRQ0,
 	KM_IRQ1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
 	KM_TYPE_NR
 };
 
diff -Nru a/include/asm-m68k/linux_logo.h b/include/asm-m68k/linux_logo.h
--- a/include/asm-m68k/linux_logo.h	Mon Feb  4 23:41:05 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,924 +0,0 @@
-/* $Id: linux_logo.h,v 1.1 1997/04/16 17:51:24 jj Exp $
- * include/asm-m68k/linux_logo.h: This is a linux logo
- *                                 to be displayed on boot.
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * image size has to be 80x80
- * values have to start from 0x20
- * (i.e. RGB(linux_logo_red[0],
- *	     linux_logo_green[0],
- *	     linux_logo_blue[0]) is color 0x20)
- * BW image has to be 80x80 as well, with MS bit
- * on the left
- * Serial_console ascii image can be any size,
- * but should contain %s to display the version
- */
- 
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/version.h>
-
-#define linux_logo_banner "Linux/m68k version " UTS_RELEASE
-
-#ifdef CONFIG_MAC
-
-#define __HAVE_ARCH_LINUX_LOGO
-
-#define LINUX_LOGO_COLORS	185
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-unsigned char linux_logo_red[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0xfa,
-    0xf2, 0xf6, 0xe7, 0x74, 0x65, 0x7b, 0xea, 0xdd,
-    0xd6, 0x5e, 0xbe, 0x5a, 0xe2, 0xda, 0xee, 0xb6,
-    0xce, 0x65, 0x6e, 0x6a, 0xd2, 0xc6, 0x90, 0xca,
-    0x9e, 0xbb, 0xb2, 0x8a, 0xa2, 0x9a, 0x86, 0xc3,
-    0xfd, 0xae, 0x3e, 0xaa, 0x95, 0x80, 0x76, 0x79,
-    0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
-    0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
-    0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
-    0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
-    0xf6, 0xa6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8,
-    0x9c, 0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66,
-    0x5e, 0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae,
-    0x9c, 0xc5, 0x8d, 0xbe, 0xbe, 0xb2, 0x9a, 0xa8,
-    0x16, 0x12, 0x4a, 0x8e, 0xf2, 0xf6, 0xe4, 0xf1,
-    0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x9a, 0x2e,
-    0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62, 0xd6, 0xa3,
-    0x74, 0xa7, 0xa2, 0xca, 0xe0, 0xae, 0xbe, 0xce,
-    0xa3, 0x8e, 0x6d, 0x8e, 0x32, 0xaf, 0x50, 0x9e,
-    0x5b, 0x8a, 0x98, 0x82, 0x7a, 0x82, 0x56, 0x7c,
-    0x8a, 0x56, 0x5e, 0x86, 0x6a, 0x52, 0x59, 0x64,
-    0x5e,
-};
-
-unsigned char linux_logo_green[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0xfa,
-    0xf2, 0xf6, 0xe7, 0x74, 0x65, 0x7b, 0xea, 0xdd,
-    0xd6, 0x5e, 0xbe, 0x5a, 0xe2, 0xda, 0xee, 0xb6,
-    0xce, 0x62, 0x6e, 0x6a, 0xd2, 0xc6, 0x90, 0xca,
-    0x9e, 0xbb, 0xb2, 0x8a, 0xa2, 0x9a, 0x86, 0xc3,
-    0xfd, 0xae, 0x3e, 0xaa, 0x95, 0x80, 0x62, 0x5c,
-    0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
-    0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
-    0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
-    0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
-    0xda, 0xa6, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90,
-    0x76, 0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e,
-    0x46, 0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a,
-    0x6b, 0x8a, 0x8d, 0x8e, 0xb2, 0xa6, 0x79, 0x7c,
-    0x12, 0x0e, 0x36, 0x86, 0xba, 0xbe, 0xb8, 0xc4,
-    0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x7a, 0x20,
-    0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46, 0xa6, 0x6e,
-    0x51, 0x72, 0x92, 0xa2, 0xa6, 0x87, 0x96, 0xa2,
-    0x85, 0x7a, 0x6a, 0x6e, 0x22, 0x76, 0x36, 0x76,
-    0x3c, 0x6e, 0x63, 0x53, 0x66, 0x62, 0x42, 0x50,
-    0x56, 0x42, 0x56, 0x56, 0x56, 0x3e, 0x51, 0x52,
-    0x56,
-};
-
-unsigned char linux_logo_blue[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0xfa,
-    0xf2, 0xf6, 0xe7, 0x74, 0x65, 0x7b, 0xea, 0xdd,
-    0xd6, 0x5e, 0xbe, 0x5a, 0xe2, 0xda, 0xee, 0xb6,
-    0xce, 0x59, 0x6e, 0x6a, 0xd2, 0xc6, 0x90, 0xca,
-    0x9e, 0xbb, 0xb2, 0x8a, 0xa2, 0x9a, 0x86, 0xc3,
-    0xfd, 0xae, 0x3e, 0xaa, 0x95, 0x80, 0x2e, 0x08,
-    0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
-    0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
-    0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
-    0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
-    0x4a, 0xa6, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b,
-    0x0a, 0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a,
-    0x1e, 0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72,
-    0x0b, 0x0b, 0x8d, 0x22, 0x90, 0x92, 0x3c, 0x2c,
-    0x06, 0x06, 0x0e, 0x6a, 0x0e, 0x0e, 0x3e, 0x0e,
-    0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x2e, 0x06,
-    0x4e, 0x36, 0x06, 0x58, 0x24, 0x06, 0x3a, 0x08,
-    0x08, 0x07, 0x5e, 0x45, 0x0a, 0x32, 0x2e, 0x2a,
-    0x43, 0x48, 0x5f, 0x2e, 0x06, 0x06, 0x07, 0x24,
-    0x06, 0x32, 0x06, 0x06, 0x46, 0x2e, 0x22, 0x06,
-    0x06, 0x1e, 0x4c, 0x06, 0x3a, 0x22, 0x42, 0x34,
-    0x42,
-};
-
-unsigned char linux_logo[] __initdata = {
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
-    0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-    0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
-    0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
-    0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
-    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-    0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
-    0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-    0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
-    0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x37, 0x37, 0x37, 0x37, 0x38,
-    0x37, 0x37, 0x39, 0x37, 0x39, 0x38, 0x39, 0x3a,
-    0x32, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
-    0x34, 0x38, 0x38, 0x39, 0x38, 0x37, 0x38, 0x39,
-    0x38, 0x37, 0x38, 0x37, 0x37, 0x37, 0x37, 0x37,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x38, 0x37, 0x37, 0x37, 0x37,
-    0x38, 0x39, 0x37, 0x37, 0x37, 0x37, 0x38, 0x3b,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x25, 0x2f, 0x3c, 0x32, 0x22,
-    0x36, 0x3d, 0x38, 0x37, 0x39, 0x37, 0x38, 0x37,
-    0x39, 0x37, 0x38, 0x37, 0x38, 0x37, 0x37, 0x37,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x3d, 0x3e, 0x3a, 0x3e, 0x3e,
-    0x3e, 0x3f, 0x3e, 0x3a, 0x3e, 0x3e, 0x40, 0x22,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x26, 0x41, 0x41, 0x35, 0x25,
-    0x36, 0x22, 0x42, 0x38, 0x38, 0x37, 0x37, 0x38,
-    0x39, 0x37, 0x37, 0x38, 0x37, 0x38, 0x38, 0x3a,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x43, 0x3e, 0x44, 0x44, 0x45,
-    0x44, 0x40, 0x3a, 0x3f, 0x3a, 0x3f, 0x3b, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
-    0x36, 0x36, 0x35, 0x38, 0x38, 0x38, 0x38, 0x38,
-    0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x37, 0x44,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x34, 0x3e, 0x3a, 0x38, 0x38,
-    0x3e, 0x3e, 0x46, 0x3e, 0x46, 0x46, 0x33, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x47, 0x38, 0x37, 0x37, 0x37,
-    0x38, 0x37, 0x37, 0x37, 0x38, 0x38, 0x37, 0x48,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x33, 0x37, 0x44, 0x3e, 0x22,
-    0x2d, 0x2c, 0x49, 0x43, 0x4a, 0x4b, 0x22, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x49, 0x4c, 0x46, 0x44, 0x46,
-    0x4c, 0x38, 0x44, 0x38, 0x38, 0x3e, 0x37, 0x4d,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x34, 0x3e, 0x3e, 0x3a, 0x36,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
-    0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
-    0x21, 0x20, 0x20, 0x20, 0x4e, 0x37, 0x38, 0x4f,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x34, 0x44, 0x3a, 0x3e, 0x43,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-    0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
-    0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x50, 0x38, 0x3e, 0x51,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x2c, 0x3a, 0x44, 0x44, 0x52,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-    0x30, 0x3b, 0x41, 0x24, 0x24, 0x36, 0x36, 0x36,
-    0x23, 0x2f, 0x53, 0x54, 0x55, 0x30, 0x25, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x51, 0x3e, 0x37, 0x42,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x34, 0x44, 0x45, 0x3e, 0x45,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
-    0x56, 0x4d, 0x57, 0x3b, 0x22, 0x36, 0x36, 0x21,
-    0x49, 0x51, 0x4c, 0x45, 0x40, 0x56, 0x23, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x40, 0x44, 0x38, 0x51,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x2e, 0x44, 0x40, 0x44, 0x42,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
-    0x45, 0x57, 0x44, 0x39, 0x35, 0x36, 0x36, 0x26,
-    0x4c, 0x58, 0x59, 0x3d, 0x3f, 0x3e, 0x2e, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x57, 0x44, 0x3e, 0x48,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x5a, 0x44, 0x45, 0x3e, 0x44,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4b,
-    0x5b, 0x25, 0x2f, 0x44, 0x3d, 0x22, 0x23, 0x32,
-    0x3a, 0x42, 0x21, 0x31, 0x43, 0x46, 0x50, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x47, 0x3e, 0x38, 0x50,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x49, 0x40, 0x40, 0x44, 0x38,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3b,
-    0x4b, 0x21, 0x31, 0x5c, 0x5d, 0x28, 0x30, 0x2b,
-    0x3f, 0x4b, 0x36, 0x23, 0x32, 0x42, 0x4d, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x2e, 0x5a, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x42, 0x44, 0x44, 0x52,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x2c, 0x4c, 0x40, 0x4c, 0x37,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x41, 0x23, 0x3c,
-    0x5d, 0x36, 0x28, 0x3b, 0x5e, 0x5f, 0x5f, 0x60,
-    0x54, 0x4b, 0x36, 0x36, 0x36, 0x57, 0x57, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2e, 0x5a, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x40, 0x44, 0x3a, 0x5c,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x2a, 0x44, 0x45, 0x4c, 0x3a,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x43, 0x23, 0x35,
-    0x4c, 0x25, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
-    0x67, 0x68, 0x69, 0x36, 0x31, 0x39, 0x53, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x52, 0x45, 0x44, 0x54,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x2a, 0x40, 0x4d, 0x4c, 0x38,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
-    0x57, 0x6a, 0x6b, 0x65, 0x6c, 0x6d, 0x6e, 0x6f,
-    0x70, 0x71, 0x6e, 0x66, 0x72, 0x73, 0x2a, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x51, 0x3a, 0x44, 0x47,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x2c, 0x45, 0x4c, 0x4c, 0x38,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
-    0x74, 0x6b, 0x75, 0x6c, 0x64, 0x6e, 0x71, 0x76,
-    0x77, 0x78, 0x79, 0x71, 0x71, 0x7a, 0x74, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
-    0x20, 0x20, 0x20, 0x20, 0x54, 0x44, 0x44, 0x54,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x5a, 0x48, 0x48, 0x4f, 0x37,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x7b,
-    0x7c, 0x7d, 0x7e, 0x6c, 0x6d, 0x7f, 0x71, 0x80,
-    0x78, 0x79, 0x79, 0x79, 0x7a, 0x67, 0x66, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x25, 0x41, 0x2a, 0x23,
-    0x20, 0x20, 0x20, 0x20, 0x81, 0x44, 0x40, 0x5b,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x2c, 0x44, 0x45, 0x4f, 0x38,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x82,
-    0x6b, 0x83, 0x84, 0x64, 0x6e, 0x71, 0x76, 0x85,
-    0x79, 0x79, 0x71, 0x86, 0x87, 0x83, 0x88, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x21, 0x43, 0x2b, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x52, 0x44, 0x44, 0x50,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x5a, 0x40, 0x4d, 0x4f, 0x38,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
-    0x89, 0x8a, 0x6c, 0x8b, 0x7f, 0x71, 0x79, 0x79,
-    0x71, 0x8c, 0x8d, 0x8e, 0x83, 0x8e, 0x8f, 0x36,
-    0x21, 0x2b, 0x23, 0x36, 0x36, 0x5a, 0x2e, 0x26,
-    0x22, 0x20, 0x20, 0x20, 0x42, 0x40, 0x38, 0x50,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x2c, 0x4c, 0x4f, 0x4f, 0x38,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
-    0x90, 0x91, 0x92, 0x7a, 0x6f, 0x6e, 0x67, 0x92,
-    0x93, 0x6b, 0x8e, 0x94, 0x95, 0x96, 0x49, 0x36,
-    0x36, 0x2d, 0x3b, 0x35, 0x36, 0x24, 0x43, 0x32,
-    0x28, 0x21, 0x20, 0x20, 0x57, 0x40, 0x44, 0x54,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x34, 0x4d, 0x42, 0x51, 0x38,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
-    0x5d, 0x97, 0x98, 0x93, 0x86, 0x66, 0x99, 0x87,
-    0x7d, 0x7d, 0x99, 0x6a, 0x57, 0x4d, 0x59, 0x23,
-    0x36, 0x24, 0x3b, 0x3b, 0x24, 0x36, 0x2e, 0x31,
-    0x26, 0x22, 0x20, 0x20, 0x52, 0x44, 0x44, 0x9a,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x5a, 0x57, 0x57, 0x57, 0x37,
-    0x20, 0x20, 0x21, 0x28, 0x33, 0x3c, 0x25, 0x22,
-    0x53, 0x42, 0x97, 0x98, 0x99, 0x87, 0x99, 0x6b,
-    0x7c, 0x9b, 0x9c, 0x51, 0x4f, 0x3f, 0x40, 0x2c,
-    0x36, 0x36, 0x33, 0x5a, 0x21, 0x36, 0x22, 0x43,
-    0x33, 0x28, 0x21, 0x20, 0x42, 0x44, 0x37, 0x4f,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x2a, 0x51, 0x42, 0x51, 0x37,
-    0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
-    0x4e, 0x4d, 0x42, 0x9d, 0x9e, 0x98, 0x98, 0x9f,
-    0x97, 0x51, 0x42, 0x4c, 0x39, 0x58, 0x58, 0x47,
-    0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x5a,
-    0x2e, 0x27, 0x23, 0x20, 0x59, 0x48, 0x38, 0x50,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x2a, 0x42, 0x51, 0x42, 0x3e,
-    0x20, 0x22, 0x24, 0x2b, 0x41, 0x28, 0x36, 0x32,
-    0x3e, 0x3f, 0x42, 0x42, 0x42, 0x51, 0x51, 0x42,
-    0x42, 0x57, 0x40, 0x38, 0x58, 0x58, 0x58, 0x58,
-    0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
-    0x2f, 0x2b, 0x24, 0x21, 0x57, 0x4f, 0x3e, 0x53,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x33, 0x47, 0x51, 0x52, 0x38,
-    0x21, 0x28, 0x32, 0x43, 0x32, 0x28, 0x21, 0x47,
-    0x58, 0x39, 0x48, 0x42, 0x42, 0x42, 0x42, 0x42,
-    0x48, 0x3a, 0x37, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x4f, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x2a, 0x2f, 0x2a, 0x28, 0x42, 0x4f, 0x44, 0x52,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x5a, 0x57, 0x47, 0x51, 0x37,
-    0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x43, 0x37,
-    0x58, 0x58, 0x46, 0x4d, 0x42, 0x42, 0x57, 0x3f,
-    0x39, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2d, 0x31, 0x27, 0x4f, 0x47, 0x38, 0x50,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x25, 0x57, 0x47, 0x52, 0x38,
-    0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x45, 0x58,
-    0x58, 0x58, 0x58, 0x39, 0x44, 0x3a, 0x39, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x52, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x28, 0x43, 0x5a, 0x45, 0x4d, 0x37, 0x9a,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x2a, 0x47, 0x52, 0x59, 0x37,
-    0x35, 0x43, 0x28, 0x36, 0x36, 0x4a, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x37, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x3a, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x28, 0x41, 0x48, 0x4d, 0x38, 0x54,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x2a, 0x81, 0x5b, 0x51, 0x38,
-    0x43, 0x25, 0x36, 0x36, 0x23, 0x57, 0x37, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x37, 0x38, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x30, 0x51, 0x40, 0x3a, 0x56,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x33, 0x51, 0x47, 0x81, 0x3e,
-    0x27, 0x36, 0x36, 0x36, 0x2a, 0x57, 0x39, 0x58,
-    0x58, 0x58, 0x58, 0x37, 0x38, 0x38, 0x37, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x37, 0x39, 0x46,
-    0x44, 0x3a, 0x3c, 0x21, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x48, 0x59, 0x37, 0x5d,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x27, 0x52, 0x4e, 0x5b, 0x44,
-    0x36, 0x36, 0x36, 0x21, 0x31, 0x5b, 0x48, 0x3e,
-    0x39, 0x37, 0x37, 0x46, 0x44, 0x3a, 0x46, 0x37,
-    0x37, 0x37, 0x39, 0x3a, 0x40, 0x48, 0x4f, 0x4f,
-    0x4d, 0x4f, 0x47, 0x28, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x4f, 0x81, 0x40, 0x5d,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x33, 0x52, 0x50, 0x56, 0x38,
-    0x36, 0x36, 0x36, 0x22, 0x41, 0x47, 0x45, 0x38,
-    0x37, 0x58, 0x58, 0x37, 0x3e, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x39, 0x46, 0x44, 0x4c, 0x4f,
-    0x57, 0x57, 0x4c, 0x50, 0x21, 0x23, 0x33, 0x23,
-    0x36, 0x36, 0x36, 0x36, 0x4d, 0x51, 0x39, 0x3b,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x33, 0x57, 0x55, 0x55, 0x37,
-    0x37, 0x37, 0x38, 0x38, 0x38, 0x37, 0x37, 0x37,
-    0x37, 0x37, 0x38, 0x37, 0x37, 0x37, 0x38, 0x37,
-    0x37, 0x37, 0x37, 0x39, 0x3e, 0x37, 0x38, 0x38,
-    0x38, 0x37, 0x38, 0x38, 0x38, 0x37, 0x38, 0x38,
-    0x37, 0x38, 0x38, 0x37, 0x47, 0x42, 0x48, 0x9a,
-    0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x33, 0x5b, 0x81, 0x5d, 0x37,
-    0x38, 0x37, 0x37, 0x38, 0x37, 0x38, 0x38, 0x37,
-    0x38, 0x37, 0x37, 0x37, 0x37, 0x37, 0x38, 0x37,
-    0x38, 0x37, 0x38, 0x37, 0x37, 0x38, 0x37, 0x37,
-    0x38, 0x37, 0x37, 0x37, 0x38, 0x38, 0x37, 0x3e,
-    0x37, 0x38, 0x38, 0x37, 0x57, 0x57, 0x48, 0x5d,
-    0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x33, 0x52, 0x59, 0x50, 0x5b,
-    0x54, 0x5b, 0x5b, 0x54, 0x81, 0x5b, 0x55, 0x55,
-    0x52, 0x54, 0x81, 0x81, 0x81, 0x50, 0x52, 0x54,
-    0x5b, 0x59, 0x52, 0x52, 0x5b, 0x52, 0x5b, 0x81,
-    0x5b, 0x47, 0x51, 0x52, 0x57, 0x57, 0x57, 0x57,
-    0x51, 0x57, 0x52, 0x57, 0x48, 0x57, 0x4c, 0x3b,
-    0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x33, 0x54, 0x54, 0x5b, 0x50,
-    0x54, 0x50, 0x54, 0x81, 0x50, 0x59, 0x54, 0x50,
-    0x5b, 0x81, 0x81, 0x59, 0x81, 0x59, 0x59, 0x59,
-    0x59, 0x47, 0x81, 0x51, 0x47, 0x51, 0x59, 0x81,
-    0x81, 0x51, 0x47, 0x50, 0x59, 0x59, 0x59, 0x47,
-    0x47, 0x47, 0x52, 0x57, 0x52, 0x47, 0x59, 0x26,
-    0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x22, 0x27, 0x55, 0x50, 0x55, 0x50,
-    0x55, 0x81, 0x54, 0x52, 0x52, 0x81, 0x5b, 0x50,
-    0x5b, 0x52, 0x52, 0x51, 0x57, 0x52, 0x52, 0x52,
-    0x54, 0x51, 0x81, 0x52, 0x59, 0x52, 0x5b, 0x5b,
-    0x59, 0x5b, 0x51, 0x52, 0x52, 0x4f, 0x5b, 0x51,
-    0x52, 0x47, 0x59, 0x42, 0x47, 0x81, 0x5c, 0x21,
-    0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x33, 0x81, 0x54, 0x5c, 0x54,
-    0x50, 0x5b, 0x50, 0x50, 0x81, 0x5b, 0x5c, 0x5b,
-    0x50, 0x59, 0x81, 0x81, 0x81, 0x81, 0x47, 0x50,
-    0x50, 0x59, 0x5b, 0x50, 0x52, 0x81, 0x50, 0x59,
-    0x5b, 0x81, 0x59, 0x81, 0x59, 0x47, 0x59, 0x47,
-    0x59, 0x52, 0x51, 0x48, 0x51, 0x52, 0x5d, 0x36,
-    0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x22, 0x25, 0x2a, 0x50, 0x4e, 0x5c, 0x54,
-    0x5c, 0x5b, 0x5b, 0x5b, 0x59, 0x5b, 0x50, 0x54,
-    0x5b, 0x54, 0x5b, 0x5b, 0x54, 0x54, 0x5b, 0x5b,
-    0x5b, 0x81, 0x55, 0x81, 0x55, 0x54, 0x5b, 0x5c,
-    0x5b, 0x4e, 0x51, 0x5b, 0x5b, 0x57, 0x51, 0x4f,
-    0x4d, 0x47, 0x4f, 0x4c, 0x51, 0x52, 0x4b, 0x36,
-    0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x2a, 0x2a, 0x50, 0x9a, 0x54, 0x5c,
-    0x55, 0x50, 0x81, 0x59, 0x54, 0x50, 0x54, 0x50,
-    0x50, 0x50, 0x81, 0x81, 0x50, 0x50, 0x50, 0x81,
-    0x81, 0x5b, 0x47, 0x51, 0x81, 0x59, 0x81, 0x55,
-    0x59, 0x59, 0x81, 0x42, 0x27, 0x36, 0x28, 0x36,
-    0x27, 0x36, 0x28, 0x2d, 0x47, 0x52, 0x2d, 0x36,
-    0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x22, 0x25, 0x2c, 0x26, 0x53, 0x4e, 0x55, 0x5c,
-    0x55, 0x55, 0x55, 0x81, 0x54, 0x50, 0x54, 0x55,
-    0x5b, 0x55, 0x52, 0x54, 0x54, 0x5b, 0x54, 0x55,
-    0x36, 0x36, 0x27, 0x2a, 0x2a, 0x27, 0xa0, 0x27,
-    0x2a, 0x2a, 0x2c, 0x27, 0x5d, 0x22, 0x22, 0x28,
-    0x28, 0x22, 0x25, 0x59, 0x51, 0x53, 0x27, 0x36,
-    0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x28, 0x32, 0x2f, 0x21, 0x4a, 0x54, 0x5c, 0x4e,
-    0x5c, 0x81, 0x5c, 0x54, 0x5c, 0x54, 0x5c, 0x50,
-    0x81, 0x50, 0x50, 0x81, 0x81, 0x5c, 0x50, 0x81,
-    0x5d, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xa0, 0x25,
-    0x28, 0x21, 0x28, 0x81, 0x59, 0x4a, 0x28, 0x36,
-    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x25, 0x2c, 0x5a, 0x36, 0x32, 0x9a, 0x81, 0x4e,
-    0x55, 0x5b, 0x50, 0x54, 0x5c, 0x54, 0x55, 0x55,
-    0x54, 0x4e, 0x54, 0x55, 0x5b, 0x4e, 0x55, 0x5b,
-    0x3b, 0x4e, 0x4a, 0x3b, 0x4a, 0x4e, 0x3b, 0x5d,
-    0x56, 0x3b, 0x56, 0x5c, 0x50, 0x3a, 0x3e, 0x40,
-    0x4f, 0x57, 0x81, 0x4e, 0x4e, 0x27, 0x36, 0x36,
-    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x30, 0x2d, 0x21, 0x36, 0x23, 0x3d, 0x53, 0x43,
-    0x4a, 0x5d, 0x55, 0x5c, 0x4e, 0x5c, 0x50, 0x5c,
-    0x81, 0x50, 0x50, 0x81, 0x50, 0x50, 0x50, 0x50,
-    0x4e, 0x5b, 0x54, 0x5b, 0x51, 0x59, 0x5b, 0x5b,
-    0x54, 0x5b, 0x5b, 0x52, 0x51, 0x42, 0x5b, 0x5c,
-    0x5c, 0x53, 0x5b, 0x3b, 0x28, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x5a, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0x2e, 0x36, 0x36, 0x23, 0x41, 0x56, 0x2e,
-    0x33, 0x50, 0x55, 0x81, 0x54, 0x5b, 0x54, 0x52,
-    0x5b, 0x55, 0x54, 0x55, 0x55, 0x55, 0x5b, 0x9a,
-    0x5c, 0x81, 0x81, 0x81, 0x52, 0x59, 0x50, 0x59,
-    0x59, 0x59, 0x59, 0x50, 0x81, 0x81, 0x5b, 0x5b,
-    0x5b, 0x54, 0x34, 0x22, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x5a, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x2b, 0x5a, 0x36, 0x36, 0x36, 0x27, 0x3d, 0x28,
-    0xa0, 0x5d, 0x5c, 0x55, 0x50, 0x50, 0x5c, 0x81,
-    0x81, 0x50, 0x50, 0x47, 0x50, 0x5c, 0x5c, 0x52,
-    0x54, 0x5b, 0x5b, 0x5b, 0x59, 0x52, 0x5b, 0x52,
-    0x5b, 0x52, 0x52, 0x54, 0x59, 0x5b, 0x81, 0x81,
-    0x9a, 0x33, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x35, 0x5a, 0x36, 0x36, 0x36, 0x36, 0x30, 0x4e,
-    0x52, 0x54, 0x56, 0x55, 0x55, 0x55, 0x55, 0x5b,
-    0x55, 0x55, 0x54, 0x5b, 0x54, 0x55, 0x50, 0x59,
-    0x5c, 0x81, 0x59, 0x52, 0x59, 0x59, 0x81, 0x59,
-    0x81, 0x81, 0x81, 0x81, 0x5b, 0x5b, 0x81, 0x53,
-    0x2a, 0x27, 0xa1, 0x24, 0x25, 0x28, 0x21, 0x36,
-    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
-    0x5a, 0x4b, 0xa2, 0x8d, 0x8a, 0x5f, 0x21, 0x2d,
-    0x55, 0x5c, 0x9a, 0x5c, 0x5c, 0x5c, 0x50, 0x9a,
-    0x5c, 0x9a, 0x50, 0x5c, 0x5c, 0x5c, 0x54, 0x5b,
-    0x55, 0x5b, 0x54, 0x81, 0x5b, 0x5b, 0x5b, 0x54,
-    0x54, 0x5b, 0x5b, 0x5b, 0x5b, 0x54, 0x54, 0x30,
-    0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
-    0x21, 0x41, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
-    0x2d, 0xa3, 0x83, 0xa4, 0xa5, 0xa5, 0x88, 0x22,
-    0x3b, 0x47, 0x53, 0x55, 0x55, 0x53, 0x54, 0x5b,
-    0x52, 0x53, 0x54, 0x54, 0x54, 0x50, 0x5c, 0x59,
-    0x56, 0x59, 0x5b, 0x50, 0x50, 0x59, 0x9a, 0x59,
-    0x5c, 0x81, 0x50, 0x59, 0x9a, 0x52, 0x68, 0x69,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
-    0x25, 0x4b, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
-    0x4b, 0x9b, 0x63, 0xa4, 0xa5, 0xa5, 0xa5, 0x62,
-    0x21, 0x2e, 0x44, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x3a, 0x37, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0xa6, 0xa7, 0x71, 0x6e, 0xa8,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
-    0x8c, 0xa9, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x3c, 0x3d,
-    0x68, 0x8e, 0xaa, 0xab, 0xa5, 0xa5, 0xa5, 0x8b,
-    0x8f, 0x36, 0x32, 0x4d, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x3e, 0x38, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0xac, 0xa4, 0xa7, 0xad, 0xa0,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x5f,
-    0x7f, 0x6e, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x23, 0x30, 0x31, 0xae, 0x9b, 0x87, 0x99, 0x99,
-    0x94, 0x63, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0x65, 0xaf, 0x36, 0x24, 0x50, 0x37, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x37, 0x38, 0xac, 0x6c, 0x64, 0x94, 0xaf,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x7b, 0x65,
-    0x8b, 0x64, 0xb0, 0x2a, 0x23, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x24, 0x2b, 0xae, 0x94, 0x63, 0x7e, 0x63, 0x63,
-    0x84, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa7, 0x66, 0x22, 0x36, 0x21, 0x3b, 0x38, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x3a, 0x4d, 0xb1, 0x84, 0x84, 0x8e, 0x89,
-    0xa1, 0x36, 0x36, 0x36, 0x21, 0xb2, 0x87, 0x84,
-    0x6c, 0x6c, 0xb3, 0x35, 0x24, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x31, 0xb4, 0x63, 0x6c, 0xa4, 0xa4, 0xab,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0x6e, 0xb5, 0x36, 0x36, 0x36, 0x2c, 0x3f,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x48, 0x4d, 0xb6, 0x7e, 0x7e, 0x83, 0x6b,
-    0xb7, 0xb8, 0x8f, 0xb8, 0xb9, 0x99, 0x63, 0x6c,
-    0xa4, 0xa4, 0xba, 0x2d, 0x27, 0x23, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x26, 0x2d, 0x9b, 0x63, 0x6c, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa7, 0x8c, 0xa0, 0x36, 0x36, 0x36, 0x30,
-    0x45, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x37, 0x48, 0x4d, 0xbb, 0x63, 0x84, 0xbc, 0x8e,
-    0x87, 0x99, 0x6b, 0x99, 0x8e, 0x63, 0xa4, 0xa5,
-    0xa5, 0xab, 0x65, 0xb3, 0x5a, 0x26, 0x23, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2d, 0xbd, 0xbc, 0x6c, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa7, 0x91, 0x36, 0x36, 0x36, 0x36,
-    0x2d, 0x37, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x37, 0x40, 0x4d, 0xbe, 0x75, 0x84, 0xaa, 0xbc,
-    0x83, 0x94, 0x94, 0x83, 0x63, 0x6c, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa4, 0xbf, 0x3c, 0x35, 0x26, 0x23,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2e, 0xbd, 0x83, 0x84, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa7, 0x7a, 0x7b, 0x36, 0x36, 0x36,
-    0x24, 0x46, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x44, 0x51, 0xb4, 0x83, 0x84, 0x6c, 0x84,
-    0x7e, 0x63, 0x63, 0x7e, 0x84, 0xa4, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xab, 0x6c, 0xbf, 0x4b, 0x2c, 0x27,
-    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x25, 0x31, 0xc0, 0x94, 0x84, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa7, 0x92, 0xa1, 0x36, 0x36,
-    0x32, 0x39, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x3f, 0x2f, 0x98, 0x83, 0x84, 0xa4, 0xab,
-    0xa4, 0x6c, 0x6c, 0xa4, 0xa4, 0xab, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0x65, 0xc1, 0x2c,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x25, 0x31, 0xc0, 0x8e, 0x84, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0x6e, 0x5f, 0x27, 0x4b,
-    0x3f, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x38, 0x34, 0xa1, 0xb7, 0x83, 0x84, 0xa4, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xc0,
-    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2d, 0xc0, 0x8e, 0x84, 0xab, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa7, 0x67, 0x9c, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x45,
-    0x35, 0x36, 0xa0, 0xb9, 0x83, 0x84, 0xab, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xab, 0xa4, 0xbe,
-    0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x30, 0x2f, 0xb4, 0x94, 0x84, 0xab, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0x6e, 0x92, 0x40,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x58, 0x37, 0x5b, 0x25,
-    0x36, 0x36, 0x69, 0xb7, 0x75, 0x6c, 0xab, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xab, 0x84, 0xbc, 0xc1,
-    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0xc2, 0x6b, 0xbc, 0xa4, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0x7a, 0x8a, 0xc3,
-    0x44, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
-    0x58, 0x58, 0x58, 0x58, 0x4d, 0x2c, 0x36, 0x36,
-    0x36, 0x36, 0xc4, 0x98, 0x75, 0x6c, 0xab, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa4, 0xaa, 0x94, 0xae, 0x2c,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x35, 0x9e, 0x7d, 0xaa, 0xa4, 0xab, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xab, 0x84, 0x8a, 0xb7,
-    0x7b, 0x53, 0x45, 0x37, 0x58, 0x58, 0x58, 0x37,
-    0x38, 0x4c, 0x4e, 0x2c, 0x21, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x7b, 0xb7, 0x83, 0x84, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0x6c, 0x7e, 0x83, 0x9b, 0xb3, 0x31, 0x30,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x5a, 0x9f, 0x7d, 0xbc, 0x84, 0x6c, 0xa4, 0xa4,
-    0xab, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0x84, 0x83, 0xc5,
-    0xc6, 0x36, 0x21, 0x26, 0x2b, 0x5a, 0x33, 0x30,
-    0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xc6, 0xb9, 0x94, 0x84, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0x6c, 0x6c,
-    0x7e, 0x8e, 0xbd, 0xb3, 0x34, 0x2b, 0x27, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0xc7, 0x6b, 0x87, 0x83, 0x75, 0xbc, 0x63,
-    0x7e, 0x84, 0x6c, 0x6c, 0xa4, 0xab, 0xa5, 0xa5,
-    0xa5, 0xa5, 0xa5, 0xa5, 0xab, 0x7e, 0x8e, 0xb7,
-    0x82, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xc8, 0xb9, 0x7d, 0x7e, 0xa4, 0xa5,
-    0xa5, 0xa5, 0xab, 0xa4, 0x6c, 0x7e, 0xbc, 0x94,
-    0xb4, 0xb3, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x27, 0x31, 0xc9, 0xc7, 0xb9, 0x7c, 0x6b, 0x99,
-    0x87, 0x7d, 0x94, 0x75, 0xbc, 0x7e, 0x6c, 0xa4,
-    0xab, 0xab, 0xab, 0xab, 0x6c, 0x83, 0x8d, 0xca,
-    0x82, 0xa1, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xc6, 0xca, 0x6b, 0x75, 0x84, 0x6c,
-    0xab, 0xa4, 0x6c, 0x84, 0xbc, 0x7d, 0x6b, 0x9e,
-    0x41, 0x5a, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x28, 0x27, 0x35, 0x2d, 0x49, 0xb3, 0xc3, 0x98,
-    0xb7, 0xb9, 0xc5, 0x7c, 0x8d, 0x99, 0x8e, 0x75,
-    0x63, 0x84, 0x84, 0xaa, 0x75, 0x99, 0xb7, 0xcb,
-    0xc8, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
-    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
-    0x36, 0x21, 0xb2, 0x89, 0xc5, 0x87, 0x75, 0x7e,
-    0xaa, 0x7e, 0x75, 0x8e, 0x6b, 0xb7, 0xb3, 0x34,
-    0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
-    0x49, 0xcc, 0xcd, 0x74, 0x89, 0xca, 0xb7, 0x7c,
-    0x8d, 0x99, 0x7d, 0x87, 0x7c, 0x98, 0xcb, 0x82,
-    0xc4, 0x2b, 0x4a, 0x49, 0x2f, 0x34, 0x2d, 0x2d,
-    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x41,
-    0x4b, 0x3c, 0xce, 0xcf, 0x98, 0x7c, 0x6b, 0x87,
-    0x7d, 0x87, 0x6b, 0xc5, 0x91, 0xc2, 0x31, 0x2a,
-    0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
-    0x33, 0x5a, 0x2e, 0x43, 0x49, 0xb0, 0x74, 0xcf,
-    0x89, 0xca, 0xca, 0xca, 0xd0, 0xcf, 0xb5, 0xd1,
-    0x49, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
-    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
-    0x2b, 0x34, 0xd2, 0xc8, 0xd3, 0x98, 0xb9, 0xc5,
-    0xc5, 0xb9, 0xca, 0x74, 0x49, 0x5a, 0x27, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
-    0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x49,
-    0xd4, 0xb5, 0x82, 0x82, 0x82, 0xc8, 0xd5, 0x43,
-    0x5a, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
-    0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
-    0x24, 0x2a, 0x31, 0xd6, 0xc6, 0x82, 0xcf, 0x89,
-    0xd3, 0xb8, 0xd7, 0x2f, 0x35, 0x26, 0x23, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
-    0x31, 0x2f, 0xd2, 0xd6, 0xd6, 0x2f, 0x2e, 0x33,
-    0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x27, 0x35, 0x34, 0xd6, 0xd6, 0xd6,
-    0xd8, 0xd2, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
-    0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
-    0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
-    0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-};
-
-#endif /* !INCLUDE_LINUX_LOGO_DATA */
-
-#endif /* CONFIG_MAC */
-
-#include <linux/linux_logo.h>
-
diff -Nru a/include/asm-m68k/page.h b/include/asm-m68k/page.h
--- a/include/asm-m68k/page.h	Mon Feb 24 10:29:43 2003
+++ b/include/asm-m68k/page.h	Fri Feb  7 14:02:31 2003
@@ -6,10 +6,13 @@
 /* PAGE_SHIFT determines the page size */
 #ifndef CONFIG_SUN3
 #define PAGE_SHIFT	(12)
-#define PAGE_SIZE	(4096)
 #else
 #define PAGE_SHIFT	(13)
-#define PAGE_SIZE	(8192)
+#endif
+#ifdef __ASSEMBLY__
+#define PAGE_SIZE	(1 << PAGE_SHIFT)
+#else
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
 #endif
 #define PAGE_MASK	(~(PAGE_SIZE-1))
 
@@ -142,7 +145,7 @@
 {
      if(x == 0)
 	  return 0;
-     if(x > PAGE_OFFSET)
+     if(x >= PAGE_OFFSET)
         return (x-PAGE_OFFSET);
      else
         return (x+0x2000000);
diff -Nru a/include/asm-m68k/rtc.h b/include/asm-m68k/rtc.h
--- a/include/asm-m68k/rtc.h	Fri Jan  3 09:01:08 2003
+++ b/include/asm-m68k/rtc.h	Sun Mar  2 10:06:06 2003
@@ -14,23 +14,21 @@
 #ifdef __KERNEL__
 
 #include <linux/rtc.h>
+#include <asm/errno.h>
 #include <asm/machdep.h>
 
-/* a few implementation details for the emulation : */
-
 #define RTC_PIE 0x40		/* periodic interrupt enable */
 #define RTC_AIE 0x20		/* alarm interrupt enable */
 #define RTC_UIE 0x10		/* update-finished interrupt enable */
 
-extern void gen_rtc_interrupt(unsigned long);
-
 /* some dummy definitions */
+#define RTC_BATT_BAD 0x100	/* battery bad */
 #define RTC_SQWE 0x08		/* enable square-wave output */
 #define RTC_DM_BINARY 0x04	/* all time/date values are BCD if clear */
 #define RTC_24H 0x02		/* 24 hour mode - else hours bit 7 means pm */
 #define RTC_DST_EN 0x01	        /* auto switch DST - works f. USA only */
 
-static inline void get_rtc_time(struct rtc_time *time)
+static inline unsigned int get_rtc_time(struct rtc_time *time)
 {
 	/*
 	 * Only the values that we read from the RTC are set. We leave
@@ -39,6 +37,7 @@
 	 * by the RTC when initially set to a non-zero value.
 	 */
 	mach_hwclk(0, time);
+	return RTC_24H;
 }
 
 static inline int set_rtc_time(struct rtc_time *time)
@@ -52,7 +51,7 @@
 		return mach_get_ss();
 	else{
 		struct rtc_time h;
-
+		
 		get_rtc_time(&h);
 		return h.tm_sec;
 	}
@@ -72,7 +71,6 @@
 	else
 		return -EINVAL;
 }
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM__RTC_H */
diff -Nru a/include/asm-m68k/siginfo.h b/include/asm-m68k/siginfo.h
--- a/include/asm-m68k/siginfo.h	Fri May 31 03:28:37 2002
+++ b/include/asm-m68k/siginfo.h	Tue Feb 25 05:18:49 2003
@@ -23,8 +23,11 @@
 
 		/* POSIX.1b timers */
 		struct {
-			unsigned int _timer1;
-			unsigned int _timer2;
+			timer_t _tid;		/* timer id */
+			int _overrun;		/* overrun count */
+			char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
+			sigval_t _sigval;	/* same as below */
+			int _sys_private;       /* not to be passed to user */
 		} _timer;
 
 		/* POSIX.1b signals */
diff -Nru a/include/asm-m68k/sun3-head.h b/include/asm-m68k/sun3-head.h
--- a/include/asm-m68k/sun3-head.h	Tue Feb  5 09:39:47 2002
+++ b/include/asm-m68k/sun3-head.h	Wed Feb 26 10:33:30 2003
@@ -9,4 +9,4 @@
 #define FC_SUPERD    5
 #define FC_CPU      7
 
-#endif __SUN3_HEAD_H
+#endif /* __SUN3_HEAD_H */
diff -Nru a/include/asm-m68k/system.h b/include/asm-m68k/system.h
--- a/include/asm-m68k/system.h	Mon Dec 16 03:17:20 2002
+++ b/include/asm-m68k/system.h	Wed Feb 26 10:53:19 2003
@@ -101,21 +101,24 @@
 	case 1:
 		tmp = *(u8 *)ptr;
 		*(u8 *)ptr = x;
+		x = tmp;
 		break;
 	case 2:
 		tmp = *(u16 *)ptr;
 		*(u16 *)ptr = x;
+		x = tmp;
 		break;
 	case 4:
 		tmp = *(u32 *)ptr;
 		*(u32 *)ptr = x;
+		x = tmp;
 		break;
 	default:
 		BUG();
 	}
 
 	local_irq_restore(flags);
-	return tmp;
+	return x;
 }
 #else
 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
diff -Nru a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h
--- a/include/asm-m68k/unistd.h	Fri Oct  4 13:52:52 2002
+++ b/include/asm-m68k/unistd.h	Tue Feb 25 05:41:42 2003
@@ -239,7 +239,9 @@
 #define __NR_fremovexattr	234
 #define __NR_futex		235
 
-/* user-visible error numbers are in the range -1 - -122: see
+#define NR_syscalls		236
+
+/* user-visible error numbers are in the range -1 - -124: see
    <asm-m68k/errno.h> */
 
 #define __syscall_return(type, res) \
diff -Nru a/include/asm-m68knommu/elf.h b/include/asm-m68knommu/elf.h
--- a/include/asm-m68knommu/elf.h	Tue Dec 10 16:41:17 2002
+++ b/include/asm-m68knommu/elf.h	Mon Mar 17 21:31:50 2003
@@ -31,7 +31,7 @@
 /* For SVR4/m68k the function pointer to be registered with `atexit' is
    passed in %a1.  Although my copy of the ABI has no such statement, it
    is actually used on ASV.  */
-#define ELF_PLAT_INIT(_r)	_r->a1 = 0
+#define ELF_PLAT_INIT(_r, load_addr)	_r->a1 = 0
 
 #define USE_ELF_CORE_DUMP
 #ifndef CONFIG_SUN3
diff -Nru a/include/asm-m68knommu/linux_logo.h b/include/asm-m68knommu/linux_logo.h
--- a/include/asm-m68knommu/linux_logo.h	Fri Nov  1 08:37:46 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,13 +0,0 @@
-/*
- * include/asm-m68knommu/linux_logo.h: This is a linux logo
- *                                 to be displayed on boot.
- */
- 
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/version.h>
-
-#define linux_logo_banner "Linux/m68knommu version " UTS_RELEASE
-
-#include <linux/linux_logo.h>
-
diff -Nru a/include/asm-mips/elf.h b/include/asm-mips/elf.h
--- a/include/asm-mips/elf.h	Mon Feb  4 23:45:05 2002
+++ b/include/asm-mips/elf.h	Mon Mar 17 21:31:50 2003
@@ -73,7 +73,7 @@
  * See comments in asm-alpha/elf.h, this is the same thing
  * on the MIPS.
  */
-#define ELF_PLAT_INIT(_r)	do { \
+#define ELF_PLAT_INIT(_r, load_addr)	do { \
 	_r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0;	\
 	_r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0;	\
 	_r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0;	\
diff -Nru a/include/asm-mips/linux_logo.h b/include/asm-mips/linux_logo.h
--- a/include/asm-mips/linux_logo.h	Mon Feb  4 23:45:05 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,43 +0,0 @@
-/*
- * include/asm-mips/linux_logo.h: This is a linux logo
- *                                to be displayed on boot.
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * image size has to be 80x80
- * values have to start from 0x20
- * (i.e. RGB(linux_logo_red[0],
- *	     linux_logo_green[0],
- *	     linux_logo_blue[0]) is color 0x20)
- * BW image has to be 80x80 as well, with MS bit
- * on the left
- * Serial_console ascii image can be any size,
- * but should contain %s to display the version
- */
- 
-#include <linux/init.h>
-#include <linux/version.h>
-#include <linux/config.h>
-
-#ifndef CONFIG_DECSTATION
-#	include <asm/linux_logo_sgi.h>
-#else
-#	include <asm/linux_logo_dec.h>
-#endif
-
-#ifndef INCLUDE_LINUX_LOGO_DATA
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16_red[];
-extern unsigned char linux_logo16_green[];
-extern unsigned char linux_logo16_blue[];
-extern unsigned char linux_logo16[];
-
-#endif
diff -Nru a/include/asm-mips/linux_logo_dec.h b/include/asm-mips/linux_logo_dec.h
--- a/include/asm-mips/linux_logo_dec.h	Tue Feb  5 12:17:18 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,907 +0,0 @@
-/*
- * include/asm-mips/linux_logo_dec.h: This is a linux logo
- *                                for eg. DECstations
- *                                to be displayed on boot.
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 2001 Jan-Benedict Glaw <jbglaw@lug-owl.de>
- *
- */
- 
-#include <linux/init.h>
-#include <linux/version.h>
-#include <linux/config.h>
-
-#define linux_logo_banner "Linux/MIPSel version " UTS_RELEASE
-#define LINUX_LOGO_COLORS 183
-
-#define __HAVE_ARCH_LINUX_LOGO
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-unsigned char linux_logo_red[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79,
-    0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
-    0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
-    0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
-    0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
-    0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c,
-    0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e,
-    0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c,
-    0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xaf,
-    0x12, 0x4a, 0x8e, 0xf2, 0xf6, 0xb5, 0x26, 0x9a,
-    0xea, 0xf6, 0xd2, 0x16, 0x9a, 0x2e, 0x70, 0xf1,
-    0xd6, 0x46, 0x7c, 0xb4, 0x62, 0xd6, 0xa3, 0x74,
-    0xa7, 0xa2, 0xca, 0xe0, 0xae, 0xbe, 0xce, 0xa3,
-    0x8e, 0x6d, 0x8e, 0x32, 0x50, 0x9e, 0x5b, 0x8a,
-    0x98, 0x82, 0x7a, 0x82, 0x56, 0x7c, 0x8a, 0x56,
-    0x5e, 0x86, 0x6a, 0x52, 0x59, 0x64, 0x5e,
-};
-
-unsigned char linux_logo_green[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c,
-    0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
-    0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
-    0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
-    0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
-    0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76,
-    0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46,
-    0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b,
-    0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x76,
-    0x0e, 0x36, 0x86, 0xba, 0xbe, 0x8e, 0x1e, 0x8e,
-    0xae, 0xba, 0xa6, 0x12, 0x7a, 0x20, 0x64, 0xc4,
-    0xaa, 0x2f, 0x70, 0x85, 0x46, 0xa6, 0x6e, 0x51,
-    0x72, 0x92, 0xa2, 0xa6, 0x87, 0x96, 0xa2, 0x85,
-    0x7a, 0x6a, 0x6e, 0x22, 0x36, 0x76, 0x3c, 0x6e,
-    0x63, 0x53, 0x66, 0x62, 0x42, 0x50, 0x56, 0x42,
-    0x56, 0x56, 0x56, 0x3e, 0x51, 0x52, 0x56,
-};
-
-unsigned char linux_logo_blue[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08,
-    0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
-    0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
-    0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
-    0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
-    0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a,
-    0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e,
-    0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b,
-    0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x06,
-    0x06, 0x0e, 0x6a, 0x0e, 0x0e, 0x2c, 0x0a, 0x5a,
-    0x0d, 0x0e, 0x0a, 0x06, 0x2e, 0x06, 0x4e, 0x0e,
-    0x36, 0x06, 0x58, 0x24, 0x06, 0x3a, 0x08, 0x08,
-    0x07, 0x5e, 0x45, 0x0a, 0x32, 0x2e, 0x2a, 0x43,
-    0x48, 0x5f, 0x2e, 0x06, 0x07, 0x24, 0x06, 0x32,
-    0x06, 0x06, 0x46, 0x2e, 0x22, 0x06, 0x06, 0x1e,
-    0x4c, 0x06, 0x3a, 0x22, 0x42, 0x34, 0x42,
-};
-
-unsigned char linux_logo[] __initdata = {
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
-    0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-    0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
-    0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
-    0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
-    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-    0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
-    0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-    0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
-    0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34,
-    0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
-    0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22,
-    0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25,
-    0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
-    0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
-    0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-    0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
-    0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-    0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36,
-    0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
-    0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21,
-    0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
-    0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
-    0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
-    0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32,
-    0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a,
-    0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b,
-    0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37,
-    0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
-    0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
-    0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
-    0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
-    0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67,
-    0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
-    0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
-    0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
-    0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78,
-    0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79,
-    0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c,
-    0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
-    0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
-    0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36,
-    0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
-    0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89,
-    0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36,
-    0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
-    0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e,
-    0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
-    0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22,
-    0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
-    0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c,
-    0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51,
-    0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
-    0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97,
-    0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98,
-    0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
-    0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32,
-    0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50,
-    0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
-    0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
-    0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98,
-    0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
-    0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
-    0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b,
-    0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48,
-    0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-    0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-    0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
-    0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
-    0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c,
-    0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c,
-    0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
-    0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93,
-    0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28,
-    0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
-    0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93,
-    0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
-    0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x99, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
-    0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30,
-    0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c,
-    0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36,
-    0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36,
-    0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
-    0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36,
-    0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
-    0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d,
-    0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
-    0x24, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x48, 0x9f, 0x9f, 0x9f, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x48, 0x9f, 0x9f, 0x9f, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x48, 0x21, 0x30,
-    0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32,
-    0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a,
-    0x36, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x9f, 0x9f, 0x9f, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x48, 0x9f, 0x9f, 0x9f, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x48, 0x32, 0x30,
-    0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
-    0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25,
-    0x36, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x9f, 0x9f, 0x9f, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x48, 0x9f, 0x9f, 0x9f, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x48, 0x38, 0x21,
-    0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36,
-    0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
-    0x23, 0x9f, 0x9f, 0x9f, 0x48, 0x48, 0x9f, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x9f, 0x48, 0x48, 0x48,
-    0x48, 0x9f, 0x9f, 0x48, 0x9f, 0x9f, 0x9f, 0x48,
-    0x48, 0x48, 0x9f, 0x9f, 0x9f, 0x48, 0x94, 0x36,
-    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-    0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36,
-    0x2e, 0x9f, 0x9f, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x9f, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x9f, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x9f, 0x9f, 0x48, 0x98, 0x36,
-    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-    0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36,
-    0x54, 0x9f, 0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48, 0x9f,
-    0x48, 0x48, 0x48, 0x48, 0x9f, 0x48, 0x48, 0x48,
-    0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48, 0x9a, 0x36,
-    0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36,
-    0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
-    0x43, 0x9f, 0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48, 0x9f,
-    0x48, 0x48, 0x48, 0x48, 0x9f, 0x48, 0x48, 0x48,
-    0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48, 0x4b, 0x21,
-    0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25,
-    0x52, 0x9f, 0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x9f, 0x48, 0x48, 0x48,
-    0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48, 0x4f, 0x21,
-    0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a,
-    0x47, 0x9f, 0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x9f, 0x48, 0x48, 0x48,
-    0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x48, 0x4c, 0x22,
-    0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
-    0x9b, 0x9f, 0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x48, 0x9f, 0x48, 0x48, 0x48,
-    0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x48, 0x4c, 0x23,
-    0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31,
-    0x9b, 0x9f, 0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48, 0x9f,
-    0x48, 0x48, 0x48, 0x48, 0x9f, 0x48, 0x48, 0x48,
-    0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48, 0x46, 0x22,
-    0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d,
-    0x9b, 0x9f, 0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48, 0x9f,
-    0x48, 0x48, 0x48, 0x48, 0x9f, 0x48, 0x48, 0x48,
-    0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48, 0x9a, 0x36,
-    0x24, 0x27, 0xa0, 0x24, 0x25, 0x28, 0x21, 0x36,
-    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
-    0x39, 0x4d, 0xa1, 0x84, 0x81, 0x57, 0x21, 0x39,
-    0x52, 0x9f, 0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48, 0x9f,
-    0x48, 0x48, 0x48, 0x48, 0x9f, 0x48, 0x48, 0x48,
-    0x9f, 0x48, 0x48, 0x48, 0x9f, 0x48, 0x53, 0x28,
-    0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
-    0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
-    0x2d, 0xa2, 0x7a, 0xa3, 0xa4, 0xa4, 0x7f, 0x22,
-    0x51, 0x9f, 0x9f, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x9f, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x9f, 0x9f, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x9f, 0x9f, 0x48, 0xa5, 0x61,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
-    0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
-    0x4d, 0x91, 0x5b, 0xa3, 0xa4, 0xa4, 0xa4, 0x5a,
-    0x21, 0x9f, 0x9f, 0x9f, 0x48, 0x48, 0x9f, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x9f, 0x9f, 0x48, 0x48,
-    0x48, 0x48, 0x9f, 0x48, 0x9f, 0x9f, 0x48, 0x48,
-    0x48, 0x48, 0x9f, 0x9f, 0x9f, 0x48, 0x66, 0xa6,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
-    0x83, 0xa7, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a,
-    0x60, 0x85, 0xa8, 0xa9, 0xa4, 0xa4, 0xa4, 0x82,
-    0x86, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x48, 0x9f, 0x9f, 0x9f, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x48, 0x9f, 0x9f, 0x9f, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x48, 0xaa, 0xab,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57,
-    0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x23, 0x30, 0x31, 0xac, 0x91, 0x7e, 0x90, 0x90,
-    0x8b, 0x5b, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0x5d, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x48, 0x9f, 0x9f, 0x9f, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x48, 0x9f, 0x9f, 0x9f, 0x9f,
-    0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x48, 0x8b, 0xad,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
-    0x82, 0x5c, 0xae, 0x2a, 0x23, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x24, 0x2b, 0xac, 0x8b, 0x5b, 0x76, 0x5b, 0x5b,
-    0x7b, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xaf, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x99, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x4f, 0x3f, 0xb0, 0x7b, 0x7b, 0x85, 0x80,
-    0xa0, 0x36, 0x36, 0x36, 0x21, 0xb1, 0x7e, 0x7b,
-    0x64, 0x64, 0xb2, 0x35, 0x24, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x31, 0xb3, 0x5b, 0x64, 0xa3, 0xa3, 0xa9,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0x66, 0xb4, 0x36, 0x36, 0x36, 0x2c, 0x4b,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x9a, 0x3f, 0xb5, 0x76, 0x76, 0x7a, 0x63,
-    0xb6, 0xb7, 0x86, 0xb7, 0xb8, 0x90, 0x5b, 0x64,
-    0xa3, 0xa3, 0xb9, 0x2d, 0x27, 0x23, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x26, 0x2d, 0x91, 0x5b, 0x64, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xaf, 0x83, 0xab, 0x36, 0x36, 0x36, 0x30,
-    0x44, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x9b, 0x9a, 0x3f, 0xba, 0x5b, 0x7b, 0xbb, 0x85,
-    0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xa3, 0xa4,
-    0xa4, 0xa9, 0x5d, 0xb2, 0x39, 0x26, 0x23, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2d, 0xbc, 0xbb, 0x64, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xaf, 0x88, 0x36, 0x36, 0x36, 0x36,
-    0x2d, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x9b, 0x45, 0x3f, 0xbd, 0x6d, 0x7b, 0xa8, 0xbb,
-    0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa3, 0xbe, 0x37, 0x35, 0x26, 0x23,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2e, 0xbc, 0x7a, 0x7b, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xaf, 0x72, 0x73, 0x36, 0x36, 0x36,
-    0x24, 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x46, 0x42, 0xb3, 0x7a, 0x7b, 0x64, 0x7b,
-    0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xa3, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa9, 0x64, 0xbe, 0x4d, 0x2c, 0x27,
-    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x25, 0x31, 0xbf, 0x8b, 0x7b, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xaf, 0x89, 0xa0, 0x36, 0x36,
-    0x32, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xa3, 0xa9,
-    0xa3, 0x64, 0x64, 0xa3, 0xa3, 0xa9, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0x5d, 0xc0, 0x2c,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x25, 0x31, 0xbf, 0x85, 0x7b, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0x66, 0x57, 0x27, 0x4d,
-    0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x99, 0x34, 0xa0, 0xb6, 0x7a, 0x7b, 0xa3, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0xbf,
-    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2d, 0xbf, 0x85, 0x7b, 0xa9, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xaf, 0x5f, 0x92, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
-    0x35, 0x36, 0xab, 0xb8, 0x7a, 0x7b, 0xa9, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa9, 0xa3, 0xbd,
-    0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x30, 0x2f, 0xb3, 0x8b, 0x7b, 0xa9, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0x66, 0x89, 0x45,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25,
-    0x36, 0x36, 0x61, 0xb6, 0x6d, 0x64, 0xa9, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa9, 0x7b, 0xbb, 0xc0,
-    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0xc1, 0x63, 0xbb, 0xa3, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0x72, 0x81, 0xc2,
-    0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36,
-    0x36, 0x36, 0xc3, 0x8f, 0x6d, 0x64, 0xa9, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa3, 0xa8, 0x8b, 0xac, 0x2c,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x35, 0x96, 0x75, 0xa8, 0xa3, 0xa9, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa9, 0x7b, 0x81, 0xb6,
-    0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b,
-    0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x73, 0xb6, 0x7a, 0x7b, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0x64, 0x76, 0x7a, 0x91, 0xb2, 0x31, 0x30,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x39, 0x97, 0x75, 0xbb, 0x7b, 0x64, 0xa3, 0xa3,
-    0xa9, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0x7b, 0x7a, 0x9f,
-    0xc4, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
-    0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xc4, 0xb8, 0x8b, 0x7b, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0x64, 0x64,
-    0x76, 0x85, 0xbc, 0xb2, 0x34, 0x2b, 0x27, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0xc5, 0x63, 0x7e, 0x7a, 0x6d, 0xbb, 0x5b,
-    0x76, 0x7b, 0x64, 0x64, 0xa3, 0xa9, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa9, 0x76, 0x85, 0xb6,
-    0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xc6, 0xb8, 0x75, 0x76, 0xa3, 0xa4,
-    0xa4, 0xa4, 0xa9, 0xa3, 0x64, 0x76, 0xbb, 0x8b,
-    0xb3, 0xb2, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x27, 0x31, 0xc7, 0xc5, 0xb8, 0x74, 0x63, 0x90,
-    0x7e, 0x75, 0x8b, 0x6d, 0xbb, 0x76, 0x64, 0xa3,
-    0xa9, 0xa9, 0xa9, 0xa9, 0x64, 0x7a, 0x84, 0xc8,
-    0x79, 0xa0, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xc4, 0xc8, 0x63, 0x6d, 0x7b, 0x64,
-    0xa9, 0xa3, 0x64, 0x7b, 0xbb, 0x75, 0x63, 0x96,
-    0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x28, 0x27, 0x35, 0x2d, 0x41, 0xb2, 0xc2, 0x8f,
-    0xb6, 0xb8, 0x9f, 0x74, 0x84, 0x90, 0x85, 0x6d,
-    0x5b, 0x7b, 0x7b, 0xa8, 0x6d, 0x90, 0xb6, 0xc9,
-    0xc6, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
-    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
-    0x36, 0x21, 0xb1, 0x80, 0x9f, 0x7e, 0x6d, 0x76,
-    0xa8, 0x76, 0x6d, 0x85, 0x63, 0xb6, 0xb2, 0x34,
-    0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
-    0x41, 0xca, 0xcb, 0x6c, 0x80, 0xc8, 0xb6, 0x74,
-    0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xc9, 0x79,
-    0xc3, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d,
-    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38,
-    0x4d, 0x37, 0xcc, 0xcd, 0x8f, 0x74, 0x63, 0x7e,
-    0x75, 0x7e, 0x63, 0x9f, 0x88, 0xc1, 0x31, 0x2a,
-    0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
-    0x33, 0x39, 0x2e, 0x51, 0x41, 0xae, 0x6c, 0xcd,
-    0x80, 0xc8, 0xc8, 0xc8, 0xce, 0xcd, 0xb4, 0xcf,
-    0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
-    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
-    0x2b, 0x34, 0xd0, 0xc6, 0xd1, 0x8f, 0xb8, 0x9f,
-    0x9f, 0xb8, 0xc8, 0x6c, 0x41, 0x39, 0x27, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
-    0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41,
-    0xd2, 0xb4, 0x79, 0x79, 0x79, 0xc6, 0xd3, 0x51,
-    0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
-    0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
-    0x24, 0x2a, 0x31, 0xd4, 0xc4, 0x79, 0xcd, 0x80,
-    0xd1, 0xb7, 0xd5, 0x2f, 0x35, 0x26, 0x23, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
-    0x31, 0x2f, 0xd0, 0xd4, 0xd4, 0x2f, 0x2e, 0x33,
-    0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x27, 0x35, 0x34, 0xd4, 0xd4, 0xd4,
-    0xd6, 0xd0, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
-    0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
-    0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
-    0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-};
-
-#define INCLUDE_LINUX_LOGOBW
-#define INCLUDE_LINUX_LOGO16
-#include <linux/linux_logo.h>
-
-#endif
diff -Nru a/include/asm-mips/linux_logo_sgi.h b/include/asm-mips/linux_logo_sgi.h
--- a/include/asm-mips/linux_logo_sgi.h	Tue Feb  5 12:17:18 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,919 +0,0 @@
-/*
- * include/asm-mips/linux_logo_sgi.h: This is a linux logo
- *                                for SGI based machines
- *                                to be displayed on boot.
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 2001 Jan-Benedict Glaw <jbglaw@lug-owl.de>
- *
- */
- 
-#include <linux/init.h>
-#include <linux/version.h>
-#include <linux/config.h>
-
-#define linux_logo_banner "Linux/MIPS version " UTS_RELEASE
-#define LINUX_LOGO_COLORS 212
-
-#define __HAVE_ARCH_LINUX_LOGO
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-unsigned char linux_logo_red[] __initdata = {
-  0x03, 0x82, 0xE9, 0xBF, 0x42, 0xC9, 0x7E, 0xC0,
-  0xE9, 0xE3, 0xC2, 0x24, 0xA4, 0x65, 0xEC, 0xC4,
-  0x82, 0x9F, 0xF3, 0x12, 0x5F, 0xA0, 0xC2, 0xED,
-  0x3E, 0xD5, 0xDB, 0xA0, 0x1C, 0xF4, 0xEB, 0xA4,
-  0xCD, 0x0A, 0x9A, 0x51, 0xCC, 0xBE, 0xC0, 0xBA,
-  0x74, 0xDC, 0xAA, 0xF6, 0xD3, 0xC5, 0xE6, 0x26,
-  0xC2, 0x83, 0x38, 0xEA, 0x49, 0xB0, 0xED, 0xE5,
-  0xF4, 0x96, 0x96, 0x1B, 0xFA, 0xCC, 0xF2, 0x0F,
-  0xCD, 0xE5, 0xF4, 0xD3, 0x50, 0x7A, 0xB5, 0xDE,
-  0xD5, 0xB6, 0x60, 0x0A, 0x6A, 0xEA, 0xD4, 0xEB,
-  0xC1, 0xCA, 0xEA, 0xEC, 0x2A, 0x96, 0x95, 0xDC,
-  0xE4, 0xCE, 0xEC, 0x1E, 0xDC, 0x8A, 0xD1, 0xF6,
-  0x3C, 0x5E, 0xC6, 0xB4, 0xB2, 0xAC, 0xBA, 0x9E,
-  0x0F, 0x59, 0xBA, 0xFA, 0xCC, 0xBF, 0x82, 0xCE,
-  0xE6, 0x4F, 0xAA, 0x4C, 0xCA, 0x8E, 0x8E, 0xDF,
-  0x2C, 0xB6, 0x3B, 0xDE, 0xCE, 0xEE, 0x46, 0x4A,
-  0x6F, 0x7A, 0x82, 0xE4, 0xAA, 0x88, 0xE2, 0xCE,
-  0xAE, 0xB6, 0x70, 0xC2, 0x9A, 0xDA, 0x35, 0x9E,
-  0x95, 0xC0, 0x7E, 0x8C, 0xC2, 0xB6, 0xCE, 0xB9,
-  0xD5, 0xAA, 0xC1, 0xF4, 0xC7, 0xB6, 0xB6, 0xA3,
-  0xF2, 0x68, 0xDB, 0x76, 0xDC, 0x57, 0xD3, 0xA8,
-  0xC0, 0xEF, 0x46, 0xF4, 0x2F, 0xD7, 0x53, 0x36,
-  0xE6, 0xA7, 0xCA, 0xCB, 0x7E, 0xE4, 0x86, 0x9A,
-  0xCE, 0x94, 0xB4, 0x1D, 0xDA, 0xCE, 0x6C, 0xE6,
-  0x9E, 0xC6, 0xDA, 0x16, 0xFA, 0xAA, 0x56, 0xB6,
-  0xFE, 0x6E, 0xEA, 0xCE, 0xE5, 0xCC, 0xDB, 0xD3,
-  0xED, 0xDC, 0xF4, 0x72
-};
-
-unsigned char linux_logo_green[] __initdata = {
-  0x03, 0x82, 0xC4, 0x83, 0x42, 0xA2, 0x4A, 0xA4,
-  0xE5, 0xA6, 0xC2, 0x24, 0xA4, 0x65, 0xB4, 0x94,
-  0x66, 0x87, 0xB6, 0x12, 0x44, 0x6C, 0x96, 0xD4,
-  0x36, 0x95, 0xB2, 0x92, 0x0E, 0xF4, 0xBC, 0x77,
-  0xA5, 0x0A, 0x92, 0x52, 0xB4, 0x9A, 0x8C, 0xB2,
-  0x74, 0xC2, 0x8E, 0xBD, 0xA2, 0xCA, 0xD2, 0x12,
-  0xB6, 0x61, 0x24, 0xDA, 0x33, 0x79, 0xCB, 0xAC,
-  0xDA, 0x84, 0x7A, 0x1B, 0xFA, 0x8D, 0xBE, 0x06,
-  0x93, 0xBB, 0xBC, 0xAB, 0x44, 0x62, 0x83, 0xDA,
-  0x9B, 0xA2, 0x4C, 0x04, 0x6A, 0xB6, 0xC8, 0xBD,
-  0x8D, 0xB6, 0xAD, 0xEC, 0x2A, 0x68, 0x62, 0x9D,
-  0xC4, 0xC4, 0xB4, 0x13, 0xA3, 0x8A, 0xD2, 0xD6,
-  0x3C, 0x5D, 0x8C, 0x7E, 0x82, 0xAC, 0x96, 0x7E,
-  0x0D, 0x5A, 0xBA, 0xBB, 0xCC, 0xBE, 0x76, 0xB6,
-  0xDE, 0x4E, 0x9A, 0x3C, 0xBE, 0x8E, 0x6E, 0xCB,
-  0x1C, 0xAA, 0x2E, 0xBE, 0xAA, 0xDE, 0x3E, 0x4B,
-  0x4D, 0x7A, 0x54, 0xE4, 0x8E, 0x6E, 0xCA, 0x9B,
-  0x70, 0x9E, 0x5A, 0xAA, 0x9A, 0xBE, 0x34, 0x9E,
-  0x71, 0x9E, 0x7E, 0x5F, 0xAA, 0x8A, 0xBE, 0x91,
-  0xCE, 0x88, 0x92, 0xDB, 0xC6, 0xAB, 0x8A, 0x72,
-  0xE2, 0x44, 0xC3, 0x54, 0xAA, 0x45, 0xBB, 0x92,
-  0xBA, 0xC4, 0x46, 0xCA, 0x2D, 0xD6, 0x3B, 0x1A,
-  0xC2, 0x7E, 0xA6, 0xCB, 0x7A, 0xDC, 0x86, 0x72,
-  0xB6, 0x94, 0xB4, 0x1C, 0xBC, 0xAE, 0x4C, 0xD6,
-  0x62, 0x86, 0xD3, 0x16, 0xF6, 0x7A, 0x55, 0x79,
-  0xFE, 0x6E, 0xC6, 0xC6, 0xAA, 0x93, 0xDC, 0x9D,
-  0xAE, 0xA4, 0xD4, 0x56
-};
-
-unsigned char linux_logo_blue[] __initdata = {
-  0x04, 0x84, 0x10, 0x0C, 0x41, 0x14, 0x04, 0x78,
-  0xC7, 0x0E, 0xC4, 0x24, 0xA4, 0x64, 0x0C, 0x0D,
-  0x17, 0x24, 0x0D, 0x13, 0x11, 0x07, 0x40, 0x22,
-  0x0C, 0x0C, 0x11, 0x78, 0x06, 0xF4, 0x0B, 0x0A,
-  0x47, 0x0B, 0x7C, 0x54, 0x6C, 0x0C, 0x0D, 0x9C,
-  0x73, 0x54, 0x14, 0x0C, 0x0F, 0xC7, 0x94, 0x04,
-  0x94, 0x17, 0x0A, 0x6C, 0x08, 0x0F, 0x14, 0x0B,
-  0x12, 0x68, 0x28, 0x11, 0xFA, 0x0A, 0x34, 0x09,
-  0x0A, 0x2F, 0x15, 0x19, 0x14, 0x3C, 0x06, 0xC4,
-  0x0B, 0x84, 0x24, 0x08, 0x69, 0x38, 0xBC, 0x15,
-  0x1F, 0xA0, 0x0A, 0xEC, 0x2A, 0x0C, 0x0C, 0x0C,
-  0x2C, 0xA0, 0x15, 0x07, 0x0B, 0x8C, 0xD3, 0x10,
-  0x3B, 0x5C, 0x0C, 0x04, 0x3C, 0xAC, 0x54, 0x1C,
-  0x0B, 0x5B, 0xBB, 0x0A, 0xC1, 0xBB, 0x5C, 0x3C,
-  0xBC, 0x4D, 0x74, 0x10, 0x8C, 0x8C, 0x14, 0x91,
-  0x0C, 0x74, 0x17, 0x0C, 0x48, 0x9C, 0x3C, 0x4C,
-  0x09, 0x7C, 0x05, 0xE4, 0x34, 0x38, 0x6C, 0x11,
-  0x08, 0x7C, 0x18, 0x2C, 0x9C, 0x4C, 0x34, 0x9C,
-  0x29, 0x54, 0x7C, 0x0C, 0x78, 0x18, 0x9C, 0x14,
-  0xBA, 0x30, 0x27, 0x31, 0xC2, 0x97, 0x24, 0x09,
-  0xB4, 0x04, 0x87, 0x0C, 0x14, 0x1F, 0x7C, 0x64,
-  0xB0, 0x0F, 0x45, 0x10, 0x2C, 0xD4, 0x0A, 0x04,
-  0x44, 0x1F, 0x2C, 0xCC, 0x7C, 0xD8, 0x84, 0x0C,
-  0x8C, 0x94, 0xB4, 0x1D, 0x20, 0x5C, 0x18, 0xB4,
-  0x04, 0x09, 0xBC, 0x14, 0xF4, 0x08, 0x54, 0x07,
-  0xFC, 0x6C, 0x24, 0xB4, 0x15, 0x18, 0xDB, 0x17,
-  0x17, 0x18, 0x21, 0x24
-};
-
-unsigned char linux_logo[] __initdata = {
-  0xBC, 0xAC, 0x7D, 0x95, 0xAF, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0x2C, 0xAF,
-  0x7D, 0x48, 0xB2, 0xAC, 0x85, 0xDA, 0xDA, 0x2C,
-  0x7D, 0x48, 0x21, 0x2C, 0x8D, 0x2A, 0x8A, 0xDA,
-  0x85, 0x2C, 0xD9, 0xAC, 0x2C, 0x2C, 0xD9, 0xD9,
-  0xAF, 0x85, 0x85, 0x85, 0x8D, 0xBC, 0x2A, 0x2A,
-  0xBC, 0x8C, 0xBC, 0xAC, 0x7D, 0x95, 0xAF, 0x85,
-  0x2C, 0x2C, 0xAC, 0xD9, 0x95, 0x7D, 0x95, 0xAC,
-  0x2C, 0xAF, 0x7D, 0x48, 0xB2, 0xAC, 0x85, 0xDA,
-  0xDA, 0x2C, 0x7D, 0x48, 0x21, 0x2C, 0x8D, 0x2A,
-  0xAF, 0xA1, 0x48, 0x7D, 0xAF, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0xD9, 0x7D,
-  0x48, 0xE9, 0x21, 0xAF, 0xDA, 0xDA, 0x85, 0x2C,
-  0xD9, 0xD9, 0xAC, 0xDA, 0x8A, 0xDA, 0x85, 0x2C,
-  0x2C, 0xAC, 0xD9, 0xAC, 0xAF, 0xAF, 0x2C, 0x2C,
-  0x2C, 0x85, 0x2C, 0x2C, 0x85, 0xDA, 0xDA, 0xDA,
-  0xDA, 0xDA, 0xAF, 0xA1, 0x48, 0x7D, 0xAF, 0x2C,
-  0x2C, 0xAC, 0xD9, 0xD9, 0x95, 0x7D, 0x95, 0xAC,
-  0xD9, 0x7D, 0x48, 0xE9, 0x21, 0xAF, 0xDA, 0xDA,
-  0x85, 0x2C, 0xD9, 0xD9, 0xAC, 0xDA, 0x8A, 0xDA,
-  0x7D, 0x48, 0x48, 0x7D, 0x2C, 0x85, 0x2C, 0xAF,
-  0xD9, 0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0xD9, 0x7D,
-  0xB2, 0x21, 0xD9, 0x85, 0xDA, 0xDA, 0x85, 0x2C,
-  0xAF, 0x2C, 0x2C, 0xDA, 0x85, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xD9, 0xAF, 0xDA, 0x85, 0x2C, 0x2C,
-  0x85, 0xDA, 0xDA, 0x85, 0x85, 0xDA, 0x85, 0x85,
-  0x85, 0xAF, 0x7D, 0x48, 0x48, 0x7D, 0x2C, 0x85,
-  0x2C, 0xAF, 0xD9, 0xD9, 0x7D, 0x95, 0xD9, 0xD9,
-  0xD9, 0x7D, 0xB2, 0x21, 0xD9, 0x85, 0xDA, 0xDA,
-  0x85, 0x2C, 0xAF, 0x2C, 0x2C, 0xDA, 0xDA, 0x85,
-  0xA1, 0xE9, 0x48, 0x95, 0x85, 0xDA, 0x85, 0xAF,
-  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0x95, 0x95,
-  0xD9, 0xAC, 0x85, 0x85, 0xDA, 0xDA, 0x85, 0x2C,
-  0xAC, 0xAC, 0x2C, 0x2C, 0x85, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0x2C, 0x91, 0x41, 0x20, 0x6B, 0x20,
-  0x6B, 0x20, 0x6B, 0xAE, 0x2C, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xA1, 0xE9, 0x48, 0x95, 0x85, 0xDA,
-  0x85, 0xAF, 0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9,
-  0x95, 0x95, 0xD9, 0xAC, 0x85, 0x85, 0xDA, 0xDA,
-  0x85, 0x2C, 0xAC, 0xAC, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xA1, 0xA1, 0xD6, 0xAF, 0xDA, 0xDA, 0x85, 0x2C,
-  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x2C, 0x2C, 0xDA, 0xDA, 0xDA, 0x85, 0x2C, 0xD9,
-  0xD9, 0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xAF, 0xAC,
-  0x2C, 0xB2, 0x88, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x6B, 0x80, 0x85, 0x2C,
-  0xD9, 0xD6, 0xA1, 0xA1, 0xD6, 0xAF, 0xDA, 0xDA,
-  0x85, 0x2C, 0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9,
-  0xD9, 0xD9, 0x2C, 0x2C, 0xDA, 0xDA, 0xDA, 0x85,
-  0x2C, 0xD9, 0xD9, 0xD9, 0xD9, 0xAF, 0xAF, 0xAF,
-  0xD6, 0xD6, 0xD9, 0x2C, 0xDA, 0xDA, 0x2C, 0xAC,
-  0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0xD9, 0xAF, 0x2C,
-  0x85, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0xAC, 0xD9,
-  0xD9, 0xD9, 0xAF, 0xAF, 0x2C, 0x2C, 0xAF, 0xDA,
-  0xAE, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xE3, 0x20, 0x6B, 0x48,
-  0xAC, 0x95, 0xD6, 0xD6, 0xD9, 0x2C, 0xDA, 0xDA,
-  0x2C, 0xAC, 0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0xD9,
-  0xAF, 0x2C, 0x85, 0x85, 0x85, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xD9, 0xD9, 0xAF, 0xAF, 0xAF, 0xAF,
-  0xD9, 0xD9, 0xD9, 0x2C, 0x85, 0x85, 0x2C, 0xD9,
-  0x7D, 0x21, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x85, 0x2C, 0xAF, 0xAF, 0xAC,
-  0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x89,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x74, 0x43, 0x80, 0x41, 0x20,
-  0x9F, 0x2C, 0xD9, 0xD9, 0xD9, 0x2C, 0x85, 0x85,
-  0x2C, 0xD9, 0x7D, 0x21, 0xD6, 0xD9, 0xAF, 0x2C,
-  0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x2C, 0xAF,
-  0xAF, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xD9, 0x7D, 0xD9, 0xAF, 0x85, 0x85, 0x2C, 0xD9,
-  0xB2, 0x21, 0x7D, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
-  0x85, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC,
-  0xAF, 0xAC, 0xAF, 0xAF, 0xAC, 0xAC, 0x85, 0x41,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xAE, 0x48, 0x89, 0x74, 0x41,
-  0x6B, 0xD6, 0xD9, 0x7D, 0xD9, 0xAF, 0x85, 0x85,
-  0x2C, 0xD9, 0xB2, 0x21, 0x7D, 0xD9, 0xAF, 0x2C,
-  0x85, 0x85, 0x85, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF,
-  0xAF, 0xAC, 0xAF, 0xAC, 0xAC, 0x2C, 0xAF, 0xAC,
-  0x2C, 0x7D, 0xD9, 0x2C, 0xDA, 0x85, 0x2C, 0x7D,
-  0xB2, 0xD6, 0xD9, 0xAF, 0x85, 0x85, 0x85, 0x85,
-  0xAF, 0xAC, 0xAC, 0xAF, 0xAF, 0xAC, 0xAC, 0xD9,
-  0x95, 0x7D, 0x95, 0x95, 0xD9, 0xD9, 0x48, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x6B, 0xAE, 0xE6, 0x80, 0x2B, 0x88,
-  0x20, 0x33, 0xDA, 0x95, 0xD9, 0x2C, 0xDA, 0x85,
-  0x2C, 0x7D, 0xB2, 0xD6, 0xD9, 0xAF, 0x85, 0x85,
-  0x85, 0x85, 0xAF, 0xAC, 0xAC, 0xAF, 0xAF, 0xAC,
-  0xAC, 0xD9, 0x95, 0x95, 0x7D, 0x95, 0x95, 0xD9,
-  0x85, 0xD9, 0x2C, 0x85, 0xDA, 0xDA, 0xD9, 0x21,
-  0xA1, 0xD9, 0xAF, 0x2C, 0x85, 0xDA, 0x85, 0xAF,
-  0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9, 0x7D, 0xD6,
-  0xD6, 0x7D, 0x95, 0xD9, 0xD9, 0x85, 0xDB, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xDB, 0xE3, 0x6B, 0x20, 0x20,
-  0x20, 0x20, 0xE9, 0xD9, 0x2C, 0x85, 0xDA, 0xDA,
-  0xD9, 0x21, 0xA1, 0xD9, 0xAF, 0x2C, 0x85, 0xDA,
-  0x85, 0xAF, 0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9,
-  0x7D, 0xD6, 0xD6, 0x7D, 0x95, 0xD9, 0xD9, 0xD9,
-  0xDA, 0x2C, 0x85, 0xDA, 0xDA, 0x85, 0x95, 0x21,
-  0x21, 0xD9, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0xD9,
-  0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xAC, 0xAC, 0x2C, 0xAF, 0x2C, 0x85, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x88, 0xDA, 0x85, 0xDA, 0xDA, 0x85,
-  0x95, 0x21, 0x21, 0xD9, 0x85, 0x85, 0x85, 0x2C,
-  0x2C, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xDA, 0x2C, 0x85, 0x85, 0x2C, 0xD9, 0xD6, 0xB2,
-  0x95, 0x2C, 0x85, 0x85, 0xAF, 0xAC, 0x95, 0x95,
-  0x7D, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0x2C, 0x85,
-  0x85, 0x85, 0x85, 0x85, 0x85, 0xAC, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xAC, 0x85, 0x85, 0x2C, 0xD9,
-  0xD6, 0xB2, 0x95, 0x2C, 0x85, 0x85, 0xAF, 0xAC,
-  0x95, 0x95, 0x7D, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x2C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x2C, 0x2C, 0x2C, 0xAC, 0x95, 0xD6, 0x7D,
-  0xD9, 0x2C, 0x2C, 0xAF, 0x95, 0x7D, 0x7D, 0x95,
-  0x95, 0xD9, 0xD9, 0x95, 0xD9, 0xD9, 0x2C, 0x85,
-  0xDA, 0xDA, 0xDA, 0x85, 0x85, 0x21, 0x20, 0x20,
-  0x6B, 0x41, 0xDB, 0x6B, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xDB, 0xDB, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xE6, 0x2C, 0x2C, 0xAC, 0x95,
-  0xD6, 0x7D, 0xD9, 0x2C, 0x2C, 0xAF, 0x95, 0x7D,
-  0x7D, 0x95, 0x95, 0xD9, 0xD9, 0x95, 0xD9, 0xD9,
-  0x2C, 0x85, 0xDA, 0xDA, 0xDA, 0x85, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xAC, 0xD9, 0x95, 0xD6, 0xD6, 0xD9,
-  0x2C, 0x2C, 0x2C, 0xD9, 0xD6, 0xD6, 0xD9, 0xAF,
-  0xAC, 0x95, 0xD6, 0x7D, 0x7D, 0xD9, 0x2C, 0x85,
-  0xDA, 0xDA, 0x2C, 0xAF, 0xAF, 0x21, 0x20, 0x20,
-  0x88, 0x2B, 0x88, 0x74, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xAE, 0x2D, 0x2D, 0x74, 0x74, 0x88, 0x20,
-  0x20, 0x20, 0x20, 0x80, 0xAC, 0xD9, 0x95, 0xD6,
-  0xD6, 0xD9, 0x2C, 0x2C, 0x2C, 0xD9, 0xD6, 0xD6,
-  0xD9, 0xAF, 0xAC, 0x95, 0xD6, 0x7D, 0x7D, 0xD9,
-  0x2C, 0xDA, 0xDA, 0x85, 0x2C, 0xAF, 0xAF, 0xAF,
-  0x2C, 0xAF, 0xD9, 0x95, 0xD6, 0xD6, 0x95, 0xAF,
-  0x2C, 0x2C, 0xD9, 0x95, 0xD6, 0x95, 0xAF, 0x2C,
-  0xAC, 0x7D, 0x21, 0x95, 0xD9, 0x2C, 0x85, 0x85,
-  0x85, 0xAF, 0xD9, 0x95, 0xD9, 0x7D, 0x20, 0x33,
-  0x7D, 0x8A, 0x7D, 0x5B, 0x6B, 0x20, 0x20, 0x6B,
-  0xE6, 0xD9, 0x85, 0x2A, 0xDA, 0x2B, 0x41, 0x20,
-  0x20, 0x20, 0x6B, 0x74, 0xD9, 0x95, 0xD6, 0xD6,
-  0x95, 0xAF, 0x2C, 0x2C, 0xD9, 0x95, 0xD6, 0x95,
-  0xAF, 0x2C, 0xAC, 0x7D, 0x21, 0x95, 0xD9, 0x2C,
-  0x85, 0x85, 0x85, 0x2C, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x85, 0xD9, 0x7D, 0x21, 0x21, 0x7D, 0xAC, 0x2C,
-  0x2C, 0xAC, 0xD9, 0x7D, 0xD9, 0xAF, 0x2C, 0x85,
-  0xAC, 0x7D, 0x7D, 0xAC, 0x85, 0xDA, 0x8A, 0xDA,
-  0x85, 0xAF, 0xD9, 0x7D, 0xD9, 0x95, 0x20, 0x91,
-  0xBC, 0x73, 0xEE, 0x7D, 0x20, 0x20, 0x20, 0x80,
-  0x4D, 0x3D, 0x73, 0x73, 0xA3, 0xD6, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x2B, 0x7D, 0x21, 0x21, 0x7D,
-  0xAC, 0x2C, 0x2C, 0xAC, 0xD9, 0x7D, 0xD9, 0xAF,
-  0x2C, 0x85, 0xAC, 0x7D, 0x7D, 0xAC, 0x85, 0xDA,
-  0x8A, 0x8A, 0x85, 0xAC, 0xD9, 0x7D, 0xD9, 0xAC,
-  0x2C, 0xD9, 0xD6, 0xB2, 0xB2, 0x7D, 0xAF, 0x85,
-  0x2C, 0xD9, 0x95, 0x95, 0xAF, 0x2C, 0x2C, 0x2C,
-  0xD9, 0xD9, 0xAC, 0x85, 0x8D, 0x2A, 0x2A, 0xDA,
-  0xAF, 0xD9, 0x95, 0x95, 0xD9, 0xAC, 0x20, 0xAF,
-  0x2C, 0xE6, 0x8D, 0x73, 0xE3, 0x20, 0x20, 0x48,
-  0x5C, 0xDA, 0x5B, 0x43, 0xBC, 0x73, 0x2B, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xD6, 0xB2, 0xB2, 0x7D,
-  0xAF, 0x85, 0x2C, 0xD9, 0x95, 0x95, 0xAF, 0x2C,
-  0x2C, 0x2C, 0xD9, 0xD9, 0xAC, 0x85, 0x8A, 0x2A,
-  0x8D, 0xDA, 0xAF, 0xD9, 0x95, 0x95, 0xD9, 0xAF,
-  0xAC, 0xD9, 0xD6, 0xB2, 0x21, 0xD9, 0x2C, 0x85,
-  0x2C, 0xD9, 0x95, 0xD9, 0xAF, 0x2C, 0x2C, 0xAC,
-  0xAC, 0xAF, 0x85, 0x8D, 0xBC, 0xBC, 0xDA, 0xD9,
-  0xD6, 0xA1, 0xA1, 0x21, 0xD9, 0xAC, 0x20, 0x2A,
-  0xCC, 0xAE, 0x9F, 0xE4, 0xAE, 0x5B, 0x74, 0xA1,
-  0xE4, 0xAE, 0x20, 0x9F, 0x89, 0xE8, 0xE6, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xD6, 0xB2, 0x21, 0xD9,
-  0x2C, 0x85, 0x2C, 0xD9, 0x95, 0xD9, 0xAF, 0x2C,
-  0x2C, 0xAC, 0xAC, 0xAF, 0x85, 0x8D, 0xBC, 0x2A,
-  0xDA, 0xD9, 0xD6, 0xA1, 0xA1, 0x21, 0xD9, 0xD9,
-  0xD9, 0x95, 0x21, 0xA1, 0x21, 0xAC, 0x85, 0x85,
-  0xAC, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0xAF, 0xAC,
-  0xAF, 0x85, 0x8A, 0x2A, 0x2A, 0xDA, 0xD9, 0xA1,
-  0x48, 0xE9, 0x48, 0x21, 0x95, 0xAC, 0x20, 0x2A,
-  0xDB, 0x41, 0x74, 0xBC, 0x2B, 0x7B, 0x7B, 0x80,
-  0x73, 0x41, 0x20, 0x6B, 0x2B, 0xE8, 0x2D, 0x20,
-  0x20, 0x20, 0x20, 0x33, 0x21, 0xA1, 0x21, 0xAC,
-  0x85, 0x85, 0xAC, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C,
-  0xAF, 0xAC, 0xAF, 0x85, 0x8A, 0xBC, 0x2A, 0xDA,
-  0xD9, 0xA1, 0x48, 0xE9, 0x48, 0x21, 0xD9, 0xD9,
-  0xA1, 0xB2, 0xB2, 0x48, 0xD6, 0xAC, 0x2C, 0x2C,
-  0xD9, 0x95, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0x85, 0x8A, 0x8D, 0x8D, 0x85, 0x95, 0xA1, 0x6C,
-  0x6C, 0x48, 0xD6, 0xD9, 0x2C, 0x85, 0x20, 0x2C,
-  0x89, 0x20, 0x3C, 0xB9, 0xA7, 0x63, 0xD2, 0xB9,
-  0xC6, 0x9A, 0x20, 0x20, 0x43, 0x5C, 0xE6, 0x20,
-  0x20, 0x20, 0x20, 0x33, 0xB2, 0x48, 0xD6, 0xAC,
-  0x2C, 0x2C, 0xD9, 0x95, 0xAF, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x2C, 0x85, 0x8A, 0x8D, 0x8D, 0x85, 0x95,
-  0xA1, 0x6C, 0x6C, 0x48, 0xD6, 0xD9, 0xAF, 0xAC,
-  0xA1, 0xD6, 0x7D, 0xB2, 0xD6, 0xAF, 0x85, 0x85,
-  0xD9, 0x95, 0x2C, 0x85, 0xDA, 0x85, 0x85, 0x2C,
-  0x85, 0x8A, 0x8D, 0xDA, 0xD9, 0x48, 0x81, 0x2D,
-  0x48, 0xD6, 0xD9, 0xAC, 0x2C, 0x85, 0x20, 0x2D,
-  0xEE, 0x93, 0xD1, 0xA7, 0x3E, 0x3E, 0x3A, 0x25,
-  0x56, 0xAB, 0xAA, 0xC5, 0xEE, 0xEE, 0x33, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0xD9, 0xB2, 0xD6, 0xAF,
-  0x85, 0x85, 0xD9, 0x95, 0x2C, 0x85, 0xDA, 0x85,
-  0x85, 0x2C, 0x85, 0x8A, 0x8D, 0xDA, 0xD9, 0x48,
-  0x81, 0x2D, 0x48, 0xD6, 0xD9, 0xAF, 0x2C, 0x2C,
-  0xAC, 0xAF, 0xD9, 0x7D, 0xD6, 0x2C, 0x85, 0x2C,
-  0xD9, 0xD9, 0x2C, 0xDA, 0xDA, 0xDA, 0x2C, 0x2C,
-  0x85, 0x8D, 0x8D, 0x2C, 0x21, 0x2D, 0x2D, 0xE9,
-  0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0xDA, 0x20, 0xE3,
-  0xB4, 0xBE, 0xF1, 0x3E, 0x9B, 0x22, 0x56, 0xF2,
-  0xBB, 0x7F, 0x56, 0xDC, 0x8F, 0x5A, 0x5F, 0x20,
-  0x20, 0x20, 0x20, 0x6B, 0x2C, 0x7D, 0xD6, 0x2C,
-  0x85, 0x2C, 0xD9, 0xD9, 0x2C, 0xDA, 0xDA, 0xDA,
-  0x2C, 0x2C, 0x85, 0x8D, 0x8A, 0x85, 0x21, 0x2D,
-  0x2D, 0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
-  0x2A, 0x85, 0xAC, 0x95, 0x95, 0x2C, 0x85, 0x85,
-  0xAC, 0xAF, 0x85, 0xDA, 0xDA, 0x85, 0x2C, 0x2C,
-  0xDA, 0x8A, 0x8A, 0xAF, 0xA1, 0x2D, 0xE9, 0xD6,
-  0xD9, 0xAC, 0x85, 0x85, 0x85, 0xDA, 0x20, 0x52,
-  0x55, 0xED, 0x57, 0x3E, 0x22, 0x56, 0x37, 0xBB,
-  0xBB, 0x58, 0x7F, 0x7F, 0x56, 0x5E, 0xC5, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x2C, 0x95, 0x95, 0x2C,
-  0x85, 0x85, 0xAC, 0xAF, 0x85, 0xDA, 0xDA, 0x85,
-  0x2C, 0x2C, 0xDA, 0x8D, 0xDA, 0xAF, 0xA1, 0x2D,
-  0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85, 0x85,
-  0xCD, 0xAF, 0xD9, 0x95, 0xD9, 0x2C, 0xDA, 0x85,
-  0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x2C, 0xAC, 0xAF,
-  0x85, 0x8A, 0x85, 0xD9, 0x48, 0x48, 0xB2, 0x95,
-  0x95, 0xAC, 0x2C, 0x85, 0xDA, 0xDA, 0x6B, 0xB3,
-  0x46, 0x7C, 0x2E, 0x9B, 0x22, 0x56, 0xBB, 0x37,
-  0x58, 0x58, 0xF2, 0x3A, 0x46, 0x63, 0x64, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x2D, 0x95, 0xD9, 0x2C,
-  0xDA, 0x85, 0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x2C,
-  0xAC, 0xAF, 0x85, 0xDA, 0x85, 0xD9, 0x48, 0x48,
-  0xB2, 0x95, 0x95, 0xD9, 0x85, 0xDA, 0x85, 0x85,
-  0xBC, 0xB2, 0xB2, 0x7D, 0xD9, 0x2C, 0xDA, 0x85,
-  0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x85, 0xAF, 0x2C,
-  0x85, 0xDA, 0x2C, 0x7D, 0xA1, 0x48, 0xB2, 0x21,
-  0xD6, 0xD9, 0x85, 0xDA, 0x85, 0xDA, 0x41, 0x51,
-  0xB7, 0xEC, 0x2E, 0x22, 0x56, 0x37, 0xBB, 0xF2,
-  0x37, 0xEA, 0x2F, 0x2F, 0x77, 0xA7, 0x38, 0x20,
-  0x20, 0x6B, 0x20, 0x20, 0x5B, 0x2C, 0xD9, 0x2C,
-  0xDA, 0x85, 0xAF, 0xD9, 0x85, 0xDA, 0x85, 0x85,
-  0xAF, 0x2C, 0xDA, 0xDA, 0x2C, 0x7D, 0xA1, 0x48,
-  0xB2, 0x21, 0xD6, 0xD9, 0x2C, 0xDA, 0x85, 0xAF,
-  0x2C, 0x2D, 0x48, 0x7D, 0xAF, 0x2C, 0x85, 0x2C,
-  0xD9, 0xAC, 0xAF, 0x85, 0x85, 0x2C, 0x2C, 0x2C,
-  0x85, 0x2C, 0xD9, 0xD6, 0xA1, 0xA1, 0x48, 0xA1,
-  0x21, 0x2C, 0xDA, 0xDA, 0x2C, 0x85, 0x41, 0x98,
-  0xA2, 0xA7, 0x6F, 0xC9, 0x37, 0xF2, 0xF2, 0x9B,
-  0xB7, 0x66, 0x60, 0x4C, 0xED, 0x84, 0x3C, 0x20,
-  0x5B, 0x2D, 0x2B, 0x6B, 0x20, 0xAF, 0xAF, 0x2C,
-  0x85, 0x2C, 0xD9, 0xAC, 0xAF, 0x85, 0x85, 0x2C,
-  0x2C, 0x2C, 0x2C, 0x85, 0xD9, 0xD6, 0xA1, 0xA1,
-  0x48, 0xA1, 0xD6, 0xAF, 0xDA, 0x8A, 0x2C, 0xD9,
-  0xB2, 0x2D, 0x48, 0x95, 0x2C, 0x2C, 0x2C, 0x85,
-  0xAC, 0xAC, 0xAF, 0x85, 0xDA, 0x85, 0xAF, 0xAC,
-  0xAF, 0x2C, 0xD9, 0xD6, 0xD6, 0xD6, 0x21, 0xD6,
-  0xD9, 0xDA, 0x8D, 0xDA, 0xAF, 0x2C, 0x20, 0x88,
-  0x42, 0x51, 0x3F, 0x2F, 0x45, 0xB7, 0x66, 0x55,
-  0x46, 0x60, 0x5D, 0x36, 0xD8, 0x71, 0x43, 0x20,
-  0x20, 0x2D, 0xB2, 0x80, 0x20, 0x2D, 0x2C, 0x2C,
-  0x2C, 0x85, 0xAC, 0xAC, 0xAF, 0x85, 0xDA, 0x85,
-  0xAF, 0xAC, 0xAC, 0xAF, 0xD9, 0xD6, 0xD6, 0xD6,
-  0x21, 0xD6, 0xD9, 0xDA, 0x8D, 0x8A, 0x2C, 0xD9,
-  0xB2, 0x48, 0xD6, 0xAC, 0xAF, 0x2C, 0x2C, 0x85,
-  0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85, 0xAF, 0xD9,
-  0xD9, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC,
-  0x85, 0x8D, 0xBC, 0xDA, 0xD9, 0xDA, 0x20, 0xE3,
-  0xDA, 0x69, 0x96, 0xB5, 0xF1, 0x68, 0x5D, 0x82,
-  0xE1, 0xBE, 0x27, 0x8D, 0x4D, 0xD3, 0x7D, 0x20,
-  0x20, 0xDB, 0xA1, 0xCA, 0x20, 0x88, 0x85, 0x2C,
-  0x2C, 0x85, 0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85,
-  0xAF, 0xD9, 0xAC, 0xAF, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xAC, 0xDA, 0x8D, 0xBC, 0xDA, 0xD9, 0x95,
-  0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0x2C, 0x2C, 0x85,
-  0x85, 0xAF, 0xAF, 0x85, 0x85, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x85,
-  0x8D, 0x2A, 0x2A, 0x85, 0xD9, 0x95, 0x20, 0xDB,
-  0x8D, 0x8D, 0x99, 0xB0, 0x35, 0xE5, 0x3F, 0x35,
-  0xB9, 0x50, 0x8A, 0x4D, 0x73, 0xE8, 0xA3, 0xCC,
-  0x20, 0x20, 0x33, 0x6B, 0x20, 0x20, 0xCC, 0x85,
-  0x2C, 0x85, 0x85, 0xAF, 0xAF, 0x85, 0x85, 0x85,
-  0x2C, 0xD9, 0xD9, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x85, 0x8A, 0x2A, 0x8D, 0x2C, 0xD9, 0xD9,
-  0xAF, 0xAF, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x85,
-  0x2C, 0xAF, 0xAF, 0xAF, 0x2C, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xAC, 0xAF, 0x2C, 0x85, 0x85, 0xDA, 0xDA,
-  0x8A, 0x8A, 0x85, 0xD9, 0x2C, 0x2B, 0x20, 0xAE,
-  0xA3, 0xBC, 0x8D, 0xC8, 0xA9, 0xC7, 0x92, 0x47,
-  0x8D, 0x8D, 0x7E, 0xE4, 0xE8, 0xE8, 0x5C, 0x2C,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6B, 0xAF,
-  0x2C, 0x85, 0x2C, 0xAF, 0xAF, 0xAF, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0x85,
-  0x85, 0xDA, 0x8D, 0x8A, 0x85, 0xAC, 0x95, 0xD9,
-  0xAC, 0xAC, 0xAC, 0xAC, 0x2C, 0xAF, 0xAF, 0x2C,
-  0x2C, 0xAF, 0xAF, 0xAC, 0x2C, 0xAF, 0x2C, 0xAF,
-  0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x2C, 0xD9, 0xD9, 0x2D, 0x6B, 0x41, 0x2A,
-  0xE8, 0xA3, 0xC8, 0x8D, 0x8A, 0x8A, 0x8A, 0x8D,
-  0x4D, 0xA3, 0x3D, 0xE8, 0xE8, 0xE8, 0xE8, 0x5C,
-  0xAE, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xDB,
-  0xDA, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC, 0xAF,
-  0x2C, 0xAC, 0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0x85,
-  0x85, 0x85, 0x85, 0x2C, 0xD9, 0x95, 0x7D, 0xD9,
-  0x7D, 0x7D, 0xD9, 0xAC, 0xAC, 0xAF, 0xAF, 0xAF,
-  0x2C, 0x2C, 0xAC, 0xAC, 0xD9, 0xAC, 0xAC, 0xD9,
-  0x95, 0xD9, 0xAC, 0xAF, 0xAF, 0xAC, 0xAF, 0xAC,
-  0xD9, 0x7D, 0x7D, 0x7D, 0x33, 0x41, 0x2D, 0xE8,
-  0xE8, 0x5C, 0xD3, 0x8D, 0x8D, 0x8D, 0x8D, 0x7E,
-  0x3D, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xDA, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x81, 0x2C, 0x2C, 0x2C, 0xAC, 0xAC, 0xAC, 0xAC,
-  0xAC, 0xD9, 0x95, 0x95, 0xAC, 0xAF, 0xAF, 0xAF,
-  0xAF, 0xAC, 0xD9, 0x95, 0x7D, 0xD6, 0xD6, 0x7D,
-  0x21, 0xD6, 0x95, 0xD9, 0xD9, 0xAC, 0xAF, 0xAF,
-  0x2C, 0xAF, 0xAC, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x21, 0x21, 0x7D, 0x95, 0x95, 0x7D, 0xD6, 0x21,
-  0xB2, 0xA1, 0x2C, 0x88, 0x20, 0xE3, 0xA3, 0xE8,
-  0xE8, 0xE8, 0xE4, 0xEE, 0xD3, 0x7E, 0x73, 0x5C,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0x5C, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x2C, 0xAF, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xD9, 0xD6, 0x21, 0x7D, 0x95, 0x95, 0x7D,
-  0xD6, 0xB2, 0xA1, 0xA1, 0xB2, 0xD6, 0x21, 0x21,
-  0x21, 0xD9, 0xD9, 0xD9, 0xAC, 0xAF, 0xAC, 0xAF,
-  0x2C, 0x2C, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9, 0x95,
-  0x7D, 0xB2, 0xD6, 0x95, 0xD9, 0x95, 0xD6, 0xA1,
-  0xA1, 0xAF, 0x5B, 0x20, 0x20, 0xD6, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0x5C, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0x48, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xE3, 0x8A, 0x2C, 0xAC, 0xAC, 0xD9, 0xD9,
-  0xD9, 0x95, 0xD6, 0xB2, 0xD6, 0x95, 0xD9, 0x95,
-  0x21, 0xB2, 0xA1, 0xB2, 0xD6, 0xD6, 0xD6, 0xA1,
-  0xD9, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAF,
-  0x2C, 0x2C, 0xAF, 0xAC, 0xD9, 0xAC, 0xD9, 0xD9,
-  0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0xAC, 0x95, 0x7D,
-  0xD9, 0x91, 0x20, 0x20, 0xE3, 0xA3, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0x85, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x2B, 0x8A, 0xAF, 0xAC, 0xD9, 0xAC,
-  0xD9, 0xD9, 0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0xAC,
-  0x95, 0x7D, 0x95, 0x95, 0xD9, 0x95, 0x7D, 0x21,
-  0x2C, 0xDA, 0xDA, 0x85, 0x2C, 0xAF, 0xAF, 0xAF,
-  0xAF, 0xAF, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC, 0xAC,
-  0xD9, 0xAF, 0x85, 0x85, 0x2C, 0xAF, 0xD9, 0xAF,
-  0x48, 0x20, 0x20, 0x20, 0xE6, 0xA3, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0x5C,
-  0xE4, 0x73, 0x41, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x2B, 0xDA, 0xAF, 0xAF, 0xAC,
-  0xAC, 0xAF, 0xD9, 0x2C, 0x85, 0x85, 0x2C, 0xAF,
-  0xD9, 0xD9, 0xAC, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9,
-  0x85, 0xDA, 0xDA, 0x85, 0x2C, 0x2C, 0xAC, 0xAF,
-  0xAF, 0xAF, 0xAF, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC,
-  0xAF, 0x2C, 0x2C, 0x2C, 0xAC, 0x95, 0x95, 0xA1,
-  0x20, 0x20, 0x20, 0x20, 0xE9, 0x8C, 0x5C, 0xE8,
-  0xE8, 0xE8, 0xE8, 0x3D, 0x73, 0x73, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE4, 0x73, 0x73, 0x73, 0xCD,
-  0x7E, 0xA3, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x24, 0x85, 0xAF, 0xAF,
-  0xAC, 0xAC, 0xAC, 0xAF, 0x85, 0x2C, 0xAC, 0x95,
-  0x95, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9, 0xAC, 0xAF,
-  0x8A, 0x8A, 0xDA, 0xDA, 0x85, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAF, 0xAC,
-  0xAC, 0xAF, 0xAF, 0xD9, 0xD6, 0xD6, 0x2C, 0x88,
-  0x20, 0x20, 0x20, 0x88, 0xB2, 0xDA, 0x7E, 0x73,
-  0xE8, 0xE8, 0xE8, 0x3D, 0x73, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xA3, 0xCD, 0xD3, 0x2A, 0x2A,
-  0x2A, 0x8C, 0x8D, 0x88, 0x20, 0xE3, 0x6B, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x41, 0x85, 0xAF, 0xAC,
-  0xAC, 0xAC, 0xAC, 0xAF, 0xAC, 0xD9, 0x7D, 0xD6,
-  0x7D, 0x7D, 0xD9, 0x95, 0xD9, 0xAC, 0xAC, 0xAF,
-  0xD3, 0x8D, 0xDA, 0xDA, 0x85, 0x85, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xAF, 0xAF, 0xAC, 0xD9, 0x95, 0x7D, 0xAC, 0x20,
-  0x20, 0x20, 0x20, 0xDB, 0x2C, 0xA3, 0x5C, 0xE8,
-  0xE8, 0xE8, 0xE8, 0x5C, 0x3D, 0x3D, 0xE8, 0xE8,
-  0xE8, 0xE4, 0xE8, 0xE8, 0xE8, 0xE4, 0x73, 0xEE,
-  0xD3, 0x2A, 0xEE, 0xAC, 0x20, 0x33, 0x2B, 0xE3,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x9F, 0xAF, 0xD9,
-  0xD9, 0xAC, 0xAF, 0xAF, 0xAC, 0xD9, 0x95, 0x7D,
-  0xD9, 0x95, 0x95, 0x95, 0x95, 0xD9, 0xAF, 0xAF,
-  0x7E, 0x85, 0x85, 0x2C, 0x85, 0x85, 0x85, 0x2C,
-  0x2C, 0x2C, 0xAF, 0xD9, 0xD9, 0x95, 0xD9, 0xAC,
-  0xAC, 0xAF, 0xAF, 0xAC, 0xAC, 0xAC, 0x91, 0x20,
-  0x33, 0xE3, 0x41, 0x48, 0x73, 0x5C, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xA3, 0xD6, 0x6C, 0x85, 0xE8,
-  0xDA, 0xAE, 0xB2, 0xA3, 0x5C, 0xE8, 0xE8, 0xE8,
-  0x3D, 0xEE, 0x4D, 0xA3, 0x24, 0x20, 0x6B, 0xDB,
-  0x2B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x85, 0x95,
-  0xD9, 0xD9, 0xAC, 0xAF, 0xAF, 0xAC, 0xD9, 0xAC,
-  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC, 0xD9, 0xAC,
-  0x8A, 0xD9, 0xAC, 0xD9, 0xAC, 0xAC, 0x2C, 0x2C,
-  0xAF, 0xAF, 0xAF, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xAF, 0xAF, 0xAF, 0xAC, 0xAC, 0x85, 0x33, 0x20,
-  0xCC, 0x20, 0xE3, 0xA3, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xA3, 0xD9, 0x81, 0xAC, 0xDA, 0x2D, 0x5C,
-  0x48, 0x41, 0x88, 0x74, 0x21, 0xA3, 0xE8, 0xE8,
-  0xE8, 0xE8, 0x73, 0x8C, 0x8A, 0x20, 0x20, 0x20,
-  0xDB, 0x33, 0x20, 0x20, 0x20, 0x20, 0xE6, 0xD9,
-  0xD9, 0xAC, 0xAC, 0xAF, 0xAC, 0xAF, 0xAC, 0xAF,
-  0xAF, 0xAC, 0xD9, 0xAF, 0xD9, 0xAC, 0xAC, 0xAF,
-  0x85, 0xD9, 0x95, 0xD9, 0x95, 0xD9, 0xD9, 0xAC,
-  0xAF, 0xAC, 0xAF, 0xAF, 0x2C, 0xAF, 0x2C, 0x2C,
-  0xAF, 0xAF, 0xAF, 0xAC, 0xAC, 0x2C, 0x20, 0x5B,
-  0x33, 0x20, 0xD6, 0xE8, 0xE8, 0xE8, 0xE8, 0x73,
-  0xAF, 0x2D, 0xD9, 0xDA, 0xB2, 0x81, 0x81, 0xE4,
-  0xA1, 0x91, 0x2B, 0x88, 0x33, 0x80, 0xAF, 0x73,
-  0xE8, 0xE8, 0xE8, 0x5C, 0xA3, 0x80, 0x41, 0xCC,
-  0x2B, 0xCC, 0x20, 0x20, 0x20, 0x20, 0x88, 0xDA,
-  0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0xAC, 0xAC, 0xAF,
-  0xAF, 0xAF, 0xAF, 0xAC, 0xAF, 0xAF, 0xAF, 0x2C,
-  0x85, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC, 0xAC, 0xD9,
-  0xD9, 0xD9, 0xAC, 0x2C, 0x2C, 0x2C, 0x85, 0x85,
-  0x85, 0x2C, 0x2C, 0xAF, 0x2C, 0x91, 0x20, 0xAE,
-  0x20, 0xDB, 0x3D, 0xE8, 0xE8, 0x5C, 0xB2, 0x80,
-  0xB2, 0xAF, 0x48, 0xB2, 0x48, 0x89, 0x89, 0x3D,
-  0x21, 0x48, 0x6C, 0x2D, 0x2B, 0x41, 0xE3, 0xAE,
-  0xD9, 0x5C, 0xE8, 0xE8, 0xE8, 0x95, 0x33, 0x80,
-  0xAE, 0x33, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x95,
-  0x85, 0x2C, 0x85, 0x2C, 0x2C, 0xAF, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xAC, 0xAF, 0xAF, 0x2C, 0x2C, 0x2C,
-  0xDA, 0xAF, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xAC, 0xAF, 0x2C, 0x85, 0x2C, 0x85,
-  0x85, 0x2C, 0x2C, 0x2C, 0x8A, 0x41, 0xDB, 0x33,
-  0x20, 0x95, 0xE8, 0xE8, 0xE8, 0xA3, 0xDB, 0x88,
-  0xDB, 0x80, 0xD6, 0x7E, 0x85, 0x2D, 0xE6, 0x5C,
-  0x21, 0x48, 0xD9, 0x7E, 0xD6, 0x2B, 0xCC, 0xAC,
-  0x85, 0xBC, 0xE8, 0xE8, 0xE8, 0xCD, 0x88, 0x5B,
-  0x41, 0x20, 0xAE, 0x20, 0x20, 0x20, 0x20, 0x74,
-  0xDA, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xAF, 0xAC, 0xD9, 0xD9, 0xAC, 0xAC, 0xAC, 0xD9,
-  0x8A, 0xAF, 0xAC, 0xAC, 0x2C, 0x85, 0x2C, 0xAF,
-  0xD9, 0xD9, 0xAF, 0xAF, 0xAF, 0x2C, 0xAF, 0x2C,
-  0x2C, 0x2C, 0x2C, 0xAF, 0x95, 0x20, 0x74, 0x20,
-  0x33, 0xA3, 0xE8, 0xE8, 0xE8, 0xE4, 0x7D, 0xCC,
-  0x6B, 0x33, 0xAE, 0x2C, 0x85, 0x2D, 0x9F, 0x73,
-  0xA1, 0x2D, 0x2C, 0xDA, 0x89, 0x48, 0xD3, 0xD9,
-  0x21, 0xA3, 0xE8, 0xE8, 0xE8, 0xE8, 0xE3, 0x20,
-  0x20, 0x20, 0xDB, 0x41, 0x20, 0x20, 0x20, 0x20,
-  0xDA, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF, 0xAC, 0xAC,
-  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0x95, 0x95, 0xD9,
-  0x2C, 0xD9, 0xD9, 0xAC, 0x2C, 0x2C, 0x85, 0xAF,
-  0xAF, 0xAF, 0xAC, 0xAC, 0xD9, 0xAC, 0xAF, 0xAC,
-  0xAC, 0x95, 0xD6, 0x7D, 0xAE, 0x88, 0x2B, 0x20,
-  0x6C, 0xE8, 0xE8, 0xE8, 0x73, 0xEE, 0x73, 0x2C,
-  0x89, 0x2B, 0x41, 0x33, 0xCC, 0xCC, 0x80, 0x3D,
-  0x2D, 0x74, 0x80, 0x48, 0x8D, 0x95, 0x48, 0x95,
-  0xEE, 0x5C, 0x5C, 0xE8, 0xE8, 0xE8, 0x24, 0x20,
-  0x20, 0x20, 0x5B, 0xDB, 0x20, 0x20, 0x20, 0x20,
-  0xAF, 0xAC, 0xD9, 0x95, 0xD6, 0xD6, 0xD6, 0x7D,
-  0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0xD9, 0xAC,
-  0xAC, 0xD9, 0xD9, 0xAC, 0x2C, 0x2C, 0x2C, 0xAF,
-  0xAC, 0xAC, 0xAC, 0xAC, 0xD9, 0xAC, 0xAC, 0xD9,
-  0xD6, 0x48, 0xE9, 0x95, 0x20, 0x2B, 0x41, 0x6B,
-  0x8D, 0xE8, 0xE8, 0xCD, 0x2B, 0x2B, 0x2C, 0x73,
-  0xCD, 0x48, 0xCA, 0x5B, 0x41, 0x5B, 0x74, 0xDA,
-  0x80, 0xE6, 0xC8, 0x85, 0xA1, 0x7D, 0x8D, 0x3D,
-  0x7E, 0xE9, 0x7D, 0xEE, 0xE8, 0xE8, 0x81, 0x20,
-  0x20, 0x20, 0xE3, 0xE3, 0x20, 0x20, 0x20, 0x20,
-  0x2D, 0xD9, 0xD6, 0x48, 0x6C, 0xE9, 0xA1, 0xD6,
-  0xD9, 0xD9, 0xAC, 0xD9, 0xD9, 0x95, 0xAC, 0x2C,
-  0x2C, 0x2C, 0x2C, 0xD9, 0xAC, 0x2C, 0x2C, 0x2C,
-  0xAF, 0x2C, 0xAF, 0xD9, 0xAC, 0xAF, 0xAF, 0x95,
-  0xB2, 0xE9, 0x21, 0x2B, 0x41, 0x2B, 0x20, 0x5B,
-  0x3D, 0xE8, 0xE8, 0x8D, 0x2B, 0x88, 0x5B, 0xE6,
-  0xBC, 0x73, 0x85, 0x89, 0x80, 0x5B, 0xE3, 0xAE,
-  0x2C, 0x8A, 0xD6, 0xB2, 0x2C, 0xA3, 0xA3, 0xD9,
-  0xA1, 0x2C, 0x85, 0x8D, 0xE8, 0xE8, 0x48, 0x20,
-  0x20, 0x20, 0xE3, 0x88, 0x20, 0x20, 0x20, 0x20,
-  0xAE, 0xD9, 0xB2, 0xE9, 0x6C, 0x48, 0xD6, 0xD9,
-  0x2C, 0x85, 0x2C, 0xD9, 0x7D, 0xD9, 0x2C, 0x85,
-  0x8D, 0x85, 0x2C, 0xAC, 0xAF, 0x2C, 0x2C, 0x85,
-  0x2C, 0x2C, 0xAF, 0xAC, 0xAC, 0xAF, 0xAF, 0xD9,
-  0xB2, 0x48, 0xB2, 0x20, 0x20, 0xCC, 0x20, 0x9F,
-  0xE8, 0xE8, 0xE8, 0xCD, 0x48, 0x89, 0xDB, 0x88,
-  0x2B, 0xE9, 0xCD, 0x2A, 0x48, 0x80, 0xAE, 0xAE,
-  0x7D, 0x48, 0x21, 0xEE, 0x3D, 0x2C, 0x48, 0x85,
-  0x2C, 0x95, 0x7D, 0x8C, 0xE8, 0xE8, 0xB2, 0x20,
-  0x20, 0x20, 0xDB, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0xDB, 0x2C, 0xB2, 0x48, 0x48, 0x7D, 0xD9, 0xAF,
-  0x85, 0x8A, 0x85, 0x7D, 0xB2, 0x95, 0x85, 0xDA,
-  0xD3, 0x85, 0xAF, 0xAC, 0x2C, 0x85, 0x85, 0x2C,
-  0xAC, 0xAC, 0xAC, 0xD9, 0xD9, 0xAC, 0x2C, 0x2C,
-  0xD9, 0xAC, 0x5B, 0x20, 0x20, 0xAE, 0x20, 0x2D,
-  0xE8, 0xE8, 0xE8, 0x7E, 0xD6, 0x48, 0xE9, 0xAE,
-  0x88, 0x5B, 0x80, 0x6C, 0xAE, 0xCA, 0x91, 0xE9,
-  0x43, 0x9F, 0xE6, 0x2C, 0x48, 0x21, 0xBC, 0x95,
-  0x95, 0xD6, 0x21, 0x7E, 0xE8, 0xE8, 0x7D, 0x20,
-  0x20, 0x20, 0x2B, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6B, 0xDA, 0xD9, 0x48, 0xB2, 0xD9, 0x2C, 0x85,
-  0xDA, 0xDA, 0x2C, 0xA1, 0x48, 0xAC, 0xDA, 0x8D,
-  0x2A, 0xAC, 0x7D, 0x95, 0xAF, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0x2C, 0xAF,
-  0x7D, 0xD6, 0x20, 0x20, 0x88, 0x9F, 0x20, 0xA1,
-  0xE8, 0xE8, 0xE8, 0xA3, 0xD6, 0x6C, 0xB2, 0x2C,
-  0x89, 0xE3, 0x88, 0xDB, 0xCC, 0x24, 0x7D, 0xEE,
-  0xB2, 0xCC, 0xAE, 0x2D, 0xDA, 0x2C, 0xD6, 0x2C,
-  0xB2, 0x2D, 0xD6, 0xEE, 0xE8, 0xE8, 0x95, 0x20,
-  0x20, 0x20, 0xDB, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6B, 0xDA, 0x95, 0xA1, 0xB2, 0xAC, 0x85, 0x85,
-  0xDA, 0x2C, 0x95, 0xA1, 0x21, 0x2C, 0x8A, 0x2A,
-  0xAF, 0xA1, 0x48, 0xD6, 0xAF, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0x95, 0x7D, 0x95, 0xAC, 0xD9, 0x7D,
-  0x48, 0xE6, 0x20, 0x20, 0x33, 0x89, 0x6B, 0x95,
-  0xE8, 0xE8, 0xE8, 0xA3, 0x21, 0x48, 0xAF, 0xAF,
-  0x9F, 0xE9, 0x43, 0x33, 0x33, 0x2D, 0xDA, 0xCD,
-  0xD6, 0xAE, 0x85, 0x2C, 0x7D, 0xD6, 0x91, 0xB8,
-  0xD4, 0x48, 0x7D, 0xA3, 0xE8, 0xE8, 0x95, 0x20,
-  0x20, 0x33, 0xE3, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x2C, 0x48, 0x6C, 0xB2, 0xAF, 0xDA, 0xDA,
-  0x85, 0xAF, 0xD9, 0x95, 0xAC, 0xDA, 0x8A, 0xDA,
-  0x7D, 0x48, 0x48, 0x7D, 0x2C, 0x85, 0x2C, 0xAF,
-  0xD9, 0xD9, 0x7D, 0x95, 0xD9, 0xD9, 0x95, 0xD6,
-  0x21, 0x24, 0x20, 0x20, 0x20, 0x5B, 0xDB, 0xAC,
-  0xE8, 0xE8, 0xE8, 0x3D, 0x7D, 0x48, 0xE6, 0x2D,
-  0x85, 0x81, 0x81, 0x48, 0xAE, 0xCA, 0x89, 0xCC,
-  0xAE, 0xDB, 0x2D, 0x95, 0x21, 0xCC, 0xDB, 0xAE,
-  0x91, 0xE9, 0x7D, 0x73, 0xE8, 0xE8, 0x48, 0x20,
-  0x6B, 0x74, 0x41, 0x88, 0x6B, 0x20, 0x20, 0x20,
-  0x6B, 0x95, 0xB2, 0xD6, 0xD9, 0x85, 0xDA, 0xDA,
-  0xDA, 0x2C, 0xAF, 0xAF, 0x2C, 0xDA, 0xDA, 0x85,
-  0xA1, 0xE9, 0x48, 0x95, 0x85, 0xDA, 0x85, 0xAC,
-  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0x95,
-  0x95, 0x6C, 0x41, 0x93, 0x93, 0x41, 0xDB, 0x95,
-  0xE8, 0xE8, 0xE8, 0x3D, 0x95, 0xD4, 0x6C, 0x21,
-  0x2D, 0x95, 0xCD, 0x2C, 0xD6, 0xD9, 0x6C, 0x91,
-  0x89, 0x7D, 0xAC, 0x2A, 0x8D, 0xE6, 0xCC, 0x88,
-  0x74, 0x48, 0xD9, 0xE4, 0xE8, 0xE8, 0xE6, 0x88,
-  0x2B, 0x88, 0x20, 0x33, 0xDB, 0x2B, 0xDB, 0x20,
-  0x91, 0x7D, 0xD9, 0xD9, 0x85, 0x85, 0xDA, 0xDA,
-  0x85, 0xAF, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xA1, 0xA1, 0xD6, 0xAF, 0x85, 0xDA, 0x85, 0x2C,
-  0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xD9, 0xD9, 0xAC,
-  0x2C, 0x47, 0x87, 0x3E, 0x3E, 0xA4, 0x7B, 0x80,
-  0xA3, 0xE8, 0xE8, 0x5C, 0x7D, 0x48, 0xE6, 0xD9,
-  0xBC, 0xEE, 0x7D, 0x43, 0xD6, 0x21, 0x43, 0x6C,
-  0x43, 0x7D, 0x7D, 0xB2, 0x8A, 0xEE, 0x2C, 0xCA,
-  0xAE, 0x48, 0x2C, 0xE4, 0xE8, 0x5C, 0xCC, 0x88,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x91, 0xE3,
-  0x21, 0xD9, 0x2C, 0x2C, 0xDA, 0xDA, 0xDA, 0x85,
-  0x2C, 0xAC, 0xD9, 0xD9, 0xAC, 0xAF, 0xAF, 0xAF,
-  0xD6, 0x7D, 0xD9, 0x2C, 0xDA, 0xDA, 0x85, 0xAC,
-  0xD9, 0x7D, 0x7D, 0xD9, 0xD9, 0xD9, 0x2C, 0x2C,
-  0xB8, 0x9C, 0xEC, 0x62, 0x6F, 0x62, 0x70, 0x3C,
-  0xAE, 0xCD, 0xE8, 0xE8, 0x8C, 0x7D, 0xC8, 0x3D,
-  0x8A, 0xE9, 0x2D, 0x9E, 0xA1, 0xD6, 0x48, 0x73,
-  0x81, 0xD6, 0xD6, 0xAE, 0x5B, 0x2D, 0xA3, 0xA3,
-  0x21, 0x21, 0xCD, 0xE8, 0xC0, 0x56, 0x31, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0xCC, 0xDB,
-  0x42, 0x85, 0x85, 0x85, 0x85, 0x85, 0x2C, 0x2C,
-  0xAC, 0xD9, 0xD9, 0xD9, 0xAC, 0xAF, 0xAF, 0xAF,
-  0xD9, 0x95, 0xAC, 0x2C, 0x85, 0x85, 0x2C, 0xD9,
-  0x7D, 0xD6, 0xD6, 0xD9, 0xAC, 0xAF, 0x8A, 0xBC,
-  0xC2, 0x68, 0x2E, 0x4B, 0xC9, 0x8B, 0x62, 0x87,
-  0x3C, 0x74, 0xBC, 0xE8, 0xE8, 0xE4, 0xEE, 0xA1,
-  0xE9, 0x21, 0xE6, 0x89, 0x48, 0x7D, 0xB2, 0x5C,
-  0x6C, 0x7D, 0x21, 0x80, 0xE3, 0x33, 0xCC, 0x2C,
-  0x3D, 0x3D, 0xE8, 0xE8, 0xEC, 0xCB, 0x5A, 0x6B,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x88, 0x41, 0x51,
-  0x49, 0x28, 0x85, 0x85, 0x85, 0x85, 0x2C, 0xAF,
-  0xAC, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xD9, 0x95, 0xD9, 0x2C, 0x85, 0x85, 0x2C, 0xD9,
-  0xB2, 0xB2, 0x2C, 0x2A, 0x79, 0x79, 0x97, 0x44,
-  0xED, 0x29, 0x32, 0x62, 0x4B, 0x62, 0x6F, 0x22,
-  0xF3, 0x6B, 0x33, 0x85, 0x73, 0xE4, 0x2D, 0x2B,
-  0xCC, 0x9F, 0xDA, 0xBC, 0x48, 0xD6, 0xA1, 0xE4,
-  0xE9, 0xD6, 0xD9, 0x2A, 0xB2, 0x2B, 0x2B, 0xA1,
-  0xB8, 0xE8, 0xE8, 0xE8, 0xEC, 0x3E, 0x30, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x6B, 0x54, 0xDC,
-  0xC9, 0x53, 0xBC, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF,
-  0xAF, 0xAC, 0xAF, 0xAC, 0xAC, 0x2C, 0xAF, 0xAC,
-  0x2C, 0x7D, 0xD9, 0x2C, 0x85, 0xDA, 0xAF, 0x7D,
-  0xB2, 0xAC, 0xC6, 0xBA, 0x4C, 0xEF, 0xA7, 0xEF,
-  0xEC, 0x7A, 0x62, 0x4B, 0x62, 0x4B, 0x8B, 0x4B,
-  0x3A, 0x52, 0x20, 0x6B, 0x21, 0x73, 0xAC, 0x2B,
-  0x41, 0x33, 0x48, 0x67, 0xA1, 0xD6, 0xD6, 0x5C,
-  0xE9, 0xD6, 0x2C, 0xEE, 0xB2, 0x9F, 0x8A, 0x95,
-  0x4D, 0xE8, 0xE8, 0x3D, 0x7A, 0x57, 0xD1, 0x7B,
-  0x20, 0x20, 0x20, 0x20, 0x6B, 0xCF, 0xBA, 0x3E,
-  0x3E, 0xD0, 0xBC, 0xAC, 0xAC, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0x95, 0x95, 0x7D, 0x95, 0x95, 0xD9,
-  0x85, 0xD9, 0xAF, 0xDA, 0xDA, 0x85, 0xAC, 0x21,
-  0xB2, 0x2A, 0xBA, 0x57, 0x2E, 0x2E, 0x2E, 0x7A,
-  0x32, 0x62, 0x8B, 0x4B, 0x8B, 0x4B, 0x4B, 0x4B,
-  0xC9, 0x4A, 0x5F, 0x20, 0x20, 0x2D, 0xA3, 0xD9,
-  0xCA, 0x88, 0xDB, 0x24, 0x48, 0x7D, 0xB2, 0xE4,
-  0x2D, 0x7D, 0x7D, 0x81, 0xA1, 0xDA, 0x21, 0xDA,
-  0xE4, 0xE8, 0xEE, 0xF1, 0x2E, 0x57, 0x82, 0x76,
-  0x52, 0x4F, 0x4F, 0x98, 0xDE, 0xB5, 0xEC, 0x2E,
-  0x3E, 0x6D, 0x85, 0x2C, 0xAC, 0xAC, 0xD9, 0xD9,
-  0x95, 0xD6, 0x7D, 0x7D, 0x95, 0xD9, 0xD9, 0xD9,
-  0xDA, 0x2C, 0x85, 0xDA, 0xDA, 0x2C, 0x95, 0xB2,
-  0x21, 0xB8, 0xED, 0x2E, 0x3E, 0x4B, 0xC9, 0x4B,
-  0x8B, 0x62, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x22, 0x6F, 0xCE, 0x20, 0x20, 0x20, 0x80, 0xCD,
-  0xDA, 0x2D, 0x2B, 0xDB, 0xE9, 0xD6, 0x95, 0x5C,
-  0x2D, 0x7D, 0x7D, 0xAF, 0xAF, 0xAC, 0xEE, 0x5C,
-  0xE8, 0xE8, 0xEB, 0x25, 0x7A, 0x57, 0x39, 0xE1,
-  0x83, 0xA8, 0x55, 0x83, 0x82, 0x57, 0x32, 0x8B,
-  0x62, 0x6D, 0xEB, 0x95, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C,
-  0xDA, 0x2C, 0x85, 0x85, 0x85, 0xAC, 0xD6, 0x21,
-  0x95, 0x6E, 0xED, 0x57, 0x62, 0x4B, 0x8B, 0x4B,
-  0x4B, 0x62, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x62,
-  0x62, 0x62, 0x25, 0x3C, 0x20, 0x20, 0x20, 0xE3,
-  0x2A, 0xBC, 0x7D, 0xCA, 0x6C, 0xD6, 0x95, 0x3D,
-  0x81, 0x7D, 0xD6, 0xD6, 0xDA, 0x73, 0xE8, 0xE8,
-  0xE8, 0x4D, 0x94, 0xED, 0x72, 0x3A, 0xF1, 0xA7,
-  0x39, 0xED, 0x39, 0xEF, 0x57, 0x32, 0x8B, 0x4B,
-  0x62, 0x62, 0xA6, 0x2A, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x2C, 0x2C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
-  0x85, 0x2C, 0x2C, 0xAF, 0xAC, 0x95, 0x21, 0x7D,
-  0xAC, 0x8C, 0x46, 0xC4, 0x62, 0x8B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x62, 0xC9, 0x30, 0x7B, 0x20, 0x20, 0x20,
-  0x41, 0x4D, 0x3D, 0x85, 0x48, 0x21, 0xDA, 0x3D,
-  0xE9, 0xD6, 0xD9, 0xCD, 0x5C, 0xE8, 0xE8, 0xE8,
-  0xE8, 0x4D, 0x71, 0x46, 0xEC, 0x2E, 0x72, 0xEC,
-  0x29, 0x29, 0x7C, 0x29, 0x2E, 0x4B, 0x4B, 0x62,
-  0x62, 0x4B, 0x3A, 0xAD, 0xE2, 0xAF, 0xD9, 0xD9,
-  0x2C, 0xDA, 0xDA, 0xDA, 0xDA, 0x85, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xAC, 0xD9, 0x95, 0xD6, 0xD6, 0xD9,
-  0x2C, 0x8C, 0xBA, 0x7C, 0x2E, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x62, 0xC9, 0xDC, 0x34, 0x20, 0x20, 0x20,
-  0x20, 0xAC, 0xE8, 0x5C, 0x8C, 0xBC, 0xE4, 0xE8,
-  0xEE, 0x2A, 0xA3, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE4, 0x7E, 0x65, 0x46, 0x29, 0x62, 0x62, 0x2E,
-  0x2E, 0x72, 0x2E, 0x2E, 0x32, 0x4B, 0x4B, 0x62,
-  0x4B, 0x4B, 0x4B, 0x32, 0x61, 0x9D, 0x2C, 0xD9,
-  0x2C, 0x85, 0xDA, 0x85, 0x2C, 0xAF, 0xAF, 0xAF,
-  0x2C, 0xAC, 0xD9, 0x95, 0xD6, 0x7D, 0x95, 0xAC,
-  0x2C, 0xDA, 0x40, 0x7C, 0x2E, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x62, 0x62, 0x22, 0xB7, 0xCE, 0x20, 0x20,
-  0x20, 0x95, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0x5C,
-  0x3D, 0xE9, 0x9A, 0x46, 0x7C, 0x32, 0x8B, 0x62,
-  0x4B, 0x8B, 0x8B, 0x4B, 0x4B, 0x4B, 0x4B, 0x62,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x62, 0x61, 0x4E, 0xDA,
-  0x85, 0x85, 0x85, 0x2C, 0xD9, 0xD9, 0xD9, 0xD9,
-  0x85, 0xD9, 0x7D, 0x21, 0x21, 0xD6, 0xAC, 0x2C,
-  0x2C, 0xDA, 0xDD, 0x77, 0x8B, 0x62, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x3E, 0x8B, 0x32, 0xC9, 0x22, 0x68, 0x88, 0x33,
-  0xA1, 0x73, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0x5C, 0x5C, 0x5C, 0x5C, 0x3D,
-  0x89, 0x20, 0x54, 0x23, 0x29, 0x2E, 0x4B, 0x62,
-  0x4B, 0x3E, 0x4B, 0x62, 0x4B, 0x4B, 0x4B, 0x8B,
-  0x8B, 0xC9, 0x6F, 0x4B, 0x8B, 0x4B, 0x78, 0xE2,
-  0x8A, 0x8A, 0x85, 0xAC, 0xD9, 0x7D, 0xD9, 0xAC,
-  0x2C, 0xD9, 0xD6, 0xB2, 0x21, 0x7D, 0xAF, 0x85,
-  0x2C, 0xDA, 0x40, 0xEF, 0x62, 0x62, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x8B, 0x4B, 0xC9, 0x63, 0xB4, 0x5C,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0xE8, 0xE8, 0xE8, 0xE8, 0x5C, 0x5C, 0xCD, 0xAE,
-  0x20, 0x20, 0xCE, 0xE1, 0x57, 0x32, 0x4B, 0x4B,
-  0x8B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x8B, 0x4B, 0x62, 0x4B, 0x62, 0x2E, 0x61, 0x28,
-  0x8D, 0xDA, 0xAF, 0xD9, 0x95, 0x95, 0xD9, 0xAF,
-  0xAF, 0xD9, 0xD6, 0xB2, 0x21, 0xD9, 0x2C, 0x85,
-  0xAF, 0xEB, 0xE1, 0x57, 0x2E, 0x62, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x3E, 0x9B, 0x31, 0x6E,
-  0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
-  0x5C, 0xE8, 0xE8, 0xE8, 0x3D, 0x7D, 0x33, 0x6B,
-  0x20, 0x20, 0x34, 0x23, 0x29, 0x3E, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x3E, 0x62, 0x62, 0x2E, 0xC4, 0x49, 0xD5,
-  0xDA, 0xD9, 0xD6, 0xA1, 0xA1, 0x21, 0xD9, 0xD9,
-  0xD9, 0x95, 0x21, 0x48, 0xD6, 0xAC, 0x85, 0x85,
-  0xAF, 0xB6, 0x5D, 0x2E, 0x32, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x62, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x62, 0x2E, 0x45, 0xDE,
-  0xDA, 0x5C, 0xE8, 0x5C, 0xE8, 0xE8, 0x5C, 0xE8,
-  0x5C, 0x5C, 0xA3, 0xAC, 0x2B, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x34, 0x23, 0x29, 0x62, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x62, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x3E, 0x3E, 0x63, 0x40, 0x97, 0x28, 0xDA,
-  0xD9, 0xA1, 0x48, 0xE9, 0x48, 0x21, 0xD9, 0xD9,
-  0xA1, 0xB2, 0xB2, 0xA1, 0x21, 0xAC, 0x85, 0x2C,
-  0xDA, 0x36, 0x77, 0x72, 0x62, 0x8B, 0x62, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x3E, 0xEC, 0x2F, 0x51,
-  0xE3, 0xAE, 0x48, 0x2C, 0xDA, 0xDA, 0x85, 0xAC,
-  0x48, 0x9E, 0x88, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x41, 0xA0, 0x23, 0x72, 0x2E, 0x4B, 0x4B,
-  0x4B, 0x62, 0x62, 0x4B, 0x4B, 0x4B, 0x2E, 0x8B,
-  0xF0, 0x4C, 0x40, 0xC2, 0x90, 0x8D, 0x85, 0xD9,
-  0xA1, 0x6C, 0x6C, 0x48, 0xD6, 0xD9, 0xAF, 0xAC,
-  0xA1, 0xD6, 0xD6, 0xB2, 0xD6, 0xAC, 0x85, 0x85,
-  0x4D, 0xBE, 0x39, 0x4C, 0x57, 0x2E, 0x2E, 0x2E,
-  0x3E, 0x3E, 0x62, 0x3E, 0x4B, 0x4B, 0x4B, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x8B, 0x8B, 0x57, 0x60, 0x76,
-  0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x3C, 0xA0, 0x23, 0x7C, 0x2E, 0x4B, 0x4B,
-  0x8B, 0x62, 0x4B, 0x4B, 0x3E, 0x7A, 0xF0, 0x29,
-  0x36, 0x97, 0xBC, 0x8A, 0x8D, 0xDA, 0xD9, 0x48,
-  0x81, 0x2D, 0x48, 0xD6, 0xD9, 0xAF, 0x2C, 0x2C,
-  0xAC, 0xAF, 0xD9, 0x7D, 0x7D, 0x2C, 0x85, 0x85,
-  0x85, 0xB4, 0x66, 0x23, 0x46, 0x2F, 0x60, 0x68,
-  0x77, 0x29, 0x29, 0xF0, 0x2E, 0x2E, 0x62, 0x4B,
-  0x4B, 0x4B, 0x4B, 0x4B, 0x32, 0x7C, 0x83, 0xB3,
-  0x54, 0x6B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6B, 0x7B, 0xC3, 0xE7, 0x39, 0x72, 0x62, 0x62,
-  0x62, 0x62, 0x62, 0x2E, 0x29, 0x77, 0xA7, 0x36,
-  0xB8, 0x85, 0x85, 0x8D, 0x8D, 0x85, 0xB2, 0x2D,
-  0x2D, 0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85,
-  0x2A, 0x85, 0xAC, 0x95, 0x95, 0xAF, 0x85, 0x85,
-  0xAF, 0x8C, 0xDF, 0xC6, 0xB1, 0xD1, 0xE5, 0xE7,
-  0x83, 0x23, 0x5D, 0x60, 0x39, 0x77, 0xEC, 0x2E,
-  0x2E, 0x32, 0x32, 0x2E, 0x7C, 0x5D, 0x35, 0xA2,
-  0x54, 0x6B, 0x6B, 0x20, 0x6B, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x6B, 0x88, 0xC1, 0x35, 0xE1, 0x77, 0x57, 0x2E,
-  0x2E, 0x72, 0x29, 0x77, 0x60, 0xB5, 0x44, 0xE2,
-  0x2C, 0x2C, 0xDA, 0x8A, 0xDA, 0xAF, 0xA1, 0x2D,
-  0xE9, 0xD6, 0xD9, 0xAF, 0x2C, 0x85, 0x85, 0x85,
-  0xEE, 0xAF, 0xD9, 0x7D, 0xD9, 0x2C, 0xDA, 0x85,
-  0xAC, 0xAF, 0x85, 0xDA, 0x8A, 0x2A, 0xE2, 0x50,
-  0x86, 0xD7, 0x75, 0x35, 0xA8, 0xE7, 0xE1, 0x5D,
-  0x68, 0x7C, 0xF1, 0x68, 0xE1, 0xBF, 0xA2, 0xC1,
-  0x52, 0x2B, 0x7D, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x85, 0x85, 0x85, 0x2C, 0x2C, 0x2C, 0x95,
-  0xE9, 0x74, 0xCE, 0xE0, 0xE7, 0x60, 0x77, 0x77,
-  0x7C, 0xEF, 0x5D, 0x23, 0x3F, 0xB6, 0x8A, 0x2C,
-  0xAC, 0xAF, 0x85, 0x8A, 0x85, 0xD9, 0x48, 0x48,
-  0xB2, 0x95, 0x95, 0xD9, 0x85, 0xDA, 0x85, 0x85,
-  0xD3, 0xB2, 0x21, 0x7D, 0xAC, 0x2C, 0xDA, 0x85,
-  0xAC, 0xAC, 0x85, 0x85, 0x85, 0x2C, 0xAF, 0x2C,
-  0xDA, 0x8C, 0x79, 0xC7, 0xB0, 0x51, 0xB3, 0x35,
-  0xBF, 0xE5, 0xE7, 0xA8, 0xE0, 0xA2, 0xC1, 0x34,
-  0x7D, 0x85, 0xAC, 0xD9, 0xAC, 0xAF, 0xAC, 0xAC,
-  0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0xAF, 0xAF, 0x85,
-  0xC8, 0xCD, 0x6A, 0x26, 0x35, 0x3F, 0x83, 0x23,
-  0x23, 0xE7, 0xBF, 0x96, 0xEB, 0xDA, 0xDA, 0x2C,
-  0x2C, 0x2C, 0x85, 0xDA, 0x2C, 0x7D, 0xA1, 0x48,
-  0xB2, 0x21, 0xD6, 0xD9, 0x2C, 0xDA, 0x85, 0xAF,
-  0xAF, 0x2D, 0xE9, 0x7D, 0xAC, 0x2C, 0x85, 0x2C,
-  0xD9, 0xD9, 0xAF, 0x85, 0x85, 0x85, 0x2C, 0x2C,
-  0x2C, 0x85, 0xD9, 0x21, 0xAC, 0x2C, 0xBD, 0xA5,
-  0xC3, 0xA2, 0xA2, 0xA2, 0x26, 0xC1, 0xCE, 0x2A,
-  0xAF, 0x95, 0xD9, 0x2C, 0x2C, 0x85, 0x2C, 0xAF,
-  0xAC, 0x2C, 0x85, 0x2C, 0xAF, 0x2C, 0x85, 0xDA,
-  0x8D, 0x2A, 0x85, 0x34, 0xC1, 0xB3, 0x76, 0x35,
-  0xE0, 0x30, 0xA5, 0xB6, 0x2C, 0x85, 0x85, 0x85,
-  0xAF, 0x2C, 0x85, 0x85, 0xD9, 0xD6, 0xA1, 0xA1,
-  0x48, 0xA1, 0xD6, 0xAF, 0xDA, 0x8A, 0x2C, 0xD9,
-  0xB2, 0x2D, 0x48, 0xD9, 0xAF, 0x2C, 0x2C, 0x85,
-  0xAF, 0xAC, 0x2C, 0x85, 0x85, 0x85, 0xAF, 0xAC,
-  0xAC, 0x2C, 0xD9, 0xD6, 0xD6, 0x21, 0xB2, 0x2C,
-  0xC8, 0x3B, 0x65, 0xC5, 0xCE, 0x8E, 0xC8, 0x2C,
-  0xD9, 0x95, 0xAC, 0x2C, 0x2C, 0x2C, 0xAF, 0xAC,
-  0xAC, 0xAF, 0x2C, 0x85, 0x2C, 0x2C, 0x2C, 0x85,
-  0xDA, 0x2C, 0xD6, 0xAF, 0x59, 0x65, 0xDE, 0xF3,
-  0xF3, 0x59, 0xBC, 0xAC, 0xAF, 0x85, 0x85, 0x85,
-  0xAF, 0xD9, 0xAF, 0x2C, 0xD9, 0xD6, 0xD6, 0xD6,
-  0x21, 0xD6, 0xD9, 0xDA, 0x8D, 0x8A, 0x2C, 0xD9,
-  0xB2, 0xA1, 0xD6, 0xAC, 0x2C, 0x2C, 0x2C, 0x85,
-  0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85, 0xAF, 0xD9,
-  0xD9, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xAC,
-  0x85, 0x2A, 0x4D, 0xBC, 0x85, 0xAC, 0xAF, 0xAF,
-  0xAC, 0xD9, 0xAF, 0x2C, 0xAF, 0xD9, 0xD9, 0xAC,
-  0xAC, 0xAF, 0x85, 0x2C, 0x85, 0x2C, 0x2C, 0x2C,
-  0x2C, 0xD9, 0xB2, 0xD4, 0xD6, 0x2C, 0x8A, 0xDA,
-  0xC8, 0x85, 0x2C, 0xAC, 0x2C, 0xDA, 0xDA, 0x85,
-  0xAF, 0xAC, 0xD9, 0xAC, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xAC, 0xDA, 0x8D, 0xBC, 0xDA, 0xD9, 0x95,
-  0x95, 0xD9, 0xD9, 0xAF, 0x2C, 0x2C, 0x2C, 0x85,
-  0x2C, 0xAF, 0xAF, 0x85, 0x85, 0x85, 0x2C, 0xAC,
-  0xD9, 0xAF, 0xAF, 0xAF, 0x2C, 0x2C, 0x2C, 0x85,
-  0x8A, 0x2A, 0x8D, 0x2C, 0xD9, 0x95, 0xAC, 0xAC,
-  0xD9, 0xD9, 0xD9, 0xD9, 0x95, 0x95, 0xD9, 0xAF,
-  0xAF, 0x2C, 0x85, 0x85, 0x85, 0x85, 0x85, 0x2C,
-  0x85, 0x2C, 0xD9, 0xD9, 0xD9, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x85, 0x85, 0xAF, 0xAF, 0x85, 0x85, 0x85,
-  0xAF, 0xD9, 0xD9, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C,
-  0x2C, 0x85, 0x8A, 0x2A, 0x8D, 0x2C, 0xD9, 0xD9,
-  0x2C, 0xAC, 0xAF, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
-  0x85, 0xAF, 0xAC, 0x2C, 0x2C, 0x2C, 0x2C, 0xAC,
-  0xD9, 0xD9, 0xAF, 0x85, 0x85, 0x85, 0xDA, 0xDA,
-  0x8A, 0x8A, 0x85, 0xAC, 0xD9, 0xD9, 0xAC, 0xD9,
-  0xD6, 0xD6, 0x7D, 0x95, 0x7D, 0xD9, 0xAF, 0xAF,
-  0xAF, 0x2C, 0x85, 0x85, 0xDA, 0x85, 0x2C, 0x85,
-  0x85, 0x2C, 0xAF, 0xAC, 0xAF, 0xAF, 0x2C, 0x2C,
-  0x2C, 0x2C, 0x2C, 0xAF, 0xAC, 0x2C, 0x2C, 0x2C,
-  0x2C, 0xAF, 0xD9, 0xAC, 0xAF, 0x2C, 0x85, 0x85,
-  0x85, 0xDA, 0x8D, 0x8A, 0x85, 0xAC, 0x95, 0xD9
-};
-
-#define INCLUDE_LINUX_LOGOBW
-#define INCLUDE_LINUX_LOGO16
-#include <linux/linux_logo.h>
-
-#endif /* INCLUDE_LINUX_LOGO_DATA */
diff -Nru a/include/asm-mips64/elf.h b/include/asm-mips64/elf.h
--- a/include/asm-mips64/elf.h	Sat Aug  3 18:35:55 2002
+++ b/include/asm-mips64/elf.h	Mon Mar 17 21:31:50 2003
@@ -76,7 +76,7 @@
  * See comments in asm-alpha/elf.h, this is the same thing
  * on the MIPS.
  */
-#define ELF_PLAT_INIT(_r)	do { \
+#define ELF_PLAT_INIT(_r, load_addr)	do { \
 	_r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0;	\
 	_r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0;	\
 	_r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0;	\
diff -Nru a/include/asm-mips64/linux_logo.h b/include/asm-mips64/linux_logo.h
--- a/include/asm-mips64/linux_logo.h	Mon Feb  4 23:45:05 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,919 +0,0 @@
-/*
- * include/asm-mips/linux_logo.h: This is a linux logo
- *                                to be displayed on boot.
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * image size has to be 80x80
- * values have to start from 0x20
- * (i.e. RGB(linux_logo_red[0],
- *	     linux_logo_green[0],
- *	     linux_logo_blue[0]) is color 0x20)
- * BW image has to be 80x80 as well, with MS bit
- * on the left
- * Serial_console ascii image can be any size,
- * but should contain %s to display the version
- */
- 
-#include <linux/init.h>
-#include <linux/version.h>
-
-#define linux_logo_banner "Linux/MIPS64 version " UTS_RELEASE
-
-#define __HAVE_ARCH_LINUX_LOGO
-
-#define LINUX_LOGO_COLORS	187
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-unsigned char linux_logo_red[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79,
-    0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
-    0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
-    0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
-    0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
-    0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c,
-    0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e,
-    0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c,
-    0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x8d,
-    0x12, 0x4a, 0x8e, 0xf2, 0xf6, 0xee, 0xb5, 0xe4,
-    0xf1, 0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x16,
-    0x9a, 0x2e, 0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62,
-    0xd6, 0xa3, 0x74, 0xa7, 0xa2, 0xca, 0xe0, 0xae,
-    0xbe, 0xce, 0xa3, 0x8e, 0x6d, 0x8e, 0x32, 0xaf,
-    0x50, 0x9e, 0x5b, 0x8a, 0x98, 0x82, 0x7a, 0x82,
-    0x56, 0x7c, 0x8a, 0x56, 0x5e, 0x86, 0x6a, 0x52,
-    0x59, 0x64, 0x5e,
-};
-
-unsigned char linux_logo_green[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c,
-    0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
-    0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
-    0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
-    0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
-    0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76,
-    0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46,
-    0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b,
-    0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x8d,
-    0x0e, 0x36, 0x86, 0xba, 0xbe, 0xcc, 0x8e, 0xb8,
-    0xc4, 0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x12,
-    0x7a, 0x20, 0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46,
-    0xa6, 0x6e, 0x51, 0x72, 0x92, 0xa2, 0xa6, 0x87,
-    0x96, 0xa2, 0x85, 0x7a, 0x6a, 0x6e, 0x22, 0x76,
-    0x36, 0x76, 0x3c, 0x6e, 0x63, 0x53, 0x66, 0x62,
-    0x42, 0x50, 0x56, 0x42, 0x56, 0x56, 0x56, 0x3e,
-    0x51, 0x52, 0x56,
-};
-
-unsigned char linux_logo_blue[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08,
-    0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
-    0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
-    0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
-    0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
-    0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a,
-    0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e,
-    0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b,
-    0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x8d,
-    0x06, 0x0e, 0x6a, 0x0e, 0x0e, 0x5b, 0x2c, 0x3e,
-    0x0e, 0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x06,
-    0x2e, 0x06, 0x4e, 0x36, 0x06, 0x58, 0x24, 0x06,
-    0x3a, 0x08, 0x08, 0x07, 0x5e, 0x45, 0x0a, 0x32,
-    0x2e, 0x2a, 0x43, 0x48, 0x5f, 0x2e, 0x06, 0x06,
-    0x07, 0x24, 0x06, 0x32, 0x06, 0x06, 0x46, 0x2e,
-    0x22, 0x06, 0x06, 0x1e, 0x4c, 0x06, 0x3a, 0x22,
-    0x42, 0x34, 0x42,
-};
-
-unsigned char linux_logo[] __initdata = {
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
-    0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-    0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
-    0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
-    0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
-    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-    0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
-    0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-    0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
-    0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34,
-    0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
-    0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22,
-    0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25,
-    0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
-    0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
-    0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-    0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
-    0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-    0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36,
-    0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
-    0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21,
-    0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
-    0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
-    0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
-    0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32,
-    0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a,
-    0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b,
-    0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37,
-    0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
-    0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
-    0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
-    0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
-    0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67,
-    0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
-    0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
-    0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
-    0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78,
-    0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79,
-    0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c,
-    0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
-    0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
-    0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36,
-    0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
-    0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89,
-    0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36,
-    0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
-    0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e,
-    0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
-    0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22,
-    0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
-    0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c,
-    0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51,
-    0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
-    0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97,
-    0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98,
-    0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
-    0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32,
-    0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50,
-    0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
-    0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
-    0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98,
-    0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
-    0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
-    0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b,
-    0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48,
-    0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-    0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-    0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
-    0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
-    0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c,
-    0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c,
-    0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
-    0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93,
-    0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28,
-    0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
-    0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93,
-    0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
-    0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x99, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
-    0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30,
-    0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c,
-    0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36,
-    0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x4f, 0x3e, 0x4d, 0x49, 0x48,
-    0x98, 0x2b, 0x55, 0x4f, 0x9b, 0x48, 0x48, 0x48,
-    0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36,
-    0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
-    0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36,
-    0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x4f, 0x54, 0x38, 0x3d, 0x98, 0x37, 0x9b,
-    0x3a, 0x22, 0x23, 0x2a, 0x55, 0x4f, 0x48, 0x48,
-    0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
-    0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d,
-    0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
-    0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x52,
-    0x53, 0x37, 0x54, 0x98, 0x55, 0x38, 0x38, 0x47,
-    0x4a, 0x2d, 0x30, 0x23, 0x28, 0x39, 0x53, 0x52,
-    0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30,
-    0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32,
-    0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a,
-    0x36, 0x24, 0x4f, 0x48, 0x48, 0x9b, 0x55, 0x39,
-    0x55, 0x53, 0x3a, 0x55, 0x3a, 0x51, 0x51, 0x47,
-    0x55, 0x3a, 0x4d, 0x37, 0x30, 0x22, 0x24, 0x2b,
-    0x54, 0x9b, 0x48, 0x48, 0x48, 0x47, 0x32, 0x30,
-    0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
-    0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25,
-    0x36, 0x3a, 0x48, 0x48, 0x48, 0x4f, 0x26, 0x23,
-    0x26, 0x39, 0x3e, 0x43, 0x49, 0x37, 0x2f, 0x9b,
-    0x55, 0x3a, 0x54, 0x43, 0x3e, 0x30, 0x32, 0x3d,
-    0x49, 0x3f, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21,
-    0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36,
-    0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
-    0x23, 0x43, 0x48, 0x48, 0x48, 0x47, 0x3b, 0x32,
-    0x21, 0x28, 0x2b, 0x9e, 0x49, 0x37, 0x2e, 0x52,
-    0x4a, 0x37, 0x9e, 0x98, 0x51, 0x3a, 0x93, 0x54,
-    0x55, 0x4f, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36,
-    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-    0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36,
-    0x2e, 0x9b, 0x48, 0x48, 0x52, 0x4b, 0x52, 0x9e,
-    0x51, 0x30, 0x22, 0x28, 0x32, 0x32, 0x39, 0x47,
-    0x37, 0x2a, 0x39, 0x3a, 0x50, 0x9f, 0x3a, 0x9f,
-    0x4b, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x98, 0x36,
-    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-    0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36,
-    0x54, 0x48, 0x48, 0x45, 0x30, 0x30, 0x9e, 0x52,
-    0x45, 0x3a, 0x31, 0x25, 0x22, 0x25, 0x2a, 0x98,
-    0x39, 0x2f, 0x42, 0x49, 0x4a, 0x3b, 0x50, 0x47,
-    0x43, 0x9d, 0x3b, 0x4b, 0x48, 0x48, 0x9a, 0x36,
-    0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36,
-    0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
-    0x43, 0x48, 0x48, 0x50, 0x30, 0x23, 0x25, 0x2f,
-    0x3f, 0x52, 0x49, 0x51, 0x39, 0x25, 0x24, 0x2b,
-    0x9e, 0x42, 0x3e, 0x55, 0x9e, 0x4f, 0x4f, 0x54,
-    0x4a, 0x9e, 0x49, 0x50, 0x48, 0x48, 0x4b, 0x21,
-    0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25,
-    0x52, 0x48, 0x48, 0x45, 0x3a, 0x51, 0x26, 0x23,
-    0x30, 0x9d, 0x45, 0x40, 0x3a, 0x39, 0x2b, 0x2b,
-    0x3b, 0x3a, 0x55, 0x4b, 0x47, 0x9e, 0x3a, 0x49,
-    0x9e, 0x9f, 0x3b, 0x9a, 0x48, 0x48, 0x4f, 0x21,
-    0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a,
-    0x47, 0x48, 0x48, 0x43, 0x3e, 0x3a, 0x9d, 0x2b,
-    0x23, 0x25, 0x39, 0x4d, 0x2b, 0x31, 0x2d, 0x9d,
-    0x34, 0x2e, 0x2f, 0x9e, 0x3a, 0x55, 0x3f, 0x9f,
-    0x9f, 0x3e, 0x55, 0x43, 0x48, 0x48, 0x4c, 0x22,
-    0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
-    0x9b, 0x48, 0x48, 0x4f, 0x3e, 0x4d, 0x55, 0x9e,
-    0x51, 0x24, 0x23, 0x26, 0x32, 0x2c, 0x3b, 0x4b,
-    0x55, 0x32, 0x2b, 0x37, 0x98, 0x9e, 0x3e, 0x9e,
-    0x55, 0x37, 0x3e, 0x4b, 0x48, 0x48, 0x4c, 0x23,
-    0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31,
-    0x9b, 0x48, 0x48, 0x4f, 0x55, 0x3a, 0x53, 0x53,
-    0x2e, 0x9d, 0x34, 0x28, 0x28, 0x37, 0x98, 0x45,
-    0x3e, 0x2b, 0x49, 0x9e, 0x3b, 0x3e, 0x2d, 0x6b,
-    0x4a, 0x3a, 0x3b, 0x4f, 0x48, 0x48, 0x46, 0x22,
-    0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d,
-    0x9b, 0x48, 0x48, 0x47, 0x3b, 0x3a, 0x2f, 0x37,
-    0x49, 0x38, 0x38, 0x3a, 0x2b, 0x31, 0x51, 0x32,
-    0x2b, 0x26, 0x37, 0x9f, 0x55, 0x32, 0x26, 0x2b,
-    0x2d, 0x9d, 0x3b, 0x52, 0x48, 0x48, 0x9a, 0x36,
-    0x24, 0x27, 0xa0, 0x24, 0x25, 0x28, 0x21, 0x36,
-    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
-    0x39, 0x4d, 0xa1, 0x84, 0x81, 0x57, 0x21, 0x39,
-    0x52, 0x48, 0x48, 0x47, 0x9f, 0x4a, 0x4d, 0x55,
-    0x37, 0x9f, 0x45, 0x9e, 0x3e, 0x54, 0x4d, 0x2d,
-    0x51, 0x3b, 0x3d, 0x40, 0x50, 0x2f, 0x32, 0x23,
-    0x2a, 0x3a, 0x54, 0x47, 0x48, 0x48, 0x53, 0x28,
-    0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
-    0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
-    0x2d, 0xa2, 0x7a, 0xa3, 0xa4, 0xa4, 0x7f, 0x22,
-    0x51, 0x52, 0x48, 0x9b, 0x3b, 0x3a, 0x2f, 0x54,
-    0x3f, 0x4b, 0x3b, 0x34, 0x3e, 0x55, 0x34, 0x4d,
-    0x34, 0x3b, 0x3b, 0x55, 0x42, 0x4b, 0x9e, 0x31,
-    0x2b, 0x3a, 0x9e, 0x47, 0xa5, 0xa5, 0xa6, 0x61,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
-    0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
-    0x4d, 0x91, 0x5b, 0xa3, 0xa4, 0xa4, 0xa4, 0x5a,
-    0x21, 0x2e, 0x46, 0x48, 0x9a, 0x3b, 0x42, 0x47,
-    0x42, 0x9d, 0x37, 0x39, 0x4a, 0x3e, 0x3a, 0x52,
-    0x38, 0x3e, 0x3e, 0x2b, 0x25, 0x37, 0x4f, 0x4f,
-    0x55, 0x55, 0x45, 0xa7, 0xa8, 0x69, 0x66, 0xa9,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
-    0x83, 0xaa, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a,
-    0x60, 0x85, 0xab, 0xac, 0xa4, 0xa4, 0xa4, 0x82,
-    0x86, 0x36, 0x32, 0x3f, 0x48, 0x47, 0x4b, 0x4a,
-    0x9d, 0x55, 0x2f, 0x51, 0x3a, 0x3b, 0x55, 0x9b,
-    0x4d, 0x3b, 0x55, 0x39, 0x24, 0x28, 0x32, 0x9e,
-    0x47, 0x47, 0x48, 0xad, 0xa3, 0xa8, 0xae, 0xaf,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57,
-    0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x23, 0x30, 0x31, 0xb0, 0x91, 0x7e, 0x90, 0x90,
-    0x8b, 0x5b, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0x5d, 0xb1, 0x36, 0x24, 0x53, 0x47, 0x37, 0x30,
-    0x32, 0x2e, 0x98, 0x3f, 0x3a, 0x3e, 0x4a, 0x47,
-    0x9d, 0x3e, 0x54, 0x40, 0x55, 0x30, 0x30, 0x4a,
-    0x6b, 0x9b, 0x99, 0xad, 0x64, 0x5c, 0x8b, 0xb1,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
-    0x82, 0x5c, 0xb2, 0x2a, 0x23, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x24, 0x2b, 0xb0, 0x8b, 0x5b, 0x76, 0x5b, 0x5b,
-    0x7b, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa8, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x3d, 0x30,
-    0x22, 0x28, 0x3a, 0x44, 0x4a, 0x3e, 0x3e, 0x9b,
-    0x9d, 0x3e, 0x9e, 0x4b, 0x55, 0x2e, 0x42, 0x9f,
-    0x93, 0x4f, 0x3f, 0xb3, 0x7b, 0x7b, 0x85, 0x80,
-    0xa0, 0x36, 0x36, 0x36, 0x21, 0xb4, 0x7e, 0x7b,
-    0x64, 0x64, 0xb5, 0x35, 0x24, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x31, 0xb6, 0x5b, 0x64, 0xa3, 0xa3, 0xac,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0x66, 0xb7, 0x36, 0x36, 0x36, 0x2c, 0x54,
-    0x31, 0x23, 0x26, 0x2c, 0x3a, 0x3b, 0x55, 0x47,
-    0x37, 0x3b, 0x3b, 0x38, 0x4a, 0x98, 0x55, 0x98,
-    0x47, 0x9a, 0x3f, 0xb8, 0x76, 0x76, 0x7a, 0x63,
-    0xb9, 0xba, 0x86, 0xba, 0xbb, 0x90, 0x5b, 0x64,
-    0xa3, 0xa3, 0xbc, 0x2d, 0x27, 0x23, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x26, 0x2d, 0x91, 0x5b, 0x64, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa8, 0x83, 0xaf, 0x36, 0x36, 0x36, 0x30,
-    0x98, 0x37, 0x30, 0x26, 0x9d, 0x3e, 0x9f, 0x9b,
-    0x37, 0x3b, 0x3b, 0x53, 0x53, 0x3d, 0x4b, 0x48,
-    0x9b, 0x9a, 0x3f, 0xbd, 0x5b, 0x7b, 0xbe, 0x85,
-    0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xa3, 0xa4,
-    0xa4, 0xac, 0x5d, 0xb5, 0x39, 0x26, 0x23, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2d, 0xbf, 0xbe, 0x64, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa8, 0x88, 0x36, 0x36, 0x36, 0x36,
-    0x2d, 0x3f, 0x3b, 0x31, 0x4d, 0x3e, 0x9f, 0x47,
-    0x38, 0x3b, 0x3e, 0x3e, 0x98, 0x52, 0x48, 0x48,
-    0x9b, 0x45, 0x3f, 0xc0, 0x6d, 0x7b, 0xab, 0xbe,
-    0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa3, 0xc1, 0x37, 0x35, 0x26, 0x23,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2e, 0xbf, 0x7a, 0x7b, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa8, 0x72, 0x73, 0x36, 0x36, 0x36,
-    0x24, 0x52, 0x47, 0x49, 0x3a, 0x55, 0x98, 0x47,
-    0x9d, 0x3e, 0x54, 0x45, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x46, 0x42, 0xb6, 0x7a, 0x7b, 0x64, 0x7b,
-    0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xa3, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xac, 0x64, 0xc1, 0x4d, 0x2c, 0x27,
-    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x25, 0x31, 0xc2, 0x8b, 0x7b, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa8, 0x89, 0xa0, 0x36, 0x36,
-    0x32, 0x47, 0x48, 0x9b, 0x9a, 0x3f, 0x47, 0x48,
-    0x4b, 0x40, 0x4f, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xa3, 0xac,
-    0xa3, 0x64, 0x64, 0xa3, 0xa3, 0xac, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0x5d, 0xc3, 0x2c,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x25, 0x31, 0xc2, 0x85, 0x7b, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0x66, 0x57, 0x27, 0x4d,
-    0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x99, 0x34, 0xa0, 0xb9, 0x7a, 0x7b, 0xa3, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0xc2,
-    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2d, 0xc2, 0x85, 0x7b, 0xac, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa8, 0x5f, 0x92, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
-    0x35, 0x36, 0xaf, 0xbb, 0x7a, 0x7b, 0xac, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xac, 0xa3, 0xc0,
-    0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x30, 0x2f, 0xb6, 0x8b, 0x7b, 0xac, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0x66, 0x89, 0x45,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25,
-    0x36, 0x36, 0x61, 0xb9, 0x6d, 0x64, 0xac, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xac, 0x7b, 0xbe, 0xc3,
-    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0xc4, 0x63, 0xbe, 0xa3, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0x72, 0x81, 0xc5,
-    0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36,
-    0x36, 0x36, 0xc6, 0x8f, 0x6d, 0x64, 0xac, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa3, 0xab, 0x8b, 0xb0, 0x2c,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x35, 0x96, 0x75, 0xab, 0xa3, 0xac, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xac, 0x7b, 0x81, 0xb9,
-    0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b,
-    0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x73, 0xb9, 0x7a, 0x7b, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0x64, 0x76, 0x7a, 0x91, 0xb5, 0x31, 0x30,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x39, 0x97, 0x75, 0xbe, 0x7b, 0x64, 0xa3, 0xa3,
-    0xac, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0x7b, 0x7a, 0xc7,
-    0xc8, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
-    0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xc8, 0xbb, 0x8b, 0x7b, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0x64, 0x64,
-    0x76, 0x85, 0xbf, 0xb5, 0x34, 0x2b, 0x27, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0xc9, 0x63, 0x7e, 0x7a, 0x6d, 0xbe, 0x5b,
-    0x76, 0x7b, 0x64, 0x64, 0xa3, 0xac, 0xa4, 0xa4,
-    0xa4, 0xa4, 0xa4, 0xa4, 0xac, 0x76, 0x85, 0xb9,
-    0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xca, 0xbb, 0x75, 0x76, 0xa3, 0xa4,
-    0xa4, 0xa4, 0xac, 0xa3, 0x64, 0x76, 0xbe, 0x8b,
-    0xb6, 0xb5, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x27, 0x31, 0xcb, 0xc9, 0xbb, 0x74, 0x63, 0x90,
-    0x7e, 0x75, 0x8b, 0x6d, 0xbe, 0x76, 0x64, 0xa3,
-    0xac, 0xac, 0xac, 0xac, 0x64, 0x7a, 0x84, 0xcc,
-    0x79, 0xa0, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xc8, 0xcc, 0x63, 0x6d, 0x7b, 0x64,
-    0xac, 0xa3, 0x64, 0x7b, 0xbe, 0x75, 0x63, 0x96,
-    0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x28, 0x27, 0x35, 0x2d, 0x41, 0xb5, 0xc5, 0x8f,
-    0xb9, 0xbb, 0xc7, 0x74, 0x84, 0x90, 0x85, 0x6d,
-    0x5b, 0x7b, 0x7b, 0xab, 0x6d, 0x90, 0xb9, 0xcd,
-    0xca, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
-    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
-    0x36, 0x21, 0xb4, 0x80, 0xc7, 0x7e, 0x6d, 0x76,
-    0xab, 0x76, 0x6d, 0x85, 0x63, 0xb9, 0xb5, 0x34,
-    0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
-    0x41, 0xce, 0xcf, 0x6c, 0x80, 0xcc, 0xb9, 0x74,
-    0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xcd, 0x79,
-    0xc6, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d,
-    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38,
-    0x4d, 0x37, 0xd0, 0xd1, 0x8f, 0x74, 0x63, 0x7e,
-    0x75, 0x7e, 0x63, 0xc7, 0x88, 0xc4, 0x31, 0x2a,
-    0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
-    0x33, 0x39, 0x2e, 0x51, 0x41, 0xb2, 0x6c, 0xd1,
-    0x80, 0xcc, 0xcc, 0xcc, 0xd2, 0xd1, 0xb7, 0xd3,
-    0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
-    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
-    0x2b, 0x34, 0xd4, 0xca, 0xd5, 0x8f, 0xbb, 0xc7,
-    0xc7, 0xbb, 0xcc, 0x6c, 0x41, 0x39, 0x27, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
-    0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41,
-    0xd6, 0xb7, 0x79, 0x79, 0x79, 0xca, 0xd7, 0x51,
-    0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
-    0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
-    0x24, 0x2a, 0x31, 0xd8, 0xc8, 0x79, 0xd1, 0x80,
-    0xd5, 0xba, 0xd9, 0x2f, 0x35, 0x26, 0x23, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
-    0x31, 0x2f, 0xd4, 0xd8, 0xd8, 0x2f, 0x2e, 0x33,
-    0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x27, 0x35, 0x34, 0xd8, 0xd8, 0xd8,
-    0xda, 0xd4, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
-    0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
-    0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
-    0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-};
-
-#endif /* INCLUDE_LINUX_LOGO_DATA */
-
-#include <linux/linux_logo.h>
-
diff -Nru a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h
--- a/include/asm-parisc/assembly.h	Mon Feb 24 12:16:15 2003
+++ b/include/asm-parisc/assembly.h	Wed Mar  5 06:19:10 2003
@@ -21,7 +21,25 @@
 #ifndef _PARISC_ASSEMBLY_H
 #define _PARISC_ASSEMBLY_H
 
-#if defined(__LP64__) && defined(__ASSEMBLY__)
+#ifdef __LP64__
+#define LDREG	ldd
+#define STREG	std
+#define LDREGM	ldd,mb
+#define STREGM	std,ma
+#define RP_OFFSET	16
+#define FRAME_SIZE	128
+#else
+#define LDREG	ldw
+#define STREG	stw
+#define LDREGM	ldwm
+#define STREGM	stwm
+#define RP_OFFSET	20
+#define FRAME_SIZE	64
+#endif
+
+#ifdef __ASSEMBLY__
+
+#ifdef __LP64__
 /* the 64-bit pa gnu assembler unfortunately defaults to .level 1.1 or 2.0 so
  * work around that for now... */
 	.level 2.0w
@@ -101,22 +119,6 @@
 	ldo	R%\value(\reg), \reg
 	.endm
 
-#ifdef __LP64__
-#define LDREG	ldd
-#define STREG	std
-#define LDREGM	ldd,mb
-#define STREGM	std,ma
-#define RP_OFFSET	16
-#define FRAME_SIZE	128
-#else
-#define LDREG	ldw
-#define STREG	stw
-#define LDREGM	ldwm
-#define STREGM	stwm
-#define RP_OFFSET	20
-#define FRAME_SIZE	64
-#endif
-
 	.macro loadgp
 #ifdef __LP64__
 	ldil		L%__gp, %r27
@@ -420,4 +422,5 @@
 	REST_CR	(%cr22, PT_PSW	(\regs))
 	.endm
 
+#endif /* __ASSEMBLY__ */
 #endif
diff -Nru a/include/asm-parisc/bug.h b/include/asm-parisc/bug.h
--- a/include/asm-parisc/bug.h	Sun Feb 16 15:52:20 2003
+++ b/include/asm-parisc/bug.h	Mon Mar 17 09:58:50 2003
@@ -5,7 +5,9 @@
  * Tell the user there is some problem.
  */
 #define BUG() do { \
+	extern void dump_stack(void); \
 	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	dump_stack(); \
 } while (0)
 
 #define PAGE_BUG(page) do { \
diff -Nru a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
--- a/include/asm-parisc/cacheflush.h	Sun Mar  2 18:13:32 2003
+++ b/include/asm-parisc/cacheflush.h	Sat Mar  8 12:01:30 2003
@@ -25,9 +25,14 @@
 
 extern void flush_cache_all_local(void);
 
+static inline void cacheflush_h_tmp_function(void *dummy)
+{
+	flush_cache_all_local();
+}
+
 static inline void flush_cache_all(void)
 {
-	on_each_cpu((void (*)(void *))flush_cache_all_local, NULL, 1, 1);
+	on_each_cpu(cacheflush_h_tmp_function, NULL, 1, 1);
 }
 
 /* The following value needs to be tuned and probably scaled with the
@@ -62,13 +67,15 @@
 #endif
 }
 
+extern void __flush_dcache_page(struct page *page);
+
 static inline void flush_dcache_page(struct page *page)
 {
 	if (page->mapping && list_empty(&page->mapping->i_mmap) &&
 			list_empty(&page->mapping->i_mmap_shared)) {
 		set_bit(PG_dcache_dirty, &page->flags);
 	} else {
-		flush_kernel_dcache_page(page_address(page));
+		__flush_dcache_page(page);
 	}
 }
 
diff -Nru a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h
--- a/include/asm-parisc/compat.h	Sun Mar  9 01:34:45 2003
+++ b/include/asm-parisc/compat.h	Sun Mar 23 22:28:24 2003
@@ -18,6 +18,7 @@
 typedef u32	compat_ino_t;
 typedef u32	compat_dev_t;
 typedef s32	compat_off_t;
+typedef s64	compat_loff_t;
 typedef u16	compat_nlink_t;
 typedef u16	compat_ipc_pid_t;
 typedef s32	compat_daddr_t;
@@ -96,11 +97,24 @@
 typedef u32		compat_old_sigset_t;	/* at least 32 bits */
 
 #define _COMPAT_NSIG		64
-#define _COMPAT_NSIG_BPW	BITS_PER_LONG
+#define _COMPAT_NSIG_BPW	32
 
 typedef u32		compat_sigset_word;
 
 #define COMPAT_OFF_T_MAX	0x7fffffff
 #define COMPAT_LOFF_T_MAX	0x7fffffffffffffffL
+
+/*
+ * A pointer passed in from user mode. This should not
+ * be used for syscall parameters, just declare them
+ * as pointers because the syscall entry code will have
+ * appropriately comverted them already.
+ */
+typedef	u32		compat_uptr_t;
+
+static inline void *compat_ptr(compat_uptr_t uptr)
+{
+	return (void *)uptr;
+}
 
 #endif /* _ASM_PARISC_COMPAT_H */
diff -Nru a/include/asm-parisc/elf.h b/include/asm-parisc/elf.h
--- a/include/asm-parisc/elf.h	Sat Jul 20 02:52:25 2002
+++ b/include/asm-parisc/elf.h	Mon Mar 17 21:31:50 2003
@@ -99,6 +99,9 @@
 typedef double elf_fpreg_t;
 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
+extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
+#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
+
 struct pt_regs;	/* forward declaration... */
 
 
@@ -118,7 +121,7 @@
    So that we can use the same startup file with static executables,
    we start programs with a value of 0 to indicate that there is no
    such function.  */
-#define ELF_PLAT_INIT(_r)       _r->gr[23] = 0
+#define ELF_PLAT_INIT(_r, load_addr)       _r->gr[23] = 0
 
 #define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	4096
diff -Nru a/include/asm-parisc/ide.h b/include/asm-parisc/ide.h
--- a/include/asm-parisc/ide.h	Wed Nov 27 01:14:29 2002
+++ b/include/asm-parisc/ide.h	Wed Feb 26 10:11:30 2003
@@ -83,6 +83,44 @@
 #define ide_check_region(from,extent)		check_region((from), (extent))
 #define ide_request_region(from,extent,name)	request_region((from), (extent), (name))
 #define ide_release_region(from,extent)		release_region((from), (extent))
+/* Generic I/O and MEMIO string operations.  */
+
+#define __ide_insw	insw
+#define __ide_insl	insl
+#define __ide_outsw	outsw
+#define __ide_outsl	outsl
+
+static __inline__ void __ide_mm_insw(unsigned long port, void *addr, u32 count)
+{
+	while (count--) {
+		*(u16 *)addr = readw(port);
+		addr += 2;
+	}
+}
+
+static __inline__ void __ide_mm_insl(unsigned long port, void *addr, u32 count)
+{
+	while (count--) {
+		*(u32 *)addr = readl(port);
+		addr += 4;
+	}
+}
+
+static __inline__ void __ide_mm_outsw(unsigned long port, void *addr, u32 count)
+{
+	while (count--) {
+		writew(*(u16 *)addr, port);
+		addr += 2;
+	}
+}
+
+static __inline__ void __ide_mm_outsl(unsigned long port, void *addr, u32 count)
+{
+	while (count--) {
+		writel(*(u32 *)addr, port);
+		addr += 4;
+	}
+}
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-parisc/kmap_types.h b/include/asm-parisc/kmap_types.h
--- a/include/asm-parisc/kmap_types.h	Fri Aug 30 08:13:42 2002
+++ b/include/asm-parisc/kmap_types.h	Sun Mar  2 15:58:28 2003
@@ -21,7 +21,9 @@
 D(8)	KM_PTE1,
 D(9)	KM_IRQ0,
 D(10)	KM_IRQ1,
-D(11)	KM_TYPE_NR
+D(11)	KM_SOFTIRQ0,
+D(12)	KM_SOFTIRQ1,
+D(13)	KM_TYPE_NR
 };
 
 #undef D
diff -Nru a/include/asm-parisc/linux_logo.h b/include/asm-parisc/linux_logo.h
--- a/include/asm-parisc/linux_logo.h	Sun Jan  5 03:22:54 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1438 +0,0 @@
-/* linux_logo.h created with fblogo, 2002/12/21 04:44:04
- * include/linux/linux_logo.h: This is a linux logo
- *                             to be displayed on boot.
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1996,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * Generated by fblogo version 0.5.0
- *
- *
- * Remember to modify drivers/video/fbcon.c:
- * Change "#define LOGO_H 80" to "#define LOGO_H 80"
- * Change "#define LOGO_W 80" to "#define LOGO_W 80"
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * image size has to be 80x80
- * values have to start from 0x20
- * (i.e. RGB(linux_logo_red[0],
- *           linux_logo_green[0],
- *           linux_logo_blue[0]) is color 0x20)
- * BW image has to be 80x80 as well, with MS bit
- * on the left
- * Serial_console ascii image can be any size,
- * but should contain %s to display the version
- */
-
-#ifndef __HAVE_ARCH_LINUX_LOGO
-#define LINUX_LOGO_COLORS 223
-#endif
-#ifdef INCLUDE_LINUX_LOGO_DATA
-#ifndef __HAVE_ARCH_LINUX_LOGO
-unsigned char linux_logo_red[] __initdata = {
-  0x02, 0xFD, 0xF1, 0x02, 0xA2, 0x02, 0x76, 0xFE, 
-  0xB8, 0x32, 0x52, 0xCA, 0x66, 0x8E, 0x46, 0xFD, 
-  0x66, 0xB2, 0xB6, 0x3E, 0xA4, 0xFE, 0x21, 0xDB, 
-  0xEE, 0x2A, 0xCC, 0x9A, 0x1A, 0xFE, 0xFE, 0xA6, 
-  0xC2, 0xFE, 0x94, 0x12, 0xBA, 0xED, 0x8E, 0xFE, 
-  0xAE, 0xBC, 0xC2, 0xCE, 0xE2, 0x4A, 0x0E, 0x6F, 
-  0xBE, 0xA2, 0x02, 0x57, 0x78, 0xFE, 0xDA, 0xDA, 
-  0xFE, 0xEE, 0x8A, 0xF5, 0xB3, 0x0A, 0xCA, 0x77, 
-  0x52, 0xFE, 0x5A, 0x64, 0xFA, 0x96, 0xC2, 0x96, 
-  0xC2, 0x92, 0x4E, 0x52, 0xBE, 0xFE, 0x66, 0x8C, 
-  0xDA, 0xFE, 0xAA, 0x6E, 0xB6, 0x7A, 0xE2, 0x3F, 
-  0xA3, 0x06, 0xE6, 0xD6, 0xE6, 0x56, 0xF2, 0xB6, 
-  0x7E, 0xDD, 0xD6, 0xF9, 0x37, 0x26, 0xE7, 0xEC, 
-  0xBE, 0xDE, 0xA3, 0xFE, 0x92, 0xDE, 0x36, 0xC2, 
-  0x82, 0xEA, 0x26, 0xA7, 0x2D, 0xF2, 0xA6, 0x6A, 
-  0xDA, 0x2E, 0xE2, 0xFE, 0x69, 0xFE, 0x46, 0x9E, 
-  0x5E, 0xFE, 0x82, 0xFE, 0xFC, 0xAA, 0xB8, 0xFE, 
-  0xCE, 0xC6, 0x1D, 0x76, 0xF8, 0x92, 0xE2, 0xD6, 
-  0xFE, 0x9C, 0xCC, 0xB6, 0xE4, 0x0C, 0xE2, 0xC6, 
-  0xD2, 0x16, 0xD3, 0x9C, 0x59, 0x3A, 0xFE, 0x70, 
-  0xBB, 0xA6, 0xF6, 0xFA, 0x76, 0xB6, 0xAE, 0xB7, 
-  0xEE, 0x3E, 0x82, 0xCA, 0xBA, 0x17, 0xAB, 0xAF, 
-  0xCF, 0x86, 0x32, 0xB4, 0x2A, 0xFE, 0xEE, 0xE2, 
-  0x5A, 0xFE, 0x02, 0xFE, 0xEA, 0xFE, 0x77, 0x64, 
-  0xFE, 0xFD, 0xD5, 0xBF, 0x4E, 0xBB, 0xF8, 0x9B, 
-  0x78, 0x6E, 0xFA, 0xC6, 0xFE, 0xB2, 0x12, 0xF2, 
-  0xBE, 0x06, 0xAE, 0xC4, 0xEA, 0xAE, 0xFE, 0xD5, 
-  0x42, 0xBC, 0x86, 0xFE, 0x7A, 0xF0, 0xF1
-};
-
-unsigned char linux_logo_green[] __initdata = {
-  0x02, 0xCF, 0xB7, 0x9A, 0x7A, 0x66, 0x4C, 0xCF, 
-  0xBA, 0x9A, 0x3A, 0x98, 0xCE, 0x66, 0x2E, 0xE0, 
-  0x9A, 0xB6, 0xB6, 0x27, 0x7C, 0xE2, 0x22, 0x9B, 
-  0xE6, 0x1E, 0x9A, 0xCE, 0x1A, 0xE6, 0xEA, 0x6E, 
-  0x86, 0xCE, 0x59, 0x12, 0x96, 0xEE, 0x5A, 0xD4, 
-  0x7E, 0x9A, 0xBA, 0xCE, 0xBE, 0x4A, 0x0E, 0x43, 
-  0xA7, 0x8A, 0x66, 0x3D, 0x4E, 0xEA, 0xDA, 0xAD, 
-  0xE6, 0xCA, 0x62, 0xF6, 0xA4, 0x0A, 0x82, 0x77, 
-  0x52, 0xE9, 0x34, 0x64, 0xC2, 0x7E, 0xB2, 0x96, 
-  0xC2, 0x62, 0x3A, 0x33, 0x91, 0xEC, 0x9A, 0x8C, 
-  0xB6, 0xE2, 0x70, 0x56, 0x76, 0x6A, 0xBE, 0x3E, 
-  0xA2, 0x06, 0xE6, 0xD6, 0xEA, 0x56, 0xC6, 0x9E, 
-  0x7E, 0x9A, 0xAA, 0xFA, 0x22, 0x26, 0xA6, 0xAE, 
-  0xC6, 0xB6, 0x8F, 0xDE, 0x7A, 0xDE, 0x36, 0x83, 
-  0x82, 0xBE, 0x16, 0x9B, 0x1A, 0xBE, 0xA6, 0x5C, 
-  0x9F, 0x2E, 0xAE, 0xD8, 0x6B, 0xBA, 0x46, 0x9E, 
-  0x5E, 0xC6, 0x72, 0xBE, 0xDA, 0x8E, 0xB0, 0xC2, 
-  0x89, 0x92, 0x1E, 0x6A, 0xB7, 0x92, 0xA2, 0xA2, 
-  0xFE, 0x65, 0xD0, 0xAA, 0xB0, 0x0E, 0xE2, 0xC6, 
-  0xD2, 0x16, 0x91, 0x6E, 0x3B, 0x3A, 0xCA, 0x70, 
-  0xBB, 0xAE, 0xBE, 0xD6, 0x5A, 0x8A, 0x86, 0xBA, 
-  0xC6, 0x42, 0x58, 0xCA, 0x7C, 0x0E, 0xAA, 0x7F, 
-  0x8F, 0x86, 0x32, 0x72, 0x2A, 0xC2, 0xA7, 0xA0, 
-  0x5A, 0xC6, 0x02, 0xFE, 0xEA, 0xEA, 0x7A, 0x3F, 
-  0xC6, 0xCA, 0xA3, 0xBF, 0x4E, 0x91, 0xB8, 0x99, 
-  0x70, 0x5E, 0xBE, 0x7E, 0xFE, 0xB1, 0x06, 0xB1, 
-  0xC2, 0x0A, 0xA2, 0x9D, 0xAA, 0x77, 0xC2, 0x96, 
-  0x42, 0xBE, 0x52, 0xE8, 0x7E, 0xAE, 0xF2
-};
-
-unsigned char linux_logo_blue[] __initdata = {
- 0x02, 0x03, 0x07, 0x9A, 0x02, 0x66, 0x02, 0x0E, 
- 0xC3, 0x9A, 0x02, 0x02, 0xCE, 0x02, 0x02, 0x1C, 
- 0x9A, 0xBE, 0xB6, 0x02, 0x38, 0x2E, 0x23, 0x14, 
- 0x36, 0x02, 0x32, 0xCE, 0x1C, 0x46, 0x42, 0x0A, 
- 0x0A, 0x12, 0x03, 0x12, 0x4A, 0xEF, 0x05, 0x16, 
- 0x26, 0x52, 0xAE, 0xCE, 0x02, 0x4A, 0x0F, 0x03, 
- 0x6C, 0x56, 0x9A, 0x0D, 0x0C, 0xA2, 0xDB, 0x02, 
- 0x9A, 0x02, 0x12, 0xF8, 0x85, 0x0B, 0x02, 0x76, 
- 0x52, 0x07, 0x02, 0x66, 0x0D, 0x46, 0x92, 0x97, 
- 0xC3, 0x16, 0x1A, 0x07, 0x02, 0x0E, 0xCE, 0x8D, 
- 0x4E, 0x04, 0x04, 0x2A, 0x03, 0x52, 0x4E, 0x3F, 
- 0xA1, 0x07, 0xE7, 0xD7, 0xEB, 0x56, 0x02, 0x72, 
- 0x7F, 0x06, 0x1A, 0xFB, 0x03, 0x27, 0x07, 0x08, 
- 0xD6, 0x42, 0x6D, 0x07, 0x4E, 0xDF, 0x37, 0x06, 
- 0x84, 0x02, 0x02, 0x86, 0x02, 0x3A, 0xA7, 0x44, 
- 0x03, 0x2F, 0x38, 0x0E, 0x70, 0x07, 0x47, 0x9E, 
- 0x5F, 0x06, 0x56, 0x0B, 0x06, 0x32, 0x9E, 0x02, 
- 0x03, 0x36, 0x1F, 0x56, 0x03, 0x92, 0x10, 0x03, 
- 0xF2, 0x03, 0xDB, 0x92, 0x1C, 0x1A, 0xE2, 0xC8, 
- 0xD2, 0x17, 0x03, 0x02, 0x03, 0x3B, 0x0D, 0x70, 
- 0xBA, 0xBA, 0x0D, 0x03, 0x06, 0x16, 0x26, 0xBE, 
- 0x0E, 0x50, 0x02, 0xCA, 0x04, 0x02, 0xA7, 0x03, 
- 0x0C, 0x86, 0x33, 0x04, 0x2B, 0x09, 0x05, 0x06, 
- 0x5A, 0x0D, 0x0A, 0xFA, 0xEB, 0x2A, 0x82, 0x04, 
- 0x02, 0x02, 0x32, 0xBE, 0x4F, 0x35, 0x0C, 0x98, 
- 0x6C, 0x46, 0x0B, 0x02, 0xFE, 0xB1, 0x02, 0x07, 
- 0xD2, 0x18, 0x96, 0x48, 0x06, 0x04, 0x0E, 0x07, 
- 0x43, 0xC6, 0x02, 0x3A, 0x8C, 0x16, 0xF4
-};
-
-unsigned char linux_logo[] __initdata = {
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79, 0x79,
-  0x79, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x79, 0xB9, 0x99, 0xBD, 0x9E, 0x60,
-  0x60, 0xF8, 0x8E, 0x85, 0xB9, 0x79, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x79, 0xAA, 0x9E, 0xDE, 0x96, 0xE3, 0xB7, 0x4B,
-  0x4B, 0x68, 0x32, 0x9F, 0x5F, 0x9E, 0xAA, 0x5D,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4E,
-  0x8E, 0x80, 0xE3, 0xB6, 0xCB, 0x90, 0x80, 0x63,
-  0x63, 0xDE, 0x78, 0xCB, 0xB6, 0xE3, 0xD1, 0x4D,
-  0x3C, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4D,
-  0x9F, 0x8D, 0x32, 0x77, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x77, 0x96, 0x7A, 0xE3,
-  0x5F, 0x99, 0x5D, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x5D, 0xF8, 0x96,
-  0x8D, 0xBF, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x99, 0x68,
-  0x7B, 0x6F, 0x8E, 0x5D, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x85, 0x6F, 0xB6,
-  0xD8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x5D, 0x36, 0xB9, 0x20, 0x79,
-  0x6F, 0x8D, 0x6F, 0xD4, 0x79, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x4E, 0x7D, 0xCB, 0xAD,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x3C, 0x63, 0xBF, 0xD4, 0x20,
-  0x20, 0x78, 0xB8, 0x9C, 0xB9, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x36, 0xAD, 0xB6, 0x36,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xAA, 0x5F, 0x90, 0x9E, 0x3C,
-  0x20, 0x5D, 0x4B, 0xED, 0x77, 0x79, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x79, 0x9E, 0xE3, 0x78, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xAA, 0xE4, 0x77, 0xAA, 0x43,
-  0x20, 0x20, 0x7D, 0x8D, 0x5F, 0xB9, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x4E, 0x63, 0x56, 0x9E, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x5D, 0x4E, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x79, 0xB7, 0xCE, 0x8E, 0x79, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xB9, 0x80, 0x7A, 0xB9, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xBF, 0x4B, 0x7D, 0x5D, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xAA, 0xAD, 0xB8, 0x79, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x85, 0xB6, 0x5F, 0x43, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x36, 0x67, 0xCB, 0x20, 0x20,
-  0x20, 0x20, 0xB9, 0x3C, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x79, 0x8E, 0x79, 0x20,
-  0x20, 0x20, 0x20, 0x43, 0xB6, 0x6F, 0x3C, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x36, 0x67, 0xCB, 0x20, 0x20,
-  0x5D, 0xE4, 0x8E, 0x4E, 0x43, 0x20, 0x20, 0x20,
-  0x20, 0x8E, 0x90, 0xCE, 0x90, 0x4E, 0xAA, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0xB7, 0xE7, 0x36, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x36, 0x67, 0xCB, 0x20, 0x20,
-  0xD1, 0x8D, 0x7B, 0xD8, 0x20, 0x20, 0x20, 0x20,
-  0x9E, 0x32, 0x56, 0x45, 0xFE, 0x6F, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0xCB, 0x96, 0xD4, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x36, 0x67, 0xCB, 0x20, 0x85,
-  0xDC, 0xEC, 0xEC, 0xEC, 0xAA, 0x20, 0x20, 0xDA,
-  0x56, 0xEC, 0xEC, 0xB8, 0xEC, 0x83, 0x8E, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x6F, 0xED, 0x8E, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x36, 0x67, 0xCB, 0x20, 0x9C,
-  0x45, 0xAA, 0x9C, 0xEC, 0xDE, 0x20, 0x20, 0xAA,
-  0xEC, 0x83, 0x79, 0xBD, 0xBF, 0xEC, 0x96, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x6F, 0x32, 0x8E, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xAA, 0xAD, 0xB7, 0x20, 0x80,
-  0x80, 0x20, 0xE4, 0x31, 0x67, 0xDA, 0x3C, 0xD4,
-  0xEC, 0xDE, 0x20, 0xDA, 0x8E, 0xB6, 0x7A, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x6F, 0x32, 0x8E, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x3C, 0xD1, 0xDC, 0xB9, 0x5F,
-  0x90, 0x20, 0xF1, 0xFC, 0x7D, 0x39, 0x94, 0xCD,
-  0x28, 0x63, 0x20, 0x20, 0x20, 0xB8, 0xDC, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x6F, 0xC0, 0xBD, 0x79,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x43, 0x5F, 0x7A, 0xB9, 0x9E,
-  0x8D, 0x20, 0x20, 0x5A, 0x87, 0xE0, 0xC2, 0x2B,
-  0x82, 0x51, 0x20, 0x20, 0xB5, 0xEC, 0xC7, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0xAD, 0x68, 0x9E, 0x79,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x43, 0xBF, 0xB6, 0xB9, 0x79,
-  0x83, 0x93, 0xCC, 0xF4, 0xE0, 0xE1, 0x21, 0xC8,
-  0x47, 0x9B, 0x57, 0xC4, 0xB8, 0xEC, 0x77, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x60, 0x4B, 0x60, 0x5D,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x43, 0xBF, 0xB6, 0xB9, 0x20,
-  0x75, 0xD0, 0xF4, 0xA7, 0xE0, 0x21, 0xA4, 0xDD,
-  0x3E, 0xDD, 0x61, 0x71, 0x21, 0xB4, 0x2E, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x60, 0x7B, 0xA0, 0x5D,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x43, 0xBF, 0xB6, 0x85, 0xCD,
-  0xCC, 0x81, 0xAC, 0xE0, 0xE1, 0xC3, 0x8B, 0x3D,
-  0x3E, 0x61, 0x61, 0x6D, 0x71, 0x47, 0xAF, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x8E, 0xB6, 0x5F, 0xB9,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x5D, 0xA0, 0x7B, 0x7D, 0xDF,
-  0xA8, 0xD6, 0xA3, 0xE0, 0x21, 0xA4, 0x35, 0xFB,
-  0x61, 0x61, 0x61, 0x4C, 0x2B, 0x86, 0xCF, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x5D, 0x8D, 0x78, 0x99,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x5D, 0x60, 0xB8, 0x7D, 0x39,
-  0xF5, 0xAC, 0xA7, 0xE1, 0x21, 0x8B, 0x35, 0x71,
-  0x8B, 0x59, 0x6C, 0xD0, 0xD7, 0xD6, 0x5A, 0x20,
-  0x20, 0xB9, 0x20, 0x20, 0x20, 0x90, 0xCB, 0x60,
-  0x5D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x5D, 0x60, 0xB8, 0x7D, 0x20,
-  0xBC, 0xBB, 0x22, 0x21, 0x2F, 0x8B, 0xC3, 0x57,
-  0xCF, 0x3F, 0xBA, 0xD7, 0x81, 0x3A, 0x77, 0x20,
-  0x20, 0xA0, 0x63, 0x36, 0x20, 0xD2, 0x7A, 0x6F,
-  0x36, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x4E, 0xA0, 0x7B, 0x7D, 0x20,
-  0xDE, 0x51, 0x46, 0xF5, 0x6C, 0xCF, 0x72, 0xCC,
-  0x5E, 0xA8, 0x5E, 0xE5, 0x4A, 0xB2, 0xED, 0x20,
-  0x20, 0x43, 0x6F, 0x90, 0x4E, 0x20, 0xED, 0xB7,
-  0x7D, 0x4E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x36, 0xD1, 0x7A, 0x8E, 0x20,
-  0xAD, 0xCB, 0x34, 0xB1, 0xF7, 0xBA, 0xA8, 0xEB,
-  0xD3, 0x74, 0x7F, 0xF9, 0xB2, 0x7A, 0x7B, 0x36,
-  0x20, 0x20, 0xE4, 0xA0, 0x79, 0x20, 0xAA, 0xB6,
-  0x67, 0xD4, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x4E, 0x60, 0x68, 0xC0, 0x79, 0x20,
-  0x6F, 0xB2, 0x68, 0x8A, 0x42, 0x42, 0x42, 0x42,
-  0x34, 0xA6, 0x28, 0xB2, 0xEC, 0xEC, 0xEC, 0x9F,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F,
-  0x4B, 0x63, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x79, 0x8E, 0x9F, 0xB6, 0xD2, 0x20, 0x20,
-  0xDC, 0x7C, 0xB7, 0xF0, 0x28, 0xF2, 0xF2, 0xED,
-  0xC7, 0xF9, 0xB2, 0x5B, 0xEC, 0xEC, 0xEC, 0xEC,
-  0x85, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xAA,
-  0x56, 0xCE, 0xBD, 0x79, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x79, 0x85, 0xD1, 0x8D, 0xE8, 0x20, 0x20, 0x67,
-  0xEC, 0xEC, 0xB8, 0xF9, 0xF9, 0x28, 0xC7, 0xC7,
-  0x68, 0x8D, 0x83, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x63, 0x8D, 0xDE, 0xAA, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x3C, 0xBF, 0x4B, 0xCE, 0x79, 0x20, 0x99, 0xEC,
-  0xEC, 0xEC, 0xFE, 0xF9, 0xC0, 0xC7, 0xC7, 0x4B,
-  0xFE, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0x99, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x79, 0x68, 0x68, 0xD8, 0x43, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43,
-  0x7D, 0xE3, 0x4B, 0x3C, 0x20, 0x20, 0x4B, 0xEC,
-  0xEC, 0xEC, 0xEC, 0x5B, 0x56, 0x56, 0xDC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xCE, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x99, 0xB6, 0xED, 0x4D, 0x4E, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4E, 0x9E,
-  0xCE, 0xB6, 0x99, 0x20, 0x20, 0x4D, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0x83, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x77, 0xDC, 0x78, 0xF8, 0x4E, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x79, 0x8E, 0xE7,
-  0x7A, 0x60, 0x20, 0x20, 0x20, 0x68, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0x3C, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xBF, 0x7A, 0xE7, 0xBD, 0x79,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0xAA, 0x80, 0x8D,
-  0xBF, 0x20, 0x20, 0x20, 0x4E, 0x56, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0x83, 0x83, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xDB, 0xEC, 0xD8, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0xBF, 0x8D, 0xD1, 0x85,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x5D, 0x4D, 0xE3, 0x32,
-  0x79, 0x20, 0x20, 0x20, 0x99, 0x32, 0xDC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xDC, 0x8D, 0x8D, 0x45, 0x83,
-  0x83, 0x83, 0x83, 0x7A, 0x8D, 0x56, 0x7B, 0xB8,
-  0xB8, 0x8D, 0x78, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x79, 0x78, 0xCB, 0xD8,
-  0x4E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0xAA, 0xD1, 0x7A, 0xD2,
-  0x20, 0x20, 0x20, 0x20, 0xE4, 0xED, 0x7B, 0xFE,
-  0xEC, 0xEC, 0xEC, 0xDB, 0xB6, 0x5B, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xDB, 0xFE, 0x8D, 0x4B, 0xB7, 0x68,
-  0x68, 0xB7, 0xDC, 0x5F, 0x20, 0x20, 0xAA, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x8D, 0x67,
-  0x85, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x79, 0xBD, 0xED, 0xCE, 0x20,
-  0x20, 0x20, 0x20, 0x79, 0x67, 0xDC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xDB, 0x45, 0xEC, 0xDB, 0xDB,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x45,
-  0x8D, 0x4B, 0xB8, 0x83, 0x99, 0x20, 0x20, 0x85,
-  0x5D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0xB7,
-  0x60, 0x5D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x5D, 0x7D, 0xB8, 0xBF, 0x20,
-  0x20, 0x43, 0x20, 0xBF, 0xFE, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xDB, 0xDB, 0xDB, 0xDB,
-  0xDB, 0xDB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xDC, 0xB6, 0x7B, 0x20, 0x20, 0x20,
-  0xD4, 0x5D, 0x20, 0x20, 0x20, 0x20, 0x99, 0x7A,
-  0xD1, 0xAA, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x3C, 0x80, 0x7A, 0xD2, 0x20,
-  0x36, 0x20, 0x4E, 0x68, 0xEC, 0xEC, 0x5B, 0xEC,
-  0xEC, 0x7C, 0x4B, 0x4B, 0x4B, 0x4B, 0x3B, 0x3B,
-  0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x30, 0x30, 0xC1,
-  0xB6, 0xEC, 0x5B, 0x5B, 0x5B, 0x9E, 0x20, 0x20,
-  0x20, 0x85, 0x20, 0x20, 0x20, 0x20, 0x20, 0xED,
-  0xED, 0xBD, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0xD2, 0x96, 0xB8, 0x79, 0x79,
-  0x4E, 0x20, 0xD1, 0x45, 0x83, 0xEC, 0xEC, 0xEC,
-  0xEC, 0x30, 0x25, 0x52, 0x25, 0x25, 0x25, 0x25,
-  0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x29,
-  0xDC, 0xEC, 0xEC, 0xEC, 0x83, 0xB7, 0x20, 0x43,
-  0xD2, 0xB9, 0xAA, 0x20, 0x20, 0x20, 0x20, 0x9C,
-  0x7B, 0x63, 0x4E, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x5D, 0x7D, 0x4B, 0x80, 0x20, 0x85,
-  0x20, 0x79, 0x7A, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0x30, 0x25, 0x25, 0x23, 0x29, 0x2C, 0x3B,
-  0x4B, 0x7C, 0x4B, 0x3B, 0x30, 0x52, 0x25, 0x29,
-  0x5B, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x4E, 0xAA,
-  0xD2, 0x5D, 0xD4, 0x20, 0x20, 0x20, 0x20, 0x5D,
-  0xB6, 0x67, 0x36, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0xAA, 0xD1, 0x7A, 0x99, 0x20, 0xB9,
-  0x20, 0xE4, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0x29, 0x29, 0x3B, 0x7C, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x3B, 0x52, 0x23,
-  0xFE, 0xEC, 0x83, 0xEC, 0xEC, 0xEC, 0x4D, 0x20,
-  0x20, 0x20, 0x5D, 0x85, 0x20, 0x20, 0x20, 0x20,
-  0x96, 0xE3, 0xF8, 0x79, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x79, 0xF8, 0x32, 0x32, 0x20, 0xAA, 0x20,
-  0x20, 0xCB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x7C,
-  0x30, 0x3B, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x29, 0x25,
-  0x4B, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x6F, 0x20,
-  0x20, 0x20, 0x20, 0x99, 0x20, 0x20, 0x20, 0x20,
-  0xD8, 0x7B, 0x63, 0x4E, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x3C, 0xDE, 0x8D, 0xE4, 0x20, 0x36, 0x20,
-  0x36, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x7C, 0x30,
-  0x4B, 0xEC, 0xEC, 0xEC, 0x7C, 0x3B, 0x30, 0x29,
-  0x29, 0x29, 0x29, 0x3B, 0x7C, 0xEC, 0x29, 0x25,
-  0x3B, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xE3, 0x20,
-  0x20, 0x20, 0x20, 0xD2, 0x20, 0x20, 0x20, 0x20,
-  0x3C, 0x7A, 0x80, 0xB9, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x5D, 0x4D, 0xC0, 0x68, 0x79, 0x20, 0x5D, 0x20,
-  0x90, 0xEC, 0xEC, 0xEC, 0xEC, 0x7C, 0x3B, 0x7C,
-  0xEC, 0xEC, 0x3B, 0x29, 0x52, 0x52, 0x29, 0x29,
-  0x29, 0x29, 0x25, 0x25, 0x29, 0x4B, 0x29, 0x25,
-  0x2C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xB6, 0x20,
-  0x20, 0x20, 0x20, 0xD4, 0x20, 0x20, 0x20, 0x20,
-  0x79, 0x7B, 0x67, 0x36, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x85, 0x6F, 0x7A, 0x77, 0x20, 0xB9, 0x20, 0x20,
-  0xB8, 0xEC, 0xEC, 0xEC, 0xEC, 0x4B, 0xEC, 0xEC,
-  0x3B, 0x29, 0x29, 0x6E, 0x4B, 0x7C, 0xEC, 0xEC,
-  0xEC, 0x7C, 0x4B, 0x30, 0x25, 0x52, 0x52, 0x25,
-  0x30, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x5B, 0x20,
-  0x20, 0x20, 0x20, 0x36, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x68, 0xCE, 0x99, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4E,
-  0xD8, 0xCB, 0x67, 0x20, 0x20, 0xAA, 0x20, 0x20,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x7C, 0x30,
-  0x29, 0x3B, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0x6E, 0x25, 0x52, 0x25,
-  0x29, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x20,
-  0x20, 0x20, 0x20, 0xAA, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xD1, 0xC0, 0xBD, 0x79, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xAA,
-  0x6F, 0x8D, 0x3C, 0x20, 0x20, 0x36, 0x20, 0xB5,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x7C, 0x30, 0x3B,
-  0xEC, 0xEC, 0x7C, 0xEC, 0xEC, 0xEC, 0x7C, 0x7C,
-  0x7C, 0xEC, 0xEC, 0xEC, 0x7C, 0x52, 0x52, 0x25,
-  0x29, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x20,
-  0x20, 0x20, 0x79, 0x43, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xD1, 0xC0, 0xBD, 0x79, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x99,
-  0xCE, 0x68, 0x20, 0x20, 0x20, 0xBD, 0xF1, 0x36,
-  0xEC, 0xEC, 0xEC, 0xEC, 0x7C, 0x6E, 0x7C, 0xEC,
-  0xEC, 0xEC, 0x3B, 0x6E, 0x29, 0x29, 0x52, 0x52,
-  0x23, 0x29, 0x3B, 0xEC, 0x7C, 0x23, 0x52, 0x52,
-  0x23, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x20,
-  0x20, 0x20, 0x3C, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xD1, 0xC0, 0xBD, 0x79, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xBD,
-  0xC0, 0xD1, 0x20, 0x20, 0x20, 0x36, 0x3C, 0x8E,
-  0xEC, 0xEC, 0xEC, 0xEC, 0x4B, 0xEC, 0xEC, 0xEC,
-  0x3B, 0x29, 0x52, 0x29, 0x29, 0x30, 0x30, 0x30,
-  0x29, 0x25, 0x25, 0x29, 0x3B, 0x52, 0x52, 0x52,
-  0x52, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x20,
-  0x20, 0x20, 0x3C, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0xD1, 0xC0, 0xBD, 0x79, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79, 0xBD,
-  0xC0, 0xD1, 0x20, 0x20, 0x20, 0x20, 0xB5, 0x8E,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x3B, 0x30,
-  0x30, 0x3B, 0x4B, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0x4B, 0x29, 0x25, 0x52, 0x52, 0x52, 0x52,
-  0x52, 0x3B, 0xEC, 0xEC, 0xEC, 0xEC, 0x45, 0x20,
-  0x20, 0x3C, 0x4E, 0x4E, 0xB5, 0x20, 0x20, 0x20,
-  0x20, 0x78, 0x32, 0x8E, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x8E,
-  0x32, 0x68, 0xEE, 0xCA, 0x24, 0x84, 0x20, 0xC9,
-  0xEC, 0xEC, 0xEC, 0xEC, 0x7C, 0x30, 0x30, 0x7C,
-  0xEC, 0xEC, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0x29, 0x25, 0x25, 0x25, 0x25,
-  0x25, 0x2C, 0xEC, 0xEC, 0xEC, 0xEC, 0xF9, 0x20,
-  0x79, 0x20, 0x20, 0x20, 0xDA, 0xAA, 0xF8, 0xB9,
-  0x20, 0xCB, 0x78, 0xD4, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x79, 0x5D, 0x5D, 0x43, 0x4D,
-  0x68, 0x8D, 0xAE, 0x47, 0x21, 0xE1, 0x53, 0x20,
-  0x90, 0xEC, 0xEC, 0x7C, 0x30, 0x4B, 0xEC, 0xEC,
-  0xEC, 0xEC, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0x4B, 0x30, 0x30, 0x30, 0x29,
-  0x29, 0x30, 0xEC, 0xB0, 0x58, 0x55, 0x65, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x85, 0xC9,
-  0x5D, 0xFE, 0x9F, 0xD4, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x5D, 0xAA, 0x77, 0x7D, 0xA0, 0x63, 0x9F,
-  0x7A, 0x44, 0xAC, 0xBE, 0x21, 0x21, 0xE0, 0xBC,
-  0x20, 0x9C, 0xEC, 0x3B, 0x7C, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0x7C, 0x7C, 0xEC, 0x95, 0x21, 0x71, 0xC3, 0xCD,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x36, 0x4E,
-  0xA5, 0x56, 0x68, 0xE4, 0x5D, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x5D, 0xBD, 0xD1, 0xC0, 0xB8, 0x7B, 0x56, 0xDC,
-  0xA6, 0x98, 0x9D, 0xBE, 0x21, 0xE1, 0xE1, 0xC2,
-  0x92, 0x20, 0xC9, 0x5B, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0x7A, 0xFE, 0xEC, 0xEC, 0xDB, 0xDB,
-  0xDB, 0xDB, 0xDB, 0xDB, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xB4, 0x9D, 0x21, 0x91, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xDA, 0x53,
-  0x6D, 0x38, 0x7A, 0x90, 0x3C, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0xD4, 0xAD, 0xB6, 0xA6, 0x7F, 0xF3, 0x44, 0xE5,
-  0xF7, 0x87, 0xF6, 0xBE, 0xBE, 0xE1, 0xE0, 0xE0,
-  0xAF, 0x20, 0x20, 0xB5, 0x7B, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xDB,
-  0xDB, 0xDB, 0xDB, 0xDB, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0x9A, 0x9D, 0xA7, 0x98, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79, 0x22,
-  0x8B, 0x8B, 0x68, 0xE7, 0x36, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5D,
-  0x7D, 0x4B, 0x5C, 0xF4, 0x9D, 0xE6, 0xEF, 0x87,
-  0xE6, 0xA3, 0xD9, 0xD9, 0xD9, 0xA1, 0xA1, 0xE0,
-  0x21, 0x2D, 0x20, 0x20, 0x20, 0x96, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xDB,
-  0xDB, 0xDB, 0xDB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xFE, 0xB2, 0xE2, 0xAC, 0x9D, 0x81, 0xDF,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xCF, 0xBE,
-  0x47, 0x47, 0x68, 0x96, 0xD4, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43,
-  0x5F, 0x7A, 0xE2, 0x9D, 0xBE, 0xBE, 0xD9, 0xF6,
-  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xA1, 0xD5,
-  0xE0, 0x7E, 0x92, 0x20, 0x20, 0x20, 0x63, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xDB,
-  0xDB, 0xDB, 0xDB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xB2, 0xF0, 0xE2, 0xEF, 0xEF, 0xD7, 0xCC,
-  0x26, 0x84, 0x94, 0x84, 0x26, 0x40, 0xEF, 0xD9,
-  0x41, 0x41, 0xE3, 0xB7, 0x7D, 0x43, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43,
-  0xDE, 0x7A, 0x37, 0xA3, 0xBE, 0x41, 0xBE, 0xBE,
-  0xD9, 0xD9, 0xF6, 0x64, 0x64, 0xD5, 0xD5, 0xA1,
-  0xA1, 0x21, 0x6C, 0x20, 0x20, 0x20, 0x20, 0xD2,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xDB,
-  0xDB, 0xDB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xB2, 0x88, 0x3A, 0xF4, 0xAC, 0xF4, 0xBA,
-  0xA8, 0x8F, 0x8F, 0x40, 0xBA, 0xF4, 0xD9, 0x41,
-  0x41, 0x41, 0x89, 0x8D, 0x96, 0x9E, 0x4E, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4E,
-  0x9C, 0x8D, 0xF3, 0xAC, 0xD9, 0x41, 0xBE, 0xD9,
-  0xF6, 0x64, 0x64, 0x64, 0x64, 0x64, 0xD5, 0xD5,
-  0xA1, 0xA1, 0x21, 0x2A, 0x20, 0x20, 0x20, 0x20,
-  0x7D, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0x7B, 0x88, 0xE5, 0xD7, 0x22, 0x22, 0x86,
-  0x98, 0x81, 0x81, 0x98, 0x87, 0xEA, 0xBE, 0xBE,
-  0x41, 0xBE, 0xBE, 0x50, 0x7A, 0x78, 0x4D, 0xB9,
-  0x79, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5D,
-  0xD8, 0x7B, 0x49, 0xFD, 0xF6, 0xBE, 0xD9, 0xD9,
-  0x64, 0x64, 0xC2, 0xC2, 0xC2, 0xEA, 0x64, 0xD5,
-  0xD9, 0xA1, 0xE1, 0x57, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x83, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0x7C, 0x88, 0xC6, 0x81, 0xAC, 0xEA, 0x22,
-  0x87, 0x87, 0xF4, 0x87, 0x22, 0xF6, 0xD9, 0xD9,
-  0xBE, 0xBE, 0xBE, 0xD9, 0x50, 0xDC, 0x32, 0xBF,
-  0xD2, 0x5D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79,
-  0x4D, 0xCB, 0x5C, 0x86, 0xA3, 0xBE, 0xD9, 0xF6,
-  0x64, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0x64, 0x64,
-  0xD5, 0xD9, 0xA1, 0x21, 0xBB, 0x20, 0x20, 0x20,
-  0x20, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xFE, 0x9C, 0x46, 0x81, 0x22, 0xD5, 0xA3,
-  0x9D, 0x22, 0x22, 0xE6, 0xEA, 0xF6, 0xD9, 0xD9,
-  0xD9, 0xBE, 0xBE, 0x41, 0x41, 0x70, 0x7B, 0x7B,
-  0x6F, 0x85, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79,
-  0xF8, 0x68, 0xF2, 0xAE, 0xEA, 0xD9, 0xD9, 0x64,
-  0x64, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xEA, 0x64,
-  0xD5, 0xD5, 0xA1, 0xE1, 0xE1, 0x33, 0x20, 0xF1,
-  0x31, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xFC, 0x20, 0x46, 0x98, 0xAC, 0xD5, 0xD9,
-  0xD9, 0xD5, 0x64, 0x64, 0x64, 0x64, 0xF6, 0xD9,
-  0xD9, 0xBE, 0xBE, 0x41, 0x47, 0x9B, 0x41, 0x66,
-  0xB7, 0x4D, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5D,
-  0xE4, 0xCB, 0x5C, 0xAE, 0xEA, 0xD9, 0xD9, 0x64,
-  0x64, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0x64,
-  0x64, 0xD5, 0xA1, 0xD5, 0x21, 0xAF, 0xCE, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0x63, 0x20, 0x20, 0xB1, 0xD7, 0xE6, 0xD5, 0xD9,
-  0xD5, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0xF6,
-  0xD9, 0xBE, 0xBE, 0x41, 0x47, 0x9B, 0x9B, 0x76,
-  0x7B, 0xD8, 0x5D, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43,
-  0xBF, 0x8D, 0x44, 0xAE, 0xF6, 0xD9, 0xD9, 0xF6,
-  0x64, 0xEA, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0x64,
-  0x64, 0xD5, 0xD5, 0xD5, 0xE0, 0x7E, 0xC5, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xFE, 0x99,
-  0x20, 0x20, 0x20, 0xB1, 0xD7, 0x9D, 0xD5, 0xD9,
-  0xD5, 0x64, 0x64, 0x64, 0x64, 0x64, 0xF6, 0xD9,
-  0xD9, 0xBE, 0x41, 0x41, 0x47, 0x41, 0xD9, 0x66,
-  0x4B, 0x60, 0x5D, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xD4,
-  0x9F, 0xB6, 0xBA, 0x87, 0xD9, 0xBE, 0xD9, 0xD9,
-  0xF6, 0x64, 0x64, 0x64, 0x64, 0xEA, 0x64, 0x64,
-  0x64, 0xD5, 0xD5, 0xD5, 0xD5, 0x7E, 0xAF, 0x8C,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x90, 0x20, 0x20,
-  0x20, 0x20, 0xEE, 0xB1, 0x86, 0xEA, 0xD9, 0xD9,
-  0xD5, 0x64, 0x64, 0x64, 0x64, 0xF6, 0xD9, 0xD9,
-  0xBE, 0xBE, 0x41, 0x41, 0xBE, 0xE6, 0x9A, 0x8D,
-  0x9F, 0xD2, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79, 0x9E,
-  0xB7, 0xB3, 0xD7, 0xD5, 0x41, 0xBE, 0xBE, 0xD9,
-  0xD9, 0xD9, 0xF6, 0x64, 0x64, 0x64, 0x64, 0x64,
-  0x64, 0xD5, 0xD9, 0xA1, 0xA1, 0x22, 0x86, 0x46,
-  0x77, 0x7B, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
-  0xEC, 0xEC, 0x7A, 0xD1, 0x79, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x92, 0x3F, 0x86, 0xEA, 0xD9, 0xD9,
-  0xD9, 0xF6, 0xF6, 0xF6, 0xD9, 0xD9, 0xD9, 0xBE,
-  0xBE, 0xBE, 0xF6, 0xE6, 0xFD, 0x5C, 0xDC, 0xED,
-  0x60, 0x4E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5D, 0xD8,
-  0x7B, 0xF3, 0x86, 0xA3, 0xBE, 0xBE, 0xBE, 0xD9,
-  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xD5, 0xD9, 0xD9, 0xA1, 0x9D, 0x86, 0x72,
-  0x94, 0x20, 0xB5, 0xE4, 0x5F, 0x80, 0xBF, 0xA0,
-  0x8E, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x84, 0x72, 0x86, 0xA3, 0xBE, 0xBE,
-  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xF6, 0xD9,
-  0xF6, 0xFD, 0x37, 0x5C, 0x7B, 0xB8, 0x67, 0x4D,
-  0x43, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5D, 0xD8,
-  0xB8, 0xF3, 0x81, 0xF4, 0xAC, 0xE6, 0xEA, 0xEA,
-  0xA3, 0xF6, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
-  0xD9, 0xD9, 0xBE, 0xBE, 0xBE, 0xEA, 0xD7, 0x72,
-  0x62, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x6B, 0x74, 0xAE, 0xEA, 0xBE, 0xBE,
-  0xBE, 0xBE, 0xD9, 0xD9, 0xD9, 0xEA, 0xE6, 0x87,
-  0xF7, 0x93, 0xB6, 0xB8, 0x78, 0x63, 0x99, 0x5D,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79, 0xF8,
-  0xC0, 0xCB, 0xA9, 0x8F, 0xA8, 0xD0, 0xF7, 0x81,
-  0xAE, 0x86, 0x87, 0x22, 0xE6, 0xEA, 0xD9, 0xD9,
-  0xBE, 0xBE, 0xBE, 0xBE, 0xD9, 0xEF, 0xD0, 0xB1,
-  0xDF, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x6B, 0x72, 0xF7, 0xEF, 0xD9, 0xD9,
-  0xBE, 0xD9, 0xD9, 0xF6, 0x22, 0x86, 0x81, 0xE5,
-  0x4B, 0x56, 0x78, 0x63, 0x99, 0x43, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
-  0x9C, 0xC0, 0xB6, 0xB6, 0x32, 0x8A, 0x48, 0xD3,
-  0xCC, 0xCC, 0x8F, 0x40, 0xD0, 0x81, 0xF4, 0x22,
-  0xA3, 0xF6, 0xD9, 0xF6, 0xAC, 0x81, 0x74, 0x46,
-  0x62, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x2E, 0xB1, 0x40, 0xAE, 0xAC, 0xF6,
-  0xF6, 0xF6, 0xAC, 0xF4, 0x81, 0xCC, 0x8A, 0xDC,
-  0xC0, 0x5F, 0x8E, 0x4E, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79,
-  0x3C, 0x4D, 0xBF, 0x67, 0x32, 0xB8, 0x7A, 0xCB,
-  0xCE, 0x8C, 0x69, 0x46, 0xB1, 0x3F, 0xCC, 0xA8,
-  0xBA, 0x98, 0x86, 0xAE, 0xBA, 0x74, 0x42, 0x4F,
-  0x84, 0xD2, 0x32, 0x32, 0xCB, 0x45, 0xDC, 0xDC,
-  0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0x56, 0x32,
-  0xED, 0x80, 0x6A, 0xCA, 0x74, 0xA8, 0x81, 0x86,
-  0x86, 0xAE, 0xBA, 0x40, 0x3F, 0xF2, 0xB6, 0x78,
-  0xE4, 0x3C, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x79, 0x43, 0x36, 0xBD, 0xD8, 0x90, 0x78,
-  0x68, 0x56, 0xDC, 0xCB, 0x93, 0xA2, 0x26, 0x46,
-  0xB1, 0x3F, 0x72, 0x72, 0xB1, 0xFA, 0x4F, 0xBC,
-  0xAD, 0x56, 0x4B, 0xCE, 0xE7, 0x6F, 0x90, 0x80,
-  0x80, 0x80, 0x80, 0x80, 0x80, 0xD1, 0x67, 0x96,
-  0xE3, 0xDC, 0x90, 0xDF, 0xB1, 0x74, 0xCC, 0x8F,
-  0x8F, 0xCC, 0x72, 0x46, 0xCE, 0x56, 0xAD, 0x77,
-  0x4E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x79, 0x5D, 0x3C, 0xD4,
-  0xF8, 0x63, 0xD1, 0x96, 0x68, 0x8D, 0x7A, 0xE7,
-  0x73, 0x4F, 0x4F, 0x26, 0x4F, 0xDF, 0x6B, 0x32,
-  0x56, 0x9F, 0xA0, 0xD2, 0x36, 0x3C, 0xB9, 0xB9,
-  0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x3C, 0x36, 0xD4,
-  0xE4, 0x96, 0xB6, 0xE8, 0xBC, 0xFA, 0x42, 0xB1,
-  0xB1, 0x46, 0x54, 0xCE, 0x56, 0xD1, 0xD2, 0x5D,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x79, 0x4E, 0x3C, 0x99, 0x9E, 0xBF, 0xE7, 0xB7,
-  0x7A, 0xCB, 0x6F, 0xE9, 0xE9, 0xE7, 0x56, 0xCB,
-  0x80, 0xD2, 0x4E, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x4E, 0x4D, 0x78, 0x8D, 0xE3, 0x5F, 0x97, 0xE9,
-  0xAB, 0x67, 0xB6, 0xCB, 0x90, 0x99, 0x79, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x79, 0x43, 0xD4, 0xE4,
-  0x80, 0xCE, 0xB7, 0x7B, 0x7B, 0x68, 0xE7, 0x63,
-  0x36, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x4E, 0xBD, 0x80, 0xED, 0x4B, 0x7B, 0x7B,
-  0xB8, 0x68, 0x67, 0xD8, 0x85, 0x79, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5D,
-  0x3C, 0x99, 0x4D, 0xD8, 0xD8, 0x9E, 0x85, 0x4E,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x79, 0x3C, 0x8E, 0x60, 0xD8, 0xA0,
-  0x7D, 0xF8, 0x85, 0x4E, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
-};
-
-#endif /* !__HAVE_ARCH_LINUX_LOGO */
-
-#ifndef __HAVE_ARCH_LINUX_LOGOBW
-
-unsigned char linux_logo_bw[] __initdata = {
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xcf, 0xf3, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xbf, 0xfc, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfd, 0xff, 0xf3, 0xdf, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfd, 0xff, 0xf7, 0xef, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x9f, 0x87, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x0f, 0x03, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x67, 0x33, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xe7, 0x79, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xf7, 0x79, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xff, 0xf9, 0xf7, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x60, 0x3b, 0xf7, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x89, 0x07, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x00, 0x03, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x00, 0x0d, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x80, 0x33, 0xfd, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xc0, 0xc3, 0xfd, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xff, 0x0d, 0xdd, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x40, 0x31, 0xee, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf7, 0x20, 0xc1, 0xee, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf7, 0x1f, 0x00, 0xff, 0x7f, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x7f, 0xbf, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xee, 0x00, 0x00, 0x7f, 0xbf, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xde, 0x00, 0x00, 0x7f, 0xdf, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xbc, 0x00, 0x00, 0x3f, 0xef, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x3f, 0xf7, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x1f, 0xf7, 0xff, 0xff,
-    0xff, 0xff, 0xfe, 0xff, 0x1c, 0x07, 0xdf, 0xfb, 0xff, 0xff,
-    0xff, 0xff, 0xfd, 0xfc, 0x08, 0x0f, 0xef, 0xfd, 0xff, 0xff,
-    0xff, 0xff, 0xfd, 0xf8, 0x00, 0x01, 0xef, 0xfd, 0xff, 0xff,
-    0xff, 0xff, 0xfb, 0xf0, 0x00, 0x00, 0x7f, 0xfe, 0xff, 0xff,
-    0xff, 0xff, 0xfb, 0xe0, 0x00, 0x00, 0x1f, 0xfe, 0xff, 0xff,
-    0xff, 0xff, 0xf7, 0xe0, 0x00, 0x00, 0x07, 0xbf, 0x7f, 0xff,
-    0xff, 0xff, 0xf7, 0xc0, 0x00, 0x00, 0x03, 0xbf, 0x7f, 0xff,
-    0xff, 0xff, 0xef, 0xc0, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
-    0xff, 0xff, 0xef, 0x80, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
-    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
-    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x01, 0xef, 0xdf, 0xff,
-    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x01, 0xef, 0xdf, 0xff,
-    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
-    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
-    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
-    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
-    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x03, 0x03, 0xdf, 0xff,
-    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x02, 0xfd, 0xdf, 0xff,
-    0xff, 0xff, 0xa3, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xdf, 0xff,
-    0xff, 0xff, 0xc1, 0xc0, 0x00, 0x00, 0x11, 0xff, 0x3f, 0xff,
-    0xff, 0xff, 0x80, 0xe0, 0x00, 0x00, 0x21, 0xfe, 0x3f, 0xff,
-    0xff, 0xff, 0x00, 0x70, 0x00, 0x00, 0x21, 0xfc, 0x3f, 0xff,
-    0xff, 0xfe, 0x00, 0x3c, 0x00, 0x00, 0x20, 0xf8, 0x3f, 0xff,
-    0xff, 0xf0, 0x00, 0x3e, 0x00, 0x00, 0x20, 0x00, 0x3f, 0xff,
-    0xff, 0xc0, 0x00, 0x1f, 0x00, 0x00, 0x20, 0x00, 0x3f, 0xff,
-    0xff, 0xc0, 0x00, 0x1f, 0x80, 0x00, 0x20, 0x00, 0x1f, 0xff,
-    0xff, 0xc0, 0x00, 0x0f, 0x80, 0x00, 0x20, 0x00, 0x07, 0xff,
-    0xff, 0xc0, 0x00, 0x07, 0x80, 0x00, 0x20, 0x00, 0x03, 0xff,
-    0xff, 0xc0, 0x00, 0x07, 0x80, 0x00, 0x60, 0x00, 0x01, 0xff,
-    0xff, 0xc0, 0x00, 0x02, 0x00, 0x00, 0xe0, 0x00, 0x01, 0xff,
-    0xff, 0xc0, 0x00, 0x01, 0x00, 0x01, 0xe0, 0x00, 0x01, 0xff,
-    0xff, 0xc0, 0x00, 0x00, 0x80, 0x07, 0xe0, 0x00, 0x03, 0xff,
-    0xff, 0xc0, 0x00, 0x00, 0x80, 0x3f, 0xe0, 0x00, 0x0f, 0xff,
-    0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x1f, 0xff,
-    0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x7f, 0xff,
-    0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0xff, 0xff,
-    0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x03, 0xff, 0xff,
-    0xff, 0xff, 0xc0, 0x00, 0x70, 0x00, 0xc0, 0x07, 0xff, 0xff,
-    0xff, 0xff, 0xfc, 0x00, 0x8f, 0xff, 0x20, 0x0f, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-};
-
-#endif /* !__HAVE_ARCH_LINUX_LOGOBW */
-
-#ifndef __HAVE_ARCH_LINUX_LOGO16
-
-unsigned char linux_logo16[] __initdata = {
-    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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x88, 0x88, 0x88, 0x80, 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, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x88, 0x80, 0x00, 0x00, 0x08, 0x88, 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,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
-    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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-    0x80, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x88, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00,
-    0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80,
-    0x00, 0x80, 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, 0x00, 0x00, 0x00, 0x00, 0x80,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-    0x00, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x80,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x08, 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, 0x00, 0x00, 0x00, 0x08, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x08, 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, 0x00, 0x00, 0x00, 0x08, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0x08, 0x70, 0x00, 0x00, 0x00, 0x77, 0x70, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0x87, 0x77, 0x00, 0x00, 0x07, 0xff, 0xf7, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x08,
-    0x77, 0xff, 0x00, 0x00, 0x7f, 0x77, 0xf7, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x08,
-    0x70, 0x0f, 0x80, 0x00, 0xf7, 0x08, 0x7f, 0x70,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x08,
-    0x80, 0x07, 0x80, 0x00, 0xf8, 0x00, 0x8f, 0x70,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x08,
-    0x70, 0x07, 0x88, 0x88, 0xf8, 0x00, 0x8f, 0x70,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0xf0, 0x06, 0xe6, 0xe6, 0xe6, 0x00, 0x8f, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0x77, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x77, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0x06, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60,
-    0x00, 0x00, 0x08, 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, 0x00, 0x00, 0x08, 0x80,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x60,
-    0x00, 0x00, 0x08, 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, 0x00, 0x00, 0x08, 0x80,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66, 0x66, 0x80,
-    0x08, 0x00, 0x00, 0x80, 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, 0x00, 0x08, 0x80,
-    0x86, 0xe6, 0xe6, 0xe6, 0x66, 0x66, 0x66, 0x80,
-    0x08, 0x78, 0x00, 0x80, 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, 0x00, 0x08, 0x80,
-    0x86, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x70,
-    0x00, 0x77, 0x00, 0x08, 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, 0x00, 0x08, 0x00,
-    0x87, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x78,
-    0x00, 0x88, 0x00, 0x08, 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, 0x00, 0x08, 0x00,
-    0x87, 0x76, 0x66, 0x66, 0x77, 0x77, 0xff, 0xf7,
-    0x00, 0x00, 0x00, 0x08, 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, 0x00, 0x80, 0x08,
-    0xff, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff,
-    0x80, 0x00, 0x00, 0x00, 0x80, 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, 0x80, 0x07,
-    0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff,
-    0x70, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x8f,
-    0xff, 0xf7, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff,
-    0xf0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x7f,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x87, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x77,
-    0xff, 0xf7, 0x77, 0xff, 0xff, 0xff, 0x77, 0x77,
-    0x77, 0x78, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x7f,
-    0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x77,
-    0x77, 0x78, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x7f, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x77, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x80, 0x80, 0x08, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x77, 0x80, 0x00, 0x08, 0x00, 0x00, 0x08,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0x78, 0x00, 0x08, 0x80, 0x00, 0x08,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x08, 0x08, 0x00, 0x8f, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xf7, 0x08, 0x80, 0x80, 0x00, 0x08,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xf7, 0x08, 0x80, 0x80, 0x00, 0x00,
-    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x80, 0x08, 0x07, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x80, 0x00, 0x08, 0x00, 0x00,
-    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x80, 0x80, 0x0f, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
-    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x08, 0x00, 0x80, 0x8f, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
-    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x08, 0x08, 0x00, 0x7f, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x80, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x00, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x00, 0x08, 0x08, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x00, 0x08, 0x08, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x88, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf0, 0x88, 0x88, 0x80, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x06, 0xe6, 0x00, 0x8f, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x08, 0x80,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x6e, 0x6e, 0x60, 0x08, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x88,
-    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x06, 0xe6, 0xe6, 0xe6, 0x00, 0x8f, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xfe, 0x6e, 0x60, 0x00, 0x00, 0x00, 0x00,
-    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x08, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xf6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x06,
-    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x8f, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xfe, 0x6e, 0x60, 0x00, 0x00, 0x00, 0x0e,
-    0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x00, 0x08, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x76, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0xe6,
-    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x8f,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x7e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x00, 0x08,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x76, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00,
-    0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x7e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x00,
-    0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x76, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00,
-    0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x8e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x88,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0x78, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xef,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7,
-    0x80, 0x06, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78,
-    0x00, 0x06, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x80,
-    0x00, 0x06, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x0e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
-    0x67, 0xff, 0xff, 0xff, 0xff, 0x78, 0x80, 0x00,
-    0x00, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x86, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0x66, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x0e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
-    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x86, 0x6e, 0x6e, 0x6e, 0x6e, 0x66, 0x66,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66,
-    0x66, 0x66, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
-    0x60, 0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x80,
-    0x00, 0x06, 0x66, 0xe6, 0xe6, 0xe6, 0x66, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x66, 0x66, 0x66, 0x66, 0xe6, 0xe6, 0x66,
-    0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-    0x88, 0x86, 0x66, 0x6e, 0x6e, 0x66, 0x60, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x06, 0x66, 0x66, 0x66, 0x66,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x06, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x06, 0x66, 0x66, 0x60,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x66, 0x66, 0x66, 0x60, 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, 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,
-    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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-#endif /* !__HAVE_ARCH_LINUX_LOGO16 */
-
-#else /* !INCLUDE_LINUX_LOGO_DATA */
-
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16[];
-
-#endif /* !INCLUDE_LINUX_LOGO_DATA */
-
diff -Nru a/include/asm-parisc/posix_types.h b/include/asm-parisc/posix_types.h
--- a/include/asm-parisc/posix_types.h	Mon Jan 13 02:56:42 2003
+++ b/include/asm-parisc/posix_types.h	Wed Feb 26 10:12:37 2003
@@ -17,6 +17,8 @@
 typedef unsigned int		__kernel_gid_t;
 typedef int			__kernel_suseconds_t;
 typedef int			__kernel_clock_t;
+typedef int			__kernel_timer_t;
+typedef int			__kernel_clockid_t;
 typedef int			__kernel_daddr_t;
 /* Note these change from narrow to wide kernels */
 #ifdef __LP64__
diff -Nru a/include/asm-parisc/ptrace.h b/include/asm-parisc/ptrace.h
--- a/include/asm-parisc/ptrace.h	Sat Jul 20 02:52:25 2002
+++ b/include/asm-parisc/ptrace.h	Mon Feb 10 09:49:17 2003
@@ -43,9 +43,6 @@
  * since we have taken branch traps too)
  */
 #define PTRACE_SINGLEBLOCK	12	/* resume execution until next branch */
-#define PTRACE_GETSIGINFO	13	/* get child's siginfo structure */
-#define PTRACE_SETSIGINFO	14	/* set child's siginfo structure */
-
 #ifdef __KERNEL__
 
 /* XXX should we use iaoq[1] or iaoq[0] ? */
diff -Nru a/include/asm-parisc/signal.h b/include/asm-parisc/signal.h
--- a/include/asm-parisc/signal.h	Thu Feb  6 15:45:57 2003
+++ b/include/asm-parisc/signal.h	Sun Feb 16 03:10:21 2003
@@ -156,6 +156,8 @@
 	struct sigaction sa;
 };
 
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
 #include <asm/sigcontext.h>
 
 #endif /* __KERNEL__ */
diff -Nru a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h
--- a/include/asm-parisc/unistd.h	Wed Nov 27 01:14:30 2002
+++ b/include/asm-parisc/unistd.h	Sat Mar 22 22:14:58 2003
@@ -842,19 +842,19 @@
 
 static inline pid_t setsid(void)
 {
-	extern int sys_setsid(void);
+	extern long sys_setsid(void);
 	return sys_setsid();
 }
 
 static inline int write(int fd, const char *buf, off_t count)
 {
-	extern int sys_write(int, const char *, int);
+	extern long sys_write(int, const char *, int);
 	return sys_write(fd, buf, count);
 }
 
 static inline int read(int fd, char *buf, off_t count)
 {
-	extern int sys_read(int, char *, int);
+	extern long sys_read(int, char *, int);
 	return sys_read(fd, buf, count);
 }
 
@@ -866,7 +866,7 @@
 
 static inline int dup(int fd)
 {
-	extern int sys_dup(int);
+	extern long sys_dup(int);
 	return sys_dup(fd);
 }
 
@@ -891,7 +891,7 @@
 
 static inline int _exit(int exitcode)
 {
-	extern int sys_exit(int) __attribute__((noreturn));
+	extern long sys_exit(int) __attribute__((noreturn));
 	return sys_exit(exitcode);
 }
 
diff -Nru a/include/asm-ppc/ide.h b/include/asm-ppc/ide.h
--- a/include/asm-ppc/ide.h	Wed Feb 19 03:47:26 2003
+++ b/include/asm-ppc/ide.h	Sat Mar 22 16:59:59 2003
@@ -33,11 +33,11 @@
 extern void __ide_mm_outsl(unsigned long port, void *addr, u32 count);
 
 struct ide_machdep_calls {
-        int         (*default_irq)(ide_ioreg_t base);
-        ide_ioreg_t (*default_io_base)(int index);
+        int         (*default_irq)(unsigned long base);
+        unsigned long (*default_io_base)(int index);
         void        (*ide_init_hwif)(hw_regs_t *hw,
-                                     ide_ioreg_t data_port,
-                                     ide_ioreg_t ctrl_port,
+                                     unsigned long data_port,
+                                     unsigned long ctrl_port,
                                      int *irq);
 };
 
@@ -46,14 +46,14 @@
 #undef	SUPPORT_SLOW_DATA_PORTS
 #define	SUPPORT_SLOW_DATA_PORTS	0
 
-static __inline__ int ide_default_irq(ide_ioreg_t base)
+static __inline__ int ide_default_irq(unsigned long base)
 {
 	if (ppc_ide_md.default_irq)
 		return ppc_ide_md.default_irq(base);
 	return 0;
 }
 
-static __inline__ ide_ioreg_t ide_default_io_base(int index)
+static __inline__ unsigned long ide_default_io_base(int index)
 {
 	if (ppc_ide_md.default_io_base)
 		return ppc_ide_md.default_io_base(index);
@@ -66,10 +66,10 @@
  * as the pmac IDE interfaces.
  */
 static __inline__ void ide_init_hwif_ports(hw_regs_t *hw,
-					   ide_ioreg_t data_port,
-					   ide_ioreg_t ctrl_port, int *irq)
+					   unsigned long data_port,
+					   unsigned long ctrl_port, int *irq)
 {
-	ide_ioreg_t reg = data_port;
+	unsigned long reg = data_port;
 	int i;
 
 	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
@@ -92,7 +92,7 @@
 #ifndef CONFIG_PCI
 	hw_regs_t hw;
 	int index;
-	ide_ioreg_t base;
+	unsigned long base;
 
 	for (index = 0; index < MAX_HWIFS; index++) {
 		base = ide_default_io_base(index);
diff -Nru a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
--- a/include/asm-ppc/mpc8260.h	Sun Sep 15 21:52:05 2002
+++ b/include/asm-ppc/mpc8260.h	Sat Mar 22 21:03:08 2003
@@ -9,51 +9,35 @@
 #define __CONFIG_8260_DEFS
 
 #include <linux/config.h>
+#include <platforms/mpc82xx.h>
 
-#ifdef CONFIG_8260
-
-#ifdef CONFIG_EST8260
-#include <platforms/est8260.h>
+/* Make sure the memory translation stuff is there if PCI not used.
+ */
+#ifndef _IO_BASE
+#define _IO_BASE        0
 #endif
 
-#ifdef CONFIG_SBS8260
-#include <platforms/sbs8260.h>
+#ifndef _ISA_MEM_BASE
+#define _ISA_MEM_BASE   0
 #endif
 
-#ifdef CONFIG_RPX6
-#include <platforms/rpxsuper.h>
+#ifndef PCI_DRAM_OFFSET
+#define PCI_DRAM_OFFSET 0
 #endif
 
-#ifdef CONFIG_WILLOW
-#include <platforms/willow.h>
+/* Map 256MB I/O region
+ */
+#ifndef IO_PHYS_ADDR
+#define IO_PHYS_ADDR	0xe0000000
 #endif
-
-#ifdef CONFIG_TQM8260
-#include <platforms/tqm8260.h>
+#ifndef IO_VIRT_ADDR
+#define IO_VIRT_ADDR	IO_PHYS_ADDR
 #endif
 
-/* I don't yet have the ISA or PCI stuff done....no 8260 with
- * such thing.....
- */
-#define _IO_BASE        0
-#define _ISA_MEM_BASE   0
-#define PCI_DRAM_OFFSET 0
-
 /* The "residual" data board information structure the boot loader
  * hands to us.
  */
 extern unsigned char __res[];
 
-/* I need this to get pt_regs.......
-*/
-#include <asm/ptrace.h>
-
-extern int request_8xxirq(unsigned int irq,
-		       void (*handler)(int, void *, struct pt_regs *),
-		       unsigned long flags, 
-		       const char *device,
-		       void *dev_id);
-
-#endif /* CONFIG_8260 */
 #endif /* !__CONFIG_8260_DEFS */
 #endif /* __KERNEL__ */
diff -Nru a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h
--- a/include/asm-ppc/pci.h	Sun Mar 16 13:55:58 2003
+++ b/include/asm-ppc/pci.h	Wed Mar 19 18:45:17 2003
@@ -271,9 +271,10 @@
 /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
 #define HAVE_PCI_MMAP	1
 
-#endif	/* __KERNEL__ */
+extern void
+pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+			struct resource *res);
 
-/* generic pci stuff */
-#include <asm-generic/pci.h>
+#endif	/* __KERNEL__ */
 
 #endif /* __PPC_PCI_H */
diff -Nru a/include/asm-ppc/rtc.h b/include/asm-ppc/rtc.h
--- a/include/asm-ppc/rtc.h	Tue Feb 11 15:48:53 2003
+++ b/include/asm-ppc/rtc.h	Sat Mar 22 16:54:03 2003
@@ -35,15 +35,14 @@
 #define RTC_AIE 0x20		/* alarm interrupt enable */
 #define RTC_UIE 0x10		/* update-finished interrupt enable */
 
-extern void gen_rtc_interrupt(unsigned long);
-
 /* some dummy definitions */
+#define RTC_BATT_BAD 0x100	/* battery bad */
 #define RTC_SQWE 0x08		/* enable square-wave output */
 #define RTC_DM_BINARY 0x04	/* all time/date values are BCD if clear */
 #define RTC_24H 0x02		/* 24 hour mode - else hours bit 7 means pm */
 #define RTC_DST_EN 0x01	        /* auto switch DST - works f. USA only */
 
-static inline void get_rtc_time(struct rtc_time *time)
+static inline unsigned int get_rtc_time(struct rtc_time *time)
 {
 	if (ppc_md.get_rtc_time) {
 		unsigned long nowtime;
@@ -55,6 +54,7 @@
 		time->tm_year -= 1900;
 		time->tm_mon -= 1; /* Make sure userland has a 0-based month */
 	}
+	return RTC_24H;
 }
 
 /* Set the current date and time in the real time clock. */
diff -Nru a/include/asm-ppc64/compat.h b/include/asm-ppc64/compat.h
--- a/include/asm-ppc64/compat.h	Thu Mar 13 21:26:25 2003
+++ b/include/asm-ppc64/compat.h	Sun Mar 23 22:28:33 2003
@@ -98,4 +98,17 @@
 #define COMPAT_OFF_T_MAX	0x7fffffff
 #define COMPAT_LOFF_T_MAX	0x7fffffffffffffffL
 
+/*
+ * A pointer passed in from user mode. This should not
+ * be used for syscall parameters, just declare them
+ * as pointers because the syscall entry code will have
+ * appropriately comverted them already.
+ */
+typedef	u32		compat_uptr_t;
+
+static inline void *compat_ptr(compat_uptr_t uptr)
+{
+	return (void *)uptr;
+}
+
 #endif /* _ASM_PPC64_COMPAT_H */
diff -Nru a/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h
--- a/include/asm-ppc64/elf.h	Sat Feb 22 01:43:15 2003
+++ b/include/asm-ppc64/elf.h	Mon Mar 17 21:31:50 2003
@@ -84,9 +84,10 @@
 
 #define ELF_PLATFORM	(NULL)
 
-#define ELF_PLAT_INIT(_r)	do { \
+#define ELF_PLAT_INIT(_r, load_addr)	do { \
 	memset(_r->gpr, 0, sizeof(_r->gpr)); \
 	_r->ctr = _r->link = _r->xer = _r->ccr = 0; \
+	_r->gpr[2] = load_addr; \
 } while (0)
 
 #ifdef __KERNEL__
diff -Nru a/include/asm-ppc64/linux_logo.h b/include/asm-ppc64/linux_logo.h
--- a/include/asm-ppc64/linux_logo.h	Sun Apr  7 22:46:31 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,26 +0,0 @@
-/*
- * include/asm-ppc64/linux_logo.h: A linux logo to be displayed on boot
- * (pinched from the sparc port).
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * values have to start from 0x20
- * (i.e. linux_logo_{red,green,blue}[0] is color 0x20)
- *
- * 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>
-
-#define linux_logo_banner "Linux/PPC-64 version " UTS_RELEASE
-
-#define LINUX_LOGO_HEIGHT	80
-#define LINUX_LOGO_WIDTH	80
-
-#include <linux/linux_logo.h>
diff -Nru a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h
--- a/include/asm-ppc64/pgtable.h	Tue Feb 25 02:48:28 2003
+++ b/include/asm-ppc64/pgtable.h	Sat Mar 22 22:09:15 2003
@@ -83,9 +83,7 @@
 #define _PAGE_WRITETHRU	0x040UL	/* W: cache write-through */
 #define _PAGE_DIRTY	0x080UL	/* C: page changed */
 #define _PAGE_ACCESSED	0x100UL	/* R: page referenced */
-#if 0
-#define _PAGE_HPTENOIX	0x200UL /* software: pte HPTE slot unknown */
-#endif
+#define _PAGE_FILE	0x200UL /* software: pte holds file offset */
 #define _PAGE_HASHPTE	0x400UL	/* software: pte has an associated HPTE */
 #define _PAGE_EXEC	0x800UL	/* software: i-cache coherence required */
 #define _PAGE_SECONDARY 0x8000UL /* software: HPTE is in secondary group */
@@ -234,6 +232,7 @@
 static inline int pte_exec(pte_t pte)  { return pte_val(pte) & _PAGE_EXEC;}
 static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY;}
 static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;}
+static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE;}
 
 static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; }
 static inline void pte_cache(pte_t pte)   { pte_val(pte) &= ~_PAGE_NO_CACHE; }
@@ -349,11 +348,14 @@
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 
 /* Encode and de-code a swap entry */
-#define __swp_type(entry)		(((entry).val >> 1) & 0x3f)
-#define __swp_offset(entry)		((entry).val >> 8)
-#define __swp_entry(type, offset)	((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
-#define __pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) >> PTE_SHIFT })
-#define __swp_entry_to_pte(x)		((pte_t) { (x).val << PTE_SHIFT })
+#define __swp_type(entry)	(((entry).val >> 1) & 0x3f)
+#define __swp_offset(entry)	((entry).val >> 8)
+#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
+#define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) >> PTE_SHIFT })
+#define __swp_entry_to_pte(x)	((pte_t) { (x).val << PTE_SHIFT })
+#define pte_to_pgoff(pte)	(pte_val(pte) >> PTE_SHIFT)
+#define pgoff_to_pte(off)	((pte_t) {((off) << PTE_SHIFT)|_PAGE_FILE})
+#define PTE_FILE_MAX_BITS	(BITS_PER_LONG - PTE_SHIFT)
 
 /*
  * kern_addr_valid is intended to indicate whether an address is a valid
diff -Nru a/include/asm-s390/elf.h b/include/asm-s390/elf.h
--- a/include/asm-s390/elf.h	Mon Feb  4 23:39:15 2002
+++ b/include/asm-s390/elf.h	Mon Mar 17 21:31:50 2003
@@ -36,7 +36,7 @@
 
 /* For SVR4/S390 the function pointer to be registered with `atexit` is
    passed in R14. */
-#define ELF_PLAT_INIT(_r) \
+#define ELF_PLAT_INIT(_r, load_addr) \
 	_r->gprs[14] = 0
 
 #define USE_ELF_CORE_DUMP
diff -Nru a/include/asm-s390x/bitops.h b/include/asm-s390x/bitops.h
--- a/include/asm-s390x/bitops.h	Mon Feb 24 10:24:21 2003
+++ b/include/asm-s390x/bitops.h	Thu Mar 20 10:46:14 2003
@@ -55,7 +55,7 @@
 
 #ifdef CONFIG_SMP
 /*
- * SMP save set_bit routine based on compare and swap (CS)
+ * SMP safe set_bit routine based on compare and swap (CS)
  */
 static inline void set_bit_cs(unsigned long nr, volatile unsigned long *ptr)
 {
@@ -80,7 +80,7 @@
 }
 
 /*
- * SMP save clear_bit routine based on compare and swap (CS)
+ * SMP safe clear_bit routine based on compare and swap (CS)
  */
 static inline void clear_bit_cs(unsigned long nr, volatile unsigned long *ptr)
 {
@@ -105,7 +105,7 @@
 }
 
 /*
- * SMP save change_bit routine based on compare and swap (CS)
+ * SMP safe change_bit routine based on compare and swap (CS)
  */
 static inline void change_bit_cs(unsigned long nr, volatile unsigned long *ptr)
 {
@@ -130,7 +130,7 @@
 }
 
 /*
- * SMP save test_and_set_bit routine based on compare and swap (CS)
+ * SMP safe test_and_set_bit routine based on compare and swap (CS)
  */
 static inline int
 test_and_set_bit_cs(unsigned long nr, volatile unsigned long *ptr)
@@ -157,7 +157,7 @@
 }
 
 /*
- * SMP save test_and_clear_bit routine based on compare and swap (CS)
+ * SMP safe test_and_clear_bit routine based on compare and swap (CS)
  */
 static inline int
 test_and_clear_bit_cs(unsigned long nr, volatile unsigned long *ptr)
@@ -184,7 +184,7 @@
 }
 
 /*
- * SMP save test_and_change_bit routine based on compare and swap (CS) 
+ * SMP safe test_and_change_bit routine based on compare and swap (CS) 
  */
 static inline int
 test_and_change_bit_cs(unsigned long nr, volatile unsigned long *ptr)
diff -Nru a/include/asm-s390x/compat.h b/include/asm-s390x/compat.h
--- a/include/asm-s390x/compat.h	Sun Mar  9 01:34:45 2003
+++ b/include/asm-s390x/compat.h	Sun Mar 23 22:28:41 2003
@@ -101,4 +101,17 @@
 #define COMPAT_OFF_T_MAX	0x7fffffff
 #define COMPAT_LOFF_T_MAX	0x7fffffffffffffffL
 
+/*
+ * A pointer passed in from user mode. This should not
+ * be used for syscall parameters, just declare them
+ * as pointers because the syscall entry code will have
+ * appropriately comverted them already.
+ */
+typedef	u32		compat_uptr_t;
+
+static inline void *compat_ptr(compat_uptr_t uptr)
+{
+	return (void *)(uptr & 0x7fffffffUL);
+}
+
 #endif /* _ASM_S390X_COMPAT_H */
diff -Nru a/include/asm-s390x/elf.h b/include/asm-s390x/elf.h
--- a/include/asm-s390x/elf.h	Mon Feb 24 10:25:00 2003
+++ b/include/asm-s390x/elf.h	Mon Mar 17 21:31:50 2003
@@ -36,7 +36,7 @@
 
 /* For SVR4/S390 the function pointer to be registered with `atexit` is
    passed in R14. */
-#define ELF_PLAT_INIT(_r) \
+#define ELF_PLAT_INIT(_r, load_addr) \
 	do { \
 	_r->gprs[14] = 0; \
 	clear_thread_flag(TIF_31BIT); \
diff -Nru a/include/asm-sh/elf.h b/include/asm-sh/elf.h
--- a/include/asm-sh/elf.h	Mon Feb  4 23:45:03 2002
+++ b/include/asm-sh/elf.h	Mon Mar 17 21:31:50 2003
@@ -61,7 +61,7 @@
 
 #define ELF_PLATFORM  (NULL)
 
-#define ELF_PLAT_INIT(_r) \
+#define ELF_PLAT_INIT(_r, load_addr) \
   do { _r->regs[0]=0; _r->regs[1]=0; _r->regs[2]=0; _r->regs[3]=0; \
        _r->regs[4]=0; _r->regs[5]=0; _r->regs[6]=0; _r->regs[7]=0; \
        _r->regs[8]=0; _r->regs[9]=0; _r->regs[10]=0; _r->regs[11]=0; \
diff -Nru a/include/asm-sh/linux_logo.h b/include/asm-sh/linux_logo.h
--- a/include/asm-sh/linux_logo.h	Mon Feb  4 23:45:03 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1418 +0,0 @@
-/* $Id: linux_logo.h,v 1.4 2001/08/08 07:39:36 gnb Exp $
- * include/linux/linux_logo.h: This is a linux logo
- *                             to be displayed on boot.
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1996,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (c) 2001 Greg Banks <gnb@alphalink.com.au>
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * image size has to be 80x80
- * values have to start from 0x20
- * (i.e. RGB(linux_logo_red[0],
- *           linux_logo_green[0],
- *           linux_logo_blue[0]) is color 0x20)
- * BW image has to be 80x80 as well, with MS bit
- * on the left
- * Serial_console ascii image can be any size,
- * but should contain %s to display the version
- */
-
-#include <linux/init.h>
-#include <linux/version.h>
-
-#define linux_logo_banner "Linux/SuperH version " UTS_RELEASE
-
-#define __HAVE_ARCH_LINUX_LOGO 1
-#define __HAVE_ARCH_LINUX_LOGO16 1
-#define __HAVE_ARCH_LINUX_LOGOBW 1
-
-#define LINUX_LOGO_COLORS       160
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-unsigned char linux_logo_red[] __initdata = {
-  0x02, 0x06, 0x0A, 0x0E, 0x16, 0x1A, 0x1E, 0x22,
-  0x12, 0x2A, 0x36, 0x42, 0x4E, 0x4A, 0x56, 0x26,
-  0x46, 0x2E, 0x32, 0x52, 0x3A, 0x02, 0x66, 0x5E,
-  0x3E, 0x76, 0x8A, 0xA3, 0x9A, 0x86, 0xC6, 0xC2,
-  0x66, 0xBA, 0xD2, 0xDA, 0xD6, 0xE2, 0xF6, 0xFE,
-  0xAE, 0x7A, 0xDF, 0xEA, 0x6A, 0xAA, 0xE6, 0xBE,
-  0x59, 0xEE, 0x9E, 0x96, 0x82, 0x7A, 0x7A, 0x68,
-  0x3C, 0x9A, 0xE2, 0xF1, 0xE5, 0xBA, 0xD6, 0xB2,
-  0x26, 0xBE, 0xC3, 0xEE, 0xEA, 0xEA, 0xEE, 0xF6,
-  0xF4, 0xDA, 0xCE, 0x7A, 0xDC, 0xF6, 0xF6, 0xE0,
-  0xB5, 0xCC, 0xF6, 0x69, 0xDB, 0xEE, 0xF1, 0xC5,
-  0x9E, 0x8A, 0xD2, 0xEE, 0xCA, 0xBA, 0xD3, 0x5C,
-  0x8A, 0xBE, 0xAA, 0xD6, 0xCA, 0xB6, 0xAD, 0x9E,
-  0xC5, 0xBC, 0xBF, 0xC9, 0x92, 0xB2, 0x9A, 0xAA,
-  0xB6, 0xF2, 0xCE, 0xFA, 0x6E, 0xA6, 0x12, 0x4A,
-  0x8E, 0xF6, 0xF6, 0xEE, 0xE9, 0xF0, 0x26, 0x9A,
-  0xEA, 0xF6, 0xDE, 0x31, 0x72, 0xCE, 0x46, 0x7E,
-  0xB6, 0x62, 0xCF, 0xA3, 0x76, 0xA4, 0xA2, 0xE2,
-  0xAE, 0xC0, 0xCE, 0xE2, 0xE7, 0xFC, 0xCD, 0x03,
-  0xEF, 0xF9, 0xD4, 0xFE, 0xFE, 0xFE, 0x83, 0x5E
-};
-
-unsigned char linux_logo_green[] __initdata = {
-  0x02, 0x06, 0x0A, 0x0E, 0x16, 0x1A, 0x1E, 0x22,
-  0x12, 0x2A, 0x36, 0x42, 0x4E, 0x4A, 0x56, 0x26,
-  0x46, 0x2E, 0x32, 0x52, 0x3A, 0x02, 0x66, 0x5E,
-  0x3E, 0x76, 0x8A, 0xA3, 0x9A, 0x86, 0xC6, 0xC2,
-  0x62, 0xBA, 0xD2, 0xDA, 0xD6, 0xE2, 0xF6, 0xFE,
-  0xAE, 0x7A, 0xDE, 0xEA, 0x6A, 0xAA, 0xE6, 0xBE,
-  0x5A, 0xEE, 0x9E, 0x96, 0x82, 0x64, 0x5E, 0x4E,
-  0x28, 0x72, 0xAA, 0xBA, 0xAE, 0x92, 0xAE, 0x93,
-  0x1A, 0xA6, 0x86, 0xB6, 0xBE, 0xC4, 0xCA, 0xCE,
-  0xD4, 0xC2, 0xCE, 0x56, 0xA2, 0xD9, 0xD9, 0xBC,
-  0x7A, 0x92, 0xDA, 0x46, 0x9E, 0xB2, 0xD6, 0x97,
-  0x76, 0x5E, 0xA2, 0xBE, 0xA4, 0x86, 0x96, 0x45,
-  0x66, 0x92, 0x7A, 0x9A, 0x93, 0x9E, 0x9A, 0x6A,
-  0x8B, 0x8C, 0xB2, 0xCA, 0x92, 0xA6, 0x7A, 0x7E,
-  0xB6, 0xF2, 0xCE, 0xFA, 0x6E, 0xA6, 0x0E, 0x33,
-  0x86, 0xBE, 0xE6, 0xCE, 0xBC, 0xC6, 0x1E, 0x8E,
-  0xAE, 0xBA, 0xAF, 0x23, 0x66, 0xAA, 0x2E, 0x72,
-  0x86, 0x46, 0xA5, 0x6E, 0x52, 0x72, 0x92, 0xA6,
-  0x86, 0x94, 0xA0, 0xD2, 0xDC, 0xFB, 0xC3, 0x03,
-  0x9F, 0x64, 0x84, 0x03, 0x15, 0x38, 0x7E, 0x56
-};
-
-unsigned char linux_logo_blue[] __initdata = {
-  0x02, 0x06, 0x0A, 0x0D, 0x16, 0x1A, 0x1E, 0x22,
-  0x12, 0x2B, 0x36, 0x42, 0x4E, 0x4A, 0x56, 0x26,
-  0x46, 0x2E, 0x32, 0x52, 0x3A, 0x06, 0x66, 0x5D,
-  0x3E, 0x76, 0x8E, 0xA3, 0x9A, 0x86, 0xC4, 0xC2,
-  0x5A, 0xBA, 0xD2, 0xDA, 0xD6, 0xE2, 0xF6, 0xFE,
-  0xAE, 0x7A, 0xDE, 0xEA, 0x69, 0xAA, 0xE4, 0xBB,
-  0x5A, 0xEE, 0x9E, 0x96, 0x82, 0x42, 0x0A, 0x0A,
-  0x09, 0x0A, 0x0A, 0x0D, 0x0B, 0x11, 0x0E, 0x46,
-  0x0A, 0x72, 0x0A, 0x0E, 0x0A, 0x12, 0x15, 0x2E,
-  0x14, 0x86, 0xC2, 0x1A, 0x0A, 0x35, 0x27, 0x0E,
-  0x09, 0x0B, 0x4A, 0x07, 0x0B, 0x0E, 0x22, 0x0D,
-  0x0A, 0x06, 0x0C, 0x0A, 0x14, 0x0A, 0x0B, 0x1A,
-  0x0E, 0x0E, 0x0C, 0x0A, 0x1F, 0x6A, 0x73, 0x09,
-  0x0C, 0x22, 0x91, 0xCB, 0x92, 0x92, 0x36, 0x26,
-  0xB6, 0xF2, 0xCE, 0xFA, 0x6E, 0xA6, 0x06, 0x0B,
-  0x6A, 0x0E, 0xBE, 0x5A, 0x40, 0x0E, 0x0A, 0x5A,
-  0x0C, 0x0E, 0x3B, 0x06, 0x4E, 0x4A, 0x06, 0x5A,
-  0x26, 0x06, 0x44, 0x0A, 0x0A, 0x08, 0x5E, 0x0D,
-  0x32, 0x2C, 0x24, 0xCF, 0xDA, 0xFB, 0xBE, 0x03,
-  0x99, 0x5D, 0x35, 0x03, 0x15, 0x38, 0x74, 0x4B
-};
-
-unsigned char linux_logo[] __initdata = {
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
-  0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-  0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x21, 0x23, 0x25, 0x29, 0x2A, 0x2B, 0x2C, 0x2C,
-  0x2C, 0x2D, 0x2B, 0x2A, 0x29, 0x25, 0x28, 0x22,
-  0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-  0x24, 0x29, 0x2B, 0x2E, 0x2B, 0x2F, 0x2F, 0x24,
-  0x25, 0x27, 0x2A, 0x2B, 0x2E, 0x30, 0x31, 0x25,
-  0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-  0x32, 0x33, 0x34, 0x21, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x21, 0x2A, 0x2E, 0x2B,
-  0x2F, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x32,
-  0x2C, 0x27, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x21, 0x30,
-  0x2C, 0x31, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x29, 0x33,
-  0x25, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x23, 0x31, 0x27, 0x21, 0x35,
-  0x29, 0x2C, 0x29, 0x28, 0x21, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2B, 0x34,
-  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x25, 0x2E, 0x36, 0x31, 0x22,
-  0x35, 0x34, 0x30, 0x27, 0x22, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x23, 0x29, 0x2E, 0x22,
-  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x26, 0x37, 0x37, 0x34, 0x25,
-  0x35, 0x21, 0x2C, 0x2A, 0x24, 0x21, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x21, 0x24, 0x38, 0x38, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x25, 0x2A, 0x2F, 0x28, 0x22,
-  0x35, 0x35, 0x27, 0x33, 0x2F, 0x23, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x21, 0x26, 0x2C, 0x26, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x22, 0x22, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x2C, 0x32, 0x28, 0x21, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x22, 0x2F, 0x2E, 0x23, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x2A, 0x2B, 0x25, 0x21, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x23, 0x29, 0x33, 0x35, 0x35,
-  0x35, 0x21, 0x22, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x21, 0x23, 0x22, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x28, 0x33, 0x27, 0x22, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x23, 0x31, 0x2E, 0x35, 0x35,
-  0x21, 0x21, 0x24, 0x27, 0x21, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x28, 0x27, 0x22, 0x32, 0x24, 0x35,
-  0x35, 0x35, 0x35, 0x22, 0x2E, 0x29, 0x23, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x23, 0x31, 0x2E, 0x35, 0x35,
-  0x2F, 0x39, 0x37, 0x24, 0x24, 0x35, 0x35, 0x35,
-  0x23, 0x2E, 0x3A, 0x3B, 0x3C, 0x2F, 0x25, 0x21,
-  0x35, 0x35, 0x35, 0x35, 0x2E, 0x31, 0x23, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x23, 0x31, 0x2E, 0x35, 0x23,
-  0x3D, 0x3E, 0x3F, 0x39, 0x22, 0x35, 0x35, 0x21,
-  0x40, 0x41, 0x42, 0x43, 0x44, 0x3D, 0x23, 0x21,
-  0x35, 0x35, 0x35, 0x35, 0x2E, 0x32, 0x28, 0x21,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x23, 0x31, 0x2E, 0x35, 0x2A,
-  0x43, 0x3F, 0x45, 0x46, 0x34, 0x35, 0x35, 0x26,
-  0x42, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x2D, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x30, 0x34, 0x24, 0x21,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x23, 0x31, 0x33, 0x35, 0x4C,
-  0x4D, 0x25, 0x2E, 0x45, 0x49, 0x22, 0x23, 0x31,
-  0x4E, 0x4F, 0x21, 0x30, 0x50, 0x51, 0x52, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x30, 0x34, 0x24, 0x21,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x23, 0x29, 0x2E, 0x21, 0x39,
-  0x4C, 0x21, 0x30, 0x53, 0x54, 0x28, 0x2F, 0x2A,
-  0x4A, 0x4C, 0x35, 0x23, 0x31, 0x4F, 0x3E, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x2D, 0x38, 0x24, 0x21,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x23, 0x29, 0x37, 0x23, 0x36,
-  0x54, 0x35, 0x28, 0x39, 0x55, 0x56, 0x56, 0x57,
-  0x3B, 0x4C, 0x35, 0x35, 0x35, 0x3F, 0x3F, 0x21,
-  0x35, 0x35, 0x35, 0x35, 0x2D, 0x38, 0x24, 0x21,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x22, 0x2F, 0x50, 0x23, 0x34,
-  0x42, 0x25, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D,
-  0x5E, 0x5F, 0x60, 0x35, 0x30, 0x46, 0x3A, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x30, 0x2B, 0x25, 0x21,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x22, 0x2F, 0x2E, 0x23, 0x22,
-  0x3F, 0x61, 0x62, 0x5C, 0x63, 0x64, 0x65, 0x66,
-  0x67, 0x68, 0x65, 0x5D, 0x69, 0x6A, 0x29, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x32, 0x2D, 0x26, 0x21,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x22, 0x27, 0x2E, 0x23, 0x35,
-  0x6B, 0x62, 0x6C, 0x63, 0x5B, 0x65, 0x68, 0x6D,
-  0x6D, 0x6E, 0x68, 0x68, 0x68, 0x6F, 0x6B, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x32, 0x33, 0x27, 0x22,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x22, 0x27, 0x33, 0x26, 0x58,
-  0x70, 0x71, 0x5C, 0x63, 0x64, 0x66, 0x68, 0x72,
-  0x6E, 0x68, 0x68, 0x68, 0x6F, 0x5E, 0x5D, 0x21,
-  0x35, 0x35, 0x35, 0x35, 0x25, 0x37, 0x29, 0x23,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x22, 0x26, 0x2C, 0x32, 0x73,
-  0x62, 0x74, 0x75, 0x5B, 0x65, 0x68, 0x6D, 0x76,
-  0x68, 0x68, 0x68, 0x77, 0x71, 0x74, 0x78, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x21, 0x50, 0x2A, 0x28,
-  0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x22, 0x26, 0x2C, 0x31, 0x24,
-  0x79, 0x7A, 0x63, 0x7B, 0x66, 0x68, 0x68, 0x68,
-  0x68, 0x7C, 0x7D, 0x7E, 0x74, 0x7E, 0x57, 0x35,
-  0x21, 0x2A, 0x23, 0x35, 0x35, 0x38, 0x2D, 0x26,
-  0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x22, 0x27, 0x2C, 0x32, 0x21,
-  0x7F, 0x80, 0x81, 0x6F, 0x66, 0x65, 0x5E, 0x81,
-  0x82, 0x62, 0x7E, 0x83, 0x84, 0x85, 0x40, 0x35,
-  0x35, 0x2C, 0x39, 0x34, 0x35, 0x24, 0x50, 0x31,
-  0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x22, 0x2F, 0x2E, 0x32, 0x21,
-  0x54, 0x86, 0x87, 0x82, 0x77, 0x5D, 0x88, 0x71,
-  0x71, 0x71, 0x88, 0x61, 0x3F, 0x3E, 0x48, 0x23,
-  0x35, 0x24, 0x39, 0x39, 0x24, 0x35, 0x2D, 0x30,
-  0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x21, 0x28, 0x32, 0x36, 0x25, 0x22,
-  0x3A, 0x4F, 0x86, 0x87, 0x88, 0x71, 0x88, 0x62,
-  0x70, 0x89, 0x8A, 0x41, 0x8B, 0x4A, 0x44, 0x2B,
-  0x35, 0x35, 0x32, 0x38, 0x21, 0x35, 0x22, 0x50,
-  0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x22, 0x27, 0x2D, 0x2D, 0x35, 0x21,
-  0x8C, 0x3E, 0x4F, 0x8D, 0x8E, 0x87, 0x87, 0x8F,
-  0x86, 0x41, 0x4F, 0x42, 0x46, 0x47, 0x47, 0x90,
-  0x21, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x38,
-  0x2D, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x22, 0x24, 0x2A, 0x37, 0x28, 0x35, 0x31,
-  0x4B, 0x4A, 0x4F, 0x4F, 0x4F, 0x41, 0x41, 0x4F,
-  0x4F, 0x3F, 0x44, 0x91, 0x47, 0x47, 0x47, 0x47,
-  0x33, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x23,
-  0x2E, 0x2A, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x21, 0x28, 0x31, 0x50, 0x31, 0x28, 0x21, 0x90,
-  0x47, 0x46, 0x92, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F,
-  0x92, 0x4E, 0x93, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x8B, 0x23, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x29, 0x2E, 0x29, 0x28, 0x21, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-  0x23, 0x2F, 0x2D, 0x2B, 0x35, 0x21, 0x50, 0x93,
-  0x47, 0x47, 0x51, 0x3E, 0x4F, 0x4F, 0x3F, 0x4A,
-  0x46, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x33, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x2C, 0x30, 0x27, 0x23, 0x21, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-  0x27, 0x2B, 0x2C, 0x21, 0x35, 0x28, 0x43, 0x47,
-  0x47, 0x47, 0x47, 0x46, 0x45, 0x4E, 0x46, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x48, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x28, 0x50, 0x38, 0x26, 0x22, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-  0x34, 0x50, 0x28, 0x35, 0x35, 0x94, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x93, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x4E, 0x28, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x28, 0x37, 0x2A, 0x25, 0x22, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x32,
-  0x50, 0x25, 0x35, 0x35, 0x23, 0x3F, 0x93, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x93, 0x91, 0x2A, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x2F, 0x2E, 0x32, 0x24, 0x21,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x2F, 0x33,
-  0x27, 0x35, 0x35, 0x35, 0x29, 0x3F, 0x46, 0x47,
-  0x47, 0x47, 0x47, 0x93, 0x91, 0x91, 0x93, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x93, 0x46, 0x51,
-  0x45, 0x4E, 0x36, 0x21, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x2F, 0x33, 0x29, 0x23,
-  0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x38, 0x2B,
-  0x35, 0x35, 0x35, 0x21, 0x30, 0x4D, 0x92, 0x4B,
-  0x46, 0x93, 0x93, 0x51, 0x45, 0x4E, 0x51, 0x93,
-  0x93, 0x93, 0x46, 0x4E, 0x44, 0x92, 0x8B, 0x8B,
-  0x3E, 0x8B, 0x90, 0x28, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x35, 0x35, 0x35, 0x35, 0x38, 0x2B, 0x26,
-  0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x23, 0x29, 0x33, 0x28,
-  0x35, 0x35, 0x35, 0x22, 0x37, 0x90, 0x43, 0x91,
-  0x93, 0x47, 0x47, 0x93, 0x4B, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x46, 0x51, 0x45, 0x42, 0x8B,
-  0x3F, 0x3F, 0x42, 0x52, 0x21, 0x23, 0x32, 0x23,
-  0x35, 0x35, 0x35, 0x35, 0x35, 0x21, 0x2E, 0x31,
-  0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x21, 0x24, 0x2A, 0x30, 0x35,
-  0x35, 0x22, 0x35, 0x24, 0x95, 0x4E, 0x93, 0x47,
-  0x47, 0x47, 0x47, 0x93, 0x91, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x46,
-  0x4E, 0x92, 0x3E, 0x45, 0x37, 0x35, 0x21, 0x2F,
-  0x26, 0x35, 0x35, 0x35, 0x35, 0x35, 0x38, 0x2B,
-  0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x22, 0x26, 0x2D, 0x32, 0x35,
-  0x25, 0x25, 0x35, 0x4C, 0x51, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x46, 0x43, 0x8B, 0x42, 0x23, 0x35, 0x35,
-  0x26, 0x24, 0x35, 0x35, 0x35, 0x35, 0x28, 0x2E,
-  0x29, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x23, 0x29, 0x50, 0x24, 0x35,
-  0x29, 0x35, 0x28, 0x43, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x93, 0x4A, 0x43, 0x36, 0x35, 0x23,
-  0x28, 0x2F, 0x22, 0x35, 0x35, 0x35, 0x35, 0x2C,
-  0x34, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x21, 0x28, 0x2A, 0x33, 0x35, 0x25,
-  0x24, 0x35, 0x49, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x93, 0x51, 0x3E, 0x21, 0x2F,
-  0x34, 0x25, 0x2F, 0x35, 0x35, 0x35, 0x35, 0x31,
-  0x2C, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x22, 0x26, 0x2D, 0x34, 0x35, 0x29,
-  0x35, 0x24, 0x4E, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x93, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x46, 0x31, 0x2F,
-  0x29, 0x23, 0x2F, 0x23, 0x35, 0x35, 0x35, 0x21,
-  0x2E, 0x31, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x21, 0x23, 0x29, 0x50, 0x28, 0x28, 0x25,
-  0x35, 0x39, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x93, 0x51, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x37, 0x21,
-  0x35, 0x35, 0x22, 0x27, 0x35, 0x35, 0x35, 0x35,
-  0x2D, 0x34, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x22, 0x25, 0x2B, 0x33, 0x35, 0x2F, 0x21,
-  0x23, 0x42, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x46, 0x91, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x8C, 0x35,
-  0x35, 0x35, 0x35, 0x31, 0x35, 0x35, 0x35, 0x35,
-  0x29, 0x2D, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x21, 0x23, 0x29, 0x50, 0x25, 0x21, 0x29, 0x35,
-  0x2D, 0x93, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x91, 0x91, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x90, 0x35,
-  0x35, 0x35, 0x35, 0x31, 0x35, 0x35, 0x35, 0x35,
-  0x22, 0x2E, 0x2F, 0x22, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x22, 0x25, 0x2B, 0x33, 0x35, 0x24, 0x28, 0x35,
-  0x53, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x4B, 0x91, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x92, 0x35,
-  0x35, 0x35, 0x35, 0x2F, 0x35, 0x35, 0x35, 0x35,
-  0x21, 0x2E, 0x31, 0x23, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-  0x28, 0x31, 0x2E, 0x28, 0x35, 0x27, 0x22, 0x21,
-  0x42, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x4B, 0x91, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x4A, 0x21,
-  0x35, 0x35, 0x21, 0x26, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x33, 0x2A, 0x28, 0x21, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-  0x25, 0x2B, 0x38, 0x35, 0x35, 0x2F, 0x22, 0x25,
-  0x51, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x4E, 0x51, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x4E, 0x21,
-  0x35, 0x35, 0x22, 0x26, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x2B, 0x34, 0x24, 0x21, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-  0x2F, 0x2C, 0x21, 0x35, 0x35, 0x31, 0x23, 0x29,
-  0x46, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x4E, 0x91, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x4B, 0x22,
-  0x35, 0x35, 0x24, 0x23, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x2B, 0x38, 0x24, 0x21, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-  0x32, 0x2D, 0x35, 0x35, 0x23, 0x30, 0x27, 0x38,
-  0x93, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x4E, 0x46, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x4B, 0x23,
-  0x35, 0x35, 0x26, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x2B, 0x38, 0x24, 0x21, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-  0x2A, 0x38, 0x35, 0x35, 0x35, 0x26, 0x31, 0x30,
-  0x93, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x4E, 0x46, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x45, 0x22,
-  0x35, 0x21, 0x26, 0x35, 0x35, 0x35, 0x35, 0x35,
-  0x35, 0x2B, 0x34, 0x24, 0x21, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-  0x34, 0x38, 0x35, 0x35, 0x35, 0x35, 0x26, 0x2C,
-  0x93, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x4E, 0x46, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x92, 0x35,
-  0x24, 0x27, 0x96, 0x24, 0x25, 0x28, 0x21, 0x35,
-  0x35, 0x33, 0x2A, 0x28, 0x21, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
-  0x38, 0x4C, 0x97, 0x7D, 0x7A, 0x56, 0x21, 0x38,
-  0x51, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x4E, 0x46, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x52, 0x28,
-  0x23, 0x35, 0x35, 0x35, 0x21, 0x28, 0x2B, 0x2F,
-  0x21, 0x37, 0x32, 0x28, 0x21, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x2F,
-  0x2C, 0x98, 0x74, 0x5B, 0x99, 0x99, 0x78, 0x22,
-  0x50, 0x51, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x4E, 0x93, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x9A, 0x9B, 0x9B, 0x89, 0x60,
-  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x2F, 0x31,
-  0x25, 0x4C, 0x2A, 0x28, 0x21, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x21, 0x23, 0x24, 0x26, 0x2F, 0x32, 0x30,
-  0x4C, 0x89, 0x5A, 0x5B, 0x99, 0x99, 0x99, 0x59,
-  0x21, 0x2D, 0x45, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x4E, 0x93, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x9C, 0x9D, 0x68, 0x65, 0x9E,
-  0x35, 0x35, 0x35, 0x35, 0x35, 0x21, 0x26, 0x25,
-  0x7C, 0x9F, 0x2B, 0x25, 0x21, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x21, 0x28, 0x2F, 0x34, 0x2C, 0x2E, 0x36, 0x49,
-  0x5F, 0x7E, 0xA0, 0xA1, 0x99, 0x99, 0x99, 0x7B,
-  0x57, 0x35, 0x31, 0x3E, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x4B, 0x91, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0xA2, 0x5B, 0x9D, 0x7A, 0x28,
-  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x21, 0x56,
-  0x66, 0x65, 0x33, 0x27, 0x22, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x23, 0x2F, 0x30, 0x8E, 0x89, 0x71, 0x88, 0x88,
-  0x83, 0x5A, 0x5B, 0x99, 0x99, 0x99, 0x99, 0x99,
-  0x5C, 0xA3, 0x35, 0x24, 0x52, 0x93, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x93, 0x91, 0xA2, 0x63, 0x5B, 0x83, 0xA3,
-  0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x58, 0x5C,
-  0x7B, 0x5B, 0xA4, 0x29, 0x23, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-  0x24, 0x2A, 0x8E, 0x83, 0x5A, 0x5C, 0x5A, 0x5A,
-  0x75, 0x5B, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-  0x9D, 0x5D, 0x22, 0x35, 0x21, 0x39, 0x91, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x4E, 0x3E, 0xA5, 0x75, 0x75, 0x7E, 0x79,
-  0x96, 0x35, 0x35, 0x35, 0x21, 0xA6, 0x71, 0x75,
-  0x63, 0x63, 0xA7, 0x34, 0x24, 0x21, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-  0x26, 0x30, 0xA8, 0x5A, 0x63, 0x5B, 0x5B, 0xA1,
-  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-  0x99, 0x65, 0xA9, 0x35, 0x35, 0x35, 0x2B, 0x4A,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x92, 0x3E, 0xAA, 0x5C, 0x5C, 0x74, 0x62,
-  0xAB, 0xAC, 0x57, 0xAC, 0xAD, 0x88, 0x5A, 0x63,
-  0x5B, 0x5B, 0xAE, 0x2C, 0x27, 0x23, 0x21, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-  0x26, 0x2C, 0x89, 0x5A, 0x63, 0x99, 0x99, 0x99,
-  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-  0x99, 0x9D, 0x7C, 0x28, 0x35, 0x35, 0x35, 0x2F,
-  0x43, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x93, 0x92, 0x3E, 0xAA, 0x5A, 0x75, 0xAF, 0x7E,
-  0x71, 0x88, 0x62, 0x88, 0x7E, 0x5A, 0x5B, 0x99,
-  0x99, 0xA1, 0x5C, 0xA7, 0x38, 0x26, 0x23, 0x21,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-  0x26, 0x2C, 0xB0, 0xAF, 0x63, 0x99, 0x99, 0x99,
-  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-  0x99, 0x99, 0x9D, 0x80, 0x35, 0x35, 0x35, 0x35,
-  0x2C, 0x93, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x93, 0x44, 0x3E, 0xB1, 0x6C, 0x75, 0xA0, 0xAF,
-  0x74, 0x83, 0x83, 0x74, 0x5A, 0x63, 0x99, 0x99,
-  0x99, 0x99, 0x5B, 0xB2, 0x36, 0x34, 0x26, 0x23,
-  0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x2E, 0x53,
-  0x4D, 0x41, 0xB3, 0xB4, 0x9A, 0x9A, 0x9A, 0x9A,
-  0x9B, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-  0x99, 0x99, 0x9D, 0x6F, 0x58, 0x35, 0x21, 0x35,
-  0x24, 0x51, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x45, 0x41, 0xA8, 0x74, 0x75, 0x63, 0x75,
-  0x5C, 0x5A, 0x5A, 0x5C, 0x75, 0x5B, 0x99, 0x99,
-  0x99, 0x9D, 0x9A, 0x9A, 0xB3, 0x41, 0x94, 0x2F,
-  0x25, 0x49, 0x3A, 0x3A, 0x3A, 0x40, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x23, 0x3C, 0x46, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x9A, 0x9B, 0x9D, 0x9D, 0x9D, 0x9D, 0x99, 0x99,
-  0x99, 0x9D, 0x9D, 0x66, 0xB2, 0x28, 0x24, 0x26,
-  0x30, 0x46, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
-  0x47, 0x4E, 0x39, 0x8F, 0x6C, 0x75, 0x5B, 0x99,
-  0x65, 0x99, 0x99, 0x65, 0x99, 0x67, 0x9B, 0x67,
-  0x9D, 0x9A, 0x47, 0x47, 0x47, 0xB5, 0xB6, 0x94,
-  0x3D, 0x91, 0x93, 0x47, 0x93, 0x3A, 0x40, 0x20,
-  0x20, 0x20, 0xB7, 0x96, 0x53, 0x91, 0xB8, 0xB9,
-  0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9,
-  0xB8, 0x72, 0x46, 0x46, 0x46, 0x46, 0x9B, 0x99,
-  0x9A, 0x46, 0x46, 0x46, 0x9A, 0x80, 0x90, 0x91,
-  0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0x47, 0xB5,
-  0xB5, 0xB5, 0x46, 0xB5, 0x47, 0xB5, 0xB5, 0x47,
-  0x47, 0xB5, 0x91, 0x51, 0x9B, 0x75, 0x5B, 0x9A,
-  0x46, 0x46, 0x46, 0x9A, 0x9A, 0x46, 0xB5, 0x9A,
-  0x9A, 0x9A, 0xB9, 0xB9, 0xB9, 0xB9, 0x69, 0x69,
-  0x4B, 0xBA, 0xB9, 0xB9, 0xB9, 0xB8, 0x3A, 0x40,
-  0x20, 0x20, 0x22, 0x53, 0x91, 0xB9, 0xBB, 0xBB,
-  0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-  0xB8, 0x46, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
-  0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x51, 0x9A,
-  0x9A, 0x9A, 0x9A, 0x46, 0xB4, 0x69, 0x69, 0xB3,
-  0x46, 0x46, 0x46, 0xB5, 0x46, 0xB3, 0x69, 0x69,
-  0xB8, 0x69, 0xB3, 0x9A, 0x46, 0x9B, 0x9A, 0x9A,
-  0x9A, 0x9A, 0x9A, 0x9A, 0x46, 0xB3, 0xB8, 0xB3,
-  0x46, 0xB8, 0xBB, 0xBB, 0xBB, 0xBB, 0x69, 0x46,
-  0xB4, 0xBC, 0xBB, 0xBB, 0xBB, 0xBA, 0x93, 0x49,
-  0x20, 0x20, 0x50, 0x46, 0xB8, 0xBB, 0xBB, 0xBB,
-  0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC,
-  0xB3, 0xB3, 0xBC, 0xBC, 0xBC, 0xBC, 0xB8, 0xB5,
-  0xB9, 0xBC, 0xBC, 0xBC, 0xB9, 0x46, 0xB9, 0xBC,
-  0xBC, 0xBC, 0xB9, 0xB9, 0xBC, 0xBB, 0xBB, 0xBC,
-  0xBA, 0x46, 0xB5, 0xB3, 0xBD, 0xBC, 0xBB, 0xBB,
-  0xBB, 0xBB, 0xBB, 0xBC, 0xB9, 0x91, 0x46, 0xB9,
-  0xBC, 0xBC, 0xBC, 0xB9, 0xB9, 0xBB, 0xBB, 0xBD,
-  0x46, 0xB9, 0xBB, 0xBB, 0xBB, 0xBC, 0x9A, 0xB5,
-  0xB8, 0xBB, 0xBB, 0xBB, 0xBB, 0x69, 0x46, 0x34,
-  0x20, 0x21, 0x90, 0xB5, 0xBD, 0xBB, 0xBB, 0xBB,
-  0xBB, 0xB9, 0xB8, 0xB8, 0xB8, 0xBA, 0xB9, 0xB9,
-  0x46, 0xBA, 0xBB, 0xBB, 0xBB, 0xBC, 0x51, 0x9A,
-  0xBC, 0xBB, 0xBB, 0xBB, 0xB8, 0x9A, 0xBC, 0xBB,
-  0xBB, 0xBB, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-  0xBC, 0x46, 0xB4, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB,
-  0xBC, 0xBC, 0xBB, 0xBB, 0xBB, 0xB8, 0x9A, 0xBC,
-  0xBB, 0xBB, 0xBB, 0xBD, 0xBB, 0xBB, 0xBB, 0xBA,
-  0x46, 0xBC, 0xBB, 0xBB, 0xBB, 0xB9, 0x46, 0x46,
-  0xB9, 0xBB, 0xBB, 0xBB, 0xBC, 0x91, 0x44, 0x23,
-  0x20, 0x21, 0x42, 0xB5, 0xBD, 0xBB, 0xBB, 0xBB,
-  0xBB, 0xB9, 0xB8, 0xB8, 0xB8, 0xB8, 0x51, 0x46,
-  0x46, 0xBD, 0xBB, 0xBB, 0xBB, 0xB9, 0x46, 0xB8,
-  0xBB, 0xBB, 0xBB, 0xBB, 0x9A, 0xB8, 0xBB, 0xBB,
-  0xBB, 0xBB, 0xBC, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB,
-  0xBB, 0x46, 0xB9, 0xBB, 0xBB, 0xBB, 0xBC, 0x69,
-  0x91, 0xB8, 0xBB, 0xBB, 0xBB, 0xB9, 0xB8, 0xBB,
-  0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x69,
-  0xB3, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xBC, 0xBC,
-  0xBB, 0xBB, 0xBB, 0xBB, 0xB9, 0x47, 0x52, 0x20,
-  0x20, 0x22, 0x41, 0x46, 0xBD, 0xBB, 0xBB, 0xBB,
-  0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBD, 0xB5,
-  0x9A, 0xBC, 0xBB, 0xBB, 0xBB, 0xB8, 0xB5, 0xB9,
-  0xBB, 0xBB, 0xBB, 0xBD, 0xB5, 0xB9, 0xBB, 0xBB,
-  0xBB, 0xBC, 0x69, 0xB3, 0xBD, 0xBB, 0xBB, 0xBB,
-  0xBD, 0xB4, 0xBC, 0xBB, 0xBB, 0xBB, 0xBC, 0xBD,
-  0xBD, 0xBD, 0xBB, 0xBB, 0xBB, 0xB8, 0xB9, 0xBB,
-  0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0x46,
-  0xBA, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-  0xBB, 0xBB, 0xBB, 0xBB, 0xB8, 0xB5, 0x50, 0x20,
-  0x20, 0x21, 0x32, 0x92, 0xB3, 0xB9, 0xBD, 0xBC,
-  0xBC, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x51,
-  0xB8, 0xBB, 0xBB, 0xBB, 0xBC, 0xB3, 0x51, 0xBC,
-  0xBB, 0xBB, 0xBB, 0xBA, 0x51, 0xBD, 0xBB, 0xBB,
-  0xBB, 0xB8, 0x46, 0x46, 0xBD, 0xBB, 0xBB, 0xBB,
-  0xB9, 0xB8, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-  0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xB3, 0xBD, 0xBB,
-  0xBB, 0xBB, 0xBC, 0xB9, 0xB8, 0xB8, 0xB8, 0x46,
-  0xBD, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xBC, 0xBB,
-  0xBB, 0xBB, 0xBB, 0xBB, 0x9A, 0x91, 0x25, 0x20,
-  0x21, 0x32, 0x92, 0xB3, 0xB4, 0xB4, 0xB4, 0x9A,
-  0x9A, 0xB8, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0x46,
-  0xB9, 0xBB, 0xBB, 0xBB, 0xBC, 0xB4, 0xB8, 0xBB,
-  0xBB, 0xBB, 0xBB, 0x69, 0x69, 0xBB, 0xBB, 0xBB,
-  0xBB, 0xB8, 0x9A, 0xB8, 0xBB, 0xBB, 0xBB, 0xBB,
-  0xB8, 0xBA, 0xBB, 0xBB, 0xBB, 0xBC, 0x69, 0xB4,
-  0xB4, 0xB4, 0xB3, 0x69, 0xB3, 0xB4, 0xBB, 0xBB,
-  0xBB, 0xBB, 0xBA, 0x46, 0xB5, 0xB5, 0x91, 0xB4,
-  0xBC, 0xBB, 0xBB, 0xBB, 0xB9, 0x91, 0x51, 0xBD,
-  0xBB, 0xBB, 0xBB, 0xBD, 0x46, 0x3F, 0x21, 0x20,
-  0x24, 0x42, 0x9A, 0xBD, 0xBC, 0xBC, 0xBC, 0xBC,
-  0xBC, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB, 0xB9, 0x46,
-  0xBD, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xBC, 0xBB,
-  0xBB, 0xBB, 0xBD, 0x91, 0xBA, 0xBB, 0xBB, 0xBB,
-  0xBB, 0xBC, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBD,
-  0x51, 0xBA, 0xBB, 0xBB, 0xBB, 0xBB, 0xBD, 0xB9,
-  0xB9, 0xB9, 0xBD, 0xBD, 0x46, 0xB8, 0xBB, 0xBB,
-  0xBB, 0xBC, 0xB4, 0x46, 0xA5, 0x85, 0x46, 0xB8,
-  0xBB, 0xBB, 0xBB, 0xBB, 0x69, 0x91, 0x9A, 0xBC,
-  0xBB, 0xBB, 0xBB, 0xBA, 0xB5, 0xBE, 0x21, 0x20,
-  0x50, 0x46, 0xB8, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-  0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0xB3, 0x46,
-  0xB9, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-  0xBB, 0xBD, 0xB3, 0xB5, 0xBD, 0xBB, 0xBB, 0xBB,
-  0xBD, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBC, 0x69,
-  0x51, 0xB3, 0xBC, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
-  0xBB, 0xBB, 0xBB, 0xB8, 0xB5, 0xB9, 0xBB, 0xBB,
-  0xBB, 0xBD, 0x46, 0xB4, 0x80, 0x3E, 0xB5, 0xB9,
-  0xBB, 0xBB, 0xBB, 0xBC, 0x9A, 0xB5, 0xB8, 0xBB,
-  0xBB, 0xBB, 0xBB, 0x69, 0x91, 0x38, 0x21, 0x20,
-  0x34, 0x49, 0x69, 0xBA, 0xB9, 0xB9, 0xBD, 0xBD,
-  0xBD, 0xBD, 0xBD, 0xB9, 0xBA, 0x9A, 0x44, 0x8C,
-  0x91, 0xB8, 0xB9, 0xBD, 0xBD, 0xBD, 0xBD, 0xB9,
-  0xB8, 0x9A, 0x46, 0x9A, 0xBC, 0xBB, 0xBB, 0xBB,
-  0xB8, 0x69, 0xB9, 0xBD, 0xBD, 0xB9, 0xB3, 0x4E,
-  0x50, 0xB4, 0xB3, 0xB9, 0xB9, 0xBD, 0xBD, 0xBD,
-  0xB9, 0xB9, 0xB8, 0x51, 0x69, 0xB8, 0xBA, 0xB9,
-  0xB9, 0xB8, 0xB4, 0x9F, 0x36, 0x8C, 0x4D, 0xB8,
-  0xB9, 0xB9, 0xB9, 0xB8, 0x43, 0x54, 0xB8, 0xB9,
-  0xB9, 0xB9, 0xBA, 0x9A, 0x39, 0x96, 0x21, 0x20,
-  0x20, 0x34, 0x39, 0x91, 0x47, 0x93, 0x46, 0x46,
-  0x46, 0x46, 0x46, 0xB5, 0xB5, 0x44, 0x32, 0x28,
-  0x3A, 0x46, 0xB5, 0x46, 0x46, 0x46, 0x46, 0xB5,
-  0xB5, 0xB4, 0xB5, 0xB8, 0xBB, 0xBB, 0xBB, 0xBC,
-  0xB4, 0x51, 0xB5, 0x91, 0xB5, 0xB5, 0x4E, 0x2D,
-  0x28, 0x38, 0x45, 0x47, 0xB5, 0x46, 0x46, 0xB5,
-  0xB5, 0xB5, 0x93, 0x53, 0xAE, 0xB6, 0xB5, 0xB5,
-  0xB5, 0xB3, 0x98, 0x2E, 0x34, 0x27, 0x49, 0x3B,
-  0xB5, 0x47, 0x93, 0x4A, 0x40, 0x2C, 0x54, 0x47,
-  0x47, 0x47, 0x46, 0x39, 0x96, 0xB7, 0x20, 0x20,
-  0x20, 0x20, 0x34, 0x49, 0x53, 0x4D, 0x90, 0x4F,
-  0x8B, 0x8B, 0x4F, 0x4D, 0x39, 0x26, 0x21, 0x21,
-  0x22, 0x2E, 0x53, 0x90, 0x8B, 0x8B, 0x4F, 0x48,
-  0x3D, 0x8C, 0x4F, 0xB8, 0xB9, 0xB9, 0xB9, 0xB9,
-  0x4B, 0x3A, 0x95, 0x3E, 0x4F, 0x3A, 0x29, 0x21,
-  0xB7, 0x21, 0x32, 0x3A, 0x48, 0x3E, 0x3E, 0x90,
-  0x3B, 0x3A, 0x40, 0x30, 0xBF, 0x52, 0x8D, 0x4D,
-  0x48, 0x3A, 0x2D, 0x32, 0x25, 0x23, 0x22, 0x39,
-  0x54, 0x54, 0x54, 0x40, 0x21, 0xB7, 0x2C, 0x54,
-  0x54, 0x54, 0x39, 0x96, 0xB7, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21,
-  0x22, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20, 0x21,
-  0x21, 0x21, 0x21, 0x21, 0x23, 0x23, 0x24, 0x24,
-  0x27, 0x29, 0x49, 0x48, 0x47, 0x47, 0x47, 0x51,
-  0x3A, 0x21, 0x21, 0x22, 0x21, 0x20, 0x20, 0x21,
-  0x21, 0x21, 0x21, 0x20, 0x21, 0x22, 0x22, 0x21,
-  0x20, 0x21, 0x23, 0x26, 0x29, 0x2A, 0x38, 0x38,
-  0x2A, 0x29, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x21, 0x20, 0x21, 0x20, 0x20, 0x20, 0x20, 0x22,
-  0x22, 0x22, 0x23, 0x4C, 0x3B, 0x4D, 0x95, 0x3A,
-  0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x21, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x21, 0x28, 0x24, 0x24, 0x24,
-  0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
-};
-
-
-unsigned char linux_logo_bw[] __initdata = {
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xCF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFC, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
-  0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
-  0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFD, 0xFF, 0xF3, 0xDF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xF7, 0xEF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF,
-  0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
-  0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFB, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xF7, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF,
-  0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
-  0x9F, 0x87, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFB, 0x0F, 0x03, 0xFB, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFB, 0x67, 0x33, 0xFB, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xE7, 0x79,
-  0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
-  0xF7, 0x79, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFB, 0xFF, 0xF9, 0xF7, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFB, 0x60, 0x3B, 0xF7, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0x89, 0x07,
-  0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
-  0x00, 0x03, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFB, 0x00, 0x0D, 0xFB, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFB, 0x80, 0x33, 0xFD, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xC0, 0xC3,
-  0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
-  0xFF, 0x0D, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFB, 0x40, 0x31, 0xEE, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xF7, 0x20, 0xC1, 0xEE, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x1F, 0x00,
-  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF,
-  0x00, 0x00, 0x7F, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xEE, 0x00, 0x00, 0x7F, 0xBF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xDE, 0x00, 0x00, 0x7F, 0xDF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0x00, 0x00,
-  0x3F, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7C,
-  0x00, 0x00, 0x3F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0x7C, 0x00, 0x00, 0x1F, 0xF7, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFE, 0xFF, 0x1C, 0x07, 0xDF, 0xFB,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFC, 0x08, 0x0F,
-  0xEF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xF8,
-  0x00, 0x01, 0xEF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFB, 0xF0, 0x00, 0x00, 0x7F, 0xFE, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFB, 0xE0, 0x00, 0x00, 0x1F, 0xFE,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xE0, 0x00, 0x00,
-  0x07, 0xBF, 0x7F, 0xFF, 0xFF, 0xFF, 0xF7, 0xC0,
-  0x00, 0x00, 0x03, 0xBF, 0x7F, 0xFF, 0xFF, 0xFF,
-  0xEF, 0xC0, 0x00, 0x00, 0x03, 0xDF, 0xBF, 0xFF,
-  0xFF, 0xFF, 0xEF, 0x80, 0x00, 0x00, 0x03, 0xDF,
-  0xBF, 0xFF, 0xFF, 0xFF, 0xDF, 0x80, 0x00, 0x00,
-  0x03, 0xDF, 0xBF, 0xFF, 0xFF, 0xFF, 0xDF, 0x80,
-  0x00, 0x00, 0x01, 0xEF, 0xDF, 0xFF, 0xFF, 0xFF,
-  0xDF, 0x80, 0x00, 0x00, 0x01, 0xEF, 0xDF, 0xFF,
-  0xFF, 0xFF, 0xBF, 0x00, 0x20, 0x00, 0x01, 0xEF,
-  0xDF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0x20, 0x00,
-  0x01, 0xEF, 0xDF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00,
-  0x20, 0x00, 0x01, 0xEF, 0xDF, 0xFF, 0xFF, 0xFF,
-  0xBF, 0x00, 0x20, 0x00, 0x01, 0xEF, 0xDF, 0xFF,
-  0xFF, 0xFF, 0xBF, 0x00, 0x20, 0x00, 0x03, 0x03,
-  0xDF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0x20, 0x00,
-  0x02, 0xFD, 0xDF, 0xFF, 0xFF, 0xFF, 0xA3, 0x80,
-  0x00, 0x00, 0x1F, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF,
-  0xC1, 0xC0, 0x00, 0x00, 0x11, 0xFF, 0x3F, 0xFF,
-  0xFF, 0xFF, 0x80, 0xE0, 0x00, 0x00, 0x21, 0xFE,
-  0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x70, 0x00, 0x00,
-  0x21, 0xFC, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, 0x3C,
-  0x00, 0x00, 0x20, 0xF8, 0x3F, 0xFF, 0xFF, 0xF0,
-  0x00, 0x3E, 0x00, 0x00, 0x20, 0x00, 0x3F, 0xFF,
-  0xFF, 0xC0, 0x00, 0x1F, 0x00, 0x00, 0x20, 0x00,
-  0x3F, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0x80, 0x00,
-  0x20, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x0F,
-  0x80, 0x00, 0x20, 0x00, 0x07, 0xFF, 0xFE, 0x00,
-  0x00, 0x07, 0x80, 0x00, 0x20, 0x00, 0x03, 0x87,
-  0xF8, 0x00, 0x00, 0x07, 0x80, 0x00, 0x60, 0x00,
-  0x01, 0x01, 0xF1, 0xFF, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x3C, 0x7D, 0xE7, 0xFF, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x3C, 0x7C, 0xE7, 0xFF,
-  0x3E, 0x7B, 0xBE, 0x0F, 0xE1, 0xCF, 0x7C, 0x79,
-  0xCF, 0x80, 0x3E, 0x7B, 0xFF, 0x9F, 0xF9, 0xFF,
-  0x78, 0xF9, 0xCF, 0xF8, 0x7C, 0x73, 0xFF, 0xBE,
-  0x79, 0xFE, 0x7F, 0xF9, 0xCF, 0xFC, 0x7C, 0xF7,
-  0xC7, 0xBF, 0xFB, 0xFE, 0xFF, 0xF3, 0xE7, 0xFE,
-  0x78, 0xF7, 0x87, 0xBF, 0xFB, 0xF0, 0xFF, 0xF3,
-  0xC0, 0x3E, 0xF9, 0xE7, 0x8F, 0x7C, 0x03, 0xC0,
-  0xF8, 0xF3, 0x9F, 0xFE, 0xFF, 0xEF, 0xFF, 0x7F,
-  0xF3, 0xC4, 0xF1, 0xF3, 0x9F, 0xFC, 0x7F, 0xCF,
-  0xFE, 0x3F, 0xF7, 0xC9, 0xF1, 0xE7, 0x9F, 0xF8,
-  0x3F, 0x0F, 0x3C, 0x9F, 0xC7, 0x99, 0xF1, 0xE7,
-  0xC0, 0x03, 0x00, 0x1E, 0x01, 0xC0, 0x00, 0x3C,
-  0x04, 0x0F, 0xE0, 0x07, 0xC0, 0xDE, 0x03, 0xE0,
-  0x38, 0x7E, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xC0,
-  0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-};
-
-
-unsigned char linux_logo16[] __initdata = {
-  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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x88, 0x88, 0x88, 0x80, 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, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x88, 0x80, 0x00, 0x00, 0x08, 0x88, 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,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
-  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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-  0x80, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x88, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00,
-  0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80,
-  0x00, 0x80, 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, 0x00, 0x00, 0x00, 0x00, 0x80,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-  0x00, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x80,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x08, 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, 0x00, 0x00, 0x00, 0x08, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x08, 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, 0x00, 0x00, 0x00, 0x08, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-  0x08, 0x70, 0x00, 0x00, 0x00, 0x77, 0x70, 0x00,
-  0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-  0x87, 0x77, 0x00, 0x00, 0x07, 0xFF, 0xF7, 0x00,
-  0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x08,
-  0x77, 0xFF, 0x00, 0x00, 0x7F, 0x77, 0xF7, 0x00,
-  0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x08,
-  0x70, 0x0F, 0x80, 0x00, 0xF7, 0x08, 0x7F, 0x70,
-  0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x08,
-  0x80, 0x07, 0x80, 0x00, 0xF8, 0x00, 0x8F, 0x70,
-  0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x08,
-  0x70, 0x07, 0x88, 0x88, 0xF8, 0x00, 0x8F, 0x70,
-  0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-  0xF0, 0x06, 0xE6, 0xE6, 0xE6, 0x00, 0x8F, 0x00,
-  0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-  0x77, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x77, 0x00,
-  0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-  0x06, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0x00,
-  0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-  0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x60,
-  0x00, 0x00, 0x08, 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, 0x00, 0x00, 0x08, 0x80,
-  0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0x60,
-  0x00, 0x00, 0x08, 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, 0x00, 0x00, 0x08, 0x80,
-  0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x66, 0x66, 0x80,
-  0x08, 0x00, 0x00, 0x80, 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, 0x00, 0x08, 0x80,
-  0x86, 0xE6, 0xE6, 0xE6, 0x66, 0x66, 0x66, 0x80,
-  0x08, 0x78, 0x00, 0x80, 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, 0x00, 0x08, 0x80,
-  0x86, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x70,
-  0x00, 0x77, 0x00, 0x08, 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, 0x00, 0x08, 0x00,
-  0x87, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x78,
-  0x00, 0x88, 0x00, 0x08, 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, 0x00, 0x08, 0x00,
-  0x87, 0x76, 0x66, 0x66, 0x77, 0x77, 0xFF, 0xF7,
-  0x00, 0x00, 0x00, 0x08, 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, 0x00, 0x80, 0x08,
-  0xFF, 0x77, 0x77, 0x77, 0x77, 0xFF, 0xFF, 0xFF,
-  0x80, 0x00, 0x00, 0x00, 0x80, 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, 0x80, 0x07,
-  0xFF, 0x77, 0x77, 0x77, 0x7F, 0xFF, 0xFF, 0xFF,
-  0x70, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x8F,
-  0xFF, 0xF7, 0x77, 0x77, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x7F,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF7, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x87, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x77,
-  0xFF, 0xF7, 0x77, 0xFF, 0xFF, 0xFF, 0x77, 0x77,
-  0x77, 0x78, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x7F,
-  0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x77,
-  0x77, 0x78, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x7F, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF7, 0x77, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x80, 0x80, 0x08, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0x77, 0x80, 0x00, 0x08, 0x00, 0x00, 0x08,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0x78, 0x00, 0x08, 0x80, 0x00, 0x08,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x08, 0x08, 0x00, 0x8F, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xF7, 0x08, 0x80, 0x80, 0x00, 0x08,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x08, 0x08, 0x08, 0x7F, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xF7, 0x08, 0x80, 0x80, 0x00, 0x00,
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x80, 0x08, 0x07, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x08, 0x00, 0x00,
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x80, 0x80, 0x0F, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x08, 0x00, 0x00,
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x08, 0x00, 0x80, 0x8F, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x08, 0x00, 0x00,
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x08, 0x08, 0x00, 0x7F, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0x70, 0x00, 0x08, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x80, 0x08, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x08, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x08, 0x00, 0x08, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x08, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x08, 0x00, 0x08, 0x08, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x08, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x08, 0x00, 0x08, 0x08, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x08, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x88, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x08, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x08, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xF0, 0x88, 0x88, 0x80, 0x00,
-  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x08, 0x06, 0xE6, 0x00, 0x8F, 0xFF, 0xFF, 0xFF,
-  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x08, 0x80,
-  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x6E, 0x6E, 0x60, 0x08, 0xFF, 0xFF, 0xFF,
-  0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xE6, 0xE0, 0x00, 0x00, 0x00, 0x88,
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x06, 0xE6, 0xE6, 0xE6, 0x00, 0x8F, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFE, 0x6E, 0x60, 0x00, 0x00, 0x00, 0x00,
-  0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x6E, 0x6E, 0x6E, 0x6E, 0x60, 0x08, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xF6, 0xE6, 0xE0, 0x00, 0x00, 0x00, 0x06,
-  0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xE6, 0xE6,
-  0xE6, 0xE6, 0xE6, 0xE6, 0xE0, 0x00, 0x8F, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFE, 0x6E, 0x60, 0x00, 0x00, 0x00, 0x0E,
-  0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x6E, 0x6E,
-  0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x00, 0x08, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0x76, 0xE6, 0xE6, 0x00, 0x00, 0x00, 0xE6,
-  0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xE6, 0xE6,
-  0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE0, 0x00, 0x8F,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF7, 0x7E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E,
-  0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x6E, 0x6E,
-  0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x60, 0x00, 0x08,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF7, 0x76, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
-  0xE6, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xE6, 0xE6,
-  0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0x00, 0x00,
-  0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF7, 0x7E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E,
-  0x6E, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x87, 0x77, 0x7F, 0x7F, 0x7E,
-  0x7E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x60, 0x00,
-  0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF7, 0x76, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
-  0xE6, 0xF7, 0xE7, 0x80, 0x08, 0x78, 0x78, 0x00,
-  0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE0, 0x00,
-  0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xF7, 0x7E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x7E,
-  0x6F, 0xFF, 0xFF, 0x88, 0x8F, 0xFF, 0xF7, 0x80,
-  0x00, 0x00, 0x7F, 0x7C, 0xCC, 0xCC, 0xCC, 0xCC,
-  0x7E, 0xFF, 0xFF, 0x7E, 0x7F, 0xFF, 0x7E, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xF6, 0xE7, 0xFF, 0xF7, 0xEF, 0xFF,
-  0xEF, 0xCC, 0xCC, 0x77, 0xF7, 0xCC, 0xC7, 0x78,
-  0x00, 0x07, 0xFC, 0x44, 0x44, 0x44, 0x44, 0x44,
-  0x7F, 0x7F, 0xF7, 0xF7, 0xFF, 0xFF, 0xF7, 0xFF,
-  0xF7, 0xFF, 0xF7, 0x7F, 0xFF, 0xFF, 0xF7, 0x77,
-  0x77, 0x7F, 0xFE, 0x7F, 0xFF, 0xFF, 0xF7, 0x77,
-  0xF7, 0x4C, 0x4C, 0x7F, 0x74, 0x44, 0x4C, 0xF8,
-  0x00, 0x8F, 0x74, 0x44, 0x44, 0x44, 0x44, 0x44,
-  0x7F, 0x44, 0x44, 0x7F, 0xC4, 0x44, 0xCF, 0xC4,
-  0x44, 0xCC, 0x44, 0x44, 0xCF, 0xF7, 0xC4, 0x44,
-  0x44, 0x44, 0xCF, 0xFC, 0x44, 0x4C, 0xC4, 0x4C,
-  0xFC, 0x44, 0x4C, 0xFF, 0x74, 0x44, 0xC7, 0xF8,
-  0x00, 0x7F, 0xC4, 0x44, 0x4C, 0x77, 0x7C, 0xC7,
-  0xFC, 0x44, 0x4C, 0xF7, 0x44, 0x44, 0x7F, 0x44,
-  0x44, 0xC4, 0x44, 0x44, 0x4F, 0xF4, 0x44, 0x44,
-  0xC4, 0x44, 0x47, 0xF4, 0x44, 0x4C, 0x44, 0x4C,
-  0xF4, 0x44, 0x4C, 0xFF, 0xC4, 0x44, 0x4F, 0xF0,
-  0x00, 0x7F, 0xC4, 0x44, 0x4C, 0xC7, 0x77, 0xFF,
-  0xFC, 0x44, 0x4C, 0xF7, 0x44, 0x44, 0xF7, 0x44,
-  0x44, 0x44, 0x44, 0x44, 0x4F, 0xC4, 0x44, 0x47,
-  0xF7, 0x44, 0x4C, 0x74, 0x44, 0x44, 0x44, 0x47,
-  0xF4, 0x44, 0x44, 0x44, 0x44, 0x44, 0xCF, 0x70,
-  0x00, 0x7F, 0xC4, 0x44, 0x44, 0x44, 0x44, 0xCF,
-  0xF4, 0x44, 0x4C, 0xFC, 0x44, 0x4C, 0xFC, 0x44,
-  0x4C, 0x7F, 0x44, 0x44, 0xC7, 0xC4, 0x44, 0xCC,
-  0xCC, 0x44, 0x47, 0xC4, 0x44, 0x44, 0x44, 0xCF,
-  0xC4, 0x44, 0x44, 0x44, 0x44, 0x44, 0x7F, 0x80,
-  0x00, 0x0F, 0x7C, 0xC4, 0xC4, 0x44, 0x44, 0x4F,
-  0x74, 0x44, 0xC7, 0xFC, 0x44, 0x4C, 0xFC, 0x44,
-  0x4C, 0xFF, 0xC4, 0x44, 0xC7, 0x44, 0x44, 0x44,
-  0x44, 0x44, 0x4F, 0xC4, 0x44, 0x4C, 0x7C, 0x7F,
-  0xC4, 0x44, 0x44, 0xC4, 0x44, 0x44, 0xFF, 0x00,
-  0x08, 0x77, 0xFF, 0x7F, 0xF7, 0x44, 0x44, 0x4F,
-  0xC4, 0x44, 0x4F, 0x74, 0x44, 0x47, 0x74, 0x44,
-  0x47, 0xFC, 0x44, 0x44, 0x7C, 0x44, 0x44, 0xF7,
-  0xFF, 0x7F, 0x7F, 0x44, 0x44, 0x7F, 0xFF, 0xF7,
-  0x44, 0x44, 0x7F, 0xFC, 0x44, 0x4C, 0xF7, 0x00,
-  0x0F, 0xFC, 0x44, 0x44, 0x44, 0x44, 0x44, 0xCF,
-  0xC4, 0x44, 0x44, 0x44, 0x44, 0xCF, 0xC4, 0x44,
-  0x44, 0xC4, 0x44, 0x4C, 0xF7, 0x44, 0x44, 0xCC,
-  0xCC, 0x4C, 0xF7, 0x44, 0x44, 0xFF, 0xC7, 0xF7,
-  0x44, 0x44, 0x77, 0xF4, 0x44, 0x4C, 0xF7, 0x00,
-  0x8F, 0xC4, 0x44, 0x44, 0x44, 0x44, 0x4C, 0x7F,
-  0xC4, 0x44, 0x44, 0x44, 0x4C, 0x7F, 0xC4, 0x44,
-  0xC4, 0x44, 0x44, 0x47, 0xF7, 0xC4, 0x44, 0x44,
-  0x44, 0x47, 0xFC, 0x44, 0x4C, 0xF7, 0x67, 0xFC,
-  0x44, 0x4C, 0xFF, 0x74, 0x44, 0x47, 0xF8, 0x00,
-  0x87, 0x77, 0xCC, 0xCC, 0xCC, 0xCC, 0xCF, 0x77,
-  0xF7, 0xCC, 0xCC, 0xCC, 0xCF, 0xFF, 0x44, 0x44,
-  0x77, 0xCC, 0xCC, 0x7F, 0x87, 0xFC, 0xCC, 0xCC,
-  0xCC, 0x7F, 0x7C, 0x7C, 0xC7, 0xE7, 0x08, 0x7C,
-  0x7C, 0xCC, 0xFC, 0x7C, 0x7C, 0x7F, 0x80, 0x00,
-  0x08, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
-  0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x44, 0x44,
-  0xFF, 0xFF, 0xFF, 0xF8, 0x08, 0x7F, 0xFF, 0xFF,
-  0xFF, 0xF8, 0x7E, 0xFF, 0xFF, 0xC0, 0x00, 0x77,
-  0xFF, 0xFF, 0x88, 0x7F, 0xFF, 0xF6, 0x00, 0x00,
-  0x00, 0x88, 0x77, 0x77, 0x77, 0x77, 0x80, 0x00,
-  0x08, 0x77, 0x77, 0x77, 0x88, 0x77, 0xCC, 0xCC,
-  0xF6, 0x77, 0x77, 0x00, 0x00, 0x07, 0x77, 0x77,
-  0x78, 0x60, 0x08, 0x87, 0x88, 0x00, 0x00, 0x08,
-  0x78, 0x78, 0x00, 0x88, 0x78, 0x70, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0xFF, 0xFF,
-  0x80, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x77, 0x77,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-
-#endif /* INCLUDE_LINUX_LOGO_DATA */
-
-#include <linux/linux_logo.h>
diff -Nru a/include/asm-sparc/linux_logo.h b/include/asm-sparc/linux_logo.h
--- a/include/asm-sparc/linux_logo.h	Mon Feb  4 23:41:05 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,934 +0,0 @@
-/* $Id: linux_logo.h,v 1.7 2001/06/08 23:01:58 davem Exp $
- * include/asm-sparc/linux_logo.h: This is a linux logo
- *                                 to be displayed on boot.
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * image size has to be 80x80
- * values have to start from 0x20
- * (i.e. RGB(linux_logo_red[0],
- *	     linux_logo_green[0],
- *	     linux_logo_blue[0]) is color 0x20)
- * BW image has to be 80x80 as well, with MS bit
- * on the left
- * Serial_console ascii image can be any size,
- * but should contain %s to display the version
- */
- 
-#include <linux/init.h>
-#include <linux/version.h>
-
-#define linux_logo_banner "Linux/SPARC version " UTS_RELEASE
-
-#define __HAVE_ARCH_LINUX_LOGO
-#define __HAVE_ARCH_LINUX_LOGO16
-
-#define LINUX_LOGO_COLORS	221
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-unsigned char linux_logo_red[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79,
-    0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
-    0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
-    0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
-    0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
-    0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c,
-    0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e,
-    0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c,
-    0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xfe,
-    0xf6, 0xec, 0xfe, 0xd2, 0xea, 0xf5, 0xf2, 0xf2,
-    0xe9, 0xee, 0xf6, 0xf2, 0xee, 0xf6, 0xda, 0xd4,
-    0xfa, 0xca, 0xf2, 0xf6, 0xfe, 0xf2, 0xda, 0xe4,
-    0xf6, 0xdd, 0xf2, 0xee, 0xfa, 0xf0, 0x12, 0x4a,
-    0xd6, 0xf2, 0x8e, 0xf2, 0xf6, 0xf6, 0xb5, 0xf1,
-    0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x16, 0x9a,
-    0x2e, 0xd2, 0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62,
-    0xda, 0xee, 0xd6, 0xa3, 0x74, 0xa7, 0xa2, 0xe0,
-    0xae, 0xbe, 0xce, 0xe2, 0xa3, 0x8e, 0x6d, 0x8e,
-    0x32, 0xaf, 0x50, 0x9e, 0x5b, 0x8a, 0x98, 0x82,
-    0x7a, 0x82, 0x56, 0x7c, 0x8a, 0x56, 0x5e, 0x86,
-    0x6a, 0x52, 0x59, 0x64, 0x5e,
-};
-
-unsigned char linux_logo_green[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c,
-    0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
-    0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
-    0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
-    0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
-    0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76,
-    0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46,
-    0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b,
-    0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xfa,
-    0xea, 0xd7, 0xf6, 0xbc, 0xda, 0xde, 0xda, 0xe6,
-    0xca, 0xd8, 0xea, 0xe0, 0xcc, 0xf2, 0xce, 0xb2,
-    0xee, 0xa2, 0xd6, 0xe6, 0xf6, 0xd7, 0xc5, 0xb8,
-    0xc6, 0xb9, 0xce, 0xde, 0xce, 0xc6, 0x0e, 0x36,
-    0xae, 0xbe, 0x86, 0xba, 0xbe, 0xe6, 0x8e, 0xc4,
-    0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x12, 0x7a,
-    0x20, 0xc6, 0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46,
-    0xce, 0xd6, 0xa6, 0x6e, 0x51, 0x72, 0x92, 0xa6,
-    0x87, 0x96, 0xa2, 0xd6, 0x85, 0x7a, 0x6a, 0x6e,
-    0x22, 0x76, 0x36, 0x76, 0x3c, 0x6e, 0x63, 0x53,
-    0x66, 0x62, 0x42, 0x50, 0x56, 0x42, 0x56, 0x56,
-    0x56, 0x3e, 0x51, 0x52, 0x56,
-};
-
-unsigned char linux_logo_blue[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08,
-    0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
-    0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
-    0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
-    0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
-    0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a,
-    0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e,
-    0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b,
-    0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xea,
-    0xb6, 0x7c, 0xda, 0x8e, 0xa6, 0x87, 0x66, 0xb6,
-    0x81, 0x6a, 0xc6, 0x9a, 0x5b, 0xd2, 0xb6, 0x6a,
-    0xca, 0x45, 0x92, 0xb2, 0xca, 0x52, 0x8a, 0x3e,
-    0x2e, 0x66, 0x66, 0xae, 0x3e, 0x47, 0x06, 0x0e,
-    0x52, 0x36, 0x6a, 0x0e, 0x0e, 0xbe, 0x2c, 0x0e,
-    0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x06, 0x2e,
-    0x06, 0x9e, 0x4e, 0x36, 0x06, 0x58, 0x24, 0x06,
-    0x9e, 0xae, 0x3a, 0x08, 0x08, 0x07, 0x5e, 0x0a,
-    0x32, 0x2e, 0x2a, 0xb2, 0x43, 0x48, 0x5f, 0x2e,
-    0x06, 0x06, 0x07, 0x24, 0x06, 0x32, 0x06, 0x06,
-    0x46, 0x2e, 0x22, 0x06, 0x06, 0x1e, 0x4c, 0x06,
-    0x3a, 0x22, 0x42, 0x34, 0x42,
-};
-
-unsigned char linux_logo[] __initdata = {
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
-    0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-    0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
-    0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
-    0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
-    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-    0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
-    0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-    0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
-    0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34,
-    0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
-    0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22,
-    0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25,
-    0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
-    0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
-    0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-    0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
-    0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-    0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36,
-    0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
-    0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21,
-    0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
-    0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
-    0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
-    0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32,
-    0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a,
-    0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b,
-    0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37,
-    0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
-    0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
-    0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
-    0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
-    0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67,
-    0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
-    0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
-    0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
-    0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78,
-    0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79,
-    0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c,
-    0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
-    0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
-    0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36,
-    0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
-    0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89,
-    0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36,
-    0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
-    0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e,
-    0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
-    0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22,
-    0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
-    0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c,
-    0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51,
-    0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
-    0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97,
-    0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98,
-    0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
-    0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32,
-    0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50,
-    0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
-    0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
-    0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98,
-    0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
-    0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
-    0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b,
-    0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48,
-    0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-    0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-    0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
-    0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
-    0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c,
-    0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c,
-    0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
-    0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93,
-    0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28,
-    0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
-    0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93,
-    0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
-    0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x99, 0x9f, 0x52, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
-    0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30,
-    0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c,
-    0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36,
-    0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48,
-    0x47, 0x9f, 0x48, 0x48, 0x48, 0xa0, 0xa1, 0xa2,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36,
-    0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
-    0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36,
-    0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
-    0xa3, 0xa4, 0x48, 0x48, 0x9f, 0xa5, 0xa6, 0x9f,
-    0x48, 0x48, 0x48, 0xa2, 0xa7, 0x47, 0x48, 0x48,
-    0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
-    0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d,
-    0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
-    0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0xa8, 0xa1, 0x48, 0x48, 0x9f, 0xa9, 0xa6, 0x9f,
-    0x48, 0x48, 0xaa, 0xa1, 0xa5, 0x9f, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30,
-    0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32,
-    0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a,
-    0x36, 0x24, 0x4f, 0x48, 0x52, 0x52, 0x48, 0x48,
-    0xab, 0xac, 0xa0, 0x48, 0xad, 0xa6, 0xa6, 0x9f,
-    0x48, 0xa2, 0xa9, 0xa6, 0xa2, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x47, 0x32, 0x30,
-    0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
-    0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25,
-    0x36, 0x3a, 0x48, 0x48, 0xae, 0xaf, 0x48, 0x48,
-    0xad, 0xac, 0xa1, 0x9f, 0xa2, 0xa9, 0xa9, 0xa2,
-    0x48, 0xab, 0x78, 0xa7, 0x48, 0x48, 0x48, 0x48,
-    0x9f, 0x48, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21,
-    0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36,
-    0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
-    0x23, 0x43, 0x48, 0x48, 0xb0, 0xb1, 0xb2, 0x9f,
-    0x48, 0xb3, 0xa5, 0xb3, 0xab, 0xa9, 0xa9, 0xb3,
-    0xb4, 0xa9, 0xb5, 0xb0, 0x48, 0x48, 0xa0, 0xa5,
-    0xa1, 0xad, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36,
-    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-    0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36,
-    0x2e, 0x9b, 0x48, 0x48, 0x48, 0xb6, 0xb7, 0xa4,
-    0xa2, 0xa7, 0xb5, 0x78, 0x6f, 0x6f, 0x6e, 0x6f,
-    0xa9, 0xb5, 0xab, 0x48, 0x9f, 0xab, 0xa9, 0xa1,
-    0xaa, 0x48, 0x48, 0x48, 0x48, 0x48, 0x98, 0x36,
-    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-    0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36,
-    0x54, 0x48, 0x48, 0x48, 0x48, 0xa2, 0xa8, 0xa1,
-    0xa5, 0xa6, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f,
-    0x6f, 0x78, 0xa5, 0xa0, 0xa0, 0x78, 0xa6, 0xa2,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
-    0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36,
-    0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
-    0x43, 0x48, 0x4b, 0xa2, 0x9f, 0x48, 0xa2, 0xa1,
-    0xb8, 0x6e, 0x6e, 0xb5, 0x78, 0x6f, 0x78, 0x78,
-    0x6e, 0x6f, 0x78, 0xb5, 0xa6, 0xa1, 0xa0, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4b, 0x21,
-    0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25,
-    0x52, 0x48, 0xa3, 0xb1, 0xb6, 0xb3, 0xaa, 0xac,
-    0x68, 0x68, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
-    0x78, 0x6f, 0x6f, 0xb5, 0xa6, 0xb4, 0x48, 0x9f,
-    0xb4, 0xb4, 0xa2, 0x9f, 0x48, 0x48, 0x4f, 0x21,
-    0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a,
-    0x47, 0x48, 0xa2, 0xb6, 0xaf, 0xb9, 0xba, 0x68,
-    0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x78,
-    0x6f, 0x6f, 0xa6, 0x6f, 0xb5, 0xa0, 0xaa, 0xa6,
-    0xa6, 0xa9, 0xb2, 0xb3, 0x48, 0x48, 0x4c, 0x22,
-    0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
-    0x9b, 0x48, 0x48, 0x48, 0xb0, 0xb0, 0xba, 0xb8,
-    0x68, 0x68, 0x69, 0x78, 0x6f, 0xb5, 0x6f, 0xb5,
-    0x78, 0x78, 0x78, 0x78, 0x78, 0xa5, 0xbb, 0xa9,
-    0xa5, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x23,
-    0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31,
-    0x9b, 0x48, 0x48, 0x48, 0x48, 0x9f, 0xac, 0x68,
-    0xbc, 0x6e, 0x6e, 0x6e, 0xb5, 0x6f, 0x6e, 0x6f,
-    0x6f, 0x78, 0x78, 0xb5, 0xb5, 0xa5, 0x9f, 0x9f,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x46, 0x22,
-    0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d,
-    0x9b, 0x48, 0x48, 0xb0, 0xaa, 0xb3, 0xbd, 0xb8,
-    0xb8, 0x68, 0x6e, 0x6e, 0xb5, 0x6f, 0x78, 0x6e,
-    0x78, 0x6f, 0x78, 0x78, 0xb5, 0xa9, 0xa2, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
-    0x24, 0x27, 0xbe, 0x24, 0x25, 0x28, 0x21, 0x36,
-    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
-    0x39, 0x4d, 0xbf, 0x84, 0x81, 0x57, 0x21, 0x39,
-    0x52, 0x48, 0x48, 0x62, 0xb1, 0xc0, 0xc1, 0xc1,
-    0xb8, 0xb8, 0x68, 0xbc, 0x6e, 0x6e, 0x6e, 0x78,
-    0x78, 0x78, 0x78, 0x6e, 0x78, 0xa9, 0xa0, 0xab,
-    0xb3, 0xa2, 0x48, 0x48, 0x48, 0x48, 0x53, 0x28,
-    0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
-    0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
-    0x2d, 0xc2, 0x7a, 0xc3, 0xc4, 0xc4, 0x7f, 0x22,
-    0x51, 0x52, 0x48, 0x48, 0xb0, 0xaa, 0xa8, 0xbd,
-    0x68, 0xb8, 0xb8, 0x68, 0x68, 0x6e, 0x6e, 0x6f,
-    0x6e, 0x6e, 0xb5, 0x6e, 0x78, 0xab, 0xab, 0xb5,
-    0x78, 0xa6, 0xb3, 0xc5, 0xac, 0xac, 0xc6, 0x61,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
-    0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
-    0x4d, 0x91, 0x5b, 0xc3, 0xc4, 0xc4, 0xc4, 0x5a,
-    0x21, 0x2e, 0x46, 0x48, 0x48, 0x48, 0xb0, 0x64,
-    0xc1, 0xb8, 0xb8, 0xb8, 0x68, 0x71, 0x6e, 0x6e,
-    0x6f, 0x71, 0x6f, 0x6f, 0xa6, 0xa0, 0x9f, 0xb4,
-    0xb4, 0xa0, 0xa1, 0xb7, 0xc7, 0x69, 0x66, 0xc8,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
-    0x83, 0xc9, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a,
-    0x60, 0x85, 0xca, 0xcb, 0xc4, 0xc4, 0xc4, 0x82,
-    0x86, 0x36, 0x32, 0x3f, 0xa2, 0xa4, 0xa8, 0xa9,
-    0xb8, 0xb8, 0xb8, 0xb8, 0x68, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x71, 0x6f, 0x71, 0xa6, 0xb4, 0x9f, 0x9f,
-    0x48, 0x48, 0x48, 0xcc, 0xc3, 0xc7, 0xcd, 0xce,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57,
-    0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x23, 0x30, 0x31, 0xcf, 0x91, 0x7e, 0x90, 0x90,
-    0x8b, 0x5b, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0x5d, 0xd0, 0x36, 0x24, 0xd1, 0xb1, 0xaf, 0xaa,
-    0xba, 0xb8, 0x68, 0x68, 0x68, 0x71, 0x6e, 0x6e,
-    0x6e, 0x6f, 0x6e, 0x78, 0xa1, 0xa9, 0xa1, 0xb0,
-    0x9f, 0x9b, 0x99, 0xcc, 0x64, 0x5c, 0x8b, 0xd0,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
-    0x82, 0x5c, 0xd2, 0x2a, 0x23, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x24, 0x2b, 0xcf, 0x8b, 0x5b, 0x76, 0x5b, 0x5b,
-    0x7b, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc7, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x99, 0x48,
-    0xa2, 0xa8, 0xb7, 0xc1, 0xb8, 0x68, 0x68, 0xbc,
-    0x68, 0x6e, 0xb5, 0xb4, 0xb4, 0xab, 0xb5, 0xa1,
-    0xb0, 0x4f, 0x3f, 0xd3, 0x7b, 0x7b, 0x85, 0x80,
-    0xbe, 0x36, 0x36, 0x36, 0x21, 0xd4, 0x7e, 0x7b,
-    0x64, 0x64, 0xd5, 0x35, 0x24, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x31, 0xd6, 0x5b, 0x64, 0xc3, 0xc3, 0xcb,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0x66, 0xd7, 0x36, 0x36, 0x36, 0x2c, 0x4b,
-    0xd8, 0xd9, 0xb3, 0xa8, 0xbd, 0xbd, 0xbd, 0xbd,
-    0xa9, 0xab, 0xb3, 0xa5, 0xa2, 0x9f, 0xa2, 0xa1,
-    0x6a, 0x9a, 0x3f, 0xda, 0x76, 0x76, 0x7a, 0x63,
-    0xdb, 0xdc, 0x86, 0xdc, 0xdd, 0x90, 0x5b, 0x64,
-    0xc3, 0xc3, 0xde, 0x2d, 0x27, 0x23, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x26, 0x2d, 0x91, 0x5b, 0x64, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc7, 0x83, 0xce, 0x36, 0x36, 0x36, 0x30,
-    0xb1, 0xd9, 0x48, 0xa1, 0xb2, 0xb0, 0xb0, 0xb3,
-    0xa2, 0x48, 0xa7, 0xbd, 0xa9, 0xa2, 0x48, 0x9f,
-    0xaa, 0x9a, 0x3f, 0xb1, 0x5b, 0x7b, 0xdf, 0x85,
-    0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xc3, 0xc4,
-    0xc4, 0xcb, 0x5d, 0xd5, 0x39, 0x26, 0x23, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2d, 0xe0, 0xdf, 0x64, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc7, 0x88, 0x36, 0x36, 0x36, 0x36,
-    0x2d, 0x9b, 0x48, 0xb9, 0xaf, 0xa2, 0xa2, 0xb9,
-    0xa8, 0x9f, 0x48, 0xa7, 0xb7, 0xd9, 0x48, 0x48,
-    0x9b, 0x45, 0x3f, 0xe1, 0x6d, 0x7b, 0xca, 0xdf,
-    0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc3, 0xe2, 0x37, 0x35, 0x26, 0x23,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2e, 0xe0, 0x7a, 0x7b, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc7, 0x72, 0x73, 0x36, 0x36, 0x36,
-    0x24, 0x52, 0x48, 0xa3, 0xaf, 0x9f, 0x48, 0xb6,
-    0xaf, 0xa2, 0x48, 0x9f, 0xe3, 0xd8, 0x48, 0x48,
-    0x48, 0x46, 0x42, 0xd6, 0x7a, 0x7b, 0x64, 0x7b,
-    0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xc3, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xcb, 0x64, 0xe2, 0x4d, 0x2c, 0x27,
-    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x25, 0x31, 0xe4, 0x8b, 0x7b, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc7, 0x89, 0xbe, 0x36, 0x36,
-    0x32, 0x47, 0x48, 0x4f, 0xa0, 0x48, 0x48, 0xe3,
-    0x92, 0x9f, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xc3, 0xcb,
-    0xc3, 0x64, 0x64, 0xc3, 0xc3, 0xcb, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x5d, 0xe5, 0x2c,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x25, 0x31, 0xe4, 0x85, 0x7b, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0x66, 0x57, 0x27, 0x4d,
-    0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x99, 0x34, 0xbe, 0xdb, 0x7a, 0x7b, 0xc3, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0xe4,
-    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2d, 0xe4, 0x85, 0x7b, 0xcb, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc7, 0x5f, 0x92, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
-    0x35, 0x36, 0xce, 0xdd, 0x7a, 0x7b, 0xcb, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0xc3, 0xe1,
-    0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x30, 0x2f, 0xd6, 0x8b, 0x7b, 0xcb, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0x66, 0x89, 0x45,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25,
-    0x36, 0x36, 0x61, 0xdb, 0x6d, 0x64, 0xcb, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x7b, 0xdf, 0xe5,
-    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0xe6, 0x63, 0xdf, 0xc3, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x72, 0x81, 0xe7,
-    0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36,
-    0x36, 0x36, 0xe8, 0x8f, 0x6d, 0x64, 0xcb, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc3, 0xca, 0x8b, 0xcf, 0x2c,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x35, 0x96, 0x75, 0xca, 0xc3, 0xcb, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x7b, 0x81, 0xdb,
-    0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b,
-    0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x73, 0xdb, 0x7a, 0x7b, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0x64, 0x76, 0x7a, 0x91, 0xd5, 0x31, 0x30,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x39, 0x97, 0x75, 0xdf, 0x7b, 0x64, 0xc3, 0xc3,
-    0xcb, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0x7b, 0x7a, 0xe9,
-    0xea, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
-    0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xea, 0xdd, 0x8b, 0x7b, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x64, 0x64,
-    0x76, 0x85, 0xe0, 0xd5, 0x34, 0x2b, 0x27, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0xeb, 0x63, 0x7e, 0x7a, 0x6d, 0xdf, 0x5b,
-    0x76, 0x7b, 0x64, 0x64, 0xc3, 0xcb, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x76, 0x85, 0xdb,
-    0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xec, 0xdd, 0x75, 0x76, 0xc3, 0xc4,
-    0xc4, 0xc4, 0xcb, 0xc3, 0x64, 0x76, 0xdf, 0x8b,
-    0xd6, 0xd5, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x27, 0x31, 0xed, 0xeb, 0xdd, 0x74, 0x63, 0x90,
-    0x7e, 0x75, 0x8b, 0x6d, 0xdf, 0x76, 0x64, 0xc3,
-    0xcb, 0xcb, 0xcb, 0xcb, 0x64, 0x7a, 0x84, 0xee,
-    0x79, 0xbe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xea, 0xee, 0x63, 0x6d, 0x7b, 0x64,
-    0xcb, 0xc3, 0x64, 0x7b, 0xdf, 0x75, 0x63, 0x96,
-    0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x28, 0x27, 0x35, 0x2d, 0x41, 0xd5, 0xe7, 0x8f,
-    0xdb, 0xdd, 0xe9, 0x74, 0x84, 0x90, 0x85, 0x6d,
-    0x5b, 0x7b, 0x7b, 0xca, 0x6d, 0x90, 0xdb, 0xef,
-    0xec, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
-    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
-    0x36, 0x21, 0xd4, 0x80, 0xe9, 0x7e, 0x6d, 0x76,
-    0xca, 0x76, 0x6d, 0x85, 0x63, 0xdb, 0xd5, 0x34,
-    0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
-    0x41, 0xf0, 0xf1, 0x6c, 0x80, 0xee, 0xdb, 0x74,
-    0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xef, 0x79,
-    0xe8, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d,
-    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38,
-    0x4d, 0x37, 0xf2, 0xf3, 0x8f, 0x74, 0x63, 0x7e,
-    0x75, 0x7e, 0x63, 0xe9, 0x88, 0xe6, 0x31, 0x2a,
-    0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
-    0x33, 0x39, 0x2e, 0x51, 0x41, 0xd2, 0x6c, 0xf3,
-    0x80, 0xee, 0xee, 0xee, 0xf4, 0xf3, 0xd7, 0xf5,
-    0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
-    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
-    0x2b, 0x34, 0xf6, 0xec, 0xf7, 0x8f, 0xdd, 0xe9,
-    0xe9, 0xdd, 0xee, 0x6c, 0x41, 0x39, 0x27, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
-    0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41,
-    0xf8, 0xd7, 0x79, 0x79, 0x79, 0xec, 0xf9, 0x51,
-    0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
-    0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
-    0x24, 0x2a, 0x31, 0xfa, 0xea, 0x79, 0xf3, 0x80,
-    0xf7, 0xdc, 0xfb, 0x2f, 0x35, 0x26, 0x23, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
-    0x31, 0x2f, 0xf6, 0xfa, 0xfa, 0x2f, 0x2e, 0x33,
-    0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x27, 0x35, 0x34, 0xfa, 0xfa, 0xfa,
-    0xfc, 0xf6, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
-    0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
-    0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
-    0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-};
-
-unsigned char linux_logo16[1];
-
-#endif /* INCLUDE_LINUX_LOGO_DATA */
-
-#include <linux/linux_logo.h>
-
diff -Nru a/include/asm-sparc64/compat.h b/include/asm-sparc64/compat.h
--- a/include/asm-sparc64/compat.h	Tue Mar 11 15:41:39 2003
+++ b/include/asm-sparc64/compat.h	Sun Mar 23 23:55:03 2003
@@ -100,4 +100,17 @@
 #define COMPAT_OFF_T_MAX	0x7fffffff
 #define COMPAT_LOFF_T_MAX	0x7fffffffffffffffL
 
+/*
+ * A pointer passed in from user mode. This should not
+ * be used for syscall parameters, just declare them
+ * as pointers because the syscall entry code will have
+ * appropriately comverted them already.
+ */
+typedef	u32		compat_uptr_t;
+
+static inline void *compat_ptr(compat_uptr_t uptr)
+{
+	return (void *)(unsigned long)uptr;
+}
+
 #endif /* _ASM_SPARC64_COMPAT_H */
diff -Nru a/include/asm-sparc64/ide.h b/include/asm-sparc64/ide.h
--- a/include/asm-sparc64/ide.h	Wed Feb 19 14:28:16 2003
+++ b/include/asm-sparc64/ide.h	Sun Mar 23 22:03:00 2003
@@ -17,8 +17,13 @@
 #include <asm/page.h>
 #include <asm/spitfire.h>
 
-#undef  MAX_HWIFS
+#ifndef MAX_HWIFS
+# ifdef CONFIG_BLK_DEV_IDEPCI
+#define MAX_HWIFS	10
+# else
 #define MAX_HWIFS	2
+# endif
+#endif
 
 static __inline__ int ide_default_irq(unsigned long base)
 {
diff -Nru a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h
--- a/include/asm-sparc64/irq.h	Tue Feb 18 18:59:01 2003
+++ b/include/asm-sparc64/irq.h	Wed Mar 12 03:53:15 2003
@@ -117,8 +117,6 @@
 extern void disable_irq(unsigned int);
 #define disable_irq_nosync disable_irq
 extern void enable_irq(unsigned int);
-extern void sparc64_init_timers(void (*lvl10_irq)(int, void *, struct pt_regs *),
-				unsigned long *);
 extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap);
 extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);
 extern unsigned int psycho_build_irq(void *psycho, int imap_off, int ino, int need_dma_sync);
diff -Nru a/include/asm-sparc64/linux_logo.h b/include/asm-sparc64/linux_logo.h
--- a/include/asm-sparc64/linux_logo.h	Mon Feb  4 23:41:05 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,934 +0,0 @@
-/* $Id: linux_logo.h,v 1.7 2001/06/08 23:01:58 davem Exp $
- * include/asm-sparc64/linux_logo.h: This is a linux logo
- *                                   to be displayed on boot.
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * image size has to be 80x80
- * values have to start from 0x20
- * (i.e. RGB(linux_logo_red[0],
- *	     linux_logo_green[0],
- *	     linux_logo_blue[0]) is color 0x20)
- * BW image has to be 80x80 as well, with MS bit
- * on the left
- * Serial_console ascii image can be any size,
- * but should contain %s to display the version
- */
- 
-#include <linux/init.h>
-#include <linux/version.h>
-
-#define linux_logo_banner "Linux/UltraSPARC version " UTS_RELEASE
-
-#define __HAVE_ARCH_LINUX_LOGO
-#define __HAVE_ARCH_LINUX_LOGO16
-
-#define LINUX_LOGO_COLORS	221
-
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-unsigned char linux_logo_red[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79,
-    0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
-    0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
-    0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
-    0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
-    0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c,
-    0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e,
-    0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c,
-    0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xfe,
-    0xf6, 0xec, 0xfe, 0xd2, 0xea, 0xf5, 0xf2, 0xf2,
-    0xe9, 0xee, 0xf6, 0xf2, 0xee, 0xf6, 0xda, 0xd4,
-    0xfa, 0xca, 0xf2, 0xf6, 0xfe, 0xf2, 0xda, 0xe4,
-    0xf6, 0xdd, 0xf2, 0xee, 0xfa, 0xf0, 0x12, 0x4a,
-    0xd6, 0xf2, 0x8e, 0xf2, 0xf6, 0xf6, 0xb5, 0xf1,
-    0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x16, 0x9a,
-    0x2e, 0xd2, 0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62,
-    0xda, 0xee, 0xd6, 0xa3, 0x74, 0xa7, 0xa2, 0xe0,
-    0xae, 0xbe, 0xce, 0xe2, 0xa3, 0x8e, 0x6d, 0x8e,
-    0x32, 0xaf, 0x50, 0x9e, 0x5b, 0x8a, 0x98, 0x82,
-    0x7a, 0x82, 0x56, 0x7c, 0x8a, 0x56, 0x5e, 0x86,
-    0x6a, 0x52, 0x59, 0x64, 0x5e,
-};
-
-unsigned char linux_logo_green[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c,
-    0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
-    0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
-    0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
-    0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
-    0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76,
-    0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46,
-    0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b,
-    0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xfa,
-    0xea, 0xd7, 0xf6, 0xbc, 0xda, 0xde, 0xda, 0xe6,
-    0xca, 0xd8, 0xea, 0xe0, 0xcc, 0xf2, 0xce, 0xb2,
-    0xee, 0xa2, 0xd6, 0xe6, 0xf6, 0xd7, 0xc5, 0xb8,
-    0xc6, 0xb9, 0xce, 0xde, 0xce, 0xc6, 0x0e, 0x36,
-    0xae, 0xbe, 0x86, 0xba, 0xbe, 0xe6, 0x8e, 0xc4,
-    0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x12, 0x7a,
-    0x20, 0xc6, 0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46,
-    0xce, 0xd6, 0xa6, 0x6e, 0x51, 0x72, 0x92, 0xa6,
-    0x87, 0x96, 0xa2, 0xd6, 0x85, 0x7a, 0x6a, 0x6e,
-    0x22, 0x76, 0x36, 0x76, 0x3c, 0x6e, 0x63, 0x53,
-    0x66, 0x62, 0x42, 0x50, 0x56, 0x42, 0x56, 0x56,
-    0x56, 0x3e, 0x51, 0x52, 0x56,
-};
-
-unsigned char linux_logo_blue[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08,
-    0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
-    0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
-    0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
-    0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
-    0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a,
-    0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e,
-    0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b,
-    0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0xea,
-    0xb6, 0x7c, 0xda, 0x8e, 0xa6, 0x87, 0x66, 0xb6,
-    0x81, 0x6a, 0xc6, 0x9a, 0x5b, 0xd2, 0xb6, 0x6a,
-    0xca, 0x45, 0x92, 0xb2, 0xca, 0x52, 0x8a, 0x3e,
-    0x2e, 0x66, 0x66, 0xae, 0x3e, 0x47, 0x06, 0x0e,
-    0x52, 0x36, 0x6a, 0x0e, 0x0e, 0xbe, 0x2c, 0x0e,
-    0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x06, 0x2e,
-    0x06, 0x9e, 0x4e, 0x36, 0x06, 0x58, 0x24, 0x06,
-    0x9e, 0xae, 0x3a, 0x08, 0x08, 0x07, 0x5e, 0x0a,
-    0x32, 0x2e, 0x2a, 0xb2, 0x43, 0x48, 0x5f, 0x2e,
-    0x06, 0x06, 0x07, 0x24, 0x06, 0x32, 0x06, 0x06,
-    0x46, 0x2e, 0x22, 0x06, 0x06, 0x1e, 0x4c, 0x06,
-    0x3a, 0x22, 0x42, 0x34, 0x42,
-};
-
-unsigned char linux_logo[] __initdata = {
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
-    0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-    0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
-    0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
-    0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
-    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-    0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
-    0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-    0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
-    0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34,
-    0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
-    0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22,
-    0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25,
-    0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
-    0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
-    0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-    0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
-    0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-    0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36,
-    0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
-    0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21,
-    0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
-    0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
-    0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
-    0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32,
-    0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a,
-    0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b,
-    0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37,
-    0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
-    0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
-    0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
-    0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
-    0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67,
-    0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
-    0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
-    0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
-    0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78,
-    0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79,
-    0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c,
-    0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
-    0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
-    0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36,
-    0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
-    0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89,
-    0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36,
-    0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
-    0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e,
-    0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
-    0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22,
-    0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
-    0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c,
-    0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51,
-    0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
-    0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97,
-    0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98,
-    0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
-    0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32,
-    0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50,
-    0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
-    0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
-    0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98,
-    0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
-    0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
-    0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b,
-    0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48,
-    0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-    0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-    0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
-    0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
-    0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c,
-    0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c,
-    0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
-    0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93,
-    0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28,
-    0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
-    0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93,
-    0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
-    0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x99, 0x9f, 0x52, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
-    0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30,
-    0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c,
-    0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36,
-    0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48,
-    0x47, 0x9f, 0x48, 0x48, 0x48, 0xa0, 0xa1, 0xa2,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36,
-    0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
-    0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36,
-    0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
-    0xa3, 0xa4, 0x48, 0x48, 0x9f, 0xa5, 0xa6, 0x9f,
-    0x48, 0x48, 0x48, 0xa2, 0xa7, 0x47, 0x48, 0x48,
-    0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
-    0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d,
-    0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
-    0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0xa8, 0xa1, 0x48, 0x48, 0x9f, 0xa9, 0xa6, 0x9f,
-    0x48, 0x48, 0xaa, 0xa1, 0xa5, 0x9f, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30,
-    0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32,
-    0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a,
-    0x36, 0x24, 0x4f, 0x48, 0x52, 0x52, 0x48, 0x48,
-    0xab, 0xac, 0xa0, 0x48, 0xad, 0xa6, 0xa6, 0x9f,
-    0x48, 0xa2, 0xa9, 0xa6, 0xa2, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x47, 0x32, 0x30,
-    0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
-    0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25,
-    0x36, 0x3a, 0x48, 0x48, 0xae, 0xaf, 0x48, 0x48,
-    0xad, 0xac, 0xa1, 0x9f, 0xa2, 0xa9, 0xa9, 0xa2,
-    0x48, 0xab, 0x78, 0xa7, 0x48, 0x48, 0x48, 0x48,
-    0x9f, 0x48, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21,
-    0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36,
-    0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
-    0x23, 0x43, 0x48, 0x48, 0xb0, 0xb1, 0xb2, 0x9f,
-    0x48, 0xb3, 0xa5, 0xb3, 0xab, 0xa9, 0xa9, 0xb3,
-    0xb4, 0xa9, 0xb5, 0xb0, 0x48, 0x48, 0xa0, 0xa5,
-    0xa1, 0xad, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36,
-    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-    0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36,
-    0x2e, 0x9b, 0x48, 0x48, 0x48, 0xb6, 0xb7, 0xa4,
-    0xa2, 0xa7, 0xb5, 0x78, 0x6f, 0x6f, 0x6e, 0x6f,
-    0xa9, 0xb5, 0xab, 0x48, 0x9f, 0xab, 0xa9, 0xa1,
-    0xaa, 0x48, 0x48, 0x48, 0x48, 0x48, 0x98, 0x36,
-    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-    0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36,
-    0x54, 0x48, 0x48, 0x48, 0x48, 0xa2, 0xa8, 0xa1,
-    0xa5, 0xa6, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f,
-    0x6f, 0x78, 0xa5, 0xa0, 0xa0, 0x78, 0xa6, 0xa2,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
-    0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36,
-    0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
-    0x43, 0x48, 0x4b, 0xa2, 0x9f, 0x48, 0xa2, 0xa1,
-    0xb8, 0x6e, 0x6e, 0xb5, 0x78, 0x6f, 0x78, 0x78,
-    0x6e, 0x6f, 0x78, 0xb5, 0xa6, 0xa1, 0xa0, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4b, 0x21,
-    0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25,
-    0x52, 0x48, 0xa3, 0xb1, 0xb6, 0xb3, 0xaa, 0xac,
-    0x68, 0x68, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
-    0x78, 0x6f, 0x6f, 0xb5, 0xa6, 0xb4, 0x48, 0x9f,
-    0xb4, 0xb4, 0xa2, 0x9f, 0x48, 0x48, 0x4f, 0x21,
-    0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a,
-    0x47, 0x48, 0xa2, 0xb6, 0xaf, 0xb9, 0xba, 0x68,
-    0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x78,
-    0x6f, 0x6f, 0xa6, 0x6f, 0xb5, 0xa0, 0xaa, 0xa6,
-    0xa6, 0xa9, 0xb2, 0xb3, 0x48, 0x48, 0x4c, 0x22,
-    0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
-    0x9b, 0x48, 0x48, 0x48, 0xb0, 0xb0, 0xba, 0xb8,
-    0x68, 0x68, 0x69, 0x78, 0x6f, 0xb5, 0x6f, 0xb5,
-    0x78, 0x78, 0x78, 0x78, 0x78, 0xa5, 0xbb, 0xa9,
-    0xa5, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x23,
-    0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31,
-    0x9b, 0x48, 0x48, 0x48, 0x48, 0x9f, 0xac, 0x68,
-    0xbc, 0x6e, 0x6e, 0x6e, 0xb5, 0x6f, 0x6e, 0x6f,
-    0x6f, 0x78, 0x78, 0xb5, 0xb5, 0xa5, 0x9f, 0x9f,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x46, 0x22,
-    0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d,
-    0x9b, 0x48, 0x48, 0xb0, 0xaa, 0xb3, 0xbd, 0xb8,
-    0xb8, 0x68, 0x6e, 0x6e, 0xb5, 0x6f, 0x78, 0x6e,
-    0x78, 0x6f, 0x78, 0x78, 0xb5, 0xa9, 0xa2, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
-    0x24, 0x27, 0xbe, 0x24, 0x25, 0x28, 0x21, 0x36,
-    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
-    0x39, 0x4d, 0xbf, 0x84, 0x81, 0x57, 0x21, 0x39,
-    0x52, 0x48, 0x48, 0x62, 0xb1, 0xc0, 0xc1, 0xc1,
-    0xb8, 0xb8, 0x68, 0xbc, 0x6e, 0x6e, 0x6e, 0x78,
-    0x78, 0x78, 0x78, 0x6e, 0x78, 0xa9, 0xa0, 0xab,
-    0xb3, 0xa2, 0x48, 0x48, 0x48, 0x48, 0x53, 0x28,
-    0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
-    0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
-    0x2d, 0xc2, 0x7a, 0xc3, 0xc4, 0xc4, 0x7f, 0x22,
-    0x51, 0x52, 0x48, 0x48, 0xb0, 0xaa, 0xa8, 0xbd,
-    0x68, 0xb8, 0xb8, 0x68, 0x68, 0x6e, 0x6e, 0x6f,
-    0x6e, 0x6e, 0xb5, 0x6e, 0x78, 0xab, 0xab, 0xb5,
-    0x78, 0xa6, 0xb3, 0xc5, 0xac, 0xac, 0xc6, 0x61,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
-    0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
-    0x4d, 0x91, 0x5b, 0xc3, 0xc4, 0xc4, 0xc4, 0x5a,
-    0x21, 0x2e, 0x46, 0x48, 0x48, 0x48, 0xb0, 0x64,
-    0xc1, 0xb8, 0xb8, 0xb8, 0x68, 0x71, 0x6e, 0x6e,
-    0x6f, 0x71, 0x6f, 0x6f, 0xa6, 0xa0, 0x9f, 0xb4,
-    0xb4, 0xa0, 0xa1, 0xb7, 0xc7, 0x69, 0x66, 0xc8,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
-    0x83, 0xc9, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a,
-    0x60, 0x85, 0xca, 0xcb, 0xc4, 0xc4, 0xc4, 0x82,
-    0x86, 0x36, 0x32, 0x3f, 0xa2, 0xa4, 0xa8, 0xa9,
-    0xb8, 0xb8, 0xb8, 0xb8, 0x68, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x71, 0x6f, 0x71, 0xa6, 0xb4, 0x9f, 0x9f,
-    0x48, 0x48, 0x48, 0xcc, 0xc3, 0xc7, 0xcd, 0xce,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57,
-    0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x23, 0x30, 0x31, 0xcf, 0x91, 0x7e, 0x90, 0x90,
-    0x8b, 0x5b, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0x5d, 0xd0, 0x36, 0x24, 0xd1, 0xb1, 0xaf, 0xaa,
-    0xba, 0xb8, 0x68, 0x68, 0x68, 0x71, 0x6e, 0x6e,
-    0x6e, 0x6f, 0x6e, 0x78, 0xa1, 0xa9, 0xa1, 0xb0,
-    0x9f, 0x9b, 0x99, 0xcc, 0x64, 0x5c, 0x8b, 0xd0,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
-    0x82, 0x5c, 0xd2, 0x2a, 0x23, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x24, 0x2b, 0xcf, 0x8b, 0x5b, 0x76, 0x5b, 0x5b,
-    0x7b, 0xc3, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc7, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x99, 0x48,
-    0xa2, 0xa8, 0xb7, 0xc1, 0xb8, 0x68, 0x68, 0xbc,
-    0x68, 0x6e, 0xb5, 0xb4, 0xb4, 0xab, 0xb5, 0xa1,
-    0xb0, 0x4f, 0x3f, 0xd3, 0x7b, 0x7b, 0x85, 0x80,
-    0xbe, 0x36, 0x36, 0x36, 0x21, 0xd4, 0x7e, 0x7b,
-    0x64, 0x64, 0xd5, 0x35, 0x24, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x31, 0xd6, 0x5b, 0x64, 0xc3, 0xc3, 0xcb,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0x66, 0xd7, 0x36, 0x36, 0x36, 0x2c, 0x4b,
-    0xd8, 0xd9, 0xb3, 0xa8, 0xbd, 0xbd, 0xbd, 0xbd,
-    0xa9, 0xab, 0xb3, 0xa5, 0xa2, 0x9f, 0xa2, 0xa1,
-    0x6a, 0x9a, 0x3f, 0xda, 0x76, 0x76, 0x7a, 0x63,
-    0xdb, 0xdc, 0x86, 0xdc, 0xdd, 0x90, 0x5b, 0x64,
-    0xc3, 0xc3, 0xde, 0x2d, 0x27, 0x23, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x26, 0x2d, 0x91, 0x5b, 0x64, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc7, 0x83, 0xce, 0x36, 0x36, 0x36, 0x30,
-    0xb1, 0xd9, 0x48, 0xa1, 0xb2, 0xb0, 0xb0, 0xb3,
-    0xa2, 0x48, 0xa7, 0xbd, 0xa9, 0xa2, 0x48, 0x9f,
-    0xaa, 0x9a, 0x3f, 0xb1, 0x5b, 0x7b, 0xdf, 0x85,
-    0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xc3, 0xc4,
-    0xc4, 0xcb, 0x5d, 0xd5, 0x39, 0x26, 0x23, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2d, 0xe0, 0xdf, 0x64, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc7, 0x88, 0x36, 0x36, 0x36, 0x36,
-    0x2d, 0x9b, 0x48, 0xb9, 0xaf, 0xa2, 0xa2, 0xb9,
-    0xa8, 0x9f, 0x48, 0xa7, 0xb7, 0xd9, 0x48, 0x48,
-    0x9b, 0x45, 0x3f, 0xe1, 0x6d, 0x7b, 0xca, 0xdf,
-    0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc3, 0xe2, 0x37, 0x35, 0x26, 0x23,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2e, 0xe0, 0x7a, 0x7b, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc7, 0x72, 0x73, 0x36, 0x36, 0x36,
-    0x24, 0x52, 0x48, 0xa3, 0xaf, 0x9f, 0x48, 0xb6,
-    0xaf, 0xa2, 0x48, 0x9f, 0xe3, 0xd8, 0x48, 0x48,
-    0x48, 0x46, 0x42, 0xd6, 0x7a, 0x7b, 0x64, 0x7b,
-    0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xc3, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xcb, 0x64, 0xe2, 0x4d, 0x2c, 0x27,
-    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x25, 0x31, 0xe4, 0x8b, 0x7b, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc7, 0x89, 0xbe, 0x36, 0x36,
-    0x32, 0x47, 0x48, 0x4f, 0xa0, 0x48, 0x48, 0xe3,
-    0x92, 0x9f, 0x48, 0x9f, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xc3, 0xcb,
-    0xc3, 0x64, 0x64, 0xc3, 0xc3, 0xcb, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x5d, 0xe5, 0x2c,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x25, 0x31, 0xe4, 0x85, 0x7b, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0x66, 0x57, 0x27, 0x4d,
-    0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x99, 0x34, 0xbe, 0xdb, 0x7a, 0x7b, 0xc3, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0xe4,
-    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2d, 0xe4, 0x85, 0x7b, 0xcb, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc7, 0x5f, 0x92, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
-    0x35, 0x36, 0xce, 0xdd, 0x7a, 0x7b, 0xcb, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0xc3, 0xe1,
-    0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x30, 0x2f, 0xd6, 0x8b, 0x7b, 0xcb, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0x66, 0x89, 0x45,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25,
-    0x36, 0x36, 0x61, 0xdb, 0x6d, 0x64, 0xcb, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x7b, 0xdf, 0xe5,
-    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0xe6, 0x63, 0xdf, 0xc3, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x72, 0x81, 0xe7,
-    0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36,
-    0x36, 0x36, 0xe8, 0x8f, 0x6d, 0x64, 0xcb, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc3, 0xca, 0x8b, 0xcf, 0x2c,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x35, 0x96, 0x75, 0xca, 0xc3, 0xcb, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x7b, 0x81, 0xdb,
-    0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b,
-    0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x73, 0xdb, 0x7a, 0x7b, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0x64, 0x76, 0x7a, 0x91, 0xd5, 0x31, 0x30,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x39, 0x97, 0x75, 0xdf, 0x7b, 0x64, 0xc3, 0xc3,
-    0xcb, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0x7b, 0x7a, 0xe9,
-    0xea, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
-    0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xea, 0xdd, 0x8b, 0x7b, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0x64, 0x64,
-    0x76, 0x85, 0xe0, 0xd5, 0x34, 0x2b, 0x27, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0xeb, 0x63, 0x7e, 0x7a, 0x6d, 0xdf, 0x5b,
-    0x76, 0x7b, 0x64, 0x64, 0xc3, 0xcb, 0xc4, 0xc4,
-    0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0x76, 0x85, 0xdb,
-    0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xec, 0xdd, 0x75, 0x76, 0xc3, 0xc4,
-    0xc4, 0xc4, 0xcb, 0xc3, 0x64, 0x76, 0xdf, 0x8b,
-    0xd6, 0xd5, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x27, 0x31, 0xed, 0xeb, 0xdd, 0x74, 0x63, 0x90,
-    0x7e, 0x75, 0x8b, 0x6d, 0xdf, 0x76, 0x64, 0xc3,
-    0xcb, 0xcb, 0xcb, 0xcb, 0x64, 0x7a, 0x84, 0xee,
-    0x79, 0xbe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xea, 0xee, 0x63, 0x6d, 0x7b, 0x64,
-    0xcb, 0xc3, 0x64, 0x7b, 0xdf, 0x75, 0x63, 0x96,
-    0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x28, 0x27, 0x35, 0x2d, 0x41, 0xd5, 0xe7, 0x8f,
-    0xdb, 0xdd, 0xe9, 0x74, 0x84, 0x90, 0x85, 0x6d,
-    0x5b, 0x7b, 0x7b, 0xca, 0x6d, 0x90, 0xdb, 0xef,
-    0xec, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
-    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
-    0x36, 0x21, 0xd4, 0x80, 0xe9, 0x7e, 0x6d, 0x76,
-    0xca, 0x76, 0x6d, 0x85, 0x63, 0xdb, 0xd5, 0x34,
-    0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
-    0x41, 0xf0, 0xf1, 0x6c, 0x80, 0xee, 0xdb, 0x74,
-    0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xef, 0x79,
-    0xe8, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d,
-    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38,
-    0x4d, 0x37, 0xf2, 0xf3, 0x8f, 0x74, 0x63, 0x7e,
-    0x75, 0x7e, 0x63, 0xe9, 0x88, 0xe6, 0x31, 0x2a,
-    0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
-    0x33, 0x39, 0x2e, 0x51, 0x41, 0xd2, 0x6c, 0xf3,
-    0x80, 0xee, 0xee, 0xee, 0xf4, 0xf3, 0xd7, 0xf5,
-    0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
-    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
-    0x2b, 0x34, 0xf6, 0xec, 0xf7, 0x8f, 0xdd, 0xe9,
-    0xe9, 0xdd, 0xee, 0x6c, 0x41, 0x39, 0x27, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
-    0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41,
-    0xf8, 0xd7, 0x79, 0x79, 0x79, 0xec, 0xf9, 0x51,
-    0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
-    0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
-    0x24, 0x2a, 0x31, 0xfa, 0xea, 0x79, 0xf3, 0x80,
-    0xf7, 0xdc, 0xfb, 0x2f, 0x35, 0x26, 0x23, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
-    0x31, 0x2f, 0xf6, 0xfa, 0xfa, 0x2f, 0x2e, 0x33,
-    0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x27, 0x35, 0x34, 0xfa, 0xfa, 0xfa,
-    0xfc, 0xf6, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
-    0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
-    0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
-    0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-};
-
-unsigned char linux_logo16[0];
-
-#endif /* INCLUDE_LINUX_LOGO_DATA */
-
-#include <linux/linux_logo.h>
-
diff -Nru a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
--- a/include/asm-sparc64/pgtable.h	Thu Mar  6 08:19:09 2003
+++ b/include/asm-sparc64/pgtable.h	Sun Mar 23 22:49:12 2003
@@ -123,6 +123,7 @@
 #define _PAGE_G		0x0000000000000001	/* Global                             */
 
 /* Here are the SpitFire software bits we use in the TTE's. */
+#define _PAGE_FILE	0x0000000000001000	/* Pagecache page                     */
 #define _PAGE_MODIFIED	0x0000000000000800	/* Modified Page (ie. dirty)          */
 #define _PAGE_ACCESSED	0x0000000000000400	/* Accessed Page (ie. referenced)     */
 #define _PAGE_READ	0x0000000000000200	/* Readable SW Bit                    */
@@ -310,6 +311,12 @@
 	  } )
 #define __pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) })
 #define __swp_entry_to_pte(x)		((pte_t) { (x).val })
+
+/* File offset in PTE support. */
+#define pte_file(pte)		(pte_val(pte) & _PAGE_FILE)
+#define pte_to_pgoff(pte)	(pte_val(pte) >> PAGE_SHIFT)
+#define pgoff_to_pte(off)	(__pte(((off) << PAGE_SHIFT) | _PAGE_FILE))
+#define PTE_FILE_MAX_BITS	(64UL - PAGE_SHIFT - 1UL)
 
 extern unsigned long prom_virt_to_phys(unsigned long, int *);
 
diff -Nru a/include/asm-sparc64/spitfire.h b/include/asm-sparc64/spitfire.h
--- a/include/asm-sparc64/spitfire.h	Thu Oct  3 11:02:09 2002
+++ b/include/asm-sparc64/spitfire.h	Wed Mar 12 12:47:00 2003
@@ -45,8 +45,6 @@
 
 extern enum ultra_tlb_layout tlb_type;
 
-#define SPARC64_USE_STICK	(tlb_type != spitfire)
-
 #define CHEETAH_HIGHEST_LOCKED_TLBENT	(16 - 1)
 
 #define L1DCACHE_SIZE		0x4000
diff -Nru a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
--- a/include/asm-sparc64/thread_info.h	Sun Dec  8 12:27:27 2002
+++ b/include/asm-sparc64/thread_info.h	Wed Mar 19 23:44:41 2003
@@ -97,7 +97,7 @@
 #define TI_PCR		0x00000490
 #define TI_CEE_STUFF	0x00000498
 #define TI_RESTART_BLOCK 0x000004a0
-#define TI_FPREGS	0x000004c0
+#define TI_FPREGS	0x00000500
 
 /* We embed this in the uppermost byte of thread_info->flags */
 #define FAULT_CODE_WRITE	0x01	/* Write access, implies D-TLB		*/
diff -Nru a/include/asm-sparc64/timer.h b/include/asm-sparc64/timer.h
--- a/include/asm-sparc64/timer.h	Tue Feb  5 09:39:50 2002
+++ b/include/asm-sparc64/timer.h	Wed Mar 12 12:47:00 2003
@@ -50,6 +50,17 @@
  */
 #define SUN5_HZ_TO_LIMIT(__hz)  (1000000/(__hz))
 
+struct sparc64_tick_ops {
+	void (*init_tick)(unsigned long);
+	unsigned long (*get_tick)(void);
+	unsigned long (*get_compare)(void);
+	unsigned long (*add_tick)(unsigned long, unsigned long);
+	unsigned long (*add_compare)(unsigned long);
+	unsigned long softint_mask;
+};
+
+extern struct sparc64_tick_ops *tick_ops;
+
 #ifdef CONFIG_SMP
 extern unsigned long timer_tick_offset;
 extern void timer_tick_interrupt(struct pt_regs *);
diff -Nru a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h
--- a/include/asm-um/archparam-i386.h	Sun Dec 29 17:05:47 2002
+++ b/include/asm-um/archparam-i386.h	Mon Mar 17 21:31:50 2003
@@ -23,7 +23,7 @@
 #define ELF_DATA        ELFDATA2LSB
 #define ELF_ARCH        EM_386
 
-#define ELF_PLAT_INIT(regs) do { \
+#define ELF_PLAT_INIT(regs, load_addr) do { \
 	PT_REGS_EBX(regs) = 0; \
 	PT_REGS_ECX(regs) = 0; \
 	PT_REGS_EDX(regs) = 0; \
diff -Nru a/include/asm-um/linux_logo.h b/include/asm-um/linux_logo.h
--- a/include/asm-um/linux_logo.h	Fri Sep  6 10:29:29 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,6 +0,0 @@
-#ifndef __UM_LINUX_LOGO_H
-#define __UM_LINUX_LOGO_H
-
-#include "asm/arch/linux_logo.h"
-
-#endif
diff -Nru a/include/asm-v850/elf.h b/include/asm-v850/elf.h
--- a/include/asm-v850/elf.h	Tue Dec 17 00:23:49 2002
+++ b/include/asm-v850/elf.h	Mon Mar 17 21:31:50 2003
@@ -81,7 +81,7 @@
 
 #define ELF_PLATFORM  (NULL)
 
-#define ELF_PLAT_INIT(_r)						      \
+#define ELF_PLAT_INIT(_r, load_addr)					      \
   do {									      \
 	 _r->gpr[0] =  _r->gpr[1] =  _r->gpr[2] =  _r->gpr[3] =		      \
 	 _r->gpr[4] =  _r->gpr[5] =  _r->gpr[6] =  _r->gpr[7] =		      \
diff -Nru a/include/asm-x86_64/compat.h b/include/asm-x86_64/compat.h
--- a/include/asm-x86_64/compat.h	Mon Mar 10 16:30:59 2003
+++ b/include/asm-x86_64/compat.h	Sun Mar 23 22:28:55 2003
@@ -107,4 +107,17 @@
 #define COMPAT_OFF_T_MAX	0x7fffffff
 #define COMPAT_LOFF_T_MAX	0x7fffffffffffffff
 
+/*
+ * A pointer passed in from user mode. This should not
+ * be used for syscall parameters, just declare them
+ * as pointers because the syscall entry code will have
+ * appropriately comverted them already.
+ */
+typedef	u32		compat_uptr_t;
+
+static inline void *compat_ptr(compat_uptr_t uptr)
+{
+	return (void *)uptr;
+}
+
 #endif /* _ASM_X86_64_COMPAT_H */
diff -Nru a/include/asm-x86_64/elf.h b/include/asm-x86_64/elf.h
--- a/include/asm-x86_64/elf.h	Tue Nov 12 15:36:01 2002
+++ b/include/asm-x86_64/elf.h	Mon Mar 17 21:31:50 2003
@@ -39,7 +39,7 @@
    We might as well make sure everything else is cleared too (except for %esp),
    just to make things more deterministic.
  */
-#define ELF_PLAT_INIT(_r)	do { \
+#define ELF_PLAT_INIT(_r, load_addr)	do { \
 	struct task_struct *cur = current; \
 	(_r)->rbx = 0; (_r)->rcx = 0; (_r)->rdx = 0; \
 	(_r)->rsi = 0; (_r)->rdi = 0; (_r)->rbp = 0; \
diff -Nru a/include/asm-x86_64/linux_logo.h b/include/asm-x86_64/linux_logo.h
--- a/include/asm-x86_64/linux_logo.h	Thu Feb  7 02:55:27 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,29 +0,0 @@
-/* $Id: linux_logo.h,v 1.4 2001/07/05 23:44:45 ak Exp $
- * include/asm-x86_64/linux_logo.h: This is a linux logo
- *                                to be displayed on boot.
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * image size has to be 80x80
- * values have to start from 0x20
- * (i.e. RGB(linux_logo_red[0],
- *	     linux_logo_green[0],
- *	     linux_logo_blue[0]) is color 0x20)
- * BW image has to be 80x80 as well, with MS bit
- * on the left
- * Serial_console ascii image can be any size,
- * but should contain %s to display the version
- */
- 
-#include <linux/init.h>
-#include <linux/version.h>
-
-/* We should create logo of penguin with a big hammer (-: --pavel */
-
-#define linux_logo_banner "Linux/x86-64 version " UTS_RELEASE
-
-#include <linux/linux_logo.h>
-
diff -Nru a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
--- a/include/asm-x86_64/page.h	Tue Jan 28 05:44:39 2003
+++ b/include/asm-x86_64/page.h	Sat Mar 22 22:09:00 2003
@@ -69,8 +69,9 @@
 /* See Documentation/x86_64/mm.txt for a description of the memory map. */
 #define __START_KERNEL		0xffffffff80100000
 #define __START_KERNEL_map	0xffffffff80000000
-#define __PAGE_OFFSET           0x0000010000000000
-#define __PHYSICAL_MASK		0x000000ffffffffff
+#define __PAGE_OFFSET           0x0000010000000000	/* 1 << 40 */
+#define __PHYSICAL_MASK_SHIFT	40
+#define __PHYSICAL_MASK		((1UL << __PHYSICAL_MASK_SHIFT) - 1)
 
 #define KERNEL_TEXT_SIZE  (40UL*1024*1024)
 #define KERNEL_TEXT_START 0xffffffff80000000UL 
diff -Nru a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
--- a/include/asm-x86_64/pgtable.h	Thu Mar  6 08:19:09 2003
+++ b/include/asm-x86_64/pgtable.h	Sat Mar 22 22:09:00 2003
@@ -151,6 +151,7 @@
 #define _PAGE_ACCESSED	0x020
 #define _PAGE_DIRTY	0x040
 #define _PAGE_PSE	0x080	/* 2MB page */
+#define _PAGE_FILE	0x040	/* pagecache or swap */
 #define _PAGE_GLOBAL	0x100	/* Global TLB entry */
 
 #define _PAGE_PROTNONE	0x080	/* If not present */
@@ -245,6 +246,7 @@
 extern inline int pte_dirty(pte_t pte)		{ return pte_val(pte) & _PAGE_DIRTY; }
 extern inline int pte_young(pte_t pte)		{ return pte_val(pte) & _PAGE_ACCESSED; }
 extern inline int pte_write(pte_t pte)		{ return pte_val(pte) & _PAGE_RW; }
+static inline int pte_file(pte_t pte)		{ return pte_val(pte) & _PAGE_FILE; }
 
 extern inline pte_t pte_rdprotect(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
 extern inline pte_t pte_exprotect(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
@@ -329,6 +331,11 @@
 #define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
 #define	pmd_bad(x)	((pmd_val(x) & (~PTE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE )
 #define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot)))
+
+
+#define pte_to_pgoff(pte) ((pte_val(pte) & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT)
+#define pgoff_to_pte(off) ((pte_t) { ((off) << PAGE_SHIFT) | _PAGE_FILE })
+#define PTE_FILE_MAX_BITS __PHYSICAL_MASK_SHIFT
 
 /* PTE - Level 1 access. */
 
diff -Nru a/include/linux/adb.h b/include/linux/adb.h
--- a/include/linux/adb.h	Tue Feb  5 09:39:43 2002
+++ b/include/linux/adb.h	Sun Feb  2 13:51:33 2003
@@ -30,6 +30,15 @@
 #define POWER_PACKET	4
 #define MACIIC_PACKET	5
 #define PMU_PACKET	6
+#define ADB_QUERY	7
+
+/* ADB queries */
+
+/* ADB_QUERY_GETDEVINFO
+ * Query ADB slot for device presence
+ * data[2] = id, rep[0] = orig addr, rep[1] = handler_id
+ */
+#define ADB_QUERY_GETDEVINFO	1
 
 #ifdef __KERNEL__
 
diff -Nru a/include/linux/backing-dev.h b/include/linux/backing-dev.h
--- a/include/linux/backing-dev.h	Thu Nov 21 13:10:47 2002
+++ b/include/linux/backing-dev.h	Mon Mar 17 21:31:55 2003
@@ -17,8 +17,6 @@
 	BDI_pdflush,		/* A pdflush thread is working this device */
 	BDI_write_congested,	/* The write queue is getting full */
 	BDI_read_congested,	/* The read queue is getting full */
-	BDI_write_active,	/* There are one or more queued writes */
-	BDI_read_active,	/* There are one or more queued reads */
 	BDI_unused,		/* Available bits start here */
 };
 
@@ -42,16 +40,6 @@
 static inline int bdi_write_congested(struct backing_dev_info *bdi)
 {
 	return test_bit(BDI_write_congested, &bdi->state);
-}
-
-static inline int bdi_read_active(struct backing_dev_info *bdi)
-{
-	return test_bit(BDI_read_active, &bdi->state);
-}
-
-static inline int bdi_write_active(struct backing_dev_info *bdi)
-{
-	return test_bit(BDI_write_active, &bdi->state);
 }
 
 #endif		/* _LINUX_BACKING_DEV_H */
diff -Nru a/include/linux/buffer_head.h b/include/linux/buffer_head.h
--- a/include/linux/buffer_head.h	Wed Feb  5 08:27:03 2003
+++ b/include/linux/buffer_head.h	Mon Mar 17 13:36:07 2003
@@ -137,6 +137,7 @@
 void create_empty_buffers(struct page *, unsigned long,
 			unsigned long b_state);
 void end_buffer_io_sync(struct buffer_head *bh, int uptodate);
+void end_buffer_async_write(struct buffer_head *bh, int uptodate);
 
 /* Things to do with buffers at mapping->private_list */
 void buffer_insert_list(spinlock_t *lock,
diff -Nru a/include/linux/compat.h b/include/linux/compat.h
--- a/include/linux/compat.h	Sun Mar  9 01:34:45 2003
+++ b/include/linux/compat.h	Sun Mar 23 22:06:53 2003
@@ -43,11 +43,9 @@
 extern int put_compat_timespec(struct timespec *, struct compat_timespec *);
 
 struct compat_iovec {
-	u32		iov_base;
+	compat_uptr_t	iov_base;
 	compat_size_t	iov_len;
 };
-#else /* no CONFIG_COMPAT */
-#define compat_size_t	size_t
 
 #endif /* CONFIG_COMPAT */
 #endif /* _LINUX_COMPAT_H */
diff -Nru a/include/linux/console_struct.h b/include/linux/console_struct.h
--- a/include/linux/console_struct.h	Fri Nov 15 14:01:12 2002
+++ b/include/linux/console_struct.h	Sun Mar 23 00:01:15 2003
@@ -16,31 +16,36 @@
 	unsigned int	vc_cols;		/* [#] Console size */
 	unsigned int	vc_rows;
 	unsigned int	vc_size_row;		/* Bytes per row */
+	unsigned int	vc_scan_lines;		/* # of scan lines */
+	unsigned long	vc_origin;		/* [!] Start of real screen */
+	unsigned long	vc_scr_end;		/* [!] End of real screen */
+	unsigned long	vc_visible_origin;	/* [!] Top of visible window */
+	unsigned int	vc_top, vc_bottom;	/* Scrolling region */
 	const struct consw *vc_sw;
 	unsigned short	*vc_screenbuf;		/* In-memory character/attribute buffer */
 	unsigned int	vc_screenbuf_size;
+	/* attributes for all characters on screen */
 	unsigned char	vc_attr;		/* Current attributes */
 	unsigned char	vc_def_color;		/* Default colors */
 	unsigned char	vc_color;		/* Foreground & background */
 	unsigned char	vc_s_color;		/* Saved foreground & background */
 	unsigned char	vc_ulcolor;		/* Color for underline mode */
 	unsigned char	vc_halfcolor;		/* Color for half intensity mode */
+	/* cursor */
+	unsigned int	vc_cursor_type;
 	unsigned short	vc_complement_mask;	/* [#] Xor mask for mouse pointer */
+	unsigned short	vc_s_complement_mask;	/* Saved mouse pointer mask */
+	unsigned int	vc_x, vc_y;		/* Cursor position */
+	unsigned int	vc_saved_x, vc_saved_y;
+	unsigned long	vc_pos;			/* Cursor address */
+	/* fonts */	
 	unsigned short	vc_hi_font_mask;	/* [#] Attribute set for upper 256 chars of font or 0 if not supported */
 	struct console_font_op vc_font;		/* Current VC font set */
 	unsigned short	vc_video_erase_char;	/* Background erase character */
-	unsigned short	vc_s_complement_mask;	/* Saved mouse pointer mask */
-	unsigned int	vc_x, vc_y;		/* Cursor position */
-	unsigned int	vc_top, vc_bottom;	/* Scrolling region */
+	/* VT terminal data */
 	unsigned int	vc_state;		/* Escape sequence parser state */
 	unsigned int	vc_npar,vc_par[NPAR];	/* Parameters of current escape sequence */
 	struct tty_struct *vc_tty;		/* TTY we are attached to */
-	unsigned long	vc_origin;		/* [!] Start of real screen */
-	unsigned long	vc_scr_end;		/* [!] End of real screen */
-	unsigned long	vc_visible_origin;	/* [!] Top of visible window */
-	unsigned long	vc_pos;			/* Cursor address */
-	unsigned int	vc_saved_x;
-	unsigned int	vc_saved_y;
 	/* mode flags */
 	unsigned int	vc_charset	: 1;	/* Character set G0 / G1 */
 	unsigned int	vc_s_charset	: 1;	/* Saved character set */
@@ -79,7 +84,6 @@
 	unsigned char 	vc_saved_G1;
 	unsigned int	vc_bell_pitch;		/* Console bell pitch */
 	unsigned int	vc_bell_duration;	/* Console bell duration */
-	unsigned int	vc_cursor_type;
 	struct vc_data **vc_display_fg;		/* [!] Ptr to var holding fg console for this display */
 	unsigned long	vc_uni_pagedir;
 	unsigned long	*vc_uni_pagedir_loc;  /* [!] Location of uni_pagedir variable for this console */
diff -Nru a/include/linux/devfs_fs_kernel.h b/include/linux/devfs_fs_kernel.h
--- a/include/linux/devfs_fs_kernel.h	Tue Mar 11 05:58:19 2003
+++ b/include/linux/devfs_fs_kernel.h	Sat Mar 22 07:38:05 2003
@@ -13,7 +13,6 @@
 
 #define DEVFS_FL_NONE           0x000 /* This helps to make code more readable
 				       */
-#define DEVFS_FL_REMOVABLE      0x008 /* This is a removable media device    */
 #define DEVFS_FL_WAIT           0x010 /* Wait for devfsd to finish           */
 #define DEVFS_FL_CURRENT_OWNER  0x020 /* Set initial ownership to current    */
 #define DEVFS_FL_DEFAULT        DEVFS_FL_NONE
@@ -23,8 +22,6 @@
 
 #ifdef CONFIG_DEVFS_FS
 
-extern void devfs_remove(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
-
 struct unique_numspace
 {
     spinlock_t init_lock;
@@ -37,17 +34,16 @@
 
 #define UNIQUE_NUMBERSPACE_INITIALISER {SPIN_LOCK_UNLOCKED, 0, 0, 0, NULL}
 
-extern void devfs_put (devfs_handle_t de);
 extern devfs_handle_t devfs_register (devfs_handle_t dir, const char *name,
 				      unsigned int flags,
 				      unsigned int major, unsigned int minor,
 				      umode_t mode, void *ops, void *info);
 extern void devfs_unregister (devfs_handle_t de);
-extern int devfs_mk_symlink (devfs_handle_t dir, const char *name,
-			     unsigned int flags, const char *link,
-			     devfs_handle_t *handle, void *info);
-extern devfs_handle_t devfs_mk_dir (devfs_handle_t dir, const char *name,
-				    void *info);
+extern int devfs_mk_symlink (const char *name, const char *link);
+extern devfs_handle_t devfs_mk_dir(const char *fmt, ...)
+	__attribute__((format (printf, 1, 2)));
+extern void devfs_remove(const char *fmt, ...)
+	__attribute__((format (printf, 1, 2)));
 extern int devfs_generate_path (devfs_handle_t de, char *path, int buflen);
 extern int devfs_register_tape (devfs_handle_t de);
 extern void devfs_unregister_tape(int num);
@@ -66,10 +62,6 @@
 
 #define UNIQUE_NUMBERSPACE_INITIALISER {0}
 
-static inline void devfs_put (devfs_handle_t de)
-{
-    return;
-}
 static inline devfs_handle_t devfs_register (devfs_handle_t dir,
 					     const char *name,
 					     unsigned int flags,
@@ -84,14 +76,11 @@
 {
     return;
 }
-static inline int devfs_mk_symlink (devfs_handle_t dir, const char *name,
-				    unsigned int flags, const char *link,
-				    devfs_handle_t *handle, void *info)
+static inline int devfs_mk_symlink (const char *name, const char *link)
 {
     return 0;
 }
-static inline devfs_handle_t devfs_mk_dir (devfs_handle_t dir,
-					   const char *name, void *info)
+static inline devfs_handle_t devfs_mk_dir(const char *fmt, ...)
 {
     return NULL;
 }
diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h
--- a/include/linux/ext3_jbd.h	Mon Feb 10 19:20:37 2003
+++ b/include/linux/ext3_jbd.h	Sat Mar 22 22:14:52 2003
@@ -93,24 +93,8 @@
  * been done yet.
  */
 
-static inline void ext3_journal_abort_handle(const char *caller, 
-					     const char *err_fn,
-					     struct buffer_head *bh,
-					     handle_t *handle,
-					     int err)
-{
-	char nbuf[16];
-	const char *errstr = ext3_decode_error(NULL, err, nbuf);
-	
-	printk(KERN_ERR "%s: aborting transaction: %s in %s", 
-	       caller, errstr, err_fn);
-
-	if (bh)
-		BUFFER_TRACE(bh, "abort");
-	journal_abort_handle(handle);
-	if (!handle->h_err)
-		handle->h_err = err;
-}
+void ext3_journal_abort_handle(const char *caller, const char *err_fn,
+		struct buffer_head *bh, handle_t *handle, int err);
 
 static inline int
 __ext3_journal_get_undo_access(const char *where,
@@ -180,57 +164,11 @@
 #define ext3_journal_dirty_metadata(handle, bh) \
 	__ext3_journal_dirty_metadata(__FUNCTION__, (handle), (bh))
 
+handle_t *ext3_journal_start(struct inode *inode, int nblocks);
+int __ext3_journal_stop(const char *where, handle_t *handle);
 
-
-/* 
- * Wrappers for journal_start/end.
- *
- * The only special thing we need to do here is to make sure that all
- * journal_end calls result in the superblock being marked dirty, so
- * that sync() will call the filesystem's write_super callback if
- * appropriate. 
- */
-static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks)
-{
-	journal_t *journal;
-	
-	if (inode->i_sb->s_flags & MS_RDONLY)
-		return ERR_PTR(-EROFS);
-
-	/* Special case here: if the journal has aborted behind our
-	 * backs (eg. EIO in the commit thread), then we still need to
-	 * take the FS itself readonly cleanly. */
-	journal = EXT3_JOURNAL(inode);
-	if (is_journal_aborted(journal)) {
-		ext3_abort(inode->i_sb, __FUNCTION__,
-			   "Detected aborted journal");
-		return ERR_PTR(-EROFS);
-	}
-	
-	return journal_start(journal, nblocks);
-}
-
-/* 
- * The only special thing we need to do here is to make sure that all
- * journal_stop calls result in the superblock being marked dirty, so
- * that sync() will call the filesystem's write_super callback if
- * appropriate. 
- */
-static inline int __ext3_journal_stop(const char *where,
-				      handle_t *handle, struct inode *inode)
-{
-	int err = handle->h_err;
-	int rc = journal_stop(handle);
-
-	inode->i_sb->s_dirt = 1;
-	if (!err)
-		err = rc;
-	if (err)
-		__ext3_std_error(inode->i_sb, where, err);
-	return err;
-}
-#define ext3_journal_stop(handle, inode) \
-	__ext3_journal_stop(__FUNCTION__, (handle), (inode))
+#define ext3_journal_stop(handle) \
+	__ext3_journal_stop(__FUNCTION__, (handle))
 
 static inline handle_t *ext3_journal_current_handle(void)
 {
diff -Nru a/include/linux/fb.h b/include/linux/fb.h
--- a/include/linux/fb.h	Fri Jan 10 16:51:25 2003
+++ b/include/linux/fb.h	Mon Mar 17 13:00:04 2003
@@ -98,6 +98,8 @@
 #define FB_ACCEL_3DLABS_PERMEDIA3 37	/* 3Dlabs Permedia 3		*/
 #define FB_ACCEL_ATI_RADEON	38	/* ATI Radeon family		*/
 #define FB_ACCEL_I810           39      /* Intel 810/815                */
+#define FB_ACCEL_SIS_GLAMOUR_2  40	/* SiS 315, 650, 740		*/
+#define FB_ACCEL_SIS_XABRE      41	/* SiS 330 ("Xabre")		*/
 
 #define FB_ACCEL_NEOMAGIC_NM2070 90	/* NeoMagic NM2070              */
 #define FB_ACCEL_NEOMAGIC_NM2090 91	/* NeoMagic NM2090              */
@@ -294,7 +296,7 @@
 	__u32 fg_color;		/* Only used when a mono bitmap */
 	__u32 bg_color;
 	__u8  depth;		/* Depth of the image */
-	char  *data;		/* Pointer to image data */
+	const char *data;	/* Pointer to image data */
 	struct fb_cmap cmap;	/* color map info */
 };
 
@@ -307,8 +309,8 @@
 #define FB_CUR_SETHOT   0x04
 #define FB_CUR_SETCMAP  0x08
 #define FB_CUR_SETSHAPE 0x10
-#define FB_CUR_SETDEST	0x20
-#define FB_CUR_SETSIZE	0x40
+#define FB_CUR_SETSIZE	0x20
+#define FB_CUR_SETDEST	0x40
 #define FB_CUR_SETALL   0xFF
 
 struct fbcurpos {
@@ -325,10 +327,27 @@
 	struct fb_image	image;	/* Cursor image */
 };
 
+#define FB_PIXMAP_DEFAULT 1     /* used internally by fbcon */
+#define FB_PIXMAP_SYSTEM  2     /* memory is in system RAM  */
+#define FB_PIXMAP_IO      4     /* memory is iomapped       */
+#define FB_PIXMAP_SYNC    256   /* set if GPU can DMA       */
+
+struct fb_pixmap {
+        __u8  *addr;                      /* pointer to memory             */  
+	__u32 size;                       /* size of buffer in bytes       */
+	__u32 offset;                     /* current offset to buffer      */
+	__u32 buf_align;                  /* byte alignment of each bitmap */
+	__u32 scan_align;                 /* alignment per scanline        */
+	__u32 flags;                      /* see FB_PIXMAP_*               */
+	void (*outbuf)(u8 dst, u8 *addr); /* access methods                */
+	u8   (*inbuf) (u8 *addr);
+	unsigned long lock_flags;         /* flags for locking             */
+	spinlock_t lock;                  /* spinlock                      */
+	atomic_t count;
+};
 #ifdef __KERNEL__
 
 #include <linux/fs.h>
-#include <linux/poll.h>
 #include <linux/init.h>
 #include <linux/devfs_fs_kernel.h>
 
@@ -360,17 +379,15 @@
     /* pan display */
     int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
     /* draws a rectangle */
-    void (*fb_fillrect)(struct fb_info *info, struct fb_fillrect *rect); 
+    void (*fb_fillrect)(struct fb_info *info, const struct fb_fillrect *rect); 
     /* Copy data from area to another */
-    void (*fb_copyarea)(struct fb_info *info, struct fb_copyarea *region); 
+    void (*fb_copyarea)(struct fb_info *info,const struct fb_copyarea *region); 
     /* Draws a image to the display */
-    void (*fb_imageblit)(struct fb_info *info, struct fb_image *image);
+    void (*fb_imageblit)(struct fb_info *info, const struct fb_image *image);
     /* Draws cursor */
     int (*fb_cursor)(struct fb_info *info, struct fb_cursor *cursor);
     /* Rotates the display */
     void (*fb_rotate)(struct fb_info *info, int angle);
-    /* perform polling on fb device */
-    int (*fb_poll)(struct fb_info *info, poll_table *wait);
     /* wait for blit idle, optional */
     int (*fb_sync)(struct fb_info *info);		
     /* perform fb specific ioctl (optional) */
@@ -390,13 +407,12 @@
    struct fb_monspecs monspecs;         /* Current Monitor specs */
    struct fb_cursor cursor;		/* Current cursor */	
    struct fb_cmap cmap;                 /* Current cmap */
+   struct fb_pixmap pixmap;	        /* Current pixmap */
    struct fb_ops *fbops;
    char *screen_base;                   /* Virtual address */
    struct vc_data *display_fg;		/* Console visible on this display */
    int currcon;				/* Current VC. */	
-   void *pseudo_palette;                /* Fake palette of 16 colors and 
-					   the cursor's color for non
-                                           palette mode */
+   void *pseudo_palette;                /* Fake palette of 16 colors */ 
    /* From here on everything is device dependent */
    void *par;	
 };
@@ -457,14 +473,21 @@
 extern int fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); 
 extern int fb_blank(int blank, struct fb_info *info);
 extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
-extern void cfb_fillrect(struct fb_info *info, struct fb_fillrect *rect); 
-extern void cfb_copyarea(struct fb_info *info, struct fb_copyarea *area); 
-extern void cfb_imageblit(struct fb_info *info, struct fb_image *image);
+extern void cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); 
+extern void cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); 
+extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
 
 /* drivers/video/fbmem.c */
 extern int register_framebuffer(struct fb_info *fb_info);
 extern int unregister_framebuffer(struct fb_info *fb_info);
+extern int fb_prepare_logo(struct fb_info *fb_info);
 extern int fb_show_logo(struct fb_info *fb_info);
+extern u32 fb_get_buffer_offset(struct fb_info *info, u32 size);
+extern void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
+			     	u32 height, u32 mask, u32 shift_high, u32 shift_low,
+				u32 mod, u32 idx);
+extern void move_buf_aligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
+			     u32 s_pitch, u32 height);
 extern struct fb_info *registered_fb[FB_MAX];
 extern int num_registered_fb;
 
diff -Nru a/include/linux/file.h b/include/linux/file.h
--- a/include/linux/file.h	Fri Nov 15 11:14:31 2002
+++ b/include/linux/file.h	Mon Mar 17 21:32:04 2003
@@ -40,6 +40,9 @@
 extern void put_filp(struct file *);
 extern int get_unused_fd(void);
 extern void FASTCALL(put_unused_fd(unsigned int fd));
+struct kmem_cache_s;
+extern void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags);
+extern void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags);
 
 extern struct file ** alloc_fd_array(int);
 extern int expand_fd_array(struct files_struct *, int nr);
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	Wed Mar 12 11:10:29 2003
+++ b/include/linux/fs.h	Sat Mar 22 22:14:19 2003
@@ -110,6 +110,7 @@
 #define MS_REC		16384
 #define MS_VERBOSE	32768
 #define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
+#define MS_ONE_SECOND	(1<<17)	/* fs has 1 sec a/m/ctime resolution */
 #define MS_ACTIVE	(1<<30)
 #define MS_NOUSER	(1<<31)
 
@@ -165,6 +166,7 @@
 #define IS_NOATIME(inode)	(__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
 #define IS_NODIRATIME(inode)	__IS_FLG(inode, MS_NODIRATIME)
 #define IS_POSIXACL(inode)	__IS_FLG(inode, MS_POSIXACL)
+#define IS_ONE_SECOND(inode)	__IS_FLG(inode, MS_ONE_SECOND)
 
 #define IS_DEADDIR(inode)	((inode)->i_flags & S_DEAD)
 
@@ -329,12 +331,6 @@
 	struct address_space	*assoc_mapping;	/* ditto */
 };
 
-struct char_device {
-	struct list_head	hash;
-	atomic_t		count;
-	dev_t			dev;
-};
-
 struct block_device {
 	struct list_head	bd_hash;
 	atomic_t		bd_count;
@@ -386,7 +382,6 @@
 	struct list_head	i_devices;
 	struct pipe_inode_info	*i_pipe;
 	struct block_device	*i_bdev;
-	struct char_device	*i_cdev;
 
 	unsigned long		i_dnotify_mask; /* Directory notify events */
 	struct dnotify_struct	*i_dnotify; /* for directory notifications */
@@ -1044,8 +1039,6 @@
 extern int bd_acquire(struct inode *inode);
 extern void bd_forget(struct inode *inode);
 extern void bdput(struct block_device *);
-extern struct char_device *cdget(dev_t);
-extern void cdput(struct char_device *);
 extern int blkdev_open(struct inode *, struct file *);
 extern int blkdev_close(struct inode *, struct file *);
 extern struct file_operations def_blk_fops;
@@ -1062,15 +1055,19 @@
 extern void blk_run_queues(void);
 
 /* fs/char_dev.c */
-extern int register_chrdev(unsigned int, const char *, struct file_operations *);
+extern int register_chrdev_region(unsigned int, unsigned int, int,
+				  const char *, struct file_operations *);
+extern int register_chrdev(unsigned int, const char *,
+			   struct file_operations *);
 extern int unregister_chrdev(unsigned int, const char *);
 extern int chrdev_open(struct inode *, struct file *);
 
 /* fs/block_dev.c */
-extern const char *__bdevname(dev_t);
-extern inline const char *bdevname(struct block_device *bdev)
+#define BDEVNAME_SIZE	32	/* Largest string for a blockdev identifier */
+extern const char *__bdevname(dev_t, char *buffer);
+extern inline const char *bdevname(struct block_device *bdev, char *buffer)
 {
-	return __bdevname(bdev->bd_dev);
+	return __bdevname(bdev->bd_dev, buffer);
 }
 extern struct block_device *lookup_bdev(const char *);
 extern struct block_device *open_bdev_excl(const char *, int, int, void *);
diff -Nru a/include/linux/i2c.h b/include/linux/i2c.h
--- a/include/linux/i2c.h	Thu Mar 13 16:39:32 2003
+++ b/include/linux/i2c.h	Thu Mar 20 12:07:43 2003
@@ -143,7 +143,10 @@
 	 * with the device.
 	 */
 	int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);
+
+	struct device_driver driver;
 };
+#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
 
 extern struct bus_type i2c_bus_type;
 
diff -Nru a/include/linux/i2o.h b/include/linux/i2o.h
--- a/include/linux/i2o.h	Sun Jul 21 08:20:20 2002
+++ b/include/linux/i2o.h	Thu Mar 13 12:35:36 2003
@@ -23,7 +23,7 @@
 #include <linux/i2o-dev.h>
 
 /* How many different OSM's are we allowing */
-#define MAX_I2O_MODULES		64
+#define MAX_I2O_MODULES		4
 
 /* How many OSMs can register themselves for device status updates? */
 #define I2O_MAX_MANAGERS	4
@@ -76,10 +76,16 @@
 };
 
 /*
- *	Resource data for each PCI I2O controller
+ * Each I2O controller has one of these objects
  */
-struct i2o_pci
+struct i2o_controller
 {
+	char name[16];
+	int unit;
+	int type;
+	int enabled;
+	
+	struct pci_dev *pdev;		/* PCI device */
 	int		irq;
 	int		short_req:1;	/* Use small block sizes        */
 	int		dpt:1;		/* Don't quiesce                */
@@ -88,25 +94,6 @@
 	int		mtrr_reg0;
 	int		mtrr_reg1;
 #endif
-};
-
-/*
- * Transport types supported by I2O stack
- */
-#define I2O_TYPE_PCI		0x01		/* PCI I2O controller */
-
-
-/*
- * Each I2O controller has one of these objects
- */
-struct i2o_controller
-{
-	struct pci_dev *pdev;		/* PCI device */
-
-	char name[16];
-	int unit;
-	int type;
-	int enabled;
 
 	struct notifier_block *event_notifer;	/* Events */
 	atomic_t users;
@@ -143,22 +130,6 @@
 
 	struct proc_dir_entry *proc_entry;	/* /proc dir */
 
-	union {					/* Bus information */
-		struct i2o_pci pci;
-	} bus;
-
-	/* Bus specific destructor */
-	void (*destructor)(struct i2o_controller *);
-
-	/* Bus specific attach/detach */
-	int (*bind)(struct i2o_controller *, struct i2o_device *);
-
-	/* Bus specific initiator */
-	int (*unbind)(struct i2o_controller *, struct i2o_device *);
-
-	/* Bus specific enable/disable */
-	void (*bus_enable)(struct i2o_controller *);
-	void (*bus_disable)(struct i2o_controller *);
 
 	void *page_frame;			/* Message buffers */
 	dma_addr_t page_frame_map;		/* Cache map */
diff -Nru a/include/linux/ide.h b/include/linux/ide.h
--- a/include/linux/ide.h	Wed Feb 19 09:48:49 2003
+++ b/include/linux/ide.h	Thu Mar 20 10:23:19 2003
@@ -280,9 +280,6 @@
 	return ((hwif)->chipset == chipset) ? 1 : 0;		\
 }
 
-#define IDE_DEBUG(lineno) \
-	printk("%s,%s,line=%d\n", __FILE__, __FUNCTION__, (lineno))
-
 /*
  * Check for an interrupt and acknowledge the interrupt status
  */
@@ -302,7 +299,8 @@
 		ide_qd65xx,	ide_umc8672,	ide_ht6560b,
 		ide_pdc4030,	ide_rz1000,	ide_trm290,
 		ide_cmd646,	ide_cy82c693,	ide_4drives,
-		ide_pmac,	ide_etrax100,	ide_acorn
+		ide_pmac,	ide_etrax100,	ide_acorn,
+		ide_pc9800
 } hwif_chipset_t;
 
 /*
@@ -341,10 +339,7 @@
 #include <asm/ide.h>
 
 /* Currently only m68k, apus and m8xx need it */
-#ifdef IDE_ARCH_ACK_INTR
-extern int ide_irq_lock;
-# define ide_ack_intr(hwif) (hwif->hw.ack_intr ? hwif->hw.ack_intr(hwif) : 1)
-#else
+#ifndef IDE_ARCH_ACK_INTR
 # define ide_ack_intr(hwif) (1)
 #endif
 
@@ -731,6 +726,7 @@
 
 	unsigned present	: 1;	/* drive is physically present */
 	unsigned dead		: 1;	/* device ejected hint */
+	unsigned id_read	: 1;	/* 1=id read from disk 0 = synthetic */
 	unsigned noprobe 	: 1;	/* from:  hdx=noprobe */
 	unsigned removable	: 1;	/* 1 if need to do check_media_change */
 	unsigned is_flash	: 1;	/* 1 if probed as flash */
@@ -850,7 +846,7 @@
 #define task_rq_offset(rq) \
 	(((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE)
 
-extern inline void *ide_map_buffer(struct request *rq, unsigned long *flags)
+static inline void *ide_map_buffer(struct request *rq, unsigned long *flags)
 {
 	/*
 	 * fs request
@@ -864,7 +860,7 @@
 	return rq->buffer + task_rq_offset(rq);
 }
 
-extern inline void ide_unmap_buffer(struct request *rq, char *buffer, unsigned long *flags)
+static inline void ide_unmap_buffer(struct request *rq, char *buffer, unsigned long *flags)
 {
 	if (rq->bio)
 		bio_kunmap_irq(buffer, flags);
@@ -978,7 +974,7 @@
 	ide_startstop_t (*ide_dma_queued_start)(ide_drive_t *drive);
 
 	void (*OUTB)(u8 addr, unsigned long port);
-	void (*OUTBSYNC)(u8 addr, unsigned long port);
+	void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port);
 	void (*OUTW)(u16 addr, unsigned long port);
 	void (*OUTL)(u32 addr, unsigned long port);
 	void (*OUTSW)(unsigned long port, void *addr, u32 count);
@@ -1184,6 +1180,7 @@
 	int		(*end_request)(ide_drive_t *, int, int);
 	u8		(*sense)(ide_drive_t *, const char *, u8);
 	ide_startstop_t	(*error)(ide_drive_t *, const char *, u8);
+	ide_startstop_t	(*abort)(ide_drive_t *, const char *);
 	int		(*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
 	void		(*pre_reset)(ide_drive_t *);
 	unsigned long	(*capacity)(ide_drive_t *);
@@ -1283,6 +1280,13 @@
 ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat);
 
 /*
+ * Abort a running command on the controller triggering the abort
+ * from a host side, non error situation
+ * (drive, msg)
+ */
+extern ide_startstop_t ide_abort(ide_drive_t *, const char *);
+
+/*
  * Issue a simple drive command
  * The drive must be selected beforehand.
  *
@@ -1330,12 +1334,6 @@
 extern ide_startstop_t ide_do_reset (ide_drive_t *);
 
 /*
- * Re-Start an operation for an IDE interface.
- * The caller should return immediately after invoking this.
- */
-extern int restart_request (ide_drive_t *, struct request *);
-
-/*
  * This function is intended to be used prior to invoking ide_do_drive_cmd().
  */
 extern void ide_init_drive_cmd (struct request *rq);
@@ -1730,6 +1728,19 @@
 extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate);
 
 extern spinlock_t ide_lock;
+extern struct semaphore ide_cfg_sem;
+/*
+ * Structure locking:
+ *
+ * ide_cfg_sem and ide_lock together protect changes to
+ * ide_hwif_t->{next,hwgroup}
+ * ide_drive_t->next
+ *
+ * ide_hwgroup_t->busy: ide_lock
+ * ide_hwgroup_t->hwif: ide_lock
+ * ide_hwif_t->mate: constant, no locking
+ * ide_drive_t->hwif: constant, no locking
+ */
 
 #define local_irq_set(flags)	do { local_save_flags((flags)); local_irq_enable(); } while (0)
 
diff -Nru a/include/linux/in6.h b/include/linux/in6.h
--- a/include/linux/in6.h	Fri Feb 21 23:42:02 2003
+++ b/include/linux/in6.h	Thu Mar 20 21:23:30 2003
@@ -65,6 +65,8 @@
 	int		ipv6mr_ifindex;
 };
 
+#define ipv6mr_acaddr	ipv6mr_multiaddr
+
 struct in6_flowlabel_req
 {
 	struct in6_addr	flr_dst;
@@ -166,6 +168,8 @@
 #define IPV6_MTU		24
 #define IPV6_RECVERR		25
 #define IPV6_V6ONLY		26
+#define IPV6_JOIN_ANYCAST	27
+#define IPV6_LEAVE_ANYCAST	28
 
 /* IPV6_MTU_DISCOVER values */
 #define IPV6_PMTUDISC_DONT		0
@@ -175,6 +179,9 @@
 /* Flowlabel */
 #define IPV6_FLOWLABEL_MGR	32
 #define IPV6_FLOWINFO_SEND	33
+
+#define IPV6_IPSEC_POLICY	34
+#define IPV6_XFRM_POLICY	35
 
 
 #endif
diff -Nru a/include/linux/ioctl32.h b/include/linux/ioctl32.h
--- a/include/linux/ioctl32.h	Tue Oct 15 16:46:15 2002
+++ b/include/linux/ioctl32.h	Sat Mar 22 22:14:58 2003
@@ -3,7 +3,7 @@
 
 struct file;
 
-int sys_ioctl(unsigned int, unsigned int, unsigned long);
+extern long sys_ioctl(unsigned int, unsigned int, unsigned long);
 
 /* 
  * Register an 32bit ioctl translation handler for ioctl cmd.
diff -Nru a/include/linux/ioport.h b/include/linux/ioport.h
--- a/include/linux/ioport.h	Sat Feb 22 07:31:27 2003
+++ b/include/linux/ioport.h	Sat Mar 22 19:24:54 2003
@@ -100,6 +100,7 @@
 /* Convenience shorthand with allocation */
 #define request_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name))
 #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name))
+#define rename_region(region, newname) do { (region)->name = (newname); } while (0)
 
 extern struct resource * __request_region(struct resource *, unsigned long start, unsigned long n, const char *name);
 
diff -Nru a/include/linux/ip.h b/include/linux/ip.h
--- a/include/linux/ip.h	Fri Oct 25 03:06:44 2002
+++ b/include/linux/ip.h	Wed Mar 19 19:42:50 2003
@@ -18,8 +18,6 @@
 #define _LINUX_IP_H
 #include <asm/byteorder.h>
 
-/* SOL_IP socket options */
-
 #define IPTOS_TOS_MASK		0x1E
 #define IPTOS_TOS(tos)		((tos)&IPTOS_TOS_MASK)
 #define	IPTOS_LOWDELAY		0x10
@@ -66,14 +64,6 @@
 #define IPVERSION	4
 #define MAXTTL		255
 #define IPDEFTTL	64
-
-/* struct timestamp, struct route and MAX_ROUTES are removed.
-
-   REASONS: it is clear that nobody used them because:
-   - MAX_ROUTES value was wrong.
-   - "struct route" was wrong.
-   - "struct timestamp" had fatally misaligned bitfields and was completely unusable.
- */
 
 #define IPOPT_OPTVAL 0
 #define IPOPT_OLEN   1
diff -Nru a/include/linux/ipv6.h b/include/linux/ipv6.h
--- a/include/linux/ipv6.h	Wed Mar  5 15:45:36 2003
+++ b/include/linux/ipv6.h	Wed Mar 19 17:25:49 2003
@@ -172,6 +172,7 @@
 				ipv6only:1;
 
 	struct ipv6_mc_socklist	*ipv6_mc_list;
+	struct ipv6_ac_socklist	*ipv6_ac_list;
 	struct ipv6_fl_socklist *ipv6_fl_list;
 	__u32			dst_cookie;
 
diff -Nru a/include/linux/jbd.h b/include/linux/jbd.h
--- a/include/linux/jbd.h	Mon Feb 10 19:20:37 2003
+++ b/include/linux/jbd.h	Sat Mar 22 22:14:52 2003
@@ -633,6 +633,10 @@
 	/* The revoke table: maintains the list of revoked blocks in the */
         /*  current transaction. */
 	struct jbd_revoke_table_s *j_revoke;
+
+	/* An opaque pointer to fs-private information.  ext3 puts its
+	 * superblock pointer here */
+	void *j_private;
 };
 
 /* 
diff -Nru a/include/linux/linux_logo.h b/include/linux/linux_logo.h
--- a/include/linux/linux_logo.h	Mon Feb  4 23:41:04 2002
+++ b/include/linux/linux_logo.h	Thu Feb 13 18:50:30 2003
@@ -1,1420 +1,37 @@
-/* $Id: linux_logo.h,v 1.5 1998/07/30 16:30:58 jj Exp $
- * include/linux/linux_logo.h: This is a linux logo
- *                             to be displayed on boot.
+#ifndef _LINUX_LINUX_LOGO_H
+#define _LINUX_LINUX_LOGO_H
+
+/*
+ *  Linux logo to be displayed on boot
  *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1996,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ *  Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
+ *  Copyright (C) 1996,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ *  Copyright (C) 2001 Greg Banks <gnb@alphalink.com.au>
+ *  Copyright (C) 2001 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+ *  Copyright (C) 2003 Geert Uytterhoeven <geert@linux-m68k.org>
  *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * image size has to be 80x80
- * values have to start from 0x20
- * (i.e. RGB(linux_logo_red[0],
- *           linux_logo_green[0],
- *           linux_logo_blue[0]) is color 0x20)
- * BW image has to be 80x80 as well, with MS bit
- * on the left
- * Serial_console ascii image can be any size,
- * but should contain %s to display the version
+ *  Serial_console ascii image can be any size,
+ *  but should contain %s to display the version
  */
 
-#ifndef __HAVE_ARCH_LINUX_LOGO
-#define LINUX_LOGO_COLORS	187
-#endif
+#include <linux/init.h>
 
-#ifdef INCLUDE_LINUX_LOGO_DATA
 
-#ifndef __HAVE_ARCH_LINUX_LOGO
+#define LINUX_LOGO_MONO		1	/* monochrome black/white */
+#define LINUX_LOGO_VGA16	2	/* 16 colors VGA text palette */
+#define LINUX_LOGO_CLUT224	3	/* 224 colors */
+#define LINUX_LOGO_GRAY256	4	/* 256 levels grayscale */
 
-unsigned char linux_logo_red[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79,
-    0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
-    0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
-    0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
-    0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
-    0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c,
-    0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e,
-    0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c,
-    0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x12,
-    0x4a, 0x8e, 0xf2, 0xf6, 0xf6, 0xee, 0xb5, 0xe4,
-    0xf1, 0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x16,
-    0x9a, 0x2e, 0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62,
-    0xd6, 0xa3, 0x74, 0xa7, 0xa2, 0xca, 0xe0, 0xae,
-    0xbe, 0xce, 0xa3, 0x8e, 0x6d, 0x8e, 0x32, 0xaf,
-    0x50, 0x9e, 0x5b, 0x8a, 0x98, 0x82, 0x7a, 0x82,
-    0x56, 0x7c, 0x8a, 0x56, 0x5e, 0x86, 0x6a, 0x52,
-    0x59, 0x64, 0x5e,
-};
 
-unsigned char linux_logo_green[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c,
-    0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
-    0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
-    0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
-    0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
-    0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76,
-    0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46,
-    0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b,
-    0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x0e,
-    0x36, 0x86, 0xba, 0xbe, 0xe6, 0xcc, 0x8e, 0xb8,
-    0xc4, 0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x12,
-    0x7a, 0x20, 0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46,
-    0xa6, 0x6e, 0x51, 0x72, 0x92, 0xa2, 0xa6, 0x87,
-    0x96, 0xa2, 0x85, 0x7a, 0x6a, 0x6e, 0x22, 0x76,
-    0x36, 0x76, 0x3c, 0x6e, 0x63, 0x53, 0x66, 0x62,
-    0x42, 0x50, 0x56, 0x42, 0x56, 0x56, 0x56, 0x3e,
-    0x51, 0x52, 0x56,
+struct linux_logo {
+	int type;			/* one of LINUX_LOGO_* */
+	unsigned int width;
+	unsigned int height;
+	unsigned int clutsize;		/* LINUX_LOGO_CLUT224 only */
+	const unsigned char *clut;	/* LINUX_LOGO_CLUT224 only */
+	const unsigned char *data;
 };
 
-unsigned char linux_logo_blue[] __initdata = {
-    0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-    0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-    0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65,
-    0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-    0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-    0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-    0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08,
-    0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
-    0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
-    0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
-    0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
-    0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a,
-    0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e,
-    0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b,
-    0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c,
-    0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x06,
-    0x0e, 0x6a, 0x0e, 0x0e, 0xbe, 0x5b, 0x2c, 0x3e,
-    0x0e, 0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x06,
-    0x2e, 0x06, 0x4e, 0x36, 0x06, 0x58, 0x24, 0x06,
-    0x3a, 0x08, 0x08, 0x07, 0x5e, 0x45, 0x0a, 0x32,
-    0x2e, 0x2a, 0x43, 0x48, 0x5f, 0x2e, 0x06, 0x06,
-    0x07, 0x24, 0x06, 0x32, 0x06, 0x06, 0x46, 0x2e,
-    0x22, 0x06, 0x06, 0x1e, 0x4c, 0x06, 0x3a, 0x22,
-    0x42, 0x34, 0x42,
-};
-
-unsigned char linux_logo[] __initdata = {
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
-    0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-    0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
-    0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
-    0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
-    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-    0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
-    0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-    0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
-    0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34,
-    0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
-    0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22,
-    0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25,
-    0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
-    0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
-    0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-    0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
-    0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-    0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36,
-    0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
-    0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21,
-    0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
-    0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
-    0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
-    0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32,
-    0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a,
-    0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b,
-    0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37,
-    0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
-    0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
-    0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
-    0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
-    0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67,
-    0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
-    0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
-    0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
-    0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78,
-    0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21,
-    0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79,
-    0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c,
-    0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
-    0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
-    0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36,
-    0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
-    0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89,
-    0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36,
-    0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
-    0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e,
-    0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
-    0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22,
-    0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
-    0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c,
-    0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51,
-    0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
-    0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97,
-    0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98,
-    0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
-    0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32,
-    0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50,
-    0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
-    0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
-    0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98,
-    0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
-    0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
-    0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b,
-    0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48,
-    0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-    0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-    0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
-    0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
-    0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c,
-    0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c,
-    0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
-    0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93,
-    0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28,
-    0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
-    0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93,
-    0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
-    0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x99, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
-    0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30,
-    0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c,
-    0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36,
-    0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36,
-    0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
-    0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36,
-    0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
-    0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d,
-    0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
-    0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30,
-    0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32,
-    0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a,
-    0x36, 0x24, 0x4f, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x47, 0x32, 0x30,
-    0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
-    0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25,
-    0x36, 0x3a, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x9b, 0x52, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21,
-    0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36,
-    0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
-    0x23, 0x43, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x47, 0x99, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36,
-    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-    0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36,
-    0x2e, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x99, 0x99, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x98, 0x36,
-    0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-    0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36,
-    0x54, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x4c, 0x99, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
-    0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36,
-    0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
-    0x43, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x4c, 0x99, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4b, 0x21,
-    0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25,
-    0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x4f, 0x52, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x21,
-    0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a,
-    0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x4f, 0x99, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x22,
-    0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
-    0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x23,
-    0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31,
-    0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x46, 0x22,
-    0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d,
-    0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
-    0x24, 0x27, 0x9f, 0x24, 0x25, 0x28, 0x21, 0x36,
-    0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
-    0x39, 0x4d, 0xa0, 0x84, 0x81, 0x57, 0x21, 0x39,
-    0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x53, 0x28,
-    0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
-    0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
-    0x2d, 0xa1, 0x7a, 0xa2, 0xa3, 0xa3, 0x7f, 0x22,
-    0x51, 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0xa4, 0xa5, 0xa5, 0xa6, 0x61,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
-    0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
-    0x4d, 0x91, 0x5b, 0xa2, 0xa3, 0xa3, 0xa3, 0x5a,
-    0x21, 0x2e, 0x46, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0xa7, 0xa8, 0x69, 0x66, 0xa9,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
-    0x83, 0xaa, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a,
-    0x60, 0x85, 0xab, 0xac, 0xa3, 0xa3, 0xa3, 0x82,
-    0x86, 0x36, 0x32, 0x3f, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x4c, 0x99, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0xad, 0xa2, 0xa8, 0xae, 0xaf,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57,
-    0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x23, 0x30, 0x31, 0xb0, 0x91, 0x7e, 0x90, 0x90,
-    0x8b, 0x5b, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0x5d, 0xb1, 0x36, 0x24, 0x53, 0x9b, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x9b, 0x99, 0xad, 0x64, 0x5c, 0x8b, 0xb1,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
-    0x82, 0x5c, 0xb2, 0x2a, 0x23, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x24, 0x2b, 0xb0, 0x8b, 0x5b, 0x76, 0x5b, 0x5b,
-    0x7b, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa8, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x99, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x4f, 0x3f, 0xb3, 0x7b, 0x7b, 0x85, 0x80,
-    0x9f, 0x36, 0x36, 0x36, 0x21, 0xb4, 0x7e, 0x7b,
-    0x64, 0x64, 0xb5, 0x35, 0x24, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x31, 0xb6, 0x5b, 0x64, 0xa2, 0xa2, 0xac,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0x66, 0xb7, 0x36, 0x36, 0x36, 0x2c, 0x4b,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x9a, 0x3f, 0xb8, 0x76, 0x76, 0x7a, 0x63,
-    0xb9, 0xba, 0x86, 0xba, 0xbb, 0x90, 0x5b, 0x64,
-    0xa2, 0xa2, 0xbc, 0x2d, 0x27, 0x23, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x26, 0x2d, 0x91, 0x5b, 0x64, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa8, 0x83, 0xaf, 0x36, 0x36, 0x36, 0x30,
-    0x44, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x9b, 0x9a, 0x3f, 0xbd, 0x5b, 0x7b, 0xbe, 0x85,
-    0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xa2, 0xa3,
-    0xa3, 0xac, 0x5d, 0xb5, 0x39, 0x26, 0x23, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2d, 0xbf, 0xbe, 0x64, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa8, 0x88, 0x36, 0x36, 0x36, 0x36,
-    0x2d, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x9b, 0x45, 0x3f, 0xc0, 0x6d, 0x7b, 0xab, 0xbe,
-    0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa2, 0xc1, 0x37, 0x35, 0x26, 0x23,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2e, 0xbf, 0x7a, 0x7b, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa8, 0x72, 0x73, 0x36, 0x36, 0x36,
-    0x24, 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x46, 0x42, 0xb6, 0x7a, 0x7b, 0x64, 0x7b,
-    0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xa2, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xac, 0x64, 0xc1, 0x4d, 0x2c, 0x27,
-    0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x25, 0x31, 0xc2, 0x8b, 0x7b, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa8, 0x89, 0x9f, 0x36, 0x36,
-    0x32, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xa2, 0xac,
-    0xa2, 0x64, 0x64, 0xa2, 0xa2, 0xac, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x5d, 0xc3, 0x2c,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x25, 0x31, 0xc2, 0x85, 0x7b, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0x66, 0x57, 0x27, 0x4d,
-    0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x99, 0x34, 0x9f, 0xb9, 0x7a, 0x7b, 0xa2, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xc2,
-    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-    0x26, 0x2d, 0xc2, 0x85, 0x7b, 0xac, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa8, 0x5f, 0x92, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
-    0x35, 0x36, 0xaf, 0xbb, 0x7a, 0x7b, 0xac, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0xa2, 0xc0,
-    0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x30, 0x2f, 0xb6, 0x8b, 0x7b, 0xac, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x66, 0x89, 0x45,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25,
-    0x36, 0x36, 0x61, 0xb9, 0x6d, 0x64, 0xac, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x7b, 0xbe, 0xc3,
-    0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0xc4, 0x63, 0xbe, 0xa2, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x72, 0x81, 0xc5,
-    0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-    0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36,
-    0x36, 0x36, 0xc6, 0x8f, 0x6d, 0x64, 0xac, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa2, 0xab, 0x8b, 0xb0, 0x2c,
-    0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x35, 0x96, 0x75, 0xab, 0xa2, 0xac, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x7b, 0x81, 0xb9,
-    0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b,
-    0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x73, 0xb9, 0x7a, 0x7b, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0x64, 0x76, 0x7a, 0x91, 0xb5, 0x31, 0x30,
-    0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-    0x39, 0x97, 0x75, 0xbe, 0x7b, 0x64, 0xa2, 0xa2,
-    0xac, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x7b, 0x7a, 0xc7,
-    0xc8, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
-    0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xc8, 0xbb, 0x8b, 0x7b, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x64, 0x64,
-    0x76, 0x85, 0xbf, 0xb5, 0x34, 0x2b, 0x27, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-    0x33, 0xc9, 0x63, 0x7e, 0x7a, 0x6d, 0xbe, 0x5b,
-    0x76, 0x7b, 0x64, 0x64, 0xa2, 0xac, 0xa3, 0xa3,
-    0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x76, 0x85, 0xb9,
-    0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xca, 0xbb, 0x75, 0x76, 0xa2, 0xa3,
-    0xa3, 0xa3, 0xac, 0xa2, 0x64, 0x76, 0xbe, 0x8b,
-    0xb6, 0xb5, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-    0x27, 0x31, 0xcb, 0xc9, 0xbb, 0x74, 0x63, 0x90,
-    0x7e, 0x75, 0x8b, 0x6d, 0xbe, 0x76, 0x64, 0xa2,
-    0xac, 0xac, 0xac, 0xac, 0x64, 0x7a, 0x84, 0xcc,
-    0x79, 0x9f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-    0x36, 0x21, 0xc8, 0xcc, 0x63, 0x6d, 0x7b, 0x64,
-    0xac, 0xa2, 0x64, 0x7b, 0xbe, 0x75, 0x63, 0x96,
-    0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x28, 0x27, 0x35, 0x2d, 0x41, 0xb5, 0xc5, 0x8f,
-    0xb9, 0xbb, 0xc7, 0x74, 0x84, 0x90, 0x85, 0x6d,
-    0x5b, 0x7b, 0x7b, 0xab, 0x6d, 0x90, 0xb9, 0xcd,
-    0xca, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
-    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
-    0x36, 0x21, 0xb4, 0x80, 0xc7, 0x7e, 0x6d, 0x76,
-    0xab, 0x76, 0x6d, 0x85, 0x63, 0xb9, 0xb5, 0x34,
-    0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
-    0x41, 0xce, 0xcf, 0x6c, 0x80, 0xcc, 0xb9, 0x74,
-    0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xcd, 0x79,
-    0xc6, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d,
-    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38,
-    0x4d, 0x37, 0xd0, 0xd1, 0x8f, 0x74, 0x63, 0x7e,
-    0x75, 0x7e, 0x63, 0xc7, 0x88, 0xc4, 0x31, 0x2a,
-    0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
-    0x33, 0x39, 0x2e, 0x51, 0x41, 0xb2, 0x6c, 0xd1,
-    0x80, 0xcc, 0xcc, 0xcc, 0xd2, 0xd1, 0xb7, 0xd3,
-    0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
-    0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
-    0x2b, 0x34, 0xd4, 0xca, 0xd5, 0x8f, 0xbb, 0xc7,
-    0xc7, 0xbb, 0xcc, 0x6c, 0x41, 0x39, 0x27, 0x28,
-    0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
-    0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41,
-    0xd6, 0xb7, 0x79, 0x79, 0x79, 0xca, 0xd7, 0x51,
-    0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
-    0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
-    0x24, 0x2a, 0x31, 0xd8, 0xc8, 0x79, 0xd1, 0x80,
-    0xd5, 0xba, 0xd9, 0x2f, 0x35, 0x26, 0x23, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
-    0x31, 0x2f, 0xd4, 0xd8, 0xd8, 0x2f, 0x2e, 0x33,
-    0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x21, 0x28, 0x27, 0x35, 0x34, 0xd8, 0xd8, 0xd8,
-    0xda, 0xd4, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
-    0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
-    0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
-    0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-    0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
-    0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-};
-
-#endif /* !__HAVE_ARCH_LINUX_LOGO */
-
-#ifndef __HAVE_ARCH_LINUX_LOGOBW
-
-unsigned char linux_logo_bw[] __initdata = {
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xcf, 0xf3, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xbf, 0xfc, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfd, 0xff, 0xf3, 0xdf, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfd, 0xff, 0xf7, 0xef, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x9f, 0x87, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x0f, 0x03, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x67, 0x33, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xe7, 0x79, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xf7, 0x79, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xff, 0xf9, 0xf7, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x60, 0x3b, 0xf7, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x89, 0x07, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x00, 0x03, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x00, 0x0d, 0xfb, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x80, 0x33, 0xfd, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xc0, 0xc3, 0xfd, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0xff, 0x0d, 0xdd, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xfb, 0x40, 0x31, 0xee, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf7, 0x20, 0xc1, 0xee, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf7, 0x1f, 0x00, 0xff, 0x7f, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x7f, 0xbf, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xee, 0x00, 0x00, 0x7f, 0xbf, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xde, 0x00, 0x00, 0x7f, 0xdf, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xbc, 0x00, 0x00, 0x3f, 0xef, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x3f, 0xf7, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x1f, 0xf7, 0xff, 0xff,
-    0xff, 0xff, 0xfe, 0xff, 0x1c, 0x07, 0xdf, 0xfb, 0xff, 0xff,
-    0xff, 0xff, 0xfd, 0xfc, 0x08, 0x0f, 0xef, 0xfd, 0xff, 0xff,
-    0xff, 0xff, 0xfd, 0xf8, 0x00, 0x01, 0xef, 0xfd, 0xff, 0xff,
-    0xff, 0xff, 0xfb, 0xf0, 0x00, 0x00, 0x7f, 0xfe, 0xff, 0xff,
-    0xff, 0xff, 0xfb, 0xe0, 0x00, 0x00, 0x1f, 0xfe, 0xff, 0xff,
-    0xff, 0xff, 0xf7, 0xe0, 0x00, 0x00, 0x07, 0xbf, 0x7f, 0xff,
-    0xff, 0xff, 0xf7, 0xc0, 0x00, 0x00, 0x03, 0xbf, 0x7f, 0xff,
-    0xff, 0xff, 0xef, 0xc0, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
-    0xff, 0xff, 0xef, 0x80, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
-    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
-    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x01, 0xef, 0xdf, 0xff,
-    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x01, 0xef, 0xdf, 0xff,
-    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
-    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
-    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
-    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
-    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x03, 0x03, 0xdf, 0xff,
-    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x02, 0xfd, 0xdf, 0xff,
-    0xff, 0xff, 0xa3, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xdf, 0xff,
-    0xff, 0xff, 0xc1, 0xc0, 0x00, 0x00, 0x11, 0xff, 0x3f, 0xff,
-    0xff, 0xff, 0x80, 0xe0, 0x00, 0x00, 0x21, 0xfe, 0x3f, 0xff,
-    0xff, 0xff, 0x00, 0x70, 0x00, 0x00, 0x21, 0xfc, 0x3f, 0xff,
-    0xff, 0xfe, 0x00, 0x3c, 0x00, 0x00, 0x20, 0xf8, 0x3f, 0xff,
-    0xff, 0xf0, 0x00, 0x3e, 0x00, 0x00, 0x20, 0x00, 0x3f, 0xff,
-    0xff, 0xc0, 0x00, 0x1f, 0x00, 0x00, 0x20, 0x00, 0x3f, 0xff,
-    0xff, 0xc0, 0x00, 0x1f, 0x80, 0x00, 0x20, 0x00, 0x1f, 0xff,
-    0xff, 0xc0, 0x00, 0x0f, 0x80, 0x00, 0x20, 0x00, 0x07, 0xff,
-    0xff, 0xc0, 0x00, 0x07, 0x80, 0x00, 0x20, 0x00, 0x03, 0xff,
-    0xff, 0xc0, 0x00, 0x07, 0x80, 0x00, 0x60, 0x00, 0x01, 0xff,
-    0xff, 0xc0, 0x00, 0x02, 0x00, 0x00, 0xe0, 0x00, 0x01, 0xff,
-    0xff, 0xc0, 0x00, 0x01, 0x00, 0x01, 0xe0, 0x00, 0x01, 0xff,
-    0xff, 0xc0, 0x00, 0x00, 0x80, 0x07, 0xe0, 0x00, 0x03, 0xff,
-    0xff, 0xc0, 0x00, 0x00, 0x80, 0x3f, 0xe0, 0x00, 0x0f, 0xff,
-    0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x1f, 0xff,
-    0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x7f, 0xff,
-    0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0xff, 0xff,
-    0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x03, 0xff, 0xff,
-    0xff, 0xff, 0xc0, 0x00, 0x70, 0x00, 0xc0, 0x07, 0xff, 0xff,
-    0xff, 0xff, 0xfc, 0x00, 0x8f, 0xff, 0x20, 0x0f, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-};
-
-#endif /* !__HAVE_ARCH_LINUX_LOGOBW */
-
-#ifndef __HAVE_ARCH_LINUX_LOGO16
-
-unsigned char linux_logo16[] __initdata = {
-    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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x88, 0x88, 0x88, 0x80, 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, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x88, 0x80, 0x00, 0x00, 0x08, 0x88, 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,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
-    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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-    0x80, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x88, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00,
-    0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80,
-    0x00, 0x80, 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, 0x00, 0x00, 0x00, 0x00, 0x80,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-    0x00, 0x08, 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, 0x00, 0x00, 0x00, 0x00, 0x80,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x08, 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, 0x00, 0x00, 0x00, 0x08, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x08, 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, 0x00, 0x00, 0x00, 0x08, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0x08, 0x70, 0x00, 0x00, 0x00, 0x77, 0x70, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0x87, 0x77, 0x00, 0x00, 0x07, 0xff, 0xf7, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x08,
-    0x77, 0xff, 0x00, 0x00, 0x7f, 0x77, 0xf7, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x08,
-    0x70, 0x0f, 0x80, 0x00, 0xf7, 0x08, 0x7f, 0x70,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x08,
-    0x80, 0x07, 0x80, 0x00, 0xf8, 0x00, 0x8f, 0x70,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x08,
-    0x70, 0x07, 0x88, 0x88, 0xf8, 0x00, 0x8f, 0x70,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0xf0, 0x06, 0xe6, 0xe6, 0xe6, 0x00, 0x8f, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0x77, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x77, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0x06, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00,
-    0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x08, 0x00,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60,
-    0x00, 0x00, 0x08, 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, 0x00, 0x00, 0x08, 0x80,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x60,
-    0x00, 0x00, 0x08, 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, 0x00, 0x00, 0x08, 0x80,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66, 0x66, 0x80,
-    0x08, 0x00, 0x00, 0x80, 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, 0x00, 0x08, 0x80,
-    0x86, 0xe6, 0xe6, 0xe6, 0x66, 0x66, 0x66, 0x80,
-    0x08, 0x78, 0x00, 0x80, 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, 0x00, 0x08, 0x80,
-    0x86, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x70,
-    0x00, 0x77, 0x00, 0x08, 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, 0x00, 0x08, 0x00,
-    0x87, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x78,
-    0x00, 0x88, 0x00, 0x08, 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, 0x00, 0x08, 0x00,
-    0x87, 0x76, 0x66, 0x66, 0x77, 0x77, 0xff, 0xf7,
-    0x00, 0x00, 0x00, 0x08, 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, 0x00, 0x80, 0x08,
-    0xff, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff,
-    0x80, 0x00, 0x00, 0x00, 0x80, 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, 0x80, 0x07,
-    0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff,
-    0x70, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x8f,
-    0xff, 0xf7, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff,
-    0xf0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x7f,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x87, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x77,
-    0xff, 0xf7, 0x77, 0xff, 0xff, 0xff, 0x77, 0x77,
-    0x77, 0x78, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x7f,
-    0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x77,
-    0x77, 0x78, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x7f, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x77, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x80, 0x80, 0x08, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x77, 0x80, 0x00, 0x08, 0x00, 0x00, 0x08,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0x78, 0x00, 0x08, 0x80, 0x00, 0x08,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x08, 0x08, 0x00, 0x8f, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xf7, 0x08, 0x80, 0x80, 0x00, 0x08,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xf7, 0x08, 0x80, 0x80, 0x00, 0x00,
-    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x80, 0x08, 0x07, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x80, 0x00, 0x08, 0x00, 0x00,
-    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x80, 0x80, 0x0f, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
-    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x08, 0x00, 0x80, 0x8f, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
-    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x08, 0x08, 0x00, 0x7f, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x80, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x00, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x00, 0x08, 0x08, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x00, 0x08, 0x08, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x88, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x00, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf0, 0x88, 0x88, 0x80, 0x00,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x08, 0x06, 0xe6, 0x00, 0x8f, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x08, 0x80,
-    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x6e, 0x6e, 0x60, 0x08, 0xff, 0xff, 0xff,
-    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xff, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x88,
-    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x06, 0xe6, 0xe6, 0xe6, 0x00, 0x8f, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xfe, 0x6e, 0x60, 0x00, 0x00, 0x00, 0x00,
-    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x08, 0xff, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xf6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x06,
-    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x8f, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0xfe, 0x6e, 0x60, 0x00, 0x00, 0x00, 0x0e,
-    0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x00, 0x08, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xff, 0x76, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0xe6,
-    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x8f,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x7e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x00, 0x08,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x76, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00,
-    0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x7e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x00,
-    0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x76, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00,
-    0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0xf7, 0x8e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x88,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-    0x78, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xef,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7,
-    0x80, 0x06, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78,
-    0x00, 0x06, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x80,
-    0x00, 0x06, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x0e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
-    0x67, 0xff, 0xff, 0xff, 0xff, 0x78, 0x80, 0x00,
-    0x00, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x86, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-    0x66, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x0e, 0x6e, 0x6e, 0x6e,
-    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
-    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x86, 0x6e, 0x6e, 0x6e, 0x6e, 0x66, 0x66,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66,
-    0x66, 0x66, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
-    0x60, 0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x80,
-    0x00, 0x06, 0x66, 0xe6, 0xe6, 0xe6, 0x66, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x66, 0x66, 0x66, 0x66, 0xe6, 0xe6, 0x66,
-    0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-    0x88, 0x86, 0x66, 0x6e, 0x6e, 0x66, 0x60, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x06, 0x66, 0x66, 0x66, 0x66,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x06, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x06, 0x66, 0x66, 0x60,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x66, 0x66, 0x66, 0x60, 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, 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,
-    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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-#endif /* !__HAVE_ARCH_LINUX_LOGO16 */
-
-#else /* !INCLUDE_LINUX_LOGO_DATA */
-
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16[];
-
-#endif /* !INCLUDE_LINUX_LOGO_DATA */
+extern const struct linux_logo * __init fb_find_logo(int type);
 
+#endif /* _LINUX_LINUX_LOGO_H */
diff -Nru a/include/linux/list.h b/include/linux/list.h
--- a/include/linux/list.h	Sat Mar 15 09:52:23 2003
+++ b/include/linux/list.h	Thu Mar 20 18:25:39 2003
@@ -84,7 +84,7 @@
 {
 	new->next = next;
 	new->prev = prev;
-	wmb();
+	smp_wmb();
 	next->prev = new;
 	prev->next = new;
 }
@@ -303,11 +303,11 @@
  */
 #define list_for_each_rcu(pos, head) \
 	for (pos = (head)->next, prefetch(pos->next); pos != (head); \
-        	pos = pos->next, ({ read_barrier_depends(); 0;}), prefetch(pos->next))
+        	pos = pos->next, ({ smp_read_barrier_depends(); 0;}), prefetch(pos->next))
         	
 #define __list_for_each_rcu(pos, head) \
 	for (pos = (head)->next; pos != (head); \
-        	pos = pos->next, ({ read_barrier_depends(); 0;}))
+        	pos = pos->next, ({ smp_read_barrier_depends(); 0;}))
         	
 /**
  * list_for_each_safe_rcu	-	iterate over an rcu-protected list safe
@@ -318,7 +318,7 @@
  */
 #define list_for_each_safe_rcu(pos, n, head) \
 	for (pos = (head)->next, n = pos->next; pos != (head); \
-		pos = n, ({ read_barrier_depends(); 0;}), n = pos->next)
+		pos = n, ({ smp_read_barrier_depends(); 0;}), n = pos->next)
 
 /* 
  * Double linked lists with a single pointer list head. 
diff -Nru a/include/linux/major.h b/include/linux/major.h
--- a/include/linux/major.h	Fri Nov 29 14:50:49 2002
+++ b/include/linux/major.h	Tue Mar 18 07:58:33 2003
@@ -6,85 +6,74 @@
  * For the device number assignments, see Documentation/devices.txt.
  */
 
-/* limits */
+#define UNNAMED_MAJOR		0
+#define MEM_MAJOR		1
+#define RAMDISK_MAJOR		1
+#define FLOPPY_MAJOR		2
+#define PTY_MASTER_MAJOR	2
+#define IDE0_MAJOR		3
+#define HD_MAJOR		IDE0_MAJOR
+#define PTY_SLAVE_MAJOR		3
+#define TTY_MAJOR		4
+#define TTYAUX_MAJOR		5
+#define LP_MAJOR		6
+#define VCS_MAJOR		7
+#define LOOP_MAJOR		7
+#define SCSI_DISK0_MAJOR	8
+#define SCSI_TAPE_MAJOR		9
+#define MD_MAJOR		9
+#define MISC_MAJOR		10
+#define SCSI_CDROM_MAJOR	11
+#define MUX_MAJOR		11	/* PA-RISC only */
+#define QIC02_TAPE_MAJOR	12
+#define XT_DISK_MAJOR		13
+#define SOUND_MAJOR		14
+#define CDU31A_CDROM_MAJOR	15
+#define JOYSTICK_MAJOR		15
+#define GOLDSTAR_CDROM_MAJOR	16
+#define OPTICS_CDROM_MAJOR	17
+#define SANYO_CDROM_MAJOR	18
+#define CYCLADES_MAJOR		19
+#define CYCLADESAUX_MAJOR	20
+#define MITSUMI_X_CDROM_MAJOR	20
+#define MFM_ACORN_MAJOR		21	/* ARM Linux /dev/mfm */
+#define SCSI_GENERIC_MAJOR	21
+#define IDE1_MAJOR		22
+#define DIGICU_MAJOR		22
+#define DIGI_MAJOR		23
+#define MITSUMI_CDROM_MAJOR	23
+#define CDU535_CDROM_MAJOR	24
+#define STL_SERIALMAJOR		24
+#define MATSUSHITA_CDROM_MAJOR	25
+#define STL_CALLOUTMAJOR	25
+#define MATSUSHITA_CDROM2_MAJOR	26
+#define QIC117_TAPE_MAJOR	27
+#define MATSUSHITA_CDROM3_MAJOR	27
+#define MATSUSHITA_CDROM4_MAJOR	28
+#define STL_SIOMEMMAJOR		28
+#define ACSI_MAJOR		28
+#define AZTECH_CDROM_MAJOR	29
+#define GRAPHDEV_MAJOR		29   /* SparcLinux & Linux/68k /dev/fb */
+#define CM206_CDROM_MAJOR	32
+#define IDE2_MAJOR		33
+#define IDE3_MAJOR		34
+#define Z8530_MAJOR		34
+#define XPRAM_MAJOR		35   /* Expanded storage on S/390: "slow ram"*/
+#define NETLINK_MAJOR		36
+#define PS2ESDI_MAJOR		36
+#define IDETAPE_MAJOR		37
+#define Z2RAM_MAJOR		37
+#define APBLOCK_MAJOR		38   /* AP1000 Block device */
+#define DDV_MAJOR		39   /* AP1000 DDV block device */
+#define NBD_MAJOR		43   /* Network block device	*/
+#define RISCOM8_NORMAL_MAJOR	48
+#define DAC960_MAJOR		48   /* 48..55 */
+#define RISCOM8_CALLOUT_MAJOR	49
+#define MKISS_MAJOR		55
+#define DSP56K_MAJOR		55   /* DSP56001 processor device */
 
-/*
- * Important: Don't change this to 256.  Major number 255 is and must be
- * reserved for future expansion into a larger dev_t space.
- */
-#define MAX_CHRDEV	255
-#define MAX_BLKDEV	255
-
-#define UNNAMED_MAJOR	0
-#define MEM_MAJOR	1
-#define RAMDISK_MAJOR	1
-#define FLOPPY_MAJOR	2
-#define PTY_MASTER_MAJOR 2
-#define IDE0_MAJOR	3
-#define PTY_SLAVE_MAJOR 3
-#define HD_MAJOR	IDE0_MAJOR
-#define TTY_MAJOR	4
-#define TTYAUX_MAJOR	5
-#define LP_MAJOR	6
-#define VCS_MAJOR	7
-#define LOOP_MAJOR	7
-#define SCSI_DISK0_MAJOR 8
-#define SCSI_TAPE_MAJOR	9
-#define MD_MAJOR        9
-#define MISC_MAJOR	10
-#define SCSI_CDROM_MAJOR 11
-#define MUX_MAJOR	11	/* PA-RISC only */
-#define QIC02_TAPE_MAJOR 12
-#define XT_DISK_MAJOR	13
-#define SOUND_MAJOR	14
-#define CDU31A_CDROM_MAJOR 15
-#define JOYSTICK_MAJOR	15
-#define GOLDSTAR_CDROM_MAJOR 16
-#define OPTICS_CDROM_MAJOR 17
-#define SANYO_CDROM_MAJOR 18
-#define CYCLADES_MAJOR  19
-#define CYCLADESAUX_MAJOR 20
-#define MITSUMI_X_CDROM_MAJOR 20
-#define MFM_ACORN_MAJOR 21	/* ARM Linux /dev/mfm */
-#define SCSI_GENERIC_MAJOR 21
-#define Z8530_MAJOR 34
-#define DIGI_MAJOR 23
-#define IDE1_MAJOR	22
-#define DIGICU_MAJOR 22
-#define MITSUMI_CDROM_MAJOR 23
-#define CDU535_CDROM_MAJOR 24
-#define STL_SERIALMAJOR 24
-#define MATSUSHITA_CDROM_MAJOR 25
-#define STL_CALLOUTMAJOR 25
-#define MATSUSHITA_CDROM2_MAJOR 26
-#define QIC117_TAPE_MAJOR 27
-#define MATSUSHITA_CDROM3_MAJOR 27
-#define MATSUSHITA_CDROM4_MAJOR 28
-#define STL_SIOMEMMAJOR 28
-#define ACSI_MAJOR	28
-#define AZTECH_CDROM_MAJOR 29
-#define GRAPHDEV_MAJOR	29	/* SparcLinux & Linux/68k /dev/fb */
-#define SHMIQ_MAJOR	85	/* Linux/mips, SGI /dev/shmiq */
-#define CM206_CDROM_MAJOR 32
-#define IDE2_MAJOR	33
-#define IDE3_MAJOR	34
-#define XPRAM_MAJOR     35      /* expanded storage on S/390 = "slow ram" */
-                                /* proposed by Peter                      */
-#define NETLINK_MAJOR	36
-#define PS2ESDI_MAJOR	36
-#define IDETAPE_MAJOR	37
-#define Z2RAM_MAJOR	37
-#define APBLOCK_MAJOR   38   /* AP1000 Block device */
-#define DDV_MAJOR       39   /* AP1000 DDV block device */
-#define NBD_MAJOR	43   /* Network block device	*/
-#define RISCOM8_NORMAL_MAJOR 48
-#define DAC960_MAJOR	48	/* 48..55 */
-#define RISCOM8_CALLOUT_MAJOR 49
-#define MKISS_MAJOR	55
-#define DSP56K_MAJOR    55   /* DSP56001 processor device */
-
-#define IDE4_MAJOR	56
-#define IDE5_MAJOR	57
+#define IDE4_MAJOR		56
+#define IDE5_MAJOR		57
 
 #define SCSI_DISK1_MAJOR	65
 #define SCSI_DISK2_MAJOR	66
@@ -94,15 +83,6 @@
 #define SCSI_DISK6_MAJOR	70
 #define SCSI_DISK7_MAJOR	71
 
-#define SCSI_DISK8_MAJOR	128
-#define SCSI_DISK9_MAJOR	129
-#define SCSI_DISK10_MAJOR	130
-#define SCSI_DISK11_MAJOR	131
-#define SCSI_DISK12_MAJOR	132
-#define SCSI_DISK13_MAJOR	133
-#define SCSI_DISK14_MAJOR	134
-#define SCSI_DISK15_MAJOR	135
-
 #define COMPAQ_SMART2_MAJOR	72
 #define COMPAQ_SMART2_MAJOR1	73
 #define COMPAQ_SMART2_MAJOR2	74
@@ -112,10 +92,31 @@
 #define COMPAQ_SMART2_MAJOR6	78
 #define COMPAQ_SMART2_MAJOR7	79
 
-#define SPECIALIX_NORMAL_MAJOR 75
-#define SPECIALIX_CALLOUT_MAJOR 76
+#define SPECIALIX_NORMAL_MAJOR	75
+#define SPECIALIX_CALLOUT_MAJOR	76
+
+#define AURORA_MAJOR		79
+
+#define I2O_MAJOR		80	/* 80->87 */
+
+#define SHMIQ_MAJOR		85   /* Linux/mips, SGI /dev/shmiq */
+
+#define IDE6_MAJOR		88
+#define IDE7_MAJOR		89
+#define IDE8_MAJOR		90
+#define IDE9_MAJOR		91
+
+#define DASD_MAJOR		94
+
+#define MDISK_MAJOR		95
+
+#define UBD_MAJOR		98
+
+#define JSFD_MAJOR		99
+
+#define PHONE_MAJOR		100
 
-#define COMPAQ_CISS_MAJOR 	104
+#define COMPAQ_CISS_MAJOR	104
 #define COMPAQ_CISS_MAJOR1	105
 #define COMPAQ_CISS_MAJOR2      106
 #define COMPAQ_CISS_MAJOR3      107
@@ -126,36 +127,26 @@
 
 #define ATARAID_MAJOR		114
 
-#define DASD_MAJOR      94	/* Official assignations from Peter */
-
-#define MDISK_MAJOR     95	/* Official assignations from Peter */
-
-#define I2O_MAJOR		80	/* 80->87 */
-
-#define IDE6_MAJOR	88
-#define IDE7_MAJOR	89
-#define IDE8_MAJOR	90
-#define IDE9_MAJOR	91
-
-#define UBD_MAJOR	98
-
-#define AURORA_MAJOR 79
-
-#define JSFD_MAJOR	99
+#define SCSI_DISK8_MAJOR	128
+#define SCSI_DISK9_MAJOR	129
+#define SCSI_DISK10_MAJOR	130
+#define SCSI_DISK11_MAJOR	131
+#define SCSI_DISK12_MAJOR	132
+#define SCSI_DISK13_MAJOR	133
+#define SCSI_DISK14_MAJOR	134
+#define SCSI_DISK15_MAJOR	135
 
-#define PHONE_MAJOR	100
+#define UNIX98_PTY_MASTER_MAJOR	128
+#define UNIX98_PTY_MAJOR_COUNT	8
+#define UNIX98_PTY_SLAVE_MAJOR	(UNIX98_PTY_MASTER_MAJOR+UNIX98_PTY_MAJOR_COUNT)
 
-#define RTF_MAJOR	150
-#define RAW_MAJOR	162
+#define RTF_MAJOR		150
+#define RAW_MAJOR		162
 
 #define USB_ACM_MAJOR		166
 #define USB_ACM_AUX_MAJOR	167
 #define USB_CHAR_MAJOR		180
 
-#define UNIX98_PTY_MASTER_MAJOR	128
-#define UNIX98_PTY_MAJOR_COUNT	8
-#define UNIX98_PTY_SLAVE_MAJOR	(UNIX98_PTY_MASTER_MAJOR+UNIX98_PTY_MAJOR_COUNT)
-
 #define VXVM_MAJOR		199	/* VERITAS volume i/o driver    */
 #define VXSPEC_MAJOR		200	/* VERITAS volume config driver */
 #define VXDMP_MAJOR		201	/* VERITAS volume multipath driver */
@@ -163,17 +154,18 @@
 #define MSR_MAJOR		202
 #define CPUID_MAJOR		203
 
-#define OSST_MAJOR	206	/* OnStream-SCx0 SCSI tape */
+#define OSST_MAJOR		206	/* OnStream-SCx0 SCSI tape */
 
-#define IBM_TTY3270_MAJOR       227	/* Official allocations now */
-#define IBM_FS3270_MAJOR        228
+#define IBM_TTY3270_MAJOR	227
+#define IBM_FS3270_MAJOR	228
 
 /*
  * Tests for SCSI devices.
  */
 
 #define SCSI_DISK_MAJOR(M) ((M) == SCSI_DISK0_MAJOR || \
-  ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR))
+  ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR) || \
+  ((M) >= SCSI_DISK8_MAJOR && (M) <= SCSI_DISK15_MAJOR))
   
 #define SCSI_BLK_MAJOR(M) \
   (SCSI_DISK_MAJOR(M)	\
diff -Nru a/include/linux/mm.h b/include/linux/mm.h
--- a/include/linux/mm.h	Thu Mar  6 03:13:27 2003
+++ b/include/linux/mm.h	Sun Mar 23 01:40:11 2003
@@ -8,10 +8,8 @@
 
 #include <linux/config.h>
 #include <linux/gfp.h>
-#include <linux/string.h>
 #include <linux/list.h>
 #include <linux/mmzone.h>
-#include <linux/swap.h>
 #include <linux/rbtree.h>
 #include <linux/fs.h>
 
@@ -136,12 +134,13 @@
 	void (*open)(struct vm_area_struct * area);
 	void (*close)(struct vm_area_struct * area);
 	struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int unused);
-	int (*populate)(struct vm_area_struct * area, unsigned long address, unsigned long len, unsigned long prot, unsigned long pgoff, int nonblock);
+	int (*populate)(struct vm_area_struct * area, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int nonblock);
 };
 
 /* forward declaration; pte_chain is meant to be internal to rmap.c */
 struct pte_chain;
 struct mmu_gather;
+struct inode;
 
 /*
  * Each physical page in the system has a struct page associated with
@@ -417,11 +416,11 @@
 extern pmd_t *FASTCALL(__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address));
 extern pte_t *FASTCALL(pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
 extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
-extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, unsigned long prot);
+extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot);
 extern int handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
 extern int make_pages_present(unsigned long addr, unsigned long end);
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
-extern int sys_remap_file_pages(unsigned long start, unsigned long size, unsigned long prot, unsigned long pgoff, unsigned long nonblock);
+extern long sys_remap_file_pages(unsigned long start, unsigned long size, unsigned long prot, unsigned long pgoff, unsigned long nonblock);
 
 
 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
@@ -490,10 +489,7 @@
 extern void mem_init(void);
 extern void show_mem(void);
 extern void si_meminfo(struct sysinfo * val);
-#ifdef CONFIG_NUMA
 extern void si_meminfo_node(struct sysinfo *val, int nid);
-#endif
-extern void swapin_readahead(swp_entry_t);
 
 /* mmap.c */
 extern void insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
@@ -594,7 +590,6 @@
 
 extern struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr);
 
-extern unsigned long get_page_cache_size(void);
 extern unsigned int nr_used_zone_pages(void);
 
 #ifdef CONFIG_MMU
diff -Nru a/include/linux/mman.h b/include/linux/mman.h
--- a/include/linux/mman.h	Sat Jul 27 16:39:09 2002
+++ b/include/linux/mman.h	Tue Mar 18 01:44:12 2003
@@ -1,12 +1,29 @@
 #ifndef _LINUX_MMAN_H
 #define _LINUX_MMAN_H
 
+#include <linux/config.h>
+
+#include <asm/atomic.h>
 #include <asm/mman.h>
 
 #define MREMAP_MAYMOVE	1
 #define MREMAP_FIXED	2
 
 extern int vm_enough_memory(long pages);
-extern void vm_unacct_memory(long pages);
+extern atomic_t vm_committed_space;
+
+#ifdef CONFIG_SMP
+extern void vm_acct_memory(long pages);
+#else
+static inline void vm_acct_memory(long pages)
+{
+	atomic_add(pages, &vm_committed_space);
+}
+#endif
+
+static inline void vm_unacct_memory(long pages)
+{
+	vm_acct_memory(-pages);
+}
 
 #endif /* _LINUX_MMAN_H */
diff -Nru a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h	Fri Feb 21 19:50:41 2003
+++ b/include/linux/module.h	Fri Mar 21 04:30:33 2003
@@ -69,8 +69,6 @@
   __attribute__ ((unused, alias(__stringify(name))))
 
 #define THIS_MODULE (&__this_module)
-#define MOD_INC_USE_COUNT _MOD_INC_USE_COUNT(THIS_MODULE)
-#define MOD_DEC_USE_COUNT __MOD_DEC_USE_COUNT(THIS_MODULE)
 
 /*
  * The following license idents are currently accepted as indicating free
@@ -107,8 +105,6 @@
 #define MODULE_ALIAS(alias)
 #define MODULE_GENERIC_TABLE(gtype,name)
 #define THIS_MODULE ((struct module *)0)
-#define MOD_INC_USE_COUNT	do { } while (0)
-#define MOD_DEC_USE_COUNT	do { } while (0)
 #define MODULE_LICENSE(license)
 #endif
 
@@ -418,20 +414,6 @@
 #define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)
 
 /* BELOW HERE ALL THESE ARE OBSOLETE AND WILL VANISH */
-static inline void __deprecated __MOD_INC_USE_COUNT(struct module *module)
-{
-	__unsafe(module);
-	/*
-	 * Yes, we ignore the retval here, that's why it's deprecated.
-	 */
-	try_module_get(module);
-}
-
-static inline void __deprecated __MOD_DEC_USE_COUNT(struct module *module)
-{
-	module_put(module);
-}
-
 #define SET_MODULE_OWNER(dev) ((dev)->owner = THIS_MODULE)
 
 struct obsolete_modparm {
@@ -445,14 +427,7 @@
 struct obsolete_modparm __parm_##var __attribute__((section("__obsparm"))) = \
 { __stringify(var), type };
 
-#else
-#define MODULE_PARM(var,type)
-#endif
-
-/* People do this inside their init routines, when the module isn't
-   "live" yet.  They should no longer be doing that, but
-   meanwhile... */
-static inline void __deprecated _MOD_INC_USE_COUNT(struct module *module)
+static inline void __deprecated MOD_INC_USE_COUNT(struct module *module)
 {
 	__unsafe(module);
 
@@ -460,9 +435,23 @@
 	local_inc(&module->ref[get_cpu()].count);
 	put_cpu();
 #else
-	try_module_get(module);
+	(void)try_module_get(module);
 #endif
 }
+
+static inline void __deprecated MOD_DEC_USE_COUNT(struct module *module)
+{
+	module_put(module);
+}
+
+#define MOD_INC_USE_COUNT	MOD_INC_USE_COUNT(THIS_MODULE)
+#define MOD_DEC_USE_COUNT	MOD_DEC_USE_COUNT(THIS_MODULE)
+#else
+#define MODULE_PARM(var,type)
+#define MOD_INC_USE_COUNT	do { } while (0)
+#define MOD_DEC_USE_COUNT	do { } while (0)
+#endif
+
 #define __MODULE_STRING(x) __stringify(x)
 
 /*
diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h	Wed Jan 15 23:47:03 2003
+++ b/include/linux/netdevice.h	Wed Mar 19 21:17:02 2003
@@ -90,6 +90,11 @@
 #define MAX_HEADER (LL_MAX_HEADER + 48)
 #endif
 
+/* Reserve 16byte aligned hard_header_len, but at least 16.
+ * Alternative is: dev->hard_header_len ? (dev->hard_header_len + 15)&~15 : 0
+ */
+#define LL_RESERVED_SPACE(dev) (((dev)->hard_header_len&~15) + 16)
+
 /*
  *	Network device statistics. Akin to the 2.0 ether stats but
  *	with byte counters.
@@ -360,7 +365,6 @@
 #define NETIF_F_IP_CSUM		2	/* Can checksum only TCP/UDP over IPv4. */
 #define NETIF_F_NO_CSUM		4	/* Does not require checksum. F.e. loopack. */
 #define NETIF_F_HW_CSUM		8	/* Can checksum all the packets. */
-#define NETIF_F_DYNALLOC	16	/* Self-dectructable device. */
 #define NETIF_F_HIGHDMA		32	/* Can DMA to high memory. */
 #define NETIF_F_FRAGLIST	64	/* Scatter/gather IO. */
 #define NETIF_F_HW_VLAN_TX	128	/* Transmit VLAN hw acceleration */
@@ -469,6 +473,10 @@
 extern void		dev_add_pack(struct packet_type *pt);
 extern void		dev_remove_pack(struct packet_type *pt);
 extern int		dev_get(const char *name);
+extern struct net_device	*dev_get_by_flags(unsigned short flags,
+						  unsigned short mask);
+extern struct net_device	*__dev_get_by_flags(unsigned short flags,
+						    unsigned short mask);
 extern struct net_device	*dev_get_by_name(const char *name);
 extern struct net_device	*__dev_get_by_name(const char *name);
 extern struct net_device	*dev_alloc(const char *name, int *err);
diff -Nru a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
--- a/include/linux/netfilter_bridge/ebtables.h	Mon Mar  3 04:41:09 2003
+++ b/include/linux/netfilter_bridge/ebtables.h	Sun Mar 23 04:46:52 2003
@@ -260,6 +260,7 @@
 	   unsigned int valid_hooks);
 	/* the data used by the kernel */
 	struct ebt_table_info *private;
+	struct module *me;
 };
 
 extern int ebt_register_table(struct ebt_table *table);
diff -Nru a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
--- a/include/linux/netfilter_ipv6/ip6_tables.h	Tue Feb  5 07:24:40 2002
+++ b/include/linux/netfilter_ipv6/ip6_tables.h	Thu Mar 20 00:49:19 2003
@@ -449,6 +449,9 @@
 				  struct ip6t_table *table,
 				  void *userdata);
 
+/* Check for an extension */
+extern int ip6t_ext_hdr(u8 nexthdr);
+
 #define IP6T_ALIGN(s) (((s) + (__alignof__(struct ip6t_entry)-1)) & ~(__alignof__(struct ip6t_entry)-1))
 
 #endif /*__KERNEL__*/
diff -Nru a/include/linux/nfsd/syscall.h b/include/linux/nfsd/syscall.h
--- a/include/linux/nfsd/syscall.h	Wed Apr 10 09:31:47 2002
+++ b/include/linux/nfsd/syscall.h	Sun Mar 23 14:35:20 2003
@@ -34,8 +34,8 @@
 #define NFSCTL_DELCLIENT	2	/* Remove an NFS client. */
 #define NFSCTL_EXPORT		3	/* export a file system. */
 #define NFSCTL_UNEXPORT		4	/* unexport a file system. */
-#define NFSCTL_UGIDUPDATE	5	/* update a client's uid/gid map. */
-#define NFSCTL_GETFH		6	/* get an fh by ino (used by mountd) */
+/*#define NFSCTL_UGIDUPDATE	5	/ * update a client's uid/gid map. DISCARDED */
+/*#define NFSCTL_GETFH		6	/ * get an fh by ino DISCARDED */
 #define NFSCTL_GETFD		7	/* get an fh by path (used by mountd) */
 #define	NFSCTL_GETFS		8	/* get an fh by path with max FH len */
 
@@ -66,25 +66,6 @@
 	__kernel_gid_t		ex_anon_gid;
 };
 
-/* UGIDUPDATE */
-struct nfsctl_uidmap {
-	char *			ug_ident;
-	__kernel_uid_t		ug_uidbase;
-	int			ug_uidlen;
-	__kernel_uid_t *	ug_udimap;
-	__kernel_gid_t		ug_gidbase;
-	int			ug_gidlen;
-	__kernel_gid_t *	ug_gdimap;
-};
-
-/* GETFH */
-struct nfsctl_fhparm {
-	struct sockaddr		gf_addr;
-	__kernel_dev_t		gf_dev;
-	__kernel_ino_t		gf_ino;
-	int			gf_version;
-};
-
 /* GETFD */
 struct nfsctl_fdparm {
 	struct sockaddr		gd_addr;
@@ -108,16 +89,12 @@
 		struct nfsctl_svc	u_svc;
 		struct nfsctl_client	u_client;
 		struct nfsctl_export	u_export;
-		struct nfsctl_uidmap	u_umap;
-		struct nfsctl_fhparm	u_getfh;
 		struct nfsctl_fdparm	u_getfd;
 		struct nfsctl_fsparm	u_getfs;
 	} u;
 #define ca_svc		u.u_svc
 #define ca_client	u.u_client
 #define ca_export	u.u_export
-#define ca_umap		u.u_umap
-#define ca_getfh	u.u_getfh
 #define ca_getfd	u.u_getfd
 #define	ca_getfs	u.u_getfs
 #define ca_authd	u.u_authd
diff -Nru a/include/linux/page-flags.h b/include/linux/page-flags.h
--- a/include/linux/page-flags.h	Wed Feb  5 20:05:13 2003
+++ b/include/linux/page-flags.h	Sat Mar 22 22:14:49 2003
@@ -82,7 +82,6 @@
 struct page_state {
 	unsigned long nr_dirty;		/* Dirty writeable pages */
 	unsigned long nr_writeback;	/* Pages under writeback */
-	unsigned long nr_pagecache;	/* Pages in pagecache */
 	unsigned long nr_page_table_pages;/* Pages used for pagetables */
 	unsigned long nr_reverse_maps;	/* includes PageDirect */
 	unsigned long nr_mapped;	/* mapped into pagetables */
diff -Nru a/include/linux/pagemap.h b/include/linux/pagemap.h
--- a/include/linux/pagemap.h	Fri Feb 14 18:23:56 2003
+++ b/include/linux/pagemap.h	Sat Mar 22 22:14:49 2003
@@ -74,6 +74,48 @@
 extern void remove_from_page_cache(struct page *page);
 extern void __remove_from_page_cache(struct page *page);
 
+extern atomic_t nr_pagecache;
+
+#ifdef CONFIG_SMP
+
+#define PAGECACHE_ACCT_THRESHOLD        max(16, NR_CPUS * 2)
+DECLARE_PER_CPU(long, nr_pagecache_local);
+
+/*
+ * pagecache_acct implements approximate accounting for pagecache.
+ * vm_enough_memory() do not need high accuracy. Writers will keep
+ * an offset in their per-cpu arena and will spill that into the
+ * global count whenever the absolute value of the local count
+ * exceeds the counter's threshold.
+ *
+ * MUST be protected from preemption.
+ * current protection is mapping->page_lock.
+ */
+static inline void pagecache_acct(int count)
+{
+	long *local;
+
+	local = &__get_cpu_var(nr_pagecache_local);
+	*local += count;
+	if (*local > PAGECACHE_ACCT_THRESHOLD || *local < -PAGECACHE_ACCT_THRESHOLD) {
+		atomic_add(*local, &nr_pagecache);
+		*local = 0;
+	}
+}
+
+#else
+
+static inline void pagecache_acct(int count)
+{
+	atomic_add(count, &nr_pagecache);
+}
+#endif
+
+static inline unsigned long get_page_cache_size(void)
+{
+        return atomic_read(&nr_pagecache);
+}
+
 static inline void ___add_to_page_cache(struct page *page,
 		struct address_space *mapping, unsigned long index)
 {
@@ -82,7 +124,7 @@
 	page->index = index;
 
 	mapping->nrpages++;
-	inc_page_state(nr_pagecache);
+	pagecache_acct(1);
 }
 
 extern void FASTCALL(__lock_page(struct page *page));
diff -Nru a/include/linux/parport.h b/include/linux/parport.h
--- a/include/linux/parport.h	Sat Nov 16 18:50:26 2002
+++ b/include/linux/parport.h	Thu Mar  6 15:08:36 2003
@@ -166,9 +166,6 @@
 	void (*save_state)(struct parport *, struct parport_state *);
 	void (*restore_state)(struct parport *, struct parport_state *);
 
-	void (*inc_use_count)(void);
-	void (*dec_use_count)(void);
-
 	/* Block read/write */
 	size_t (*epp_write_data) (struct parport *port, const void *buf,
 				  size_t len, int flags);
@@ -192,6 +189,7 @@
 				    size_t len, int flags);
 	size_t (*byte_read_data) (struct parport *port, void *buf,
 				  size_t len, int flags);
+	struct module *owner;
 };
 
 struct parport_device_info {
@@ -540,9 +538,6 @@
 extern int parport_device_proc_unregister(struct pardevice *device);
 extern int parport_default_proc_register(void);
 extern int parport_default_proc_unregister(void);
-
-extern void dec_parport_count(void);
-extern void inc_parport_count(void);
 
 /* If PC hardware is the only type supported, we can optimise a bit.  */
 #if (defined(CONFIG_PARPORT_PC) || defined(CONFIG_PARPORT_PC_MODULE)) && !(defined(CONFIG_PARPORT_ARC) || defined(CONFIG_PARPORT_ARC_MODULE)) && !(defined(CONFIG_PARPORT_AMIGA) || defined(CONFIG_PARPORT_AMIGA_MODULE)) && !(defined(CONFIG_PARPORT_MFC3) || defined(CONFIG_PARPORT_MFC3_MODULE)) && !(defined(CONFIG_PARPORT_ATARI) || defined(CONFIG_PARPORT_ATARI_MODULE)) && !(defined(CONFIG_USB_USS720) || defined(CONFIG_USB_USS720_MODULE)) && !(defined(CONFIG_PARPORT_SUNBPP) || defined(CONFIG_PARPORT_SUNBPP_MODULE)) && !defined(CONFIG_PARPORT_OTHER)
diff -Nru a/include/linux/parport_pc.h b/include/linux/parport_pc.h
--- a/include/linux/parport_pc.h	Mon Feb  4 23:41:48 2002
+++ b/include/linux/parport_pc.h	Thu Mar  6 15:08:41 2003
@@ -215,10 +215,6 @@
 
 extern void parport_pc_restore_state(struct parport *p, struct parport_state *s);
 
-extern void parport_pc_inc_use_count(void);
-
-extern void parport_pc_dec_use_count(void);
-
 /* PCMCIA code will want to get us to look at a port.  Provide a mechanism. */
 extern struct parport *parport_pc_probe_port (unsigned long base,
 					      unsigned long base_hi,
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	Sat Mar 15 17:15:06 2003
+++ b/include/linux/pci_ids.h	Thu Mar 20 16:05:00 2003
@@ -144,6 +144,7 @@
 #define PCI_DEVICE_ID_COMPAQ_NETEL100I	0xb011
 #define PCI_DEVICE_ID_COMPAQ_CISS	0xb060
 #define PCI_DEVICE_ID_COMPAQ_CISSB	0xb178
+#define PCI_DEVICE_ID_COMPAQ_CISSC	0x46
 #define PCI_DEVICE_ID_COMPAQ_THUNDER	0xf130
 #define PCI_DEVICE_ID_COMPAQ_NETFLEX3B	0xf150
 
@@ -1832,8 +1833,8 @@
 #define PCI_DEVICE_ID_INTEL_82801E_0	0x2450
 #define PCI_DEVICE_ID_INTEL_82801E_2	0x2452
 #define PCI_DEVICE_ID_INTEL_82801E_3	0x2453
-#define PCI_DEVICE_ID_INTEL_82801E_9	0x245b
-#define PCI_DEVICE_ID_INTEL_82801E_11	PCI_DEVICE_ID_INTEL_82801E_9
+#define PCI_DEVICE_ID_INTEL_82801E_9	0x2459
+#define PCI_DEVICE_ID_INTEL_82801E_11	0x245b
 #define PCI_DEVICE_ID_INTEL_82801E_13	0x245d
 #define PCI_DEVICE_ID_INTEL_82801E_14	0x245e
 #define PCI_DEVICE_ID_INTEL_82801CA_0	0x2480
@@ -1853,10 +1854,20 @@
 #define PCI_DEVICE_ID_INTEL_82801DB_5	0x24c5
 #define PCI_DEVICE_ID_INTEL_82801DB_6	0x24c6
 #define PCI_DEVICE_ID_INTEL_82801DB_7	0x24c7
-#define PCI_DEVICE_ID_INTEL_82801DB_9	0x24cb
-#define PCI_DEVICE_ID_INTEL_82801DB_11	PCI_DEVICE_ID_INTEL_82801DB_9
+#define PCI_DEVICE_ID_INTEL_82801DB_9	0x24c9
+#define PCI_DEVICE_ID_INTEL_82801DB_10	0x24ca
+#define PCI_DEVICE_ID_INTEL_82801DB_11	0x24cb
 #define PCI_DEVICE_ID_INTEL_82801DB_12  0x24cc
 #define PCI_DEVICE_ID_INTEL_82801DB_13	0x24cd
+#define PCI_DEVICE_ID_INTEL_82801EB_0	0x24d0
+#define PCI_DEVICE_ID_INTEL_82801EB_2	0x24d2
+#define PCI_DEVICE_ID_INTEL_82801EB_3	0x24d3
+#define PCI_DEVICE_ID_INTEL_82801EB_4	0x24d4
+#define PCI_DEVICE_ID_INTEL_82801EB_5	0x24d5
+#define PCI_DEVICE_ID_INTEL_82801EB_6	0x24d6
+#define PCI_DEVICE_ID_INTEL_82801EB_7	0x24d7
+#define PCI_DEVICE_ID_INTEL_82801EB_11	0x24db
+#define PCI_DEVICE_ID_INTEL_82801EB_13	0x24dd
 #define PCI_DEVICE_ID_INTEL_82820_HB	0x2500
 #define PCI_DEVICE_ID_INTEL_82820_UP_HB	0x2501
 #define PCI_DEVICE_ID_INTEL_82850_HB	0x2530
diff -Nru a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h
--- a/include/linux/pfkeyv2.h	Wed Jan  8 23:59:17 2003
+++ b/include/linux/pfkeyv2.h	Sun Mar 23 02:09:10 2003
@@ -262,6 +262,14 @@
 #define SADB_X_EALG_AESCBC		12
 #define SADB_EALG_MAX			12
 
+/* Compression algorithms */
+#define SADB_X_CALG_NONE		0
+#define SADB_X_CALG_OUI			1
+#define SADB_X_CALG_DEFLATE		2
+#define SADB_X_CALG_LZS			3
+#define SADB_X_CALG_LZJH		4
+#define SADB_X_CALG_MAX			4
+
 /* Extension Header values */
 #define SADB_EXT_RESERVED		0
 #define SADB_EXT_SA			1
diff -Nru a/include/linux/pmu.h b/include/linux/pmu.h
--- a/include/linux/pmu.h	Sat May 18 07:06:16 2002
+++ b/include/linux/pmu.h	Sun Feb  2 13:51:33 2003
@@ -30,6 +30,7 @@
 #define PMU_SET_INTR_MASK	0x70	/* set PMU interrupt mask */
 #define PMU_INT_ACK		0x78	/* read interrupt bits */
 #define PMU_SHUTDOWN		0x7e	/* turn power off */
+#define PMU_CPU_SPEED		0x7d	/* control CPU speed on some models */
 #define PMU_SLEEP		0x7f	/* put CPU to sleep */
 #define PMU_POWER_EVENTS	0x8f	/* Send power-event commands to PMU */
 #define PMU_RESET		0xd0	/* reset CPU */
@@ -191,6 +192,10 @@
 /* values for pmu_battery_info.flags */
 #define PMU_BATT_PRESENT	0x00000001
 #define PMU_BATT_CHARGING	0x00000002
+#define PMU_BATT_TYPE_MASK	0x000000f0
+#define PMU_BATT_TYPE_SMART	0x00000010 /* Smart battery */
+#define PMU_BATT_TYPE_HOOPER	0x00000020 /* 3400/3500 */
+#define PMU_BATT_TYPE_COMET	0x00000030 /* 2400 */
 
 struct pmu_battery_info
 {
diff -Nru a/include/linux/rtc.h b/include/linux/rtc.h
--- a/include/linux/rtc.h	Sat Feb 15 10:49:38 2003
+++ b/include/linux/rtc.h	Sun Mar  2 08:31:53 2003
@@ -63,7 +63,7 @@
 };
 
 /*
- * ioctl calls that are permitted to the /dev/rtc interface, if 
+ * ioctl calls that are permitted to the /dev/rtc interface, if
  * any of the RTC drivers are enabled.
  */
 
@@ -87,6 +87,7 @@
 
 #define RTC_WKALM_SET	_IOW('p', 0x0f, struct rtc_wkalrm)/* Set wakeup alarm*/
 #define RTC_WKALM_RD	_IOR('p', 0x10, struct rtc_wkalrm)/* Get wakeup alarm*/
+
 #define RTC_PLL_GET	_IOR('p', 0x11, struct rtc_pll_info)  /* Get PLL correction */
 #define RTC_PLL_SET	_IOW('p', 0x12, struct rtc_pll_info)  /* Set PLL correction */
 
diff -Nru a/include/linux/serialP.h b/include/linux/serialP.h
--- a/include/linux/serialP.h	Tue Oct  8 17:10:12 2002
+++ b/include/linux/serialP.h	Sun Oct 13 03:55:56 2002
@@ -22,6 +22,7 @@
 #include <linux/config.h>
 #include <linux/termios.h>
 #include <linux/workqueue.h>
+#include <linux/interrupt.h>
 #include <linux/circ_buf.h>
 #include <linux/wait.h>
 #if (LINUX_VERSION_CODE < 0x020300)
@@ -87,6 +88,7 @@
 	u16			iomem_reg_shift;
 	int			io_type;
 	struct work_struct			work;
+	struct tasklet_struct	tlet;
 #ifdef DECLARE_WAITQUEUE
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
diff -Nru a/include/linux/serial_core.h b/include/linux/serial_core.h
--- a/include/linux/serial_core.h	Tue Mar 11 06:17:45 2003
+++ b/include/linux/serial_core.h	Tue Mar 18 09:12:12 2003
@@ -59,6 +59,14 @@
 /* NEC v850.  */
 #define PORT_NB85E_UART	40
 
+/* NEC PC-9800 */
+#define PORT_8251_PC98	41
+#define PORT_19K_PC98	42
+#define PORT_FIFO_PC98	43
+#define PORT_VFAST_PC98	44
+#define PORT_PC9861	45
+#define PORT_PC9801_101	46
+
 
 #ifdef __KERNEL__
 
diff -Nru a/include/linux/sisfb.h b/include/linux/sisfb.h
--- a/include/linux/sisfb.h	Wed Oct 16 10:39:34 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,169 +0,0 @@
-#ifndef _LINUX_SISFB
-#define _LINUX_SISFB
-
-#include <linux/spinlock.h>
-
-#include <asm/ioctl.h>
-#include <asm/types.h>
-
-#define DISPTYPE_CRT1       0x00000008L
-#define DISPTYPE_CRT2       0x00000004L
-#define DISPTYPE_LCD        0x00000002L
-#define DISPTYPE_TV         0x00000001L
-#define DISPTYPE_DISP1      DISPTYPE_CRT1
-#define DISPTYPE_DISP2      (DISPTYPE_CRT2 | DISPTYPE_LCD | DISPTYPE_TV)
-#define DISPMODE_SINGLE	    0x00000020L
-#define DISPMODE_MIRROR	    0x00000010L
-#define DISPMODE_DUALVIEW   0x00000040L
-
-#define HASVB_NONE      	0x00
-#define HASVB_301       	0x01
-#define HASVB_LVDS      	0x02
-#define HASVB_TRUMPION  	0x04
-#define HASVB_LVDS_CHRONTEL	0x10
-#define HASVB_302       	0x20
-#define HASVB_303       	0x40
-#define HASVB_CHRONTEL  	0x80
-
-/* TW: *Never* change the order of the following enum */
-typedef enum _SIS_CHIP_TYPE {
-	SIS_VGALegacy = 0,
-	SIS_300,
-	SIS_630,
-	SIS_540,
-	SIS_730, 
-	SIS_315H,
-	SIS_315,
-	SIS_550,
-	SIS_315PRO,
-	SIS_640,
-	SIS_740,
-	SIS_650,
-	SIS_330,
-	MAX_SIS_CHIP
-} SIS_CHIP_TYPE;
-
-typedef enum _VGA_ENGINE {
-	UNKNOWN_VGA = 0,
-	SIS_300_VGA,
-	SIS_315_VGA,
-} VGA_ENGINE;
-
-typedef enum _TVTYPE {
-	TVMODE_NTSC = 0,
-	TVMODE_PAL,
-	TVMODE_HIVISION,
-	TVMODE_TOTAL
-} SIS_TV_TYPE;
-
-typedef enum _TVPLUGTYPE {
-	TVPLUG_Legacy = 0,
-	TVPLUG_COMPOSITE,
-	TVPLUG_SVIDEO,
-	TVPLUG_SCART,
-	TVPLUG_TOTAL
-} SIS_TV_PLUG;
-
-struct sis_memreq {
-	unsigned long offset;
-	unsigned long size;
-};
-
-struct mode_info {
-	int    bpp;
-	int    xres;
-	int    yres;
-	int    v_xres;
-	int    v_yres;
-	int    org_x;
-	int    org_y;
-	unsigned int  vrate;
-};
-
-struct ap_data {
-	struct mode_info minfo;
-	unsigned long iobase;
-	unsigned int  mem_size;
-	unsigned long disp_state;    	
-	SIS_CHIP_TYPE chip;
-	unsigned char hasVB;
-	SIS_TV_TYPE TV_type;
-	SIS_TV_PLUG TV_plug;
-	unsigned long version;
-	char reserved[256];
-};
-
-struct video_info {
-	int           chip_id;
-	unsigned int  video_size;
-	unsigned long video_base;
-	char  *       video_vbase;
-	unsigned long mmio_base;
-	char  *       mmio_vbase;
-	unsigned long vga_base;
-	unsigned long mtrr;
-	unsigned long heapstart;
-
-	int    video_bpp;
-	int    video_cmap_len;
-	int    video_width;
-	int    video_height;
-	int    video_vwidth;
-	int    video_vheight;
-	int    org_x;
-	int    org_y;
-	int    video_linelength;
-	unsigned int refresh_rate;
-
-	unsigned long disp_state;
-	unsigned char hasVB;
-	unsigned char TV_type;
-	unsigned char TV_plug;
-
-	SIS_CHIP_TYPE chip;
-	unsigned char revision_id;
-
-        unsigned short DstColor;		/* TW: For 2d acceleration */
-	unsigned long  SiS310_AccelDepth;
-	unsigned long  CommandReg;
-
-	spinlock_t     lockaccel;
-
-	char reserved[256];
-};
-
-
-/* TW: Addtional IOCTL for communication sisfb <> X driver                 */
-/*     If changing this, vgatypes.h must also be changed (for X driver)    */
-
-/* TW: ioctl for identifying and giving some info (esp. memory heap start) */
-#define SISFB_GET_INFO	  _IOR('n',0xF8,sizeof(__u32))
-
-/* TW: Structure argument for SISFB_GET_INFO ioctl  */
-typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
-
-struct _SISFB_INFO {
-	unsigned long sisfb_id;         /* for identifying sisfb */
-#ifndef SISFB_ID
-#define SISFB_ID	  0x53495346    /* Identify myself with 'SISF' */
-#endif
- 	int    chip_id;			/* PCI ID of detected chip */
-	int    memory;			/* video memory in KB which sisfb manages */
-	int    heapstart;               /* heap start (= sisfb "mem" argument) in KB */
-	unsigned char fbvidmode;	/* current sisfb mode */
-	
-	unsigned char sisfb_version;
-	unsigned char sisfb_revision;
-	unsigned char sisfb_patchlevel;
-
-	char reserved[253]; 		/* for future use */
-};
-
-#ifdef __KERNEL__
-extern struct video_info ivideo;
-
-extern void sis_malloc(struct sis_memreq *req);
-extern void sis_free(unsigned long base);
-extern void sis_dispinfo(struct ap_data *rec);
-#endif
-#endif
diff -Nru a/include/linux/skbuff.h b/include/linux/skbuff.h
--- a/include/linux/skbuff.h	Sat Feb 22 16:12:05 2003
+++ b/include/linux/skbuff.h	Wed Mar 19 19:52:56 2003
@@ -226,7 +226,7 @@
 	unsigned int		len,
 				data_len,
 				csum;
-	unsigned char		__unused,
+	unsigned char		local_df,
 				cloned,
 				pkt_type,
 				ip_summed;
diff -Nru a/include/linux/socket.h b/include/linux/socket.h
--- a/include/linux/socket.h	Thu Mar  6 11:06:44 2003
+++ b/include/linux/socket.h	Sun Mar 23 22:06:53 2003
@@ -3,6 +3,7 @@
 
 #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
 
+#include <linux/config.h>		/* for CONFIG_COMPAT */
 #include <linux/linkage.h>
 #include <asm/socket.h>			/* arch-dependent defines	*/
 #include <linux/sockios.h>		/* the SIOCxxx I/O controls	*/
@@ -239,18 +240,10 @@
 #define MSG_CMSG_COMPAT	0x80000000	/* This message needs 32 bit fixups */
 #else
 #define MSG_CMSG_COMPAT	0		/* We never have 32 bit fixups */
-#define compat_msghdr	msghdr		/* Needed to avoid compiler hoops */
 #endif
 
-struct compat_msghdr;
-extern int msghdr_from_user_compat_to_kern(struct msghdr *, struct compat_msghdr *);
-extern int verify_compat_iovec(struct msghdr *, struct iovec *, char *, int);
-extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr *,unsigned);
-extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr *,unsigned);
 extern asmlinkage long sys_sendmsg(int fd, struct msghdr *msg, unsigned flags);
 extern asmlinkage long sys_recvmsg(int fd, struct msghdr *msg, unsigned flags);
-extern asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
-				char *optval, int *optlen);
 
 
 
@@ -295,10 +288,6 @@
 extern int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen);
 extern int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr);
 extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
-extern int put_cmsg_compat(struct msghdr*, int level, int type, int len, void *data);
-extern void cmsg_compat_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr);
-extern int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg,
-			       unsigned char *stackbuf, int stackbuf_size);
 
 #endif
 #endif /* not kernel and not glibc */
diff -Nru a/include/linux/swap.h b/include/linux/swap.h
--- a/include/linux/swap.h	Sun Mar  2 18:14:31 2003
+++ b/include/linux/swap.h	Sun Mar 23 01:40:11 2003
@@ -144,6 +144,9 @@
 /* linux/mm/oom_kill.c */
 extern void out_of_memory(void);
 
+/* linux/mm/memory.c */
+extern void swapin_readahead(swp_entry_t);
+
 /* linux/mm/page_alloc.c */
 extern unsigned long totalram_pages;
 extern unsigned long totalhigh_pages;
diff -Nru a/include/linux/swapops.h b/include/linux/swapops.h
--- a/include/linux/swapops.h	Mon Jun  3 09:50:02 2002
+++ b/include/linux/swapops.h	Sat Mar 22 22:06:03 2003
@@ -51,6 +51,7 @@
 {
 	swp_entry_t arch_entry;
 
+	BUG_ON(pte_file(pte));
 	arch_entry = __pte_to_swp_entry(pte);
 	return swp_entry(__swp_type(arch_entry), __swp_offset(arch_entry));
 }
@@ -64,5 +65,6 @@
 	swp_entry_t arch_entry;
 
 	arch_entry = __swp_entry(swp_type(entry), swp_offset(entry));
+	BUG_ON(pte_file(__swp_entry_to_pte(arch_entry)));
 	return __swp_entry_to_pte(arch_entry);
 }
diff -Nru a/include/linux/tcp.h b/include/linux/tcp.h
--- a/include/linux/tcp.h	Tue Oct 15 19:00:28 2002
+++ b/include/linux/tcp.h	Wed Mar 19 19:52:56 2003
@@ -245,6 +245,7 @@
 	__u16	mss_cache_std;	/* Like mss_cache, but without TSO */
 	__u16	mss_clamp;	/* Maximal mss, negotiated at connection setup */
 	__u16	ext_header_len;	/* Network protocol overhead (IP/IPv6 options) */
+	__u16	ext2_header_len;/* Options depending on route */
 	__u8	ca_state;	/* State of fast-retransmit machine 	*/
 	__u8	retransmits;	/* Number of unrecovered RTO timeouts.	*/
 
diff -Nru a/include/linux/thread_info.h b/include/linux/thread_info.h
--- a/include/linux/thread_info.h	Fri Dec  6 09:43:43 2002
+++ b/include/linux/thread_info.h	Mon Mar 17 21:32:12 2003
@@ -12,7 +12,7 @@
  */
 struct restart_block {
 	long (*fn)(struct restart_block *);
-	unsigned long arg0, arg1, arg2;
+	unsigned long arg0, arg1, arg2, arg3;
 };
 
 extern long do_no_restart_syscall(struct restart_block *parm);
diff -Nru a/include/linux/upd4990a.h b/include/linux/upd4990a.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/upd4990a.h	Fri Feb 14 15:35:38 2003
@@ -0,0 +1,140 @@
+/*
+ *  Constant and architecture independent procedures
+ *  for NEC uPD4990A serial I/O real-time clock.
+ *
+ *  Copyright 2001  TAKAI Kousuke <tak@kmc.kyoto-u.ac.jp>
+ *		    Kyoto University Microcomputer Club (KMC).
+ *
+ *  References:
+ *	uPD4990A serial I/O real-time clock users' manual (Japanese)
+ *	No. S12828JJ4V0UM00 (4th revision), NEC Corporation, 1999.
+ */
+
+#ifndef _LINUX_uPD4990A_H
+#define _LINUX_uPD4990A_H
+
+#include <asm/byteorder.h>
+
+#include <asm/upd4990a.h>
+
+/* Serial commands (4 bits) */
+#define UPD4990A_REGISTER_HOLD			(0x0)
+#define UPD4990A_REGISTER_SHIFT			(0x1)
+#define UPD4990A_TIME_SET_AND_COUNTER_HOLD	(0x2)
+#define UPD4990A_TIME_READ			(0x3)
+#define UPD4990A_TP_64HZ			(0x4)
+#define UPD4990A_TP_256HZ			(0x5)
+#define UPD4990A_TP_2048HZ			(0x6)
+#define UPD4990A_TP_4096HZ			(0x7)
+#define UPD4990A_TP_1S				(0x8)
+#define UPD4990A_TP_10S				(0x9)
+#define UPD4990A_TP_30S				(0xA)
+#define UPD4990A_TP_60S				(0xB)
+#define UPD4990A_INTERRUPT_RESET		(0xC)
+#define UPD4990A_INTERRUPT_TIMER_START		(0xD)
+#define UPD4990A_INTERRUPT_TIMER_STOP		(0xE)
+#define UPD4990A_TEST_MODE_SET			(0xF)
+
+/* Parallel commands (3 bits)
+   0-6 are same with serial commands.  */
+#define UPD4990A_PAR_SERIAL_MODE		7
+
+#ifndef UPD4990A_DELAY
+# include <linux/delay.h>
+# define UPD4990A_DELAY(usec)	udelay((usec))
+#endif
+#ifndef UPD4990A_OUTPUT_DATA
+# define UPD4990A_OUTPUT_DATA(bit)			\
+	do {						\
+		UPD4990A_OUTPUT_DATA_CLK((bit), 0);	\
+		UPD4990A_DELAY(1); /* t-DSU */		\
+		UPD4990A_OUTPUT_DATA_CLK((bit), 1);	\
+		UPD4990A_DELAY(1); /* t-DHLD */	\
+	} while (0)
+#endif
+
+static __inline__ void upd4990a_serial_command(int command)
+{
+	UPD4990A_OUTPUT_DATA(command >> 0);
+	UPD4990A_OUTPUT_DATA(command >> 1);
+	UPD4990A_OUTPUT_DATA(command >> 2);
+	UPD4990A_OUTPUT_DATA(command >> 3);
+	UPD4990A_DELAY(1);	/* t-HLD */
+	UPD4990A_OUTPUT_STROBE(1);
+	UPD4990A_DELAY(1);	/* t-STB & t-d1 */
+	UPD4990A_OUTPUT_STROBE(0);
+	/* 19 microseconds extra delay is needed
+	   iff previous mode is TIME READ command  */
+}
+
+struct upd4990a_raw_data {
+	u8	sec;		/* BCD */
+	u8	min;		/* BCD */
+	u8	hour;		/* BCD */
+	u8	mday;		/* BCD */
+#if   defined __LITTLE_ENDIAN_BITFIELD
+	unsigned wday :4;	/* 0-6 */
+	unsigned mon :4;	/* 1-based */
+#elif defined __BIG_ENDIAN_BITFIELD
+	unsigned mon :4;	/* 1-based */
+	unsigned wday :4;	/* 0-6 */
+#else
+# error Unknown bitfield endian!
+#endif
+	u8	year;		/* BCD */
+};
+
+static __inline__ void upd4990a_get_time(struct upd4990a_raw_data *buf,
+					  int leave_register_hold)
+{
+	int byte;
+
+	upd4990a_serial_command(UPD4990A_TIME_READ);
+	upd4990a_serial_command(UPD4990A_REGISTER_SHIFT);
+	UPD4990A_DELAY(19);	/* t-d2 - t-d1 */
+
+	for (byte = 0; byte < 6; byte++) {
+		u8 tmp;
+		int bit;
+
+		for (tmp = 0, bit = 0; bit < 8; bit++) {
+			tmp = (tmp | (UPD4990A_READ_DATA() << 8)) >> 1;
+			UPD4990A_OUTPUT_CLK(1);
+			UPD4990A_DELAY(1);
+			UPD4990A_OUTPUT_CLK(0);
+			UPD4990A_DELAY(1);
+		}
+		((u8 *) buf)[byte] = tmp;
+	}
+
+	/* The uPD4990A users' manual says that we should issue `Register
+	   Hold' command after each data retrieval, or next `Time Read'
+	   command may not work correctly.  */
+	if (!leave_register_hold)
+		upd4990a_serial_command(UPD4990A_REGISTER_HOLD);
+}
+
+static __inline__ void upd4990a_set_time(const struct upd4990a_raw_data *data,
+					  int time_set_only)
+{
+	int byte;
+
+	if (!time_set_only)
+		upd4990a_serial_command(UPD4990A_REGISTER_SHIFT);
+
+	for (byte = 0; byte < 6; byte++) {
+		int bit;
+		u8 tmp = ((const u8 *) data)[byte];
+
+		for (bit = 0; bit < 8; bit++, tmp >>= 1)
+			UPD4990A_OUTPUT_DATA(tmp);
+	}
+
+	upd4990a_serial_command(UPD4990A_TIME_SET_AND_COUNTER_HOLD);
+
+	/* Release counter hold and start the clock.  */
+	if (!time_set_only)
+		upd4990a_serial_command(UPD4990A_REGISTER_HOLD);
+}
+
+#endif /* _LINUX_uPD4990A_H */
diff -Nru a/include/linux/vt_kern.h b/include/linux/vt_kern.h
--- a/include/linux/vt_kern.h	Wed Dec  4 17:10:23 2002
+++ b/include/linux/vt_kern.h	Tue Mar 11 09:17:29 2003
@@ -78,11 +78,6 @@
 int con_copy_unimap(int dstcons, int srccons);
 
 /* vt.c */
-
-extern unsigned int video_font_height;
-extern unsigned int default_font_height;
-extern unsigned int video_scan_lines;
-
 void complete_change_console(unsigned int new_console);
 int vt_waitactive(int vt);
 void change_console(unsigned int);
diff -Nru a/include/linux/xfrm.h b/include/linux/xfrm.h
--- a/include/linux/xfrm.h	Mon Feb  3 00:14:32 2003
+++ b/include/linux/xfrm.h	Sun Mar 23 02:21:28 2003
@@ -12,12 +12,7 @@
  */
 typedef union
 {
-	struct {
-		__u32	addr;
-		__u32	mask;	/* Use unused bits to cache mask. */
-	} a4;
-#define xfrm4_addr a4.addr
-#define xfrm4_mask a4.mask
+	__u32		a4;
 	__u32		a6[4];
 } xfrm_address_t;
 
diff -Nru a/include/net/addrconf.h b/include/net/addrconf.h
--- a/include/net/addrconf.h	Sun Feb 23 22:46:32 2003
+++ b/include/net/addrconf.h	Sun Mar 23 21:38:36 2003
@@ -63,7 +63,15 @@
 extern int			ipv6_get_saddr(struct dst_entry *dst, 
 					       struct in6_addr *daddr,
 					       struct in6_addr *saddr);
+extern int			ipv6_dev_get_saddr(struct net_device *dev, 
+					       struct in6_addr *daddr,
+					       struct in6_addr *saddr,
+					       int onlink);
 extern int			ipv6_get_lladdr(struct net_device *dev, struct in6_addr *);
+extern void			addrconf_join_solict(struct net_device *dev,
+					struct in6_addr *addr);
+extern void			addrconf_leave_solict(struct net_device *dev,
+					struct in6_addr *addr);
 
 /*
  *	multicast prototypes (mcast.c)
@@ -93,6 +101,26 @@
 extern void			addrconf_prefix_rcv(struct net_device *dev,
 						    u8 *opt, int len);
 
+/*
+ *	anycast prototypes (anycast.c)
+ */
+extern int			ipv6_sock_ac_join(struct sock *sk, 
+						  int ifindex, 
+						  struct in6_addr *addr);
+extern int			ipv6_sock_ac_drop(struct sock *sk,
+						  int ifindex, 
+						  struct in6_addr *addr);
+extern void			ipv6_sock_ac_close(struct sock *sk);
+extern int			inet6_ac_check(struct sock *sk, struct in6_addr *addr, int ifindex);
+
+extern int			ipv6_dev_ac_inc(struct net_device *dev,
+						struct in6_addr *addr);
+extern int			ipv6_dev_ac_dec(struct net_device *dev,
+						struct in6_addr *addr);
+extern int			ipv6_chk_acast_addr(struct net_device *dev,
+						struct in6_addr *addr);
+
+
 /* Device notifier */
 extern int register_inet6addr_notifier(struct notifier_block *nb);
 extern int unregister_inet6addr_notifier(struct notifier_block *nb);
@@ -147,7 +175,7 @@
  *	Hash function taken from net_alias.c
  */
 
-static __inline__ u8 ipv6_addr_hash(struct in6_addr *addr)
+static __inline__ u8 ipv6_addr_hash(const struct in6_addr *addr)
 {	
 	__u32 word;
 
@@ -167,7 +195,7 @@
  *	compute link-local solicited-node multicast address
  */
 
-static inline void addrconf_addr_solict_mult(struct in6_addr *addr,
+static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,
 					     struct in6_addr *solicited)
 {
 	ipv6_addr_set(solicited,
@@ -191,7 +219,7 @@
 		      __constant_htonl(0x2));
 }
 
-static inline int ipv6_addr_is_multicast(struct in6_addr *addr)
+static inline int ipv6_addr_is_multicast(const struct in6_addr *addr)
 {
 	return (addr->s6_addr32[0] & __constant_htonl(0xFF000000)) == __constant_htonl(0xFF000000);
 }
diff -Nru a/include/net/compat.h b/include/net/compat.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/net/compat.h	Sun Mar 23 22:06:22 2003
@@ -0,0 +1,41 @@
+#ifndef NET_COMPAT_H
+#define NET_COMPAT_H
+
+#include <linux/config.h>
+
+#if defined(CONFIG_COMPAT)
+
+#include <linux/compat.h>
+
+struct compat_msghdr {
+	compat_uptr_t	msg_name;
+	s32		msg_namelen;
+	compat_uptr_t	msg_iov;
+	compat_size_t	msg_iovlen;
+	compat_uptr_t	msg_control;
+	compat_size_t	msg_controllen;
+	u32		msg_flags;
+};
+
+struct compat_cmsghdr {
+	compat_size_t	cmsg_len;
+	s32		cmsg_level;
+	s32		cmsg_type;
+};
+
+#else /* defined(CONFIG_COMPAT) */
+#define compat_msghdr	msghdr		/* to avoid compiler warnings */
+#endif /* defined(CONFIG_COMPAT) */
+
+extern int get_compat_msghdr(struct msghdr *, struct compat_msghdr *);
+extern int verify_compat_iovec(struct msghdr *, struct iovec *, char *, int);
+extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr *,unsigned);
+extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr *,unsigned);
+extern asmlinkage long compat_sys_getsockopt(int, int, int, char *, int *);
+extern int put_cmsg_compat(struct msghdr*, int, int, int, void *);
+extern int put_compat_msg_controllen(struct msghdr *, struct compat_msghdr *,
+		unsigned long);
+extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, unsigned char *,
+		int);
+
+#endif /* NET_COMPAT_H */
diff -Nru a/include/net/compat_socket.h b/include/net/compat_socket.h
--- a/include/net/compat_socket.h	Thu Mar  6 11:02:18 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,67 +0,0 @@
-#ifndef NET_COMPAT_SOCKET_H
-#define NET_COMPAT_SOCKET_H 1
-
-#include <linux/compat.h>
-
-#if defined(CONFIG_COMPAT)
-
-/* XXX This really belongs in some header file... -DaveM */
-#define MAX_SOCK_ADDR	128		/* 108 for Unix domain - 
-					   16 for IP, 16 for IPX,
-					   24 for IPv6,
-					   about 80 for AX.25 */
-
-struct compat_msghdr {
-	u32		msg_name;
-	int		msg_namelen;
-	u32		msg_iov;
-	compat_size_t	msg_iovlen;
-	u32		msg_control;
-	compat_size_t	msg_controllen;
-	unsigned	msg_flags;
-};
-
-struct compat_cmsghdr {
-	compat_size_t	cmsg_len;
-	int		cmsg_level;
-	int		cmsg_type;
-};
-
-/* Bleech... */
-#define __CMSG_COMPAT_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg_compat_nxthdr((ctl),(len),(cmsg),(cmsglen))
-#define CMSG_COMPAT_NXTHDR(mhdr, cmsg, cmsglen) cmsg_compat_nxthdr((mhdr), (cmsg), (cmsglen))
-
-#define CMSG_COMPAT_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
-
-#define CMSG_COMPAT_DATA(cmsg)	((void *)((char *)(cmsg) + CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr))))
-#define CMSG_COMPAT_SPACE(len) (CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)) + CMSG_COMPAT_ALIGN(len))
-#define CMSG_COMPAT_LEN(len) (CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)) + (len))
-
-#define __CMSG_COMPAT_FIRSTHDR(ctl,len) ((len) >= sizeof(struct compat_cmsghdr) ? \
-				    (struct compat_cmsghdr *)(ctl) : \
-				    (struct compat_cmsghdr *)NULL)
-#define CMSG_COMPAT_FIRSTHDR(msg)	__CMSG_COMPAT_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
-
-static __inline__ struct compat_cmsghdr *__cmsg_compat_nxthdr(void *__ctl, __kernel_size_t __size,
-					      struct compat_cmsghdr *__cmsg, int __cmsg_len)
-{
-	struct compat_cmsghdr * __ptr;
-
-	__ptr = (struct compat_cmsghdr *)(((unsigned char *) __cmsg) +
-				     CMSG_COMPAT_ALIGN(__cmsg_len));
-	if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
-		return NULL;
-
-	return __ptr;
-}
-
-static __inline__ struct compat_cmsghdr *cmsg_compat_nxthdr (struct msghdr *__msg,
-					    struct compat_cmsghdr *__cmsg,
-					    int __cmsg_len)
-{
-	return __cmsg_compat_nxthdr(__msg->msg_control, __msg->msg_controllen,
-			       __cmsg, __cmsg_len);
-}
-
-#endif /* CONFIG_COMPAT */
-#endif
diff -Nru a/include/net/dst.h b/include/net/dst.h
--- a/include/net/dst.h	Wed Mar  5 15:45:36 2003
+++ b/include/net/dst.h	Wed Mar 19 19:52:56 2003
@@ -50,7 +50,8 @@
 	unsigned long		lastuse;
 	unsigned long		expires;
 
-	unsigned		header_len;	/* more space at head required */
+	unsigned short		header_len;	/* more space at head required */
+	unsigned short		trailer_len;	/* space to reserve at tail */
 
 	u32			metrics[RTAX_MAX];
 	struct dst_entry	*path;
diff -Nru a/include/net/if_inet6.h b/include/net/if_inet6.h
--- a/include/net/if_inet6.h	Sun Feb 23 22:46:32 2003
+++ b/include/net/if_inet6.h	Wed Mar 19 17:25:49 2003
@@ -75,6 +75,25 @@
 	spinlock_t		mca_lock;
 };
 
+/* Anycast stuff */
+
+struct ipv6_ac_socklist
+{
+	struct in6_addr		acl_addr;
+	int			acl_ifindex;
+	struct ipv6_ac_socklist *acl_next;
+};
+
+struct ifacaddr6
+{
+	struct in6_addr		aca_addr;
+	struct inet6_dev	*aca_idev;
+	struct ifacaddr6	*aca_next;
+	int			aca_users;
+	atomic_t		aca_refcnt;
+	spinlock_t		aca_lock;
+};
+
 #define	IFA_HOST	IPV6_ADDR_LOOPBACK
 #define	IFA_LINK	IPV6_ADDR_LINKLOCAL
 #define	IFA_SITE	IPV6_ADDR_SITELOCAL
@@ -108,6 +127,7 @@
 
 	struct inet6_ifaddr	*addr_list;
 	struct ifmcaddr6	*mc_list;
+	struct ifacaddr6	*ac_list;
 	rwlock_t		lock;
 	atomic_t		refcnt;
 	__u32			if_flags;
diff -Nru a/include/net/ipv6.h b/include/net/ipv6.h
--- a/include/net/ipv6.h	Tue Jan  7 02:19:42 2003
+++ b/include/net/ipv6.h	Sun Mar 23 21:38:36 2003
@@ -203,12 +203,8 @@
 
 extern int			ip6_call_ra_chain(struct sk_buff *skb, int sel);
 
-extern int			ipv6_reassembly(struct sk_buff **skb, int);
-
 extern int			ipv6_parse_hopopts(struct sk_buff *skb, int);
 
-extern int			ipv6_parse_exthdrs(struct sk_buff **skb, int);
-
 extern struct ipv6_txoptions *  ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
 
 extern int ip6_frag_nqueues;
@@ -226,21 +222,21 @@
 					   unsigned int, unsigned int);
 
 
-extern int		ipv6_addr_type(struct in6_addr *addr);
+extern int		ipv6_addr_type(const struct in6_addr *addr);
 
-static inline int ipv6_addr_scope(struct in6_addr *addr)
+static inline int ipv6_addr_scope(const struct in6_addr *addr)
 {
 	return ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
 }
 
-static inline int ipv6_addr_cmp(struct in6_addr *a1, struct in6_addr *a2)
+static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2)
 {
-	return memcmp((void *) a1, (void *) a2, sizeof(struct in6_addr));
+	return memcmp((const void *) a1, (const void *) a2, sizeof(struct in6_addr));
 }
 
-static inline void ipv6_addr_copy(struct in6_addr *a1, struct in6_addr *a2)
+static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2)
 {
-	memcpy((void *) a1, (void *) a2, sizeof(struct in6_addr));
+	memcpy((void *) a1, (const void *) a2, sizeof(struct in6_addr));
 }
 
 #ifndef __HAVE_ARCH_ADDR_SET
@@ -255,7 +251,7 @@
 }
 #endif
 
-static inline int ipv6_addr_any(struct in6_addr *a)
+static inline int ipv6_addr_any(const struct in6_addr *a)
 {
 	return ((a->s6_addr32[0] | a->s6_addr32[1] | 
 		 a->s6_addr32[2] | a->s6_addr32[3] ) == 0); 
diff -Nru a/include/net/protocol.h b/include/net/protocol.h
--- a/include/net/protocol.h	Tue Nov  5 07:17:12 2002
+++ b/include/net/protocol.h	Sun Mar 23 21:30:34 2003
@@ -44,7 +44,7 @@
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 struct inet6_protocol 
 {
-	int	(*handler)(struct sk_buff *skb);
+	int	(*handler)(struct sk_buff **skbp);
 
 	void	(*err_handler)(struct sk_buff *skb,
 			       struct inet6_skb_parm *opt,
diff -Nru a/include/net/sctp/command.h b/include/net/sctp/command.h
--- a/include/net/sctp/command.h	Tue Feb 18 16:21:43 2003
+++ b/include/net/sctp/command.h	Tue Mar  4 07:13:48 2003
@@ -110,13 +110,13 @@
 	sctp_event_timeout_t to;
 	sctp_counter_t counter;
 	void *ptr;
-	sctp_chunk_t *chunk;
-	sctp_association_t *asoc;
+	struct sctp_chunk *chunk;
+	struct sctp_association *asoc;
 	struct sctp_transport *transport;
-	sctp_bind_addr_t  *bp;
+	struct sctp_bind_addr *bp;
 	sctp_init_chunk_t *init;
 	struct sctp_ulpevent *ulpevent;
-	sctp_packet_t *packet;
+	struct sctp_packet *packet;
 	sctp_sackhdr_t *sackh;
 } sctp_arg_t;
 
@@ -158,13 +158,13 @@
 SCTP_ARG_CONSTRUCTOR(COUNTER,	sctp_counter_t, counter)
 SCTP_ARG_CONSTRUCTOR(TO,	sctp_event_timeout_t, to)
 SCTP_ARG_CONSTRUCTOR(PTR,	void *, ptr)
-SCTP_ARG_CONSTRUCTOR(CHUNK,	sctp_chunk_t *, chunk)
-SCTP_ARG_CONSTRUCTOR(ASOC,	sctp_association_t *, asoc)
+SCTP_ARG_CONSTRUCTOR(CHUNK,	struct sctp_chunk *, chunk)
+SCTP_ARG_CONSTRUCTOR(ASOC,	struct sctp_association *, asoc)
 SCTP_ARG_CONSTRUCTOR(TRANSPORT,	struct sctp_transport *, transport)
-SCTP_ARG_CONSTRUCTOR(BA,	sctp_bind_addr_t *, bp)
+SCTP_ARG_CONSTRUCTOR(BA,	struct sctp_bind_addr *, bp)
 SCTP_ARG_CONSTRUCTOR(PEER_INIT,	sctp_init_chunk_t *, init)
 SCTP_ARG_CONSTRUCTOR(ULPEVENT,  struct sctp_ulpevent *, ulpevent)
-SCTP_ARG_CONSTRUCTOR(PACKET,	sctp_packet_t *, packet)
+SCTP_ARG_CONSTRUCTOR(PACKET,	struct sctp_packet *, packet)
 SCTP_ARG_CONSTRUCTOR(SACKH,	sctp_sackhdr_t *, sackh)
 
 typedef struct {
diff -Nru a/include/net/sctp/constants.h b/include/net/sctp/constants.h
--- a/include/net/sctp/constants.h	Fri Jan 31 13:15:59 2003
+++ b/include/net/sctp/constants.h	Thu Mar  6 09:46:22 2003
@@ -210,14 +210,19 @@
 
 /* These are values for sk->state.
  * For a UDP-style SCTP socket, the states are defined as follows
- *   (at this point of time, may change later after more discussions: FIXME)
- * A socket in SCTP_SS_UNCONNECTED state indicates that it is not willing
- * to accept new associations, but it can initiate the creation of new
- * ones.
- * A socket in SCTP_SS_LISTENING state indicates that it is willing to
- * accept new  associations and can initiate the creation of new ones.
- * A socket in SCTP_SS_ESTABLISHED state indicates that it is a peeled off
- * socket with one association.
+ * - A socket in SCTP_SS_CLOSED state indicates that it is not willing to
+ *   accept new associations, but it can initiate the creation of new ones.
+ * - A socket in SCTP_SS_LISTENING state indicates that it is willing to
+ *   accept new  associations and can initiate the creation of new ones.
+ * - A socket in SCTP_SS_ESTABLISHED state indicates that it is a peeled off
+ *   socket with one association.
+ * For a TCP-style SCTP socket, the states are defined as follows
+ * - A socket in SCTP_SS_CLOSED state indicates that it is not willing to
+ *   accept new associations, but it can initiate the creation of new ones.
+ * - A socket in SCTP_SS_LISTENING state indicates that it is willing to
+ *   accept new associations, but cannot initiate the creation of new ones.
+ * - A socket in SCTP_SS_ESTABLISHED state indicates that it has a single 
+ *   association in ESTABLISHED state.
  */
 typedef enum {
 	SCTP_SS_CLOSED         = TCP_CLOSE,
@@ -345,6 +350,7 @@
 	SCTP_XMIT_PMTU_FULL,
 	SCTP_XMIT_RWND_FULL,
 	SCTP_XMIT_MUST_FRAG,
+	SCTP_XMIT_NAGLE_DELAY,
 } sctp_xmit_t;
 
 /* These are the commands for manipulating transports.  */
diff -Nru a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
--- a/include/net/sctp/sctp.h	Wed Feb 12 10:46:17 2003
+++ b/include/net/sctp/sctp.h	Tue Mar  4 07:13:48 2003
@@ -121,9 +121,10 @@
 /*
  * sctp_protocol.c
  */
-extern sctp_protocol_t sctp_proto;
+extern struct sctp_protocol sctp_proto;
 extern struct sock *sctp_get_ctl_sock(void);
-extern int sctp_copy_local_addr_list(sctp_protocol_t *, sctp_bind_addr_t *,
+extern int sctp_copy_local_addr_list(struct sctp_protocol  *, 
+				     struct sctp_bind_addr *,
 				     sctp_scope_t, int priority, int flags);
 extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
 extern int sctp_register_pf(struct sctp_pf *, sa_family_t);
@@ -312,30 +313,21 @@
 #endif
 
 
+/* Size of Supported Address Parameter for 'x' address types. */
+#define SCTP_SAT_LEN(x) (sizeof(struct sctp_paramhdr) + (x) * sizeof(__u16))
+
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 
 extern int sctp_v6_init(void);
 extern void sctp_v6_exit(void);
-
 static inline int sctp_ipv6_addr_type(const struct in6_addr *addr)
 {
 	return ipv6_addr_type((struct in6_addr*) addr);
 }
 
-#define SCTP_SAT_LEN (sizeof(sctp_paramhdr_t) + 2 * sizeof(__u16))
-
-/* Note: These V6 macros are obsolescent.  */
-/* Use this macro to enclose code fragments which are V6-dependent. */
-#define SCTP_V6(m...)	m
-#define SCTP_V6_SUPPORT 1
-
 #else /* #ifdef defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
 
 #define sctp_ipv6_addr_type(a) 0
-#define SCTP_SAT_LEN (sizeof(sctp_paramhdr_t) + 1 * sizeof(__u16))
-#define SCTP_V6(m...) /* Do nothing. */
-#undef SCTP_V6_SUPPORT
-
 static inline int sctp_v6_init(void) { return 0; }
 static inline void sctp_v6_exit(void) { return; }
 
@@ -348,25 +340,10 @@
 	return (sctp_assoc_t) asoc;
 }
 
-/* Look up the association by its id.  */
-static inline sctp_association_t *sctp_id2assoc(const struct sock *sk, sctp_assoc_t id)
-{
-	sctp_association_t *asoc = NULL;
 
-	/* First, verify that this is a kernel address. */
-	if (sctp_is_valid_kaddr((unsigned long) id)) {
-		sctp_association_t *temp = (sctp_association_t *) id;
-
-		/* Verify that this _is_ an sctp_association_t
-		 * data structure and if so, that the socket matches.
-		 */
-		if ((SCTP_ASSOC_EYECATCHER == temp->eyecatcher) &&
-		    (temp->base.sk == sk))
-			asoc = temp;
-	}
+/* Look up the association by its id.  */
+sctp_association_t *sctp_id2assoc(struct sock *sk, sctp_assoc_t id);
 
-	return asoc;
-}
 
 /* A macro to walk a list of skbs.  */
 #define sctp_skb_for_each(pos, head, tmp) \
@@ -494,7 +471,7 @@
 /* Static inline functions. */
 
 /* Return the SCTP protocol structure. */
-static inline sctp_protocol_t *sctp_get_protocol(void)
+static inline struct sctp_protocol *sctp_get_protocol(void)
 {
 	return &sctp_proto;
 }
@@ -523,21 +500,21 @@
 /* This is the hash function for the SCTP port hash table. */
 static inline int sctp_phashfn(__u16 lport)
 {
-	sctp_protocol_t *sctp_proto = sctp_get_protocol();
+	struct sctp_protocol *sctp_proto = sctp_get_protocol();
 	return (lport & (sctp_proto->port_hashsize - 1));
 }
 
 /* This is the hash function for the endpoint hash table. */
 static inline int sctp_ep_hashfn(__u16 lport)
 {
-	sctp_protocol_t *sctp_proto = sctp_get_protocol();
+	struct sctp_protocol *sctp_proto = sctp_get_protocol();
 	return (lport & (sctp_proto->ep_hashsize - 1));
 }
 
 /* This is the hash function for the association hash table. */
 static inline int sctp_assoc_hashfn(__u16 lport, __u16 rport)
 {
-	sctp_protocol_t *sctp_proto = sctp_get_protocol();
+	struct sctp_protocol *sctp_proto = sctp_get_protocol();
 	int h = (lport << 16) + rport;
 	h ^= h>>8;
 	return (h & (sctp_proto->assoc_hashsize - 1));
@@ -549,7 +526,7 @@
  */
 static inline int sctp_vtag_hashfn(__u16 lport, __u16 rport, __u32 vtag)
 {
-	sctp_protocol_t *sctp_proto = sctp_get_protocol();
+	struct sctp_protocol *sctp_proto = sctp_get_protocol();
 	int h = (lport << 16) + rport;
 	h ^= vtag;
 	return (h & (sctp_proto->assoc_hashsize-1));
diff -Nru a/include/net/sctp/sm.h b/include/net/sctp/sm.h
--- a/include/net/sctp/sm.h	Fri Jan 31 13:15:59 2003
+++ b/include/net/sctp/sm.h	Tue Mar  4 07:13:48 2003
@@ -3,40 +3,40 @@
  * Copyright (c) 1999-2001 Motorola, Inc.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001-2002 International Business Machines Corp.
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
+ *
  * This file is part of the implementation of the add-IP extension,
  * based on <draft-ietf-tsvwg-addip-sctp-02.txt> June 29, 2001,
  * for the SCTP kernel reference Implementation.
- * 
+ *
  * These are definitions needed by the state machine.
- * 
- * The SCTP reference implementation is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation 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, or (at your option)
  * any later version.
- * 
- * The SCTP reference implementation is distributed in the hope that it 
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to the
  * email addresses:
  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- * 
+ *
  * Or submit a bug report through the following website:
  *    http://www.sf.net/projects/lksctp
  *
- * Written or modified by: 
+ * Written or modified by:
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Karl Knutson <karl@athena.chicago.il.us>
  *    Xingang Guo <xingang.guo@intel.com>
@@ -313,18 +313,18 @@
 void sctp_generate_heartbeat_event(unsigned long peer);
 
 sctp_sackhdr_t *sctp_sm_pull_sack(sctp_chunk_t *);
-sctp_packet_t *sctp_abort_pkt_new(const sctp_endpoint_t *ep,
-				  const sctp_association_t *asoc,
-				  sctp_chunk_t *chunk,
-				  const void *payload,
-				  size_t paylen);
-sctp_packet_t *sctp_ootb_pkt_new(const sctp_association_t *asoc,
-				 const sctp_chunk_t *chunk);
-void sctp_ootb_pkt_free(sctp_packet_t *packet);
+struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *,
+				       const struct sctp_association *,
+				       struct sctp_chunk *chunk,
+				       const void *payload,
+				       size_t paylen);
+struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *,
+				      const struct sctp_chunk *);
+void sctp_ootb_pkt_free(struct sctp_packet *);
 
 sctp_cookie_param_t *
-sctp_pack_cookie(const sctp_endpoint_t *, const sctp_association_t *,
-		 const sctp_chunk_t *, int *cookie_len,
+sctp_pack_cookie(const struct sctp_endpoint *, const struct sctp_association *,
+		 const struct sctp_chunk *, int *cookie_len,
 		 const __u8 *, int addrs_len);
 sctp_association_t *sctp_unpack_cookie(const sctp_endpoint_t *,
 				       const sctp_association_t *,
diff -Nru a/include/net/sctp/structs.h b/include/net/sctp/structs.h
--- a/include/net/sctp/structs.h	Mon Mar  3 00:57:24 2003
+++ b/include/net/sctp/structs.h	Thu Mar  6 13:36:44 2003
@@ -86,10 +86,8 @@
 struct sctp_endpoint_common;
 struct sctp_ssnmap;
 
-typedef struct sctp_protocol sctp_protocol_t;
 typedef struct sctp_endpoint sctp_endpoint_t;
 typedef struct sctp_association sctp_association_t;
-typedef struct sctp_packet sctp_packet_t;
 typedef struct sctp_chunk sctp_chunk_t;
 typedef struct sctp_bind_addr sctp_bind_addr_t;
 typedef struct sctp_endpoint_common sctp_endpoint_common_t;
@@ -222,7 +220,7 @@
 	void 		(*get_saddr)	(struct sctp_association *asoc,
 					 struct dst_entry *dst,
 					 union sctp_addr *daddr,
-				 	 union sctp_addr *saddr);	 
+				 	 union sctp_addr *saddr);
 	void            (*copy_addrlist) (struct list_head *,
 					  struct net_device *);
 	void            (*dst_saddr)    (union sctp_addr *saddr,
@@ -262,6 +260,9 @@
 			  const union sctp_addr *,
 			  struct sctp_opt *);
 	int  (*bind_verify) (struct sctp_opt *, union sctp_addr *);
+	int  (*supported_addrs)(const struct sctp_opt *, __u16 *);
+	struct sock *(*create_accept_sk) (struct sock *sk,
+					  struct sctp_association *asoc);
 	struct sctp_af *af;
 };
 
@@ -366,8 +367,6 @@
 	sctp_cookie_t c;
 } sctp_signed_cookie_t;
 
-
-
 /* This is another convenience type to allocate memory for address
  * params for the maximum size and pass such structures around
  * internally.
@@ -604,26 +603,26 @@
 
 typedef int (sctp_outq_thandler_t)(struct sctp_outq *, void *);
 typedef int (sctp_outq_ehandler_t)(struct sctp_outq *);
-typedef sctp_packet_t *(sctp_outq_ohandler_init_t)
-	(sctp_packet_t *,
+typedef struct sctp_packet *(sctp_outq_ohandler_init_t)
+	(struct sctp_packet *,
          struct sctp_transport *,
          __u16 sport,
          __u16 dport);
-typedef sctp_packet_t *(sctp_outq_ohandler_config_t)
-        (sctp_packet_t *,
+typedef struct sctp_packet *(sctp_outq_ohandler_config_t)
+        (struct sctp_packet *,
 	 __u32 vtag,
 	 int ecn_capable,
 	 sctp_packet_phandler_t *get_prepend_chunk);
-typedef sctp_xmit_t (sctp_outq_ohandler_t)(sctp_packet_t *,
+typedef sctp_xmit_t (sctp_outq_ohandler_t)(struct sctp_packet *,
                                                sctp_chunk_t *);
-typedef int (sctp_outq_ohandler_force_t)(sctp_packet_t *);
+typedef int (sctp_outq_ohandler_force_t)(struct sctp_packet *);
 
 sctp_outq_ohandler_init_t    sctp_packet_init;
 sctp_outq_ohandler_config_t  sctp_packet_config;
 sctp_outq_ohandler_t         sctp_packet_append_chunk;
 sctp_outq_ohandler_t         sctp_packet_transmit_chunk;
 sctp_outq_ohandler_force_t   sctp_packet_transmit;
-void sctp_packet_free(sctp_packet_t *);
+void sctp_packet_free(struct sctp_packet *);
 
 
 /* This represents a remote transport address.
@@ -789,7 +788,7 @@
 	struct list_head transmitted;
 
 	/* We build bundle-able packets for this transport here.  */
-	sctp_packet_t packet;
+	struct sctp_packet packet;
 
 	/* This is the list of transports that have chunks to send.  */
 	struct list_head send_ready;
@@ -865,12 +864,11 @@
 struct sctp_outq {
 	sctp_association_t *asoc;
 
-	/* BUG: This really should be an array of streams.
-	 * This really holds a list of chunks (one stream).
-	 * FIXME: If true, why so?
-	 */
+	/* Data pending that has never been transmitted.  */
 	struct sk_buff_head out;
 
+	unsigned out_qlen;	/* Total length of queued data chunks. */
+
 	/* These are control chunks we want to send.  */
 	struct sk_buff_head control;
 
@@ -885,7 +883,7 @@
 	struct list_head retransmit;
 
 	/* Call these functions to send chunks down to the next lower
-	 * layer.  This is always SCTP_packet, but we separate the two
+	 * layer.  This is always sctp_packet, but we separate the two
 	 * structures to make testing simpler.
 	 */
 	sctp_outq_ohandler_init_t	*init_output;
@@ -1098,8 +1096,9 @@
 }
 
 /* These are function signatures for manipulating endpoints.  */
-sctp_endpoint_t *sctp_endpoint_new(sctp_protocol_t *, struct sock *, int);
-sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *, sctp_protocol_t *,
+sctp_endpoint_t *sctp_endpoint_new(struct sctp_protocol *, struct sock *, int);
+sctp_endpoint_t *sctp_endpoint_init(struct sctp_endpoint *,
+				    struct sctp_protocol *,
 				    struct sock *, int priority);
 void sctp_endpoint_free(sctp_endpoint_t *);
 void sctp_endpoint_put(sctp_endpoint_t *);
@@ -1111,7 +1110,6 @@
 int sctp_endpoint_is_peeled_off(sctp_endpoint_t *, const union sctp_addr *);
 sctp_endpoint_t *sctp_endpoint_is_match(sctp_endpoint_t *,
 					const union sctp_addr *);
-
 int sctp_has_association(const union sctp_addr *laddr,
 			 const union sctp_addr *paddr);
 
@@ -1587,7 +1585,7 @@
 struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *,
 				     const union sctp_addr *address,
 				     const int priority);
-void sctp_assoc_control_transport(sctp_association_t *,
+void sctp_assoc_control_transport(struct sctp_association *,
 				  struct sctp_transport *,
 				  sctp_transport_cmd_t, sctp_sn_error_t);
 struct sctp_transport *sctp_assoc_lookup_tsn(sctp_association_t *, __u32);
@@ -1597,14 +1595,14 @@
 void sctp_assoc_migrate(sctp_association_t *, struct sock *);
 void sctp_assoc_update(sctp_association_t *dst, sctp_association_t *src);
 
-__u32 __sctp_association_get_next_tsn(sctp_association_t *);
-__u32 __sctp_association_get_tsn_block(sctp_association_t *, int);
-__u16 __sctp_association_get_next_ssn(sctp_association_t *, __u16 sid);
-
-void sctp_assoc_sync_pmtu(sctp_association_t *);
-void sctp_assoc_rwnd_increase(sctp_association_t *, int);
-void sctp_assoc_rwnd_decrease(sctp_association_t *, int);
+__u32 sctp_association_get_next_tsn(struct sctp_association *);
+__u32 sctp_association_get_tsn_block(struct sctp_association *, int);
 
+void sctp_assoc_sync_pmtu(struct sctp_association *);
+void sctp_assoc_rwnd_increase(struct sctp_association *, int);
+void sctp_assoc_rwnd_decrease(struct sctp_association *, int);
+void sctp_assoc_set_primary(struct sctp_association *,
+			    struct sctp_transport *);
 int sctp_assoc_set_bind_addr_from_ep(sctp_association_t *, int);
 int sctp_assoc_set_bind_addr_from_cookie(sctp_association_t *,
 					 sctp_cookie_t *, int);
diff -Nru a/include/net/sctp/user.h b/include/net/sctp/user.h
--- a/include/net/sctp/user.h	Mon Mar  3 00:57:24 2003
+++ b/include/net/sctp/user.h	Thu Mar  6 13:36:44 2003
@@ -108,6 +108,8 @@
 #define SCTP_GET_LOCAL_ADDRS_NUM	SCTP_GET_LOCAL_ADDRS_NUM
 	SCTP_GET_LOCAL_ADDRS, 	/* Get all local addresss. */
 #define SCTP_GET_LOCAL_ADDRS	SCTP_GET_LOCAL_ADDRS
+	SCTP_NODELAY, 	/* Get/set nodelay option. */
+#define SCTP_NODELAY	SCTP_NODELAY
 };
 
 
diff -Nru a/include/net/tcp.h b/include/net/tcp.h
--- a/include/net/tcp.h	Sat Mar  8 11:37:51 2003
+++ b/include/net/tcp.h	Wed Mar 19 19:52:56 2003
@@ -927,7 +927,8 @@
 
 	if (dst) {
 		u32 mtu = dst_pmtu(dst);
-		if (mtu != tp->pmtu_cookie)
+		if (mtu != tp->pmtu_cookie ||
+		    tp->ext2_header_len != dst->header_len)
 			mss_now = tcp_sync_mss(sk, mtu);
 	}
 	if (tp->eff_sacks)
diff -Nru a/include/net/transp_v6.h b/include/net/transp_v6.h
--- a/include/net/transp_v6.h	Tue Feb  5 09:39:48 2002
+++ b/include/net/transp_v6.h	Sun Mar 23 21:30:34 2003
@@ -15,6 +15,14 @@
 
 struct flowi;
 
+/* extention headers */
+extern void				ipv6_hopopts_init(void);
+extern void				ipv6_rthdr_init(void);
+extern void				ipv6_frag_init(void);
+extern void				ipv6_nodata_init(void);
+extern void				ipv6_destopt_init(void);
+
+/* transport protocols */
 extern void				rawv6_init(void);
 extern void				udpv6_init(void);
 extern void				tcpv6_init(void);
diff -Nru a/include/net/xfrm.h b/include/net/xfrm.h
--- a/include/net/xfrm.h	Thu Mar  6 16:16:15 2003
+++ b/include/net/xfrm.h	Sun Mar 23 21:30:34 2003
@@ -10,8 +10,10 @@
 #include <linux/pfkeyv2.h>
 #include <linux/in6.h>
 
+#include <net/sock.h>
 #include <net/dst.h>
 #include <net/route.h>
+#include <net/ipv6.h>
 #include <net/ip6_fib.h>
 
 #define XFRM_ALIGN8(len)	(((len) + 7) & ~7)
@@ -107,6 +109,7 @@
 		u16		family;
 		xfrm_address_t	saddr;
 		int		header_len;
+		int		trailer_len;
 	} props;
 
 	struct xfrm_lifetime_cfg lft;
@@ -143,6 +146,51 @@
 	XFRM_STATE_DEAD
 };
 
+struct xfrm_type;
+struct xfrm_dst;
+struct xfrm_policy_afinfo {
+	unsigned short		family;
+	rwlock_t		lock;
+	struct xfrm_type_map	*type_map;
+	struct dst_ops		*dst_ops;
+	void			(*garbage_collect)(void);
+	int			(*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl);
+	struct dst_entry	*(*find_bundle)(struct flowi *fl, struct rtable *rt, struct xfrm_policy *policy);
+	int			(*bundle_create)(struct xfrm_policy *policy, 
+						 struct xfrm_state **xfrm, 
+						 int nx,
+						 struct flowi *fl, 
+						 struct dst_entry **dst_p);
+	void			(*decode_session)(struct sk_buff *skb,
+						  struct flowi *fl);
+};
+
+extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
+extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo);
+extern struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
+extern void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
+
+#define XFRM_ACQ_EXPIRES	30
+
+struct xfrm_tmpl;
+struct xfrm_state_afinfo {
+	unsigned short		family;
+	rwlock_t		lock;
+	struct list_head	*state_bydst;
+	struct list_head	*state_byspi;
+	void			(*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
+						struct xfrm_tmpl *tmpl,
+						xfrm_address_t *daddr, xfrm_address_t *saddr);
+	struct xfrm_state	*(*state_lookup)(xfrm_address_t *daddr, u32 spi, u8 proto);
+	struct xfrm_state	*(*find_acq)(u8 mode, u16 reqid, u8 proto, 
+					     xfrm_address_t *daddr, xfrm_address_t *saddr, 
+					     int create);
+};
+
+extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
+extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
+extern struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family);
+extern void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
 
 struct xfrm_type
 {
@@ -158,9 +206,14 @@
 	u32			(*get_max_size)(struct xfrm_state *, int size);
 };
 
-extern int xfrm_register_type(struct xfrm_type *type);
-extern int xfrm_unregister_type(struct xfrm_type *type);
-extern struct xfrm_type *xfrm_get_type(u8 proto);
+struct xfrm_type_map {
+	rwlock_t		lock;
+	struct xfrm_type	*map[256];
+};
+
+extern int xfrm_register_type(struct xfrm_type *type, unsigned short family);
+extern int xfrm_unregister_type(struct xfrm_type *type, unsigned short family);
+extern struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family);
 extern void xfrm_put_type(struct xfrm_type *type);
 
 struct xfrm_tmpl
@@ -231,6 +284,47 @@
 extern int xfrm_unregister_km(struct xfrm_mgr *km);
 
 
+#define XFRM_FLOWCACHE_HASH_SIZE	1024
+
+static inline u32 __flow_hash4(struct flowi *fl)
+{
+	u32 hash = fl->fl4_src ^ fl->uli_u.ports.sport;
+
+	hash = ((hash & 0xF0F0F0F0) >> 4) | ((hash & 0x0F0F0F0F) << 4);
+
+	hash ^= fl->fl4_dst ^ fl->uli_u.ports.dport;
+	hash ^= (hash >> 10);
+	hash ^= (hash >> 20);
+	return hash & (XFRM_FLOWCACHE_HASH_SIZE-1);
+}
+
+static inline u32 __flow_hash6(struct flowi *fl)
+{
+	u32 hash = fl->fl6_src->s6_addr32[2] ^
+		   fl->fl6_src->s6_addr32[3] ^ 
+		   fl->uli_u.ports.sport;
+
+	hash = ((hash & 0xF0F0F0F0) >> 4) | ((hash & 0x0F0F0F0F) << 4);
+
+	hash ^= fl->fl6_dst->s6_addr32[2] ^
+		fl->fl6_dst->s6_addr32[3] ^ 
+		fl->uli_u.ports.dport;
+	hash ^= (hash >> 10);
+	hash ^= (hash >> 20);
+	return hash & (XFRM_FLOWCACHE_HASH_SIZE-1);
+}
+
+static inline u32 flow_hash(struct flowi *fl, unsigned short family)
+{
+	switch (family) {
+	case AF_INET:
+		return __flow_hash4(fl);
+	case AF_INET6:
+		return __flow_hash6(fl);
+	}
+	return 0;	/*XXX*/
+}
+
 extern struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2];
 
 static inline void xfrm_pol_hold(struct xfrm_policy *policy)
@@ -247,6 +341,68 @@
 		__xfrm_policy_destroy(policy);
 }
 
+#define XFRM_DST_HSIZE		1024
+
+static __inline__
+unsigned __xfrm4_dst_hash(xfrm_address_t *addr)
+{
+	unsigned h;
+	h = ntohl(addr->a4);
+	h = (h ^ (h>>16)) % XFRM_DST_HSIZE;
+	return h;
+}
+
+static __inline__
+unsigned __xfrm6_dst_hash(xfrm_address_t *addr)
+{
+	unsigned h;
+	h = ntohl(addr->a6[2]^addr->a6[3]);
+	h = (h ^ (h>>16)) % XFRM_DST_HSIZE;
+	return h;
+}
+
+static __inline__
+unsigned xfrm_dst_hash(xfrm_address_t *addr, unsigned short family)
+{
+	switch (family) {
+	case AF_INET:
+		return __xfrm4_dst_hash(addr);
+	case AF_INET6:
+		return __xfrm6_dst_hash(addr);
+	}
+	return 0;
+}
+
+static __inline__
+unsigned __xfrm4_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto)
+{
+	unsigned h;
+	h = ntohl(addr->a4^spi^proto);
+	h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE;
+	return h;
+}
+
+static __inline__
+unsigned __xfrm6_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto)
+{
+	unsigned h;
+	h = ntohl(addr->a6[2]^addr->a6[3]^spi^proto);
+	h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE;
+	return h;
+}
+
+static __inline__
+unsigned xfrm_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto, unsigned short family)
+{
+	switch (family) {
+	case AF_INET:
+		return __xfrm4_spi_hash(addr, spi, proto);
+	case AF_INET6:
+		return __xfrm6_spi_hash(addr, spi, proto);
+	}
+	return 0;	/*XXX*/
+}
+
 extern void __xfrm_state_destroy(struct xfrm_state *);
 
 static inline void xfrm_state_put(struct xfrm_state *x)
@@ -255,15 +411,70 @@
 		__xfrm_state_destroy(x);
 }
 
+static inline void xfrm_state_hold(struct xfrm_state *x)
+{
+	atomic_inc(&x->refcnt);
+}
+
+static __inline__ int addr_match(void *token1, void *token2, int prefixlen)
+{
+	__u32 *a1 = token1;
+	__u32 *a2 = token2;
+	int pdw;
+	int pbi;
+
+	pdw = prefixlen >> 5;	  /* num of whole __u32 in prefix */
+	pbi = prefixlen &  0x1f;  /* num of bits in incomplete u32 in prefix */
+
+	if (pdw)
+		if (memcmp(a1, a2, pdw << 2))
+			return 0;
+
+	if (pbi) {
+		__u32 mask;
+
+		mask = htonl((0xffffffff) << (32 - pbi));
+
+		if ((a1[pdw] ^ a2[pdw]) & mask)
+			return 0;
+	}
+
+	return 1;
+}
+
+static inline int
+__xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl)
+{
+	return  addr_match(&fl->fl4_dst, &sel->daddr, sel->prefixlen_d) &&
+		addr_match(&fl->fl4_src, &sel->saddr, sel->prefixlen_s) &&
+		!((fl->uli_u.ports.dport^sel->dport)&sel->dport_mask) &&
+		!((fl->uli_u.ports.sport^sel->sport)&sel->sport_mask) &&
+		(fl->proto == sel->proto || !sel->proto) &&
+		(fl->oif == sel->ifindex || !sel->ifindex);
+}
+
 static inline int
-xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl)
+__xfrm6_selector_match(struct xfrm_selector *sel, struct flowi *fl)
 {
-	return	!((fl->fl4_dst^sel->daddr.xfrm4_addr)&sel->daddr.xfrm4_mask) &&
+	return  addr_match(fl->fl6_dst, &sel->daddr, sel->prefixlen_d) &&
+		addr_match(fl->fl6_src, &sel->saddr, sel->prefixlen_s) &&
 		!((fl->uli_u.ports.dport^sel->dport)&sel->dport_mask) &&
 		!((fl->uli_u.ports.sport^sel->sport)&sel->sport_mask) &&
 		(fl->proto == sel->proto || !sel->proto) &&
-		(fl->oif == sel->ifindex || !sel->ifindex) &&
-		!((fl->fl4_src^sel->saddr.xfrm4_addr)&sel->saddr.xfrm4_mask);
+		(fl->oif == sel->ifindex || !sel->ifindex);
+}
+
+static inline int
+xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
+		    unsigned short family)
+{
+	switch (family) {
+	case AF_INET:
+		return __xfrm4_selector_match(sel, fl);
+	case AF_INET6:
+		return __xfrm6_selector_match(sel, fl);
+	}
+	return 0;
 }
 
 /* A struct encoding bundle of transformations to apply to some set of flow.
@@ -289,6 +500,7 @@
 
 struct sec_path
 {
+	kmem_cache_t		*pool;
 	atomic_t		refcnt;
 	int			len;
 	struct xfrm_state	*xvec[XFRM_MAX_DEPTH];
@@ -310,42 +522,73 @@
 	if (sp && atomic_dec_and_test(&sp->refcnt))
 		__secpath_destroy(sp);
 }
+
+static inline int
+__xfrm4_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x)
+{
+	return	(tmpl->saddr.a4 &&
+		 tmpl->saddr.a4 != x->props.saddr.a4);
+}
+
+static inline int
+__xfrm6_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x)
+{
+	return	(!ipv6_addr_any((struct in6_addr*)&tmpl->saddr) &&
+		 ipv6_addr_cmp((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));
+}
+
+static inline int
+xfrm_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x, unsigned short family)
+{
+	switch (family) {
+	case AF_INET:
+		return __xfrm4_state_addr_cmp(tmpl, x);
+	case AF_INET6:
+		return __xfrm6_state_addr_cmp(tmpl, x);
+	}
+	return !0;
+}
+
 extern int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb, unsigned short family);
 
-static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
+static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
 {
 	if (sk && sk->policy[XFRM_POLICY_IN])
-		return __xfrm_policy_check(sk, dir, skb, AF_INET);
+		return __xfrm_policy_check(sk, dir, skb, family);
 		
 	return	!xfrm_policy_list[dir] ||
 		(skb->dst->flags & DST_NOPOLICY) ||
-		__xfrm_policy_check(sk, dir, skb, AF_INET);
+		__xfrm_policy_check(sk, dir, skb, family);
+}
+
+static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
+{
+	return xfrm_policy_check(sk, dir, skb, AF_INET);
 }
 
 static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
 {
-	if (sk && sk->policy[XFRM_POLICY_IN])
-		return __xfrm_policy_check(sk, dir, skb, AF_INET6);
-		
-	return	!xfrm_policy_list[dir] ||
-		(skb->dst->flags & DST_NOPOLICY) ||
-		__xfrm_policy_check(sk, dir, skb, AF_INET6);
+	return xfrm_policy_check(sk, dir, skb, AF_INET6);
 }
 
+
 extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
 
-static inline int xfrm_route_forward(struct sk_buff *skb)
+static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
 {
 	return	!xfrm_policy_list[XFRM_POLICY_OUT] ||
 		(skb->dst->flags & DST_NOXFRM) ||
-		__xfrm_route_forward(skb, AF_INET);
+		__xfrm_route_forward(skb, family);
+}
+
+static inline int xfrm4_route_forward(struct sk_buff *skb)
+{
+	return xfrm_route_forward(skb, AF_INET);
 }
 
 static inline int xfrm6_route_forward(struct sk_buff *skb)
 {
-	return	!xfrm_policy_list[XFRM_POLICY_OUT] ||
-		(skb->dst->flags & DST_NOXFRM) ||
-		__xfrm_route_forward(skb, AF_INET6);
+	return xfrm_route_forward(skb, AF_INET6);
 }
 
 extern int __xfrm_sk_clone_policy(struct sock *sk);
@@ -353,7 +596,7 @@
 static inline int xfrm_sk_clone_policy(struct sock *sk)
 {
 	if (unlikely(sk->policy[0] || sk->policy[1]))
-		return xfrm_sk_clone_policy(sk);
+		return __xfrm_sk_clone_policy(sk);
 	return 0;
 }
 
@@ -371,6 +614,66 @@
 	}
 }
 
+static __inline__
+xfrm_address_t *xfrm_flowi_daddr(struct flowi *fl, unsigned short family)
+{
+	switch (family){
+	case AF_INET:
+		return (xfrm_address_t *)&fl->fl4_dst;
+	case AF_INET6:
+		return (xfrm_address_t *)fl->fl6_dst;
+	}
+	return NULL;
+}
+
+static __inline__
+xfrm_address_t *xfrm_flowi_saddr(struct flowi *fl, unsigned short family)
+{
+	switch (family){
+	case AF_INET:
+		return (xfrm_address_t *)&fl->fl4_src;
+	case AF_INET6:
+		return (xfrm_address_t *)fl->fl6_src;
+	}
+	return NULL;
+}
+
+static __inline__ int
+__xfrm4_state_addr_check(struct xfrm_state *x,
+			 xfrm_address_t *daddr, xfrm_address_t *saddr)
+{
+	if (daddr->a4 == x->id.daddr.a4 &&
+	    (saddr->a4 == x->props.saddr.a4 || !saddr->a4 || !x->props.saddr.a4))
+		return 1;
+	return 0;
+}
+
+static __inline__ int
+__xfrm6_state_addr_check(struct xfrm_state *x,
+			 xfrm_address_t *daddr, xfrm_address_t *saddr)
+{
+	if (!ipv6_addr_cmp((struct in6_addr *)daddr, (struct in6_addr *)&x->id.daddr) &&
+	    (!ipv6_addr_cmp((struct in6_addr *)saddr, (struct in6_addr *)&x->props.saddr)|| 
+	     ipv6_addr_any((struct in6_addr *)saddr) || 
+	     ipv6_addr_any((struct in6_addr *)&x->props.saddr)))
+		return 1;
+	return 0;
+}
+
+static __inline__ int
+xfrm_state_addr_check(struct xfrm_state *x,
+		      xfrm_address_t *daddr, xfrm_address_t *saddr,
+		      unsigned short family)
+{
+	switch (family) {
+	case AF_INET:
+		return __xfrm4_state_addr_check(x, daddr, saddr);
+	case AF_INET6:
+		return __xfrm6_state_addr_check(x, daddr, saddr);
+	}
+	return 0;
+}
+
 /*
  * xfrm algorithm information
  */
@@ -384,30 +687,42 @@
 	u16 defkeybits;
 };
 
+struct xfrm_algo_comp_info {
+	u16 threshold;
+};
+
 struct xfrm_algo_desc {
 	char *name;
 	u8 available:1;
 	union {
 		struct xfrm_algo_auth_info auth;
 		struct xfrm_algo_encr_info encr;
+		struct xfrm_algo_comp_info comp;
 	} uinfo;
 	struct sadb_alg desc;
 };
 
+extern void xfrm_init(void);
+extern void xfrm4_init(void);
+extern void xfrm4_fini(void);
+extern void xfrm6_init(void);
+extern void xfrm6_fini(void);
 extern void xfrm_state_init(void);
-extern void xfrm_input_init(void);
+extern void xfrm4_state_init(void);
+extern void xfrm4_state_fini(void);
+extern void xfrm6_state_init(void);
+extern void xfrm6_state_fini(void);
+
 extern int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), void *);
 extern struct xfrm_state *xfrm_state_alloc(void);
-extern struct xfrm_state *xfrm4_state_find(u32 daddr, u32 saddr, struct flowi *fl, struct xfrm_tmpl *tmpl,
-					   struct xfrm_policy *pol, int *err);
-extern struct xfrm_state *xfrm6_state_find(struct in6_addr *daddr, struct in6_addr *saddr,
-					   struct flowi *fl, struct xfrm_tmpl *tmpl,
-					   struct xfrm_policy *pol, int *err);
+extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, 
+					  struct flowi *fl, struct xfrm_tmpl *tmpl,
+					  struct xfrm_policy *pol, int *err,
+					  unsigned short family);
 extern int xfrm_state_check_expire(struct xfrm_state *x);
 extern void xfrm_state_insert(struct xfrm_state *x);
 extern int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb);
-extern struct xfrm_state *xfrm4_state_lookup(u32 daddr, u32 spi, u8 proto);
-extern struct xfrm_state *xfrm6_state_lookup(struct in6_addr *daddr, u32 spi, u8 proto);
+extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family);
 extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
 extern void xfrm_state_delete(struct xfrm_state *x);
 extern void xfrm_state_flush(u8 proto);
@@ -415,10 +730,13 @@
 extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
 extern int xfrm_check_selectors(struct xfrm_state **x, int n, struct flowi *fl);
 extern int xfrm4_rcv(struct sk_buff *skb);
-extern int xfrm6_rcv(struct sk_buff *skb);
+extern int xfrm6_rcv(struct sk_buff **pskb);
 extern int xfrm6_clear_mutable_options(struct sk_buff *skb, u16 *nh_offset, int dir);
 extern int xfrm_user_policy(struct sock *sk, int optname, u8 *optval, int optlen);
 
+void xfrm_policy_init(void);
+void xfrm4_policy_init(void);
+void xfrm6_policy_init(void);
 struct xfrm_policy *xfrm_policy_alloc(int gfp);
 extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *);
 struct xfrm_policy *xfrm_policy_lookup(int dir, struct flowi *fl, unsigned short family);
@@ -427,76 +745,39 @@
 struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete);
 void xfrm_policy_flush(void);
 void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
-struct xfrm_state * xfrm_find_acq(u8 mode, u16 reqid, u8 proto, u32 daddr, u32 saddr, int create);
-struct xfrm_state * xfrm6_find_acq(u8 mode, u16 reqid, u8 proto, struct in6_addr *daddr,
-				   struct in6_addr *saddr, int create);
+struct xfrm_state * xfrm_find_acq(u8 mode, u16 reqid, u8 proto, 
+				  xfrm_address_t *daddr, xfrm_address_t *saddr, 
+				  int create, unsigned short family);
 extern void xfrm_policy_flush(void);
 extern void xfrm_policy_kill(struct xfrm_policy *);
 extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
 extern struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl);
 extern int xfrm_flush_bundles(struct xfrm_state *x);
+extern int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family);
 
 extern wait_queue_head_t km_waitq;
 extern void km_warn_expired(struct xfrm_state *x);
 extern void km_expired(struct xfrm_state *x);
 extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *pol);
 
+extern void xfrm4_input_init(void);
+extern void xfrm6_input_init(void);
+extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq);
+
 extern void xfrm_probe_algs(void);
 extern int xfrm_count_auth_supported(void);
 extern int xfrm_count_enc_supported(void);
 extern struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);
 extern struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);
+extern struct xfrm_algo_desc *xfrm_calg_get_byidx(unsigned int idx);
 extern struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);
 extern struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
+extern struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);
 extern struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name);
 extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name);
-
-static __inline__ int addr_match(void *token1, void *token2, int prefixlen)
-{
-	__u32 *a1 = token1;
-	__u32 *a2 = token2;
-	int pdw;
-	int pbi;
-
-	pdw = prefixlen >> 5;	  /* num of whole __u32 in prefix */
-	pbi = prefixlen &  0x1f;  /* num of bits in incomplete u32 in prefix */
-
-	if (pdw)
-		if (memcmp(a1, a2, pdw << 2))
-			return 0;
-
-	if (pbi) {
-		__u32 mask;
-
-		mask = htonl((0xffffffff) << (32 - pbi));
-
-		if ((a1[pdw] ^ a2[pdw]) & mask)
-			return 0;
-	}
-
-	return 1;
-}
-
-static inline int
-xfrm6_selector_match(struct xfrm_selector *sel, struct flowi *fl)
-{
-	return  addr_match(fl->fl6_dst, &sel->daddr, sel->prefixlen_d) &&
-		addr_match(fl->fl6_src, &sel->saddr, sel->prefixlen_s) &&
-		!((fl->uli_u.ports.dport^sel->dport)&sel->dport_mask) &&
-		!((fl->uli_u.ports.sport^sel->sport)&sel->sport_mask) &&
-		(fl->proto == sel->proto || !sel->proto) &&
-		(fl->oif == sel->ifindex || !sel->ifindex);
-}
-
-extern int xfrm6_register_type(struct xfrm_type *type);
-extern int xfrm6_unregister_type(struct xfrm_type *type);
-extern struct xfrm_type *xfrm6_get_type(u8 proto);
+extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name);
 
 struct crypto_tfm;
 typedef void (icv_update_fn_t)(struct crypto_tfm *, struct scatterlist *, unsigned int);
-
-typedef int (xfrm_dst_lookup_t)(struct xfrm_dst **dst, struct flowi *fl);
-int xfrm_dst_lookup_register(xfrm_dst_lookup_t *dst_lookup, unsigned short family);
-void xfrm_dst_lookup_unregister(unsigned short family);
 
 #endif	/* _NET_XFRM_H */
diff -Nru a/include/pcmcia/ds.h b/include/pcmcia/ds.h
--- a/include/pcmcia/ds.h	Mon Feb  4 23:37:44 2002
+++ b/include/pcmcia/ds.h	Sun Mar 23 03:34:47 2003
@@ -32,6 +32,7 @@
 
 #include <pcmcia/driver_ops.h>
 #include <pcmcia/bulkmem.h>
+#include <linux/device.h>
 
 typedef struct tuple_parse_t {
     tuple_t		tuple;
@@ -140,8 +141,18 @@
 
 int unregister_pccard_driver(dev_info_t *dev_info);
 
-#define register_pcmcia_driver register_pccard_driver
-#define unregister_pcmcia_driver unregister_pccard_driver
+extern struct bus_type pcmcia_bus_type;
+
+struct pcmcia_driver {
+	int			use_count, status;
+	dev_link_t		*(*attach)(void);
+	void			(*detach)(dev_link_t *);
+	struct module		*owner;
+	struct device_driver	drv;
+};
+
+int pcmcia_register_driver(struct pcmcia_driver *driver);
+void pcmcia_unregister_driver(struct pcmcia_driver *driver);
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
--- a/include/sound/ac97_codec.h	Sun Feb 16 05:47:40 2003
+++ b/include/sound/ac97_codec.h	Thu Mar 20 08:41:10 2003
@@ -156,12 +156,30 @@
 /* extended modem ID bit defines */
 #define AC97_MEI_LINE1		0x0001	/* Line1 present */
 #define AC97_MEI_LINE2		0x0002	/* Line2 present */
-#define AC97_MEI_HEADSET	0x0004	/* Headset present */
+#define AC97_MEI_HANDSET	0x0004	/* Handset present */
 #define AC97_MEI_CID1		0x0008	/* caller ID decode for Line1 is supported */
 #define AC97_MEI_CID2		0x0010	/* caller ID decode for Line2 is supported */
 #define AC97_MEI_ADDR_MASK	0xc000	/* physical codec ID (address) */
 #define AC97_MEI_ADDR_SHIFT	14
 
+/* extended modem status and control bit defines */
+#define AC97_MEA_GPIO		0x0001	/* GPIO is ready (ro) */
+#define AC97_MEA_MREF		0x0002	/* Vref is up to nominal level (ro) */
+#define AC97_MEA_ADC1		0x0004	/* ADC1 operational (ro) */
+#define AC97_MEA_DAC1		0x0008	/* DAC1 operational (ro) */
+#define AC97_MEA_ADC2		0x0010	/* ADC2 operational (ro) */
+#define AC97_MEA_DAC2		0x0020	/* DAC2 operational (ro) */
+#define AC97_MEA_HADC		0x0040	/* HADC operational (ro) */
+#define AC97_MEA_HDAC		0x0080	/* HDAC operational (ro) */
+#define AC97_MEA_PRA		0x0100	/* GPIO power down (high) */
+#define AC97_MEA_PRB		0x0200	/* reserved */
+#define AC97_MEA_PRC		0x0400	/* ADC1 power down (high) */
+#define AC97_MEA_PRD		0x0800	/* DAC1 power down (high) */
+#define AC97_MEA_PRE		0x1000	/* ADC2 power down (high) */
+#define AC97_MEA_PRF		0x2000	/* DAC2 power down (high) */
+#define AC97_MEA_PRG		0x4000	/* HADC power down (high) */
+#define AC97_MEA_PRH		0x8000	/* HDAC power down (high) */
+
 /* specific - SigmaTel */
 #define AC97_SIGMATEL_ANALOG	0x6c	/* Analog Special */
 #define AC97_SIGMATEL_DAC2INVERT 0x6e
@@ -268,6 +286,14 @@
 };
 
 /* conditions */
+static inline int ac97_is_audio(ac97_t * ac97)
+{
+	return (ac97->scaps & AC97_SCAP_AUDIO);
+}
+static inline int ac97_is_modem(ac97_t * ac97)
+{
+	return (ac97->scaps & AC97_SCAP_MODEM);
+}
 static inline int ac97_is_rev22(ac97_t * ac97)
 {
 	return (ac97->ext_id & AC97_EI_REV_MASK) == AC97_EI_REV_22;
@@ -278,7 +304,8 @@
 }
 
 /* functions */
-int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97);
+int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97);	/* create mixer controls */
+int snd_ac97_modem(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97);	/* create modem controls */
 
 void snd_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short value);
 unsigned short snd_ac97_read(ac97_t *ac97, unsigned short reg);
@@ -296,6 +323,7 @@
 struct ac97_quirk {
 	unsigned short vendor;
 	unsigned short device;
+	const char *name;
 	int type;
 };
 
diff -Nru a/include/sound/asound.h b/include/sound/asound.h
--- a/include/sound/asound.h	Sun Feb  9 10:47:44 2003
+++ b/include/sound/asound.h	Thu Mar 20 08:41:11 2003
@@ -1,6 +1,6 @@
 /*
  *  Advanced Linux Sound Architecture - ALSA - Driver
- *  Copyright (c) 1994-2000 by Jaroslav Kysela <perex@suse.cz>,
+ *  Copyright (c) 1994-2003 by Jaroslav Kysela <perex@suse.cz>,
  *                             Abramo Bagnara <abramo@alsa-project.org>
  *
  *
@@ -93,7 +93,7 @@
  *                                                                          *
  ****************************************************************************/
 
-#define SNDRV_HWDEP_VERSION		SNDRV_PROTOCOL_VERSION(1, 0, 0)
+#define SNDRV_HWDEP_VERSION		SNDRV_PROTOCOL_VERSION(1, 0, 1)
 
 enum sndrv_hwdep_iface {
 	SNDRV_HWDEP_IFACE_OPL2 = 0,
@@ -104,9 +104,10 @@
 	SNDRV_HWDEP_IFACE_YSS225,	/* Yamaha FX processor */
 	SNDRV_HWDEP_IFACE_ICS2115,	/* Wavetable synth */
 	SNDRV_HWDEP_IFACE_SSCAPE,	/* Ensoniq SoundScape ISA card (MC68EC000) */
+	SNDRV_HWDEP_IFACE_VX,		/* Digigram VX cards */
 
 	/* Don't forget to change the following: */
-	SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_SSCAPE,
+	SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_VX,
 };
 
 struct sndrv_hwdep_info {
@@ -118,9 +119,29 @@
 	unsigned char reserved[64];	/* reserved for future */
 };
 
+/* generic DSP loader */
+struct sndrv_hwdep_dsp_status {
+	unsigned int version;		/* R: driver-specific version */
+	unsigned char id[32];		/* R: driver-specific ID string */
+	unsigned int num_dsps;		/* R: number of DSP images to transfer */
+	unsigned int dsp_loaded;	/* R: bit flags indicating the loaded DSPs */
+	unsigned int chip_ready;	/* R: 1 = initialization finished */
+	unsigned char reserved[16];	/* reserved for future use */
+};
+
+struct sndrv_hwdep_dsp_image {
+	unsigned int index;		/* W: DSP index */
+	unsigned char name[64];		/* W: ID (e.g. file name) */
+	unsigned char *image;		/* W: binary image */
+	size_t length;			/* W: size of image in bytes */
+	unsigned long driver_data;	/* W: driver-specific data */
+};
+
 enum {
 	SNDRV_HWDEP_IOCTL_PVERSION = _IOR ('H', 0x00, int),
 	SNDRV_HWDEP_IOCTL_INFO = _IOR ('H', 0x01, struct sndrv_hwdep_info),
+	SNDRV_HWDEP_IOCTL_DSP_STATUS = _IOR('H', 0x02, struct sndrv_hwdep_dsp_status),
+	SNDRV_HWDEP_IOCTL_DSP_LOAD   = _IOW('H', 0x03, struct sndrv_hwdep_dsp_image)
 };
 
 /*****************************************************************************
@@ -129,7 +150,7 @@
  *                                                                           *
  *****************************************************************************/
 
-#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 3)
+#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 5)
 
 typedef unsigned long sndrv_pcm_uframes_t;
 typedef long sndrv_pcm_sframes_t;
@@ -377,8 +398,8 @@
 
 struct sndrv_pcm_status {
 	enum sndrv_pcm_state state;	/* stream state */
-	struct timeval trigger_tstamp;	/* time when stream was started/stopped/paused */
-	struct timeval tstamp;		/* reference timestamp */
+	struct timespec trigger_tstamp;	/* time when stream was started/stopped/paused */
+	struct timespec tstamp;		/* reference timestamp */
 	sndrv_pcm_uframes_t appl_ptr;	/* appl ptr */
 	sndrv_pcm_uframes_t hw_ptr;	/* hw ptr */
 	sndrv_pcm_sframes_t delay;	/* current delay in frames */
@@ -393,7 +414,7 @@
 	enum sndrv_pcm_state state;	/* RO: state - SNDRV_PCM_STATE_XXXX */
 	int pad1;			/* Needed for 64 bit alignment */
 	sndrv_pcm_uframes_t hw_ptr;	/* RO: hw ptr (0...boundary-1) */
-	struct timeval tstamp;		/* Timestamp */
+	struct timespec tstamp;		/* Timestamp */
 	enum sndrv_pcm_state suspended_state; /* RO: suspended stream state */
 };
 
@@ -417,6 +438,7 @@
 enum {
 	SNDRV_PCM_IOCTL_PVERSION = _IOR('A', 0x00, int),
 	SNDRV_PCM_IOCTL_INFO = _IOR('A', 0x01, struct sndrv_pcm_info),
+	SNDRV_PCM_IOCTL_TSTAMP = _IOW('A', 0x02, int),
 	SNDRV_PCM_IOCTL_HW_REFINE = _IOWR('A', 0x10, struct sndrv_pcm_hw_params),
 	SNDRV_PCM_IOCTL_HW_PARAMS = _IOWR('A', 0x11, struct sndrv_pcm_hw_params),
 	SNDRV_PCM_IOCTL_HW_FREE = _IO('A', 0x12),
@@ -434,6 +456,7 @@
 	SNDRV_PCM_IOCTL_REWIND = _IOW('A', 0x46, sndrv_pcm_uframes_t),
 	SNDRV_PCM_IOCTL_RESUME = _IO('A', 0x47),
 	SNDRV_PCM_IOCTL_XRUN = _IO('A', 0x48),
+	SNDRV_PCM_IOCTL_FORWARD = _IOW('A', 0x49, sndrv_pcm_uframes_t),
 	SNDRV_PCM_IOCTL_WRITEI_FRAMES = _IOW('A', 0x50, struct sndrv_xferi),
 	SNDRV_PCM_IOCTL_READI_FRAMES = _IOR('A', 0x51, struct sndrv_xferi),
 	SNDRV_PCM_IOCTL_WRITEN_FRAMES = _IOW('A', 0x52, struct sndrv_xfern),
@@ -491,7 +514,7 @@
 
 struct sndrv_rawmidi_status {
 	enum sndrv_rawmidi_stream stream;
-	struct timeval tstamp;		/* Timestamp */
+	struct timespec tstamp;		/* Timestamp */
 	size_t avail;			/* available bytes */
 	size_t xruns;			/* count of overruns since last status (in bytes) */
 	unsigned char reserved[16];	/* reserved for future use */
@@ -510,7 +533,7 @@
  *  Timer section - /dev/snd/timer
  */
 
-#define SNDRV_TIMER_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 0)
+#define SNDRV_TIMER_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 1)
 
 enum sndrv_timer_class {
 	SNDRV_TIMER_CLASS_NONE = -1,
@@ -534,6 +557,9 @@
 #define SNDRV_TIMER_GLOBAL_SYSTEM	0
 #define SNDRV_TIMER_GLOBAL_RTC		1
 
+/* info flags */
+#define SNDRV_TIMER_FLG_SLAVE		(1<<0)	/* cannot be controlled */
+
 struct sndrv_timer_id {
 	enum sndrv_timer_class dev_class;	
 	enum sndrv_timer_slave_class dev_sclass;
@@ -542,36 +568,65 @@
 	int subdevice;
 };
 
+struct sndrv_timer_ginfo {
+	struct sndrv_timer_id tid;	/* requested timer ID */
+	unsigned int flags;		/* timer flags - SNDRV_TIMER_FLG_* */
+	int card;			/* card number */
+	unsigned char id[64];		/* timer identification */
+	unsigned char name[80];		/* timer name */
+	unsigned long reserved0;	/* reserved for future use */
+	unsigned long resolution;	/* average period resolution in ns */
+	unsigned long resolution_min;	/* minimal period resolution in ns */
+	unsigned long resolution_max;	/* maximal period resolution in ns */
+	unsigned int clients;		/* active timer clients */
+	unsigned char reserved[32];
+};
+
+struct sndrv_timer_gparams {
+	struct sndrv_timer_id tid;	/* requested timer ID */
+	unsigned long period_num;	/* requested precise period duration (in seconds) - numerator */
+	unsigned long period_den;	/* requested precise period duration (in seconds) - denominator */
+	unsigned char reserved[32];
+};
+
+struct sndrv_timer_gstatus {
+	struct sndrv_timer_id tid;	/* requested timer ID */
+	unsigned long resolution;	/* current period resolution in ns */
+	unsigned long resolution_num;	/* precise current period resolution (in seconds) - numerator */
+	unsigned long resolution_den;	/* precise current period resolution (in seconds) - denominator */
+	unsigned char reserved[32];
+};
+
 struct sndrv_timer_select {
 	struct sndrv_timer_id id;	/* bind to timer ID */
 	unsigned char reserved[32];	/* reserved */
 };
 
-#define SNDRV_TIMER_FLG_SLAVE		(1<<0)	/* cannot be controlled */
-
 struct sndrv_timer_info {
 	unsigned int flags;		/* timer flags - SNDRV_TIMER_FLG_* */
-	int card;			/* R: card number */
+	int card;			/* card number */
 	unsigned char id[64];		/* timer identificator */
 	unsigned char name[80];		/* timer name */
-	unsigned long ticks;		/* maximum ticks */
-	unsigned long resolution;	/* average resolution */
+	unsigned long reserved0;	/* reserved for future use */
+	unsigned long resolution;	/* average period resolution in ns */
 	unsigned char reserved[64];	/* reserved */
 };
 
-#define SNDRV_TIMER_PSFLG_AUTO		(1<<0)	/* supports auto start */
+#define SNDRV_TIMER_PSFLG_AUTO		(1<<0)	/* auto start, otherwise one-shot */
+#define SNDRV_TIMER_PSFLG_EXCLUSIVE	(1<<1)	/* exclusive use, precise start/stop/pause/continue */
 
 struct sndrv_timer_params {
 	unsigned int flags;		/* flags - SNDRV_MIXER_PSFLG_* */
 	unsigned int ticks;		/* requested resolution in ticks */
 	unsigned int queue_size;	/* total size of queue (32-1024) */
 	unsigned int reserved0;		/* reserved, was: failure locations */
-	unsigned char reserved[64];	/* reserved */
+	unsigned int filter;		/* event filter (bitmask of SNDRV_TIMER_EVENT_*) */
+	unsigned char reserved[60];	/* reserved */
 };
 
 struct sndrv_timer_status {
-	struct timeval tstamp;		/* Timestamp */
-	unsigned int resolution;	/* current resolution */
+	struct timespec tstamp;		/* Timestamp - last update */
+	unsigned int resolution;	/* current period resolution in ns */
 	unsigned int lost;		/* counter of master tick lost */
 	unsigned int overrun;		/* count of read queue overruns */
 	unsigned int queue;		/* used queue size */
@@ -581,13 +636,18 @@
 enum {
 	SNDRV_TIMER_IOCTL_PVERSION = _IOR('T', 0x00, int),
 	SNDRV_TIMER_IOCTL_NEXT_DEVICE = _IOWR('T', 0x01, struct sndrv_timer_id),
+	SNDRV_TIMER_IOCTL_TREAD = _IOW('T', 0x02, int),
+	SNDRV_TIMER_IOCTL_GINFO = _IOWR('T', 0x03, struct sndrv_timer_ginfo),
+	SNDRV_TIMER_IOCTL_GPARAMS = _IOW('T', 0x04, struct sndrv_timer_gparams),
+	SNDRV_TIMER_IOCTL_GSTATUS = _IOWR('T', 0x05, struct sndrv_timer_gstatus),
 	SNDRV_TIMER_IOCTL_SELECT = _IOW('T', 0x10, struct sndrv_timer_select),
 	SNDRV_TIMER_IOCTL_INFO = _IOR('T', 0x11, struct sndrv_timer_info),
 	SNDRV_TIMER_IOCTL_PARAMS = _IOW('T', 0x12, struct sndrv_timer_params),
-	SNDRV_TIMER_IOCTL_STATUS = _IOW('T', 0x14, struct sndrv_timer_status),
+	SNDRV_TIMER_IOCTL_STATUS = _IOR('T', 0x14, struct sndrv_timer_status),
 	SNDRV_TIMER_IOCTL_START = _IO('T', 0x20),
 	SNDRV_TIMER_IOCTL_STOP = _IO('T', 0x21),
 	SNDRV_TIMER_IOCTL_CONTINUE = _IO('T', 0x22),
+	SNDRV_TIMER_IOCTL_PAUSE = _IO('T', 0x23),
 };
 
 struct sndrv_timer_read {
@@ -595,13 +655,33 @@
 	unsigned int ticks;
 };
 
+enum sndrv_timer_event {
+	SNDRV_TIMER_EVENT_RESOLUTION = 0,	/* val = resolution in ns */
+	SNDRV_TIMER_EVENT_TICK,			/* val = ticks */
+	SNDRV_TIMER_EVENT_START,		/* val = resolution in ns */
+	SNDRV_TIMER_EVENT_STOP,			/* val = 0 */
+	SNDRV_TIMER_EVENT_CONTINUE,		/* val = resolution in ns */
+	SNDRV_TIMER_EVENT_PAUSE,		/* val = 0 */
+	/* master timer events for slave timer instances */
+	SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10,
+	SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10,
+	SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10,
+	SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10,
+};
+
+struct sndrv_timer_tread {
+	enum sndrv_timer_event event;
+	struct timespec tstamp;
+	unsigned int val;
+};
+
 /****************************************************************************
  *                                                                          *
  *        Section for driver control interface - /dev/snd/control?          *
  *                                                                          *
  ****************************************************************************/
 
-#define SNDRV_CTL_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 0)
+#define SNDRV_CTL_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 1)
 
 struct sndrv_ctl_card_info {
 	int card;			/* card number */
@@ -642,6 +722,7 @@
 #define SNDRV_CTL_ELEM_ACCESS_WRITE		(1<<1)
 #define SNDRV_CTL_ELEM_ACCESS_READWRITE		(SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE)
 #define SNDRV_CTL_ELEM_ACCESS_VOLATILE		(1<<2)	/* control value may be changed without a notification */
+#define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP		(1<<2)	/* when was control changed */
 #define SNDRV_CTL_ELEM_ACCESS_INACTIVE		(1<<8)	/* control does actually nothing, but may be updated */
 #define SNDRV_CTL_ELEM_ACCESS_LOCK		(1<<9)	/* write lock */
 #define SNDRV_CTL_ELEM_ACCESS_OWNER		(1<<10)	/* write lock owner */
@@ -722,7 +803,8 @@
 		} bytes;
 		struct sndrv_aes_iec958 iec958;
         } value;                /* RO */
-        unsigned char reserved[128];
+	struct timespec tstamp;
+        unsigned char reserved[128-sizeof(struct timespec)];
 };
 
 enum {
diff -Nru a/include/sound/core.h b/include/sound/core.h
--- a/include/sound/core.h	Sat Feb  8 12:10:44 2003
+++ b/include/sound/core.h	Thu Mar 20 08:41:11 2003
@@ -27,7 +27,7 @@
 #include <linux/rwsem.h>		/* struct rw_semaphore */
 
 /* Typedef's */
-typedef struct timeval snd_timestamp_t;
+typedef struct timespec snd_timestamp_t;
 typedef struct sndrv_interval snd_interval_t;
 typedef enum sndrv_card_type snd_card_type;
 typedef struct sndrv_xferi snd_xferi_t;
@@ -275,32 +275,6 @@
 #endif
 void *snd_kcalloc(size_t size, int flags);
 char *snd_kmalloc_strdup(const char *string, int flags);
-void *snd_malloc_pages(unsigned long size, unsigned int dma_flags);
-void *snd_malloc_pages_fallback(unsigned long size, unsigned int dma_flags, unsigned long *res_size);
-void snd_free_pages(void *ptr, unsigned long size);
-#ifdef CONFIG_PCI
-void *snd_malloc_pci_pages(struct pci_dev *pci, unsigned long size, dma_addr_t *dma_addr);
-void *snd_malloc_pci_pages_fallback(struct pci_dev *pci, unsigned long size, dma_addr_t *dma_addr, unsigned long *res_size);
-void snd_free_pci_pages(struct pci_dev *pci, unsigned long size, void *ptr, dma_addr_t dma_addr);
-void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *dma_addr);
-#define snd_free_pci_page(pci,ptr,addr) snd_free_pci_pages(pci,PAGE_SIZE,ptr,addr)
-#endif
-#ifdef CONFIG_SBUS
-void *snd_malloc_sbus_pages(struct sbus_dev *sdev, unsigned long size, dma_addr_t *dma_addr);
-void *snd_malloc_sbus_pages_fallback(struct sbus_dev *sdev, unsigned long size, dma_addr_t *dma_addr, unsigned long *res_size);
-void snd_free_sbus_pages(struct sbus_dev *sdev, unsigned long size, void *ptr, dma_addr_t dma_addr);
-#endif
-#ifdef CONFIG_ISA
-#ifdef CONFIG_PCI
-#define snd_malloc_isa_pages(size, dma_addr) snd_malloc_pci_pages(NULL, size, dma_addr)
-#define snd_malloc_isa_pages_fallback(size, dma_addr, res_size) snd_malloc_pci_pages_fallback(NULL, size, dma_addr, res_size)
-#define snd_free_isa_pages(size, ptr, dma_addr) snd_free_pci_pages(NULL, size, ptr, dma_addr)
-#else /* !CONFIG_PCI */
-void *snd_malloc_isa_pages(unsigned long size, dma_addr_t *dma_addr);
-void *snd_malloc_isa_pages_fallback(unsigned long size, dma_addr_t *dma_addr, unsigned long *res_size);
-#define snd_free_isa_pages(size, ptr, dma_addr) snd_free_pages(ptr, size)
-#endif /* CONFIG_PCI */
-#endif /* CONFIG_ISA */
 int copy_to_user_fromio(void *dst, unsigned long src, size_t count);
 int copy_from_user_toio(unsigned long dst, const void *src, size_t count);
 
@@ -450,9 +424,27 @@
 #define snd_BUG() snd_assert(0, )
 
 
-#define snd_timestamp_now(tstamp) do_gettimeofday(tstamp)
-#define snd_timestamp_zero(tstamp) do { (tstamp)->tv_sec = 0; (tstamp)->tv_usec = 0; } while (0)
-#define snd_timestamp_null(tstamp) ((tstamp)->tv_sec == 0 && (tstamp)->tv_usec ==0)
+static inline void snd_timestamp_now(struct timespec *tstamp, int timespec)
+{
+	struct timeval val;
+	/* FIXME: use a linear time source */
+	do_gettimeofday(&val);
+	tstamp->tv_sec = val.tv_sec;
+	tstamp->tv_nsec = val.tv_usec;
+	if (timespec)
+		tstamp->tv_nsec *= 1000L;
+}
+
+static inline void snd_timestamp_zero(struct timespec *tstamp)
+{
+	tstamp->tv_sec = 0;
+	tstamp->tv_nsec = 0;
+}
+
+static inline int snd_timestamp_null(struct timespec *tstamp)
+{
+	return tstamp->tv_sec == 0 && tstamp->tv_nsec == 0;
+}
 
 #define SNDRV_OSS_VERSION         ((3<<16)|(8<<8)|(1<<4)|(0))	/* 3.8.1a */
 
diff -Nru a/include/sound/driver.h b/include/sound/driver.h
--- a/include/sound/driver.h	Sun Sep 29 13:18:57 2002
+++ b/include/sound/driver.h	Thu Mar 20 08:41:11 2003
@@ -49,20 +49,6 @@
  *  ==========================================================================
  */
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-#if defined(__i386__) || defined(__ppc__) || defined(__x86_64__)
-/*
- * Here a dirty hack for 2.4 kernels.. See sound/core/memory.c.
- */
-#define HACK_PCI_ALLOC_CONSISTENT
-#include <linux/pci.h>
-void *snd_pci_hack_alloc_consistent(struct pci_dev *hwdev, size_t size,
-				    dma_addr_t *dma_handle);
-#undef pci_alloc_consistent
-#define pci_alloc_consistent snd_pci_hack_alloc_consistent
-#endif /* i386 or ppc */
-#endif /* 2.4.0 */
-
 #ifdef CONFIG_SND_DEBUG_MEMORY
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
diff -Nru a/include/sound/emu10k1.h b/include/sound/emu10k1.h
--- a/include/sound/emu10k1.h	Mon Jan 27 11:00:12 2003
+++ b/include/sound/emu10k1.h	Thu Mar 20 08:41:11 2003
@@ -49,6 +49,8 @@
 #define NUM_G           64              /* use all channels */
 #define NUM_FXSENDS     4
 
+#define EMU10K1_DMA_MASK	0x1fffffffUL
+#define AUDIGY_DMA_MASK		0xffffffffUL
 
 #define TMEMSIZE        256*1024
 #define TMEMSIZEREG     4
@@ -232,6 +234,8 @@
 #define A_GPINPUT_MASK		0xff00
 #define A_GPOUTPUT_MASK		0x00ff
 #define A_IOCFG_GPOUT0		0x0044		/* analog/digital? */
+#define A_IOCFG_GPOUT1		0x0002		/* IR */
+#define A_IOCFG_GPOUT2		0x0001		/* IR */
 
 #define TIMER			0x1a		/* Timer terminal count register		*/
 						/* NOTE: After the rate is changed, a maximum	*/
@@ -936,6 +940,7 @@
 	unsigned short model;			/* subsystem id */
 	unsigned int card_type;			/* EMU10K1_CARD_* */
 	unsigned int ecard_ctrl;		/* ecard control bits */
+	unsigned long dma_mask;			/* PCI DMA mask */
 	int max_cache_pages;			/* max memory size / PAGE_SIZE */
 	void *silent_page;			/* silent page */
 	dma_addr_t silent_page_dmaaddr;
diff -Nru a/include/sound/hwdep.h b/include/sound/hwdep.h
--- a/include/sound/hwdep.h	Wed Feb 13 11:32:01 2002
+++ b/include/sound/hwdep.h	Tue Feb 25 05:46:04 2003
@@ -27,6 +27,8 @@
 
 typedef enum sndrv_hwdep_iface snd_hwdep_iface_t;
 typedef struct sndrv_hwdep_info snd_hwdep_info_t;
+typedef struct sndrv_hwdep_dsp_status snd_hwdep_dsp_status_t;
+typedef struct sndrv_hwdep_dsp_image snd_hwdep_dsp_image_t;
 
 typedef struct _snd_hwdep_ops {
 	long long (*llseek) (snd_hwdep_t *hw, struct file * file, long long offset, int orig);
@@ -37,6 +39,8 @@
 	unsigned int (*poll) (snd_hwdep_t * hw, struct file * file, poll_table * wait);
 	int (*ioctl) (snd_hwdep_t * hw, struct file * file, unsigned int cmd, unsigned long arg);
 	int (*mmap) (snd_hwdep_t * hw, struct file * file, struct vm_area_struct * vma);
+	int (*dsp_status) (snd_hwdep_t * hw, snd_hwdep_dsp_status_t * status);
+	int (*dsp_load) (snd_hwdep_t * hw, snd_hwdep_dsp_image_t * image);
 } snd_hwdep_ops_t;
 
 struct _snd_hwdep {
@@ -56,6 +60,11 @@
 	wait_queue_head_t open_wait;
 	void *private_data;
 	void (*private_free) (snd_hwdep_t *hwdep);
+
+	struct semaphore open_mutex;
+	int used;
+	unsigned int dsp_loaded;
+	unsigned int exclusive: 1;
 };
 
 extern int snd_hwdep_new(snd_card_t * card, char *id, int device, snd_hwdep_t ** rhwdep);
diff -Nru a/include/sound/initval.h b/include/sound/initval.h
--- a/include/sound/initval.h	Mon Jan 13 17:54:26 2003
+++ b/include/sound/initval.h	Tue Feb 25 05:46:04 2003
@@ -67,7 +67,7 @@
 #define SNDRV_BOOLEAN_TRUE_DESC	"allows:{{0,Disabled},{1,Enabled}},default:1,dialog:check"
 #define SNDRV_BOOLEAN_FALSE_DESC "allows:{{0,Disabled},{1,Enabled}},default:0,dialog:check"
 
-#define SNDRV_ENABLED		"enable:(snd_enable)"
+#define SNDRV_ENABLED		"enable:(enable)"
 
 #define SNDRV_INDEX_DESC	SNDRV_ENABLED ",allows:{{0,7}},unique,skill:required,dialog:list"
 #define SNDRV_ID_DESC		SNDRV_ENABLED ",unique"
diff -Nru a/include/sound/memalloc.h b/include/sound/memalloc.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/sound/memalloc.h	Thu Mar 20 08:41:15 2003
@@ -0,0 +1,193 @@
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ *                   Takashi Iwai <tiwai@suse.de>
+ * 
+ *  Generic memory allocators
+ *
+ *
+ *   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
+ *
+ */
+
+#ifndef __SOUND_MEMALLOC_H
+#define __SOUND_MEMALLOC_H
+
+#include <linux/pci.h>
+#ifdef CONFIG_SBUS
+#include <asm/sbus.h>
+#endif
+
+/*
+ * buffer device info
+ */
+struct snd_dma_device {
+	int type;			/* SNDRV_MEM_TYPE_XXX */
+	union {
+		struct pci_dev *pci;	/* for PCI and PCI-SG types */
+		unsigned int flags;	/* GFP_XXX for continous and ISA types */
+#ifdef CONFIG_SBUS
+		struct sbus_dev *sbus;	/* for SBUS type */
+#endif
+	} dev;
+	unsigned int id;		/* a unique ID */
+};
+
+/*
+ * buffer types
+ */
+#define SNDRV_DMA_TYPE_UNKNOWN		0	/* not defined */
+#define SNDRV_DMA_TYPE_CONTINUOUS	1	/* continuous no-DMA memory */
+#define SNDRV_DMA_TYPE_ISA		2	/* ISA continuous */
+#define SNDRV_DMA_TYPE_PCI		3	/* PCI continuous */
+#define SNDRV_DMA_TYPE_SBUS		4	/* SBUS continuous */
+#define SNDRV_DMA_TYPE_PCI_SG		5	/* PCI SG-buffer */
+
+#ifdef CONFIG_PCI
+/*
+ * compose a snd_dma_device struct for the PCI device
+ */
+static inline void snd_dma_device_pci(struct snd_dma_device *dev, struct pci_dev *pci, unsigned int id)
+{
+	memset(dev, 0, sizeof(*dev));
+	dev->type = SNDRV_DMA_TYPE_PCI;
+	dev->dev.pci = pci;
+	dev->id = id;
+}
+#endif
+
+
+/*
+ * info for buffer allocation
+ */
+struct snd_dma_buffer {
+	unsigned char *area;	/* virtual pointer */
+	dma_addr_t addr;	/* physical address */
+	size_t bytes;		/* buffer size in bytes */
+	void *private_data;	/* private for allocator; don't touch */
+};
+
+/* allocate/release a buffer */
+int snd_dma_alloc_pages(const struct snd_dma_device *dev, size_t size, struct snd_dma_buffer *dmab);
+void snd_dma_free_pages(const struct snd_dma_device *dev, struct snd_dma_buffer *dmab);
+
+/* buffer-preservation managements */
+size_t snd_dma_get_reserved(const struct snd_dma_device *dev, struct snd_dma_buffer *dmab);
+int snd_dma_free_reserved(const struct snd_dma_device *dev);
+int snd_dma_set_reserved(const struct snd_dma_device *dev, struct snd_dma_buffer *dmab);
+
+
+/*
+ * Generic memory allocators
+ */
+
+/*
+ * continuous pages
+ */
+void *snd_malloc_pages(size_t size, unsigned int gfp_flags);
+void *snd_malloc_pages_fallback(size_t size, unsigned int gfp_flags, size_t *res_size);
+void snd_free_pages(void *ptr, size_t size);
+
+#ifdef CONFIG_PCI
+/*
+ * PCI continuous pages
+ */
+void *snd_malloc_pci_pages(struct pci_dev *pci, size_t size, dma_addr_t *dma_addr);
+void *snd_malloc_pci_pages_fallback(struct pci_dev *pci, size_t size, dma_addr_t *dma_addr, size_t *res_size);
+void snd_free_pci_pages(struct pci_dev *pci, size_t size, void *ptr, dma_addr_t dma_addr);
+/* one page allocation */
+void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *dma_addr);
+#define snd_free_pci_page(pci,ptr,addr) snd_free_pci_pages(pci,PAGE_SIZE,ptr,addr)
+#endif
+
+#ifdef CONFIG_SBUS
+/*
+ * SBUS continuous pages
+ */
+void *snd_malloc_sbus_pages(struct sbus_dev *sdev, size_t size, dma_addr_t *dma_addr);
+void *snd_malloc_sbus_pages_fallback(struct sbus_dev *sdev, size_t size, dma_addr_t *dma_addr, size_t *res_size);
+void snd_free_sbus_pages(struct sbus_dev *sdev, size_t size, void *ptr, dma_addr_t dma_addr);
+#endif
+
+#ifdef CONFIG_ISA
+/*
+ * ISA continuous pages
+ */
+void *snd_malloc_isa_pages(size_t size, dma_addr_t *dma_addr);
+void *snd_malloc_isa_pages_fallback(size_t size, dma_addr_t *dma_addr, size_t *res_size);
+void snd_free_isa_pages(size_t size, void *ptr, dma_addr_t addr);
+#ifdef CONFIG_PCI
+#define snd_malloc_isa_pages(size, dma_addr) snd_malloc_pci_pages(NULL, size, dma_addr)
+#define snd_malloc_isa_pages_fallback(size, dma_addr, res_size) snd_malloc_pci_pages_fallback(NULL, size, dma_addr, res_size)
+#define snd_free_isa_pages(size, ptr, dma_addr) snd_free_pci_pages(NULL, size, ptr, dma_addr)
+#else /* !CONFIG_PCI */
+#define snd_free_isa_pages(size, ptr, dma_addr) snd_free_pages(ptr, size)
+#endif /* CONFIG_PCI */
+#endif /* CONFIG_ISA */
+
+#ifdef CONFIG_PCI
+/*
+ * Scatter-Gather PCI pages
+ */
+struct snd_sg_page {
+	void *buf;
+	dma_addr_t addr;
+};
+
+struct snd_sg_buf {
+	int size;	/* allocated byte size */
+	int pages;	/* allocated pages */
+	int tblsize;	/* allocated table size */
+	struct snd_sg_page *table;	/* address table */
+	struct page **page_table;	/* page table (for vmap/vunmap) */
+	struct pci_dev *pci;
+};
+
+void *snd_malloc_sgbuf_pages(struct pci_dev *pci, size_t size, struct snd_dma_buffer *dmab);
+int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab);
+
+/*
+ * return the pages matching with the given byte size
+ */
+static inline unsigned int snd_sgbuf_aligned_pages(size_t size)
+{
+	return (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+}
+
+/*
+ * return the physical address at the corresponding offset
+ */
+static inline dma_addr_t snd_sgbuf_get_addr(struct snd_sg_buf *sgbuf, size_t offset)
+{
+	return sgbuf->table[offset >> PAGE_SHIFT].addr + offset % PAGE_SIZE;
+}
+#endif /* CONFIG_PCI */
+
+
+/*
+ * wrappers
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
+#ifdef CONFIG_PCI
+#if defined(__i386__) || defined(__ppc__) || defined(__x86_64__)
+#define HACK_PCI_ALLOC_CONSISTENT
+/* a hack for 2.4/5 kernels for better allocation of large buffers */
+void *snd_pci_hack_alloc_consistent(struct pci_dev *hwdev, size_t size,
+				    dma_addr_t *dma_handle);
+#endif /* arch */
+#endif /* CONFIG_PCI */
+#endif /* LINUX >= 2.4.0 */
+
+
+#endif /* __SOUND_MEMALLOC_H */
diff -Nru a/include/sound/mpu401.h b/include/sound/mpu401.h
--- a/include/sound/mpu401.h	Thu Dec  5 11:39:43 2002
+++ b/include/sound/mpu401.h	Thu Mar 20 08:41:11 2003
@@ -42,6 +42,7 @@
 #define MPU401_HW_ALS4000		16	/* Avance Logic ALS4000 */
 #define MPU401_HW_INTEL8X0		17	/* Intel8x0 driver */
 #define MPU401_HW_PC98II		18	/* Roland PC98II */
+#define MPU401_HW_AUREAL		19	/* Aureal Vortex */
 
 #define MPU401_MODE_BIT_INPUT		0
 #define MPU401_MODE_BIT_OUTPUT		1
@@ -87,6 +88,9 @@
 	spinlock_t timer_lock;
 
 	struct timer_list timer;
+
+	void (*write) (mpu401_t * mpu, unsigned char data, unsigned long addr);
+	unsigned char (*read) (mpu401_t * mpu, unsigned long addr);
 };
 
 /* I/O ports */
diff -Nru a/include/sound/pcm.h b/include/sound/pcm.h
--- a/include/sound/pcm.h	Sun Feb 16 05:47:40 2003
+++ b/include/sound/pcm.h	Thu Mar 20 08:41:11 2003
@@ -24,6 +24,7 @@
  */
 
 #include <sound/asound.h>
+#include <sound/memalloc.h>
 #include <linux/poll.h>
 #include <linux/bitops.h>
 
@@ -49,6 +50,7 @@
 typedef struct sndrv_pcm_mmap_status snd_pcm_mmap_status_t;
 typedef struct sndrv_pcm_mmap_control snd_pcm_mmap_control_t;
 typedef struct sndrv_mask snd_mask_t;
+typedef struct snd_sg_buf snd_pcm_sgbuf_t;
 
 #define _snd_pcm_substream_chip(substream) ((substream)->private_data)
 #define snd_pcm_substream_chip(substream) snd_magic_cast1(chip_t, _snd_pcm_substream_chip(substream), return -ENXIO)
@@ -97,6 +99,7 @@
 	int (*silence)(snd_pcm_substream_t *substream, int channel, 
 		       snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
 	struct page *(*page)(snd_pcm_substream_t *substream, unsigned long offset);
+	int (*ack)(snd_pcm_substream_t *substream);
 } snd_pcm_ops_t;
 
 /*
@@ -120,13 +123,6 @@
 #define SNDRV_PCM_TRIGGER_SUSPEND	5
 #define SNDRV_PCM_TRIGGER_RESUME	6
 
-#define SNDRV_PCM_DMA_TYPE_UNKNOWN	0	/* not defined */
-#define SNDRV_PCM_DMA_TYPE_CONTINUOUS	1	/* continuous no-DMA memory */
-#define SNDRV_PCM_DMA_TYPE_ISA		2	/* ISA continuous */
-#define SNDRV_PCM_DMA_TYPE_PCI		3	/* PCI continuous */
-#define SNDRV_PCM_DMA_TYPE_SBUS		4	/* SBUS continuous */
-#define SNDRV_PCM_DMA_TYPE_PCI_SG	5	/* PCI SG-buffer */
-
 /* If you change this don't forget to change rates[] table in pcm_native.c */
 #define SNDRV_PCM_RATE_5512		(1<<0)		/* 5512Hz */
 #define SNDRV_PCM_RATE_8000		(1<<1)		/* 8000Hz */
@@ -281,13 +277,6 @@
 	unsigned int mask;
 } snd_pcm_hw_constraint_list_t;
 
-struct snd_pcm_dma_buffer {
-	unsigned char *area;
-	dma_addr_t addr;
-	unsigned long bytes;
-	void *private_data; /* for allocator */
-};
-
 struct _snd_pcm_runtime {
 	/* -- Status -- */
 	snd_pcm_substream_t *trigger_master;
@@ -316,6 +305,7 @@
 	unsigned int rate_den;
 
 	/* -- SW params -- */
+	int tstamp_timespec;		/* use timeval (0) or timespec (1) */
 	snd_pcm_tstamp_t tstamp_mode;	/* mmap timestamp is updated */
   	unsigned int period_step;
 	unsigned int sleep_min;		/* min ticks to sleep */
@@ -361,7 +351,7 @@
 	/* -- DMA -- */           
 	unsigned char *dma_area;	/* DMA area */
 	dma_addr_t dma_addr;		/* physical bus address (not accessible from main CPU) */
-	unsigned long dma_bytes;	/* size of DMA area */
+	size_t dma_bytes;		/* size of DMA area */
 	void *dma_private;		/* private DMA data for the memory allocator */
 
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
@@ -378,17 +368,17 @@
 	char name[32];			/* substream name */
 	int stream;			/* stream (direction) */
 	size_t buffer_bytes_max;	/* limit ring buffer size */
-	int dma_type;			
-	struct snd_pcm_dma_buffer dma_buffer;
+	struct snd_dma_device dma_device;
+	struct snd_dma_buffer dma_buffer;
 	size_t dma_max;
-	void *dma_private;
 	/* -- hardware operations -- */
+	unsigned int open_flag: 1;	/* lowlevel device has been opened */
 	snd_pcm_ops_t *ops;
 	/* -- runtime information -- */
 	snd_pcm_runtime_t *runtime;
         /* -- timer section -- */
 	snd_timer_t *timer;		/* timer */
-	int timer_running;		/* time is running */
+	int timer_running: 1;		/* time is running */
 	spinlock_t timer_lock;
 	/* -- next substream -- */
 	snd_pcm_substream_t *next;
@@ -879,7 +869,18 @@
 					      snd_pcm_t *pcm,
 					      size_t size,
 					      size_t max);
+int snd_pcm_lib_preallocate_sg_pages(struct pci_dev *pci,
+				     snd_pcm_substream_t *substream,
+				     size_t size, size_t max);
+int snd_pcm_lib_preallocate_sg_pages_for_all(struct pci_dev *pci,
+					     snd_pcm_t *pcm,
+					     size_t size, size_t max);
+#define snd_pcm_substream_sgbuf(substream) ((substream)->runtime->dma_private)
+#define snd_pcm_sgbuf_pages(size) snd_sgbuf_aligned_pages(size)
+#define snd_pcm_sgbuf_get_addr(sgbuf,ofs) snd_sgbuf_get_addr(sgbuf,ofs)
+struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset);
 #endif
+
 #ifdef CONFIG_SBUS
 int snd_pcm_lib_preallocate_sbus_pages(struct sbus_dev *sdev,
 				       snd_pcm_substream_t *substream,
diff -Nru a/include/sound/pcm_sgbuf.h b/include/sound/pcm_sgbuf.h
--- a/include/sound/pcm_sgbuf.h	Sun Feb 16 05:47:40 2003
+++ b/include/sound/pcm_sgbuf.h	Thu Mar 20 08:41:11 2003
@@ -1,68 +0,0 @@
-#ifndef __SOUND_PCM_SGBUF_H
-#define __SOUND_PCM_SGBUF_H
-
-/*
- * Scatter-Gather PCM access
- *
- *  Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- *   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
- *
- */
-
-struct snd_sg_page {
-	void *buf;
-	dma_addr_t addr;
-};
-
-struct snd_sg_buf {
-	int size;	/* allocated byte size (= runtime->dma_bytes) */
-	int pages;	/* allocated pages */
-	int tblsize;	/* allocated table size */
-	struct snd_sg_page *table;
-	struct page **page_table;
-	struct pci_dev *pci;
-};
-
-typedef struct snd_sg_buf snd_pcm_sgbuf_t; /* for magic cast */
-
-/*
- * return the pages matching with the given byte size
- */
-static inline unsigned int snd_pcm_sgbuf_pages(size_t size)
-{
-	return (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
-}
-
-/*
- * return the physical address at the corresponding offset
- */
-static inline dma_addr_t snd_pcm_sgbuf_get_addr(struct snd_sg_buf *sgbuf, size_t offset)
-{
-	return sgbuf->table[offset >> PAGE_SHIFT].addr + offset % PAGE_SIZE;
-}
-
-void *snd_pcm_sgbuf_alloc_pages(struct pci_dev *pci, size_t size, struct snd_pcm_dma_buffer *dmab);
-int snd_pcm_sgbuf_free_pages(struct snd_pcm_dma_buffer *dmab);
-
-int snd_pcm_lib_preallocate_sg_pages(struct pci_dev *pci, snd_pcm_substream_t *substream, size_t size, size_t max);
-int snd_pcm_lib_preallocate_sg_pages_for_all(struct pci_dev *pci, snd_pcm_t *pcm, size_t size, size_t max);
-
-#define _snd_pcm_substream_sgbuf(substream) ((substream)->runtime->dma_private)
-#define snd_pcm_substream_sgbuf(substream) snd_magic_cast(snd_pcm_sgbuf_t, _snd_pcm_substream_sgbuf(substream), return -ENXIO)
-
-struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset);
-
-#endif /* __SOUND_PCM_SGBUF_H */
diff -Nru a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h
--- a/include/sound/seq_kernel.h	Sat Feb  8 12:10:44 2003
+++ b/include/sound/seq_kernel.h	Thu Mar 20 08:41:11 2003
@@ -174,7 +174,7 @@
 
 /* port attach/detach */
 int snd_seq_event_port_attach(int client, snd_seq_port_callback_t *pcbp,
-			      int cap, int type, int midi_channels, char *portname);
+			      int cap, int type, int midi_channels, int midi_voices, char *portname);
 int snd_seq_event_port_detach(int client, int port);
 
 #endif /* __SOUND_SEQ_KERNEL_H */
diff -Nru a/include/sound/sndmagic.h b/include/sound/sndmagic.h
--- a/include/sound/sndmagic.h	Sat Feb  8 12:10:44 2003
+++ b/include/sound/sndmagic.h	Thu Mar 20 08:41:11 2003
@@ -108,7 +108,7 @@
 #define snd_pcm_proc_private_t_magic		0xa15a0104
 #define snd_pcm_oss_file_t_magic		0xa15a0105
 #define snd_mixer_oss_t_magic			0xa15a0106
-#define snd_pcm_sgbuf_t_magic			0xa15a0107
+// #define snd_pcm_sgbuf_t_magic			0xa15a0107
 
 #define snd_info_private_data_t_magic		0xa15a0201
 #define snd_info_entry_t_magic			0xa15a0202
@@ -174,6 +174,7 @@
 #define m3_dma_t_magic				0xa15a3202
 #define nm256_t_magic				0xa15a3301
 #define nm256_dma_t_magic			0xa15a3302
+#define sam9407_t_magic				0xa15a3401
 #define pmac_t_magic				0xa15a3501
 #define ali_t_magic				0xa15a3601
 #define mtpav_t_magic				0xa15a3701
@@ -190,6 +191,8 @@
 #define snd_usb_midi_t_magic			0xa15a3f01
 #define snd_usb_midi_out_endpoint_t_magic	0xa15a3f02
 #define snd_usb_midi_in_endpoint_t_magic	0xa15a3f03
+#define ak4117_t_magic				0xa15a4000
+#define psic_t_magic				0xa15a4100
 
 
 #else
diff -Nru a/include/sound/timer.h b/include/sound/timer.h
--- a/include/sound/timer.h	Sun Feb  9 10:47:45 2003
+++ b/include/sound/timer.h	Thu Mar 20 08:41:11 2003
@@ -3,7 +3,8 @@
 
 /*
  *  Timer abstract layer
- *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ *		     Abramo Bagnara <abramo@alsa-project.org>
  *
  *
  *   This program is free software; you can redistribute it and/or modify
@@ -29,11 +30,15 @@
 typedef enum sndrv_timer_slave_class snd_timer_slave_class_t;
 typedef enum sndrv_timer_global snd_timer_global_t;
 typedef struct sndrv_timer_id snd_timer_id_t;
+typedef struct sndrv_timer_ginfo snd_timer_ginfo_t;
+typedef struct sndrv_timer_gparams snd_timer_gparams_t;
+typedef struct sndrv_timer_gstatus snd_timer_gstatus_t;
 typedef struct sndrv_timer_select snd_timer_select_t;
 typedef struct sndrv_timer_info snd_timer_info_t;
 typedef struct sndrv_timer_params snd_timer_params_t;
 typedef struct sndrv_timer_status snd_timer_status_t;
 typedef struct sndrv_timer_read snd_timer_read_t;
+typedef struct sndrv_timer_tread snd_timer_tread_t;
 
 #define _snd_timer_chip(timer) ((timer)->private_data)
 #define snd_timer_chip(timer) snd_magic_cast1(chip_t, _snd_timer_chip(timer), return -ENXIO)
@@ -54,16 +59,21 @@
 #define SNDRV_TIMER_IFLG_AUTO	  0x00000008	/* auto restart */
 #define SNDRV_TIMER_IFLG_FAST	  0x00000010	/* fast callback (do not use tasklet) */
 #define SNDRV_TIMER_IFLG_CALLBACK 0x00000020	/* timer callback is active */
+#define SNDRV_TIMER_IFLG_EXCLUSIVE 0x00000040	/* exclusive owner - no more instances */
 
 #define SNDRV_TIMER_FLG_CHANGE	0x00000001
 #define SNDRV_TIMER_FLG_RESCHED	0x00000002	/* need reschedule */
 
 typedef void (*snd_timer_callback_t) (snd_timer_instance_t * timeri, unsigned long ticks, unsigned long resolution);
+typedef void (*snd_timer_ccallback_t) (snd_timer_instance_t * timeri, enum sndrv_timer_event event,
+				       struct timespec * tstamp, unsigned long resolution);
 
 struct _snd_timer_hardware {
 	/* -- must be filled with low-level driver */
 	unsigned int flags;		/* various flags */
 	unsigned long resolution;	/* average timer resolution for one tick in nsec */
+	unsigned long resolution_min;	/* minimal resolution */
+	unsigned long resolution_max;	/* maximal resolution */
 	unsigned long ticks;		/* max timer ticks per interrupt */
 	/* -- low-level functions -- */
 	int (*open) (snd_timer_t * timer);
@@ -71,6 +81,8 @@
 	unsigned long (*c_resolution) (snd_timer_t * timer);
 	int (*start) (snd_timer_t * timer);
 	int (*stop) (snd_timer_t * timer);
+	int (*set_period) (snd_timer_t * timer, unsigned long period_num, unsigned long period_den);
+	int (*precise_resolution) (snd_timer_t * timer, unsigned long *num, unsigned long *den);
 };
 
 struct _snd_timer {
@@ -102,6 +114,7 @@
 	void *private_data;
 	void (*private_free) (snd_timer_instance_t *ti);
 	snd_timer_callback_t callback;
+	snd_timer_ccallback_t ccallback;
 	void *callback_data;
 	unsigned long ticks;		/* auto-load ticks when expired */
 	unsigned long cticks;		/* current ticks */
@@ -123,20 +136,19 @@
  */
 
 extern int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t ** rtimer);
+extern void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp);
 extern int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer);
 extern int snd_timer_global_free(snd_timer_t *timer);
 extern int snd_timer_global_register(snd_timer_t *timer);
 extern int snd_timer_global_unregister(snd_timer_t *timer);
 
-extern snd_timer_instance_t *snd_timer_open(char *owner, snd_timer_id_t *tid, unsigned int slave_id);
+extern int snd_timer_open(snd_timer_instance_t ** ti, char *owner, snd_timer_id_t *tid, unsigned int slave_id);
 extern int snd_timer_close(snd_timer_instance_t * timeri);
-extern int snd_timer_set_owner(snd_timer_instance_t * timeri, pid_t pid, gid_t gid);
-extern int snd_timer_reset_owner(snd_timer_instance_t * timeri);
-extern int snd_timer_set_resolution(snd_timer_instance_t * timeri, unsigned long resolution);
 extern unsigned long snd_timer_resolution(snd_timer_instance_t * timeri);
 extern int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks);
 extern int snd_timer_stop(snd_timer_instance_t * timeri);
 extern int snd_timer_continue(snd_timer_instance_t * timeri);
+extern int snd_timer_pause(snd_timer_instance_t * timeri);
 
 extern void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left);
 
diff -Nru a/include/sound/trident.h b/include/sound/trident.h
--- a/include/sound/trident.h	Mon Jan 27 09:30:51 2003
+++ b/include/sound/trident.h	Thu Mar 20 08:41:11 2003
@@ -365,10 +365,16 @@
 	int running: 1,
             capture: 1,
             spdif: 1,
-            foldback: 1;
+            foldback: 1,
+            isync: 1,
+            isync2: 1,
+            isync3: 1;
 	int foldback_chan;		/* foldback subdevice number */
 	unsigned int stimer;		/* global sample timer (to detect spurious interrupts) */
 	unsigned int spurious_threshold; /* spurious threshold */
+	unsigned int isync_mark;
+	unsigned int isync_max;
+	unsigned int isync_ESO;
 
 	/* --- */
 
@@ -448,6 +454,7 @@
 	snd_seq_device_t *seq_dev;
 
 	ac97_t *ac97;
+	ac97_t *ac97_sec;
 
 	unsigned int musicvol_wavevol;
 	snd_trident_pcm_mixer_t pcm_mixer[32];
diff -Nru a/include/sound/uda1341.h b/include/sound/uda1341.h
--- a/include/sound/uda1341.h	Mon Feb 24 12:36:41 2003
+++ b/include/sound/uda1341.h	Tue Feb 25 05:46:04 2003
@@ -15,9 +15,14 @@
  *                           features support
  */
 
-/* $Id: uda1341.h,v 1.2 2002/04/17 07:53:22 perex Exp $ */
+/* $Id: uda1341.h,v 1.4 2003/02/25 12:48:16 perex Exp $ */
 
 #define UDA1341_ALSA_NAME "snd-uda1341"
+
+/*
+ * Default rate set after inicialization
+ */
+#define AUDIO_RATE_DEFAULT	44100
 
 /*
  * UDA1341 L3 address and command types
diff -Nru a/include/sound/version.h b/include/sound/version.h
--- a/include/sound/version.h	Sun Feb 16 05:47:40 2003
+++ b/include/sound/version.h	Thu Mar 20 08:41:11 2003
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by configure.  */
-#define CONFIG_SND_VERSION "0.9.0rc7"
-#define CONFIG_SND_DATE " (Sat Feb 15 15:01:21 2003 UTC)"
+#define CONFIG_SND_VERSION "0.9.2"
+#define CONFIG_SND_DATE " (Thu Mar 20 13:31:57 2003 UTC)"
diff -Nru a/include/video/cirrus.h b/include/video/cirrus.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/cirrus.h	Tue Mar  4 05:31:55 2003
@@ -0,0 +1,122 @@
+/*
+ * drivers/video/clgenfb.h - Cirrus Logic chipset constants
+ *
+ * Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
+ *
+ * Original clgenfb author:  Frank Neumann
+ *
+ * Based on retz3fb.c and clgen.c:
+ *      Copyright (C) 1997 Jes Sorensen
+ *      Copyright (C) 1996 Frank Neumann
+ *
+ ***************************************************************
+ *
+ * Format this code with GNU indent '-kr -i8 -pcs' options.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#ifndef __CLGENFB_H__
+#define __CLGENFB_H__
+
+/* OLD COMMENT: definitions for Piccolo/SD64 VGA controller chip   */
+/* OLD COMMENT: these definitions might most of the time also work */
+/* OLD COMMENT: for other CL-GD542x/543x based boards..            */
+
+/*** External/General Registers ***/
+#define CL_POS102	0x102  	/* POS102 register */
+#define CL_VSSM		0x46e8 	/* Adapter Sleep */
+#define CL_VSSM2	0x3c3	/* Motherboard Sleep */
+
+/*** VGA Sequencer Registers ***/
+#define CL_SEQR0	0x0	/* Reset */
+/* the following are from the "extension registers" group */
+#define CL_SEQR6	0x6	/* Unlock ALL Extensions */
+#define CL_SEQR7	0x7	/* Extended Sequencer Mode */
+#define CL_SEQR8	0x8	/* EEPROM Control */
+#define CL_SEQR9	0x9	/* Scratch Pad 0 (do not access!) */
+#define CL_SEQRA	0xa	/* Scratch Pad 1 (do not access!) */
+#define CL_SEQRB	0xb	/* VCLK0 Numerator */
+#define CL_SEQRC	0xc	/* VCLK1 Numerator */
+#define CL_SEQRD	0xd	/* VCLK2 Numerator */
+#define CL_SEQRE	0xe	/* VCLK3 Numerator */
+#define CL_SEQRF	0xf	/* DRAM Control */
+#define CL_SEQR10	0x10	/* Graphics Cursor X Position */
+#define CL_SEQR11	0x11	/* Graphics Cursor Y Position */
+#define CL_SEQR12	0x12	/* Graphics Cursor Attributes */
+#define CL_SEQR13	0x13	/* Graphics Cursor Pattern Address Offset */
+#define CL_SEQR14	0x14	/* Scratch Pad 2 (CL-GD5426/'28 Only) (do not access!) */
+#define CL_SEQR15	0x15	/* Scratch Pad 3 (CL-GD5426/'28 Only) (do not access!) */
+#define CL_SEQR16	0x16	/* Performance Tuning (CL-GD5424/'26/'28 Only) */
+#define CL_SEQR17	0x17	/* Configuration ReadBack and Extended Control (CL-GF5428 Only) */
+#define CL_SEQR18	0x18	/* Signature Generator Control (Not CL-GD5420) */
+#define CL_SEQR19	0x19	/* Signature Generator Result Low Byte (Not CL-GD5420) */
+#define CL_SEQR1A	0x1a	/* Signature Generator Result High Byte (Not CL-GD5420) */
+#define CL_SEQR1B	0x1b	/* VCLK0 Denominator and Post-Scalar Value */
+#define CL_SEQR1C	0x1c	/* VCLK1 Denominator and Post-Scalar Value */
+#define CL_SEQR1D	0x1d	/* VCLK2 Denominator and Post-Scalar Value */
+#define CL_SEQR1E	0x1e	/* VCLK3 Denominator and Post-Scalar Value */
+#define CL_SEQR1F	0x1f	/* BIOS ROM write enable and MCLK Select */
+
+/*** CRT Controller Registers ***/
+#define CL_CRT22	0x22	/* Graphics Data Latches ReadBack */
+#define CL_CRT24	0x24	/* Attribute Controller Toggle ReadBack */
+#define CL_CRT26	0x26	/* Attribute Controller Index ReadBack */
+/* the following are from the "extension registers" group */
+#define CL_CRT19	0x19	/* Interlace End */
+#define CL_CRT1A	0x1a	/* Interlace Control */
+#define CL_CRT1B	0x1b	/* Extended Display Controls */
+#define CL_CRT1C	0x1c	/* Sync adjust and genlock register */
+#define CL_CRT1D	0x1d	/* Overlay Extended Control register */
+#define CL_CRT25	0x25	/* Part Status Register */
+#define CL_CRT27	0x27	/* ID Register */
+#define CL_CRT51	0x51	/* P4 disable "flicker fixer" */
+
+/*** Graphics Controller Registers ***/
+/* the following are from the "extension registers" group */
+#define CL_GR9		0x9	/* Offset Register 0 */
+#define CL_GRA		0xa	/* Offset Register 1 */
+#define CL_GRB		0xb	/* Graphics Controller Mode Extensions */
+#define CL_GRC		0xc	/* Color Key (CL-GD5424/'26/'28 Only) */
+#define CL_GRD		0xd	/* Color Key Mask (CL-GD5424/'26/'28 Only) */
+#define CL_GRE		0xe	/* Miscellaneous Control (Cl-GD5428 Only) */
+#define CL_GRF		0xf	/* Display Compression Control register */
+#define CL_GR10		0x10	/* 16-bit Pixel BG Color High Byte (Not CL-GD5420) */
+#define CL_GR11		0x11	/* 16-bit Pixel FG Color High Byte (Not CL-GD5420) */
+#define CL_GR12		0x12	/* Background Color Byte 2 Register */
+#define CL_GR13		0x13	/* Foreground Color Byte 2 Register */
+#define CL_GR14		0x14	/* Background Color Byte 3 Register */
+#define CL_GR15		0x15	/* Foreground Color Byte 3 Register */
+/* the following are CL-GD5426/'28 specific blitter registers */
+#define CL_GR20		0x20	/* BLT Width Low */
+#define CL_GR21		0x21	/* BLT Width High */
+#define CL_GR22		0x22	/* BLT Height Low */
+#define CL_GR23		0x23	/* BLT Height High */
+#define CL_GR24		0x24	/* BLT Destination Pitch Low */
+#define CL_GR25		0x25	/* BLT Destination Pitch High */
+#define CL_GR26		0x26	/* BLT Source Pitch Low */
+#define CL_GR27		0x27	/* BLT Source Pitch High */
+#define CL_GR28		0x28	/* BLT Destination Start Low */
+#define CL_GR29		0x29	/* BLT Destination Start Mid */
+#define CL_GR2A		0x2a	/* BLT Destination Start High */
+#define CL_GR2C		0x2c	/* BLT Source Start Low */
+#define CL_GR2D		0x2d	/* BLT Source Start Mid */
+#define CL_GR2E		0x2e	/* BLT Source Start High */
+#define CL_GR2F		0x2f	/* Picasso IV Blitter compat mode..? */
+#define CL_GR30		0x30	/* BLT Mode */
+#define CL_GR31		0x31	/* BLT Start/Status */
+#define CL_GR32		0x32	/* BLT Raster Operation */
+#define CL_GR33		0x33	/* another P4 "compat" register.. */
+#define CL_GR34		0x34	/* Transparent Color Select Low */
+#define CL_GR35		0x35	/* Transparent Color Select High */
+#define CL_GR38		0x38	/* Source Transparent Color Mask Low */
+#define CL_GR39		0x39	/* Source Transparent Color Mask High */
+
+/*** Attribute Controller Registers ***/
+#define CL_AR33		0x33	/* The "real" Pixel Panning register (?) */
+#define CL_AR34		0x34	/* TEST */
+
+#endif /* __CLGENFB_H__ */
diff -Nru a/include/video/mach64.h b/include/video/mach64.h
--- a/include/video/mach64.h	Fri Jun 28 12:07:34 2002
+++ b/include/video/mach64.h	Thu Feb 27 17:17:33 2003
@@ -558,7 +558,7 @@
 #define CRTC_CSYNC_EN		0x00000010
 #define CRTC_PIX_BY_2_EN	0x00000020	/* unused on RAGE */
 #define CRTC_DISPLAY_DIS	0x00000040
-#define CRTC_VGA_XOVERSCAN	0x00000040
+#define CRTC_VGA_XOVERSCAN	0x00000080
 
 #define CRTC_PIX_WIDTH_MASK	0x00000700
 #define CRTC_PIX_WIDTH_4BPP	0x00000100
@@ -849,7 +849,19 @@
 #define LI_CHIP_ID	0x4c49	/* RAGE LT PRO */
 #define LP_CHIP_ID	0x4c50	/* RAGE LT PRO */
 #define LT_CHIP_ID	0x4c54	/* RAGE LT */
-#define XL_CHIP_ID	0x4752	/* RAGE (XL) */
+
+/* mach64CT family / (Rage XL) class */
+#define GR_CHIP_ID	0x4752	/* RAGE XL, BGA, PCI33 */
+#define GS_CHIP_ID	0x4753	/* RAGE XL, PQFP, PCI33 */
+#define GM_CHIP_ID	0x474d	/* RAGE XL, BGA, AGP 1x,2x */
+#define GN_CHIP_ID	0x474e	/* RAGE XL, PQFP,AGP 1x,2x */
+#define GO_CHIP_ID	0x474f	/* RAGE XL, BGA, PCI66 */
+#define GL_CHIP_ID	0x474c	/* RAGE XL, PQFP, PCI66 */
+
+#define IS_XL(id) ((id)==GR_CHIP_ID || (id)==GS_CHIP_ID || \
+		   (id)==GM_CHIP_ID || (id)==GN_CHIP_ID || \
+		   (id)==GO_CHIP_ID || (id)==GL_CHIP_ID)	
+
 #define GT_CHIP_ID	0x4754	/* RAGE (GT) */
 #define GU_CHIP_ID	0x4755	/* RAGE II/II+ (GTB) */
 #define GV_CHIP_ID	0x4756	/* RAGE IIC, PCI */
@@ -1148,6 +1160,65 @@
 #define APC_LUT_MN		0x39
 #define APC_LUT_OP		0x3A
 
+/* Values in LCD_GEN_CTRL */
+#define CRT_ON                          0x00000001ul
+#define LCD_ON                          0x00000002ul
+#define HORZ_DIVBY2_EN                  0x00000004ul
+#define DONT_DS_ICON                    0x00000008ul
+#define LOCK_8DOT                       0x00000010ul
+#define ICON_ENABLE                     0x00000020ul
+#define DONT_SHADOW_VPAR                0x00000040ul
+#define V2CLK_PM_EN                     0x00000080ul
+#define RST_FM                          0x00000100ul
+#define DISABLE_PCLK_RESET              0x00000200ul    /* XC/XL */
+#define DIS_HOR_CRT_DIVBY2              0x00000400ul
+#define SCLK_SEL                        0x00000800ul
+#define SCLK_DELAY                      0x0000f000ul
+#define TVCLK_PM_EN                     0x00010000ul
+#define VCLK_DAC_PM_EN                  0x00020000ul
+#define VCLK_LCD_OFF                    0x00040000ul
+#define SELECT_WAIT_4MS                 0x00080000ul
+#define XTALIN_PM_EN                    0x00080000ul    /* XC/XL */
+#define V2CLK_DAC_PM_EN                 0x00100000ul
+#define LVDS_EN                         0x00200000ul
+#define LVDS_PLL_EN                     0x00400000ul
+#define LVDS_PLL_RESET                  0x00800000ul
+#define LVDS_RESERVED_BITS              0x07000000ul
+#define CRTC_RW_SELECT                  0x08000000ul    /* LTPro */
+#define USE_SHADOWED_VEND               0x10000000ul
+#define USE_SHADOWED_ROWCUR             0x20000000ul
+#define SHADOW_EN                       0x40000000ul
+#define SHADOW_RW_EN                    0x80000000ul
+
+/* Values in HORZ_STRETCHING */
+#define HORZ_STRETCH_BLEND              0x00000ffful
+#define HORZ_STRETCH_RATIO              0x0000fffful
+#define HORZ_STRETCH_LOOP               0x00070000ul
+#define HORZ_STRETCH_LOOP09                     0x00000000ul
+#define HORZ_STRETCH_LOOP11                     0x00010000ul
+#define HORZ_STRETCH_LOOP12                     0x00020000ul
+#define HORZ_STRETCH_LOOP14                     0x00030000ul
+#define HORZ_STRETCH_LOOP15                     0x00040000ul
+/*      ?                                       0x00050000ul */
+/*      ?                                       0x00060000ul */
+/*      ?                                       0x00070000ul */
+/*      ?                               0x00080000ul */
+#define HORZ_PANEL_SIZE                 0x0ff00000ul    /* XC/XL */
+/*      ?                               0x10000000ul */
+#define AUTO_HORZ_RATIO                 0x20000000ul    /* XC/XL */
+#define HORZ_STRETCH_MODE               0x40000000ul
+#define HORZ_STRETCH_EN                 0x80000000ul
+
+/* Values in VERT_STRETCHING */
+#define VERT_STRETCH_RATIO0             0x000003fful
+#define VERT_STRETCH_RATIO1             0x000ffc00ul
+#define VERT_STRETCH_RATIO2             0x3ff00000ul
+#define VERT_STRETCH_USE0               0x40000000ul
+#define VERT_STRETCH_EN                 0x80000000ul
+
+/* Values in EXT_VERT_STRETCH */
+#define AUTO_VERT_RATIO                 0x00400000ul
+#define VERT_STRETCH_MODE		0x00000400ul
 
 /* Values in LCD_MISC_CNTL */
 #define BIAS_MOD_LEVEL_MASK	0x0000ff00
diff -Nru a/include/video/maxinefb.h b/include/video/maxinefb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/maxinefb.h	Fri Feb 14 15:50:33 2003
@@ -0,0 +1,37 @@
+/*
+ *      linux/drivers/video/maxinefb.h
+ *
+ *      DECstation 5000/xx onboard framebuffer support, Copyright (C) 1999 by
+ *      Michael Engel <engel@unix-ag.org> and Karsten Merker <merker@guug.de>
+ *      This file is subject to the terms and conditions of the GNU General
+ *      Public License.  See the file COPYING in the main directory of this
+ *      archive for more details.
+ */
+
+
+/*
+ * IMS332 video controller register base address
+ */
+#define MAXINEFB_IMS332_ADDRESS                  0xbc140000
+
+/*
+ * Begin of DECstation 5000/xx onboard framebuffer memory, default resolution
+ * is 1024x768x8
+ */
+#define DS5000_xx_ONBOARD_FBMEM_START	0xaa000000
+
+/*
+ *      The IMS 332 video controller used in the DECstation 5000/xx series
+ *      uses 32 bits wide registers; the following defines declare the
+ *      register numbers, to get the real offset, these have to be multiplied
+ *      by four.
+ */
+
+#define IMS332_REG_CURSOR_RAM           0x200	/* hardware cursor bitmap */
+
+/*
+ * The color palette entries have the form 0x00BBGGRR
+ */
+#define IMS332_REG_COLOR_PALETTE        0x100	/* color palette, 256 entries */
+#define IMS332_REG_CURSOR_COLOR_PALETTE	0x0a1	/* cursor color palette, */
+						/* 3 entries             */
diff -Nru a/include/video/pm3fb.h b/include/video/pm3fb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/pm3fb.h	Sat Feb 15 10:14:44 2003
@@ -0,0 +1,1284 @@
+/*
+ *  linux/drivers/video/pm3fb.h -- 3DLabs Permedia3 frame buffer device
+ *  
+ *  Copyright (C) 2001 Romain Dolbeau <dolbeau@irisa.fr>
+ *  Copyright (C) 2001 Sven Luther, <luther@dpt-info.u-strasbg.fr>
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ *
+ *  $Header: /cvsroot/linux/drivers/video/pm3fb.h,v 1.1 2002/02/25 19:11:06 marcelo Exp $
+ *
+ */
+
+#ifndef PM3FB_H
+#define PM3FB_H
+
+/**********************************************
+*  GLINT Permedia3 Control Status registers   *
+***********************************************/
+/* Control Status Registers */
+#define PM3ResetStatus						0x0000
+#define PM3IntEnable						0x0008
+#define PM3IntFlags						0x0010
+#define PM3InFIFOSpace						0x0018
+#define PM3OutFIFOWords						0x0020
+#define PM3DMAAddress						0x0028
+#define PM3DMACount						0x0030
+#define PM3ErrorFlags						0x0038
+#define PM3VClkCtl						0x0040
+#define PM3TestRegister						0x0048
+#define PM3Aperture0						0x0050
+#define PM3Aperture1						0x0058
+#define PM3DMAControl						0x0060
+#define PM3FIFODis						0x0068
+#define PM3ChipConfig						0x0070
+#define PM3AGPControl						0x0078
+
+#define PM3GPOutDMAAddress					0x0080
+#define PM3PCIFeedbackCount					0x0088
+#define PM3PCIAbortStatus					0x0090
+#define PM3PCIAbortAddress					0x0098
+
+#define PM3PCIPLLStatus						0x00f0
+
+#define PM3HostTextureAddress					0x0100
+#define PM3TextureDownloadControl				0x0108
+#define PM3TextureOperation					0x0110
+#define PM3LogicalTexturePage					0x0118
+#define PM3TexDMAAddress					0x0120
+#define PM3TexFIFOSpace						0x0128
+
+/**********************************************
+*  GLINT Permedia3 Region 0 Bypass Controls   *
+***********************************************/
+#define PM3ByAperture1Mode					0x0300
+	#define PM3ByApertureMode_BYTESWAP_ABCD			(0<<0)
+	#define PM3ByApertureMode_BYTESWAP_BADC			(1<<0)
+	#define PM3ByApertureMode_BYTESWAP_CDAB			(2<<0)
+	#define PM3ByApertureMode_BYTESWAP_DCBA			(3<<0)
+	#define PM3ByApertureMode_PATCH_DISABLE			(0<<2)
+	#define PM3ByApertureMode_PATCH_ENABLE			(1<<2)
+	#define PM3ByApertureMode_FORMAT_RAW			(0<<3)
+	#define PM3ByApertureMode_FORMAT_YUYV			(1<<3)
+	#define PM3ByApertureMode_FORMAT_UYVY			(2<<3)
+	#define PM3ByApertureMode_PIXELSIZE_8BIT		(0<<5)
+	#define PM3ByApertureMode_PIXELSIZE_16BIT		(1<<5)
+	#define PM3ByApertureMode_PIXELSIZE_32BIT		(2<<5)
+                #define PM3ByApertureMode_PIXELSIZE_MASK        (3<<5)
+	#define PM3ByApertureMode_EFFECTIVE_STRIDE_1024		(0<<7)
+	#define PM3ByApertureMode_EFFECTIVE_STRIDE_2048		(1<<7)
+	#define PM3ByApertureMode_EFFECTIVE_STRIDE_4096		(2<<7)
+	#define PM3ByApertureMode_EFFECTIVE_STRIDE_8192		(3<<7)
+	#define PM3ByApertureMode_PATCH_OFFSET_X(off)	(((off)&7f)<<9)
+	#define PM3ByApertureMode_PATCH_OFFSET_Y(off)	(((off)&7f)<<16)
+	#define PM3ByApertureMode_FRAMEBUFFER			(0<<21)
+	#define PM3ByApertureMode_LOCALBUFFER			(1<<21)
+	#define PM3ByApertureMode_DOUBLE_WRITE_OFF		(0<<22)
+	#define PM3ByApertureMode_DOUBLE_WRITE_1MB		(1<<22)
+	#define PM3ByApertureMode_DOUBLE_WRITE_2MB		(2<<22)
+	#define PM3ByApertureMode_DOUBLE_WRITE_4MB		(3<<22)
+	#define PM3ByApertureMode_DOUBLE_WRITE_8MB		(4<<22)
+	#define PM3ByApertureMode_DOUBLE_WRITE_16MB		(5<<22)
+	#define PM3ByApertureMode_DOUBLE_WRITE_32MB		(6<<22)
+
+#define PM3ByAperture2Mode					0x0328
+	
+/**********************************************
+*  GLINT Permedia3 Memory Control (0x1000)    *
+***********************************************/
+#define PM3MemCounter						0x1000
+#define PM3MemBypassWriteMask					0x1008
+#define PM3MemScratch						0x1010
+#define PM3LocalMemCaps						0x1018
+        #define PM3LocalMemCaps_NoWriteMask                     (1 << 28)
+#define PM3LocalMemTimings					0x1020
+#define PM3LocalMemControl					0x1028
+#define PM3LocalMemRefresh					0x1030
+#define PM3LocalMemPowerDown					0x1038
+#define PM3RemoteMemControl					0x1100
+
+/**********************************************
+*  GLINT Permedia3 Video Control (0x3000)     *
+***********************************************/
+
+#define PM3ScreenBase						0x3000
+#define PM3ScreenStride						0x3008
+#define PM3HTotal						0x3010
+#define PM3HgEnd						0x3018
+#define PM3HbEnd						0x3020
+#define PM3HsStart						0x3028
+#define PM3HsEnd						0x3030
+#define PM3VTotal						0x3038
+#define PM3VbEnd						0x3040
+#define PM3VsStart						0x3048
+#define PM3VsEnd						0x3050
+#define PM3VideoControl						0x3058
+	#define PM3VideoControl_DISABLE				(0<<0)
+	#define PM3VideoControl_ENABLE				(1<<0)
+	#define PM3VideoControl_BLANK_ACTIVE_HIGH		(0<<1)
+	#define PM3VideoControl_BLANK_ACTIVE_LOW		(1<<1)
+	#define PM3VideoControl_LINE_DOUBLE_OFF			(0<<2)
+	#define PM3VideoControl_LINE_DOUBLE_ON			(1<<2)
+	#define PM3VideoControl_HSYNC_FORCE_HIGH		(0<<3)
+	#define PM3VideoControl_HSYNC_ACTIVE_HIGH		(1<<3)
+	#define PM3VideoControl_HSYNC_FORCE_LOW			(2<<3)
+	#define PM3VideoControl_HSYNC_ACTIVE_LOW		(3<<3)
+        #define PM3VideoControl_HSYNC_MASK          (3<<3)
+	#define PM3VideoControl_VSYNC_FORCE_HIGH		(0<<5)
+	#define PM3VideoControl_VSYNC_ACTIVE_HIGH		(1<<5)
+	#define PM3VideoControl_VSYNC_FORCE_LOW			(2<<5)
+	#define PM3VideoControl_VSYNC_ACTIVE_LOW		(3<<5)
+        #define PM3VideoControl_VSYNC_MASK          (3<<5)
+	#define PM3VideoControl_BYTE_DOUBLE_OFF			(0<<7)
+	#define PM3VideoControl_BYTE_DOUBLE_ON			(1<<7)
+	#define PM3VideoControl_BUFFER_SWAP_SYNCON_FRAMEBLANK	(0<<9)
+	#define PM3VideoControl_BUFFER_SWAP_FREE_RUNNING	(1<<9)
+	#define PM3VideoControl_BUFFER_SWAP_LIMITETO_FRAMERATE	(2<<9)
+	#define PM3VideoControl_STEREO_DISABLE			(0<<11)
+	#define PM3VideoControl_STEREO_ENABLE			(1<<11)
+	#define PM3VideoControl_RIGHT_EYE_ACTIVE_HIGH		(0<<12)
+	#define PM3VideoControl_RIGHT_EYE_ACTIVE_LOW		(1<<12)
+	#define PM3VideoControl_VIDEO_EXT_LOW			(0<<14)
+	#define PM3VideoControl_VIDEO_EXT_HIGH			(1<<14)
+	#define PM3VideoControl_SYNC_MODE_INDEPENDENT		(0<<16)
+	#define PM3VideoControl_SYNC_MODE_SYNCTO_VSA		(1<<16)
+	#define PM3VideoControl_SYNC_MODE_SYNCTO_VSB		(2<<16)
+	#define PM3VideoControl_PATCH_DISABLE			(0<<18)
+	#define PM3VideoControl_PATCH_ENABLE			(1<<18)
+	#define PM3VideoControl_PIXELSIZE_8BIT			(0<<19)
+	#define PM3VideoControl_PIXELSIZE_16BIT			(1<<19)
+	#define PM3VideoControl_PIXELSIZE_32BIT			(2<<19)
+	#define PM3VideoControl_DISPLAY_DISABLE			(0<<21)
+	#define PM3VideoControl_DISPLAY_ENABLE			(1<<21)
+	#define PM3VideoControl_PATCH_OFFSET_X(off)	(((off)&0x3f)<<22)
+	#define PM3VideoControl_PATCH_OFFSET_Y(off)	(((off)&0x3f)<<28)
+#define PM3InterruptLine					0x3060
+#define PM3DisplayData						0x3068
+#define PM3VerticalLineCount					0x3070
+#define PM3FifoControl						0x3078
+#define PM3ScreenBaseRight					0x3080
+#define PM3MiscControl						0x3088
+
+#define PM3VideoOverlayUpdate					0x3100
+        #define PM3VideoOverlayUpdate_DISABLE                   (0<<0)
+        #define PM3VideoOverlayUpdate_ENABLE                    (1<<0)
+#define PM3VideoOverlayMode					0x3108
+	#define PM3VideoOverlayMode_DISABLE			(0<<0)
+	#define PM3VideoOverlayMode_ENABLE			(1<<0)
+        #define PM3VideoOverlayMode_BUFFERSYNC_MANUAL           (0<<1)
+        #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMA     (1<<1)
+        #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMB     (2<<1)
+        #define PM3VideoOverlayMode_FIELDPOLARITY_NORMAL        (0<<4)
+        #define PM3VideoOverlayMode_FIELDPOLARITY_INVERT        (1<<4)
+        #define PM3VideoOverlayMode_PIXELSIZE_8BIT              (0<<5)
+        #define PM3VideoOverlayMode_PIXELSIZE_16BIT             (1<<5)
+        #define PM3VideoOverlayMode_PIXELSIZE_32BIT             (2<<5)
+        #define PM3VideoOverlayMode_COLORFORMAT_RGB8888 ((0<<7)|(1<<12)|(2<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_RGB4444 ((1<<7)|(1<<12)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_RGB5551 ((2<<7)|(1<<12)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_RGB565  ((3<<7)|(1<<12)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_RGB332  ((4<<7)|(1<<12)|(0<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_BGR8888 ((0<<7)|(2<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_BGR4444 ((1<<7)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_BGR5551 ((2<<7)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_BGR565  ((3<<7)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_BGR332  ((4<<7)|(0<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_CI8     ((5<<7)|(1<<12)|(0<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_VUY444  ((2<<10)|(1<<12)|(2<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_YUV444  ((2<<10)|(2<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_VUY422  ((1<<10)|(1<<12)|(1<<5))
+        #define PM3VideoOverlayMode_COLORFORMAT_YUV422  ((1<<10)|(1<<5))
+        #define PM3VideoOverlayMode_COLORORDER_BGR              (0<<12)
+        #define PM3VideoOverlayMode_COLORORDER_RGB              (1<<12)
+        #define PM3VideoOverlayMode_LINEARCOLOREXT_OFF          (0<<13)
+        #define PM3VideoOverlayMode_LINEARCOLOREXT_ON           (1<<13)
+        #define PM3VideoOverlayMode_FILTER_MASK                 (3<<14)
+        #define PM3VideoOverlayMode_FILTER_OFF                  (0<<14)
+        #define PM3VideoOverlayMode_FILTER_FULL                 (1<<14)
+        #define PM3VideoOverlayMode_FILTER_PARTIAL              (2<<14)
+        #define PM3VideoOverlayMode_DEINTERLACE_OFF             (0<<16)
+        #define PM3VideoOverlayMode_DEINTERLACE_BOB             (1<<16)
+        #define PM3VideoOverlayMode_PATCHMODE_OFF               (0<<18)
+        #define PM3VideoOverlayMode_PATCHMODE_ON                (1<<18)
+        #define PM3VideoOverlayMode_FLIP_VIDEO                  (0<<20)
+        #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMA           (1<<20)
+        #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMB           (2<<20)
+        #define PM3VideoOverlayMode_MIRROR_MASK                 (3<<23)
+        #define PM3VideoOverlayMode_MIRRORX_OFF                 (0<<23)
+        #define PM3VideoOverlayMode_MIRRORX_ON                  (1<<23)
+        #define PM3VideoOverlayMode_MIRRORY_OFF                 (0<<24)
+        #define PM3VideoOverlayMode_MIRRORY_ON                  (1<<24)
+#define PM3VideoOverlayFifoControl				0x3110
+#define PM3VideoOverlayIndex					0x3118
+#define PM3VideoOverlayBase0					0x3120
+#define PM3VideoOverlayBase1					0x3128
+#define PM3VideoOverlayBase2					0x3130
+#define PM3VideoOverlayStride					0x3138
+        #define PM3VideoOverlayStride_STRIDE(s)         (((s)&0xfff)<<0)
+#define PM3VideoOverlayWidth                                    0x3140
+        #define PM3VideoOverlayWidth_WIDTH(w)           (((w)&0xfff)<<0)
+#define PM3VideoOverlayHeight                                   0x3148
+        #define PM3VideoOverlayHeight_HEIGHT(h)         (((h)&0xfff)<<0)
+#define PM3VideoOverlayOrigin                                   0x3150
+        #define PM3VideoOverlayOrigin_XORIGIN(x)        (((x)&0xfff)<<0)
+        #define PM3VideoOverlayOrigin_YORIGIN(y)        (((y)&0xfff)<<16)
+#define PM3VideoOverlayShrinkXDelta                             0x3158
+        #define PM3VideoOverlayShrinkXDelta_NONE                (1<<16)
+        #define PM3VideoOverlayShrinkXDelta_DELTA(s,d)          \
+                ((((s)<<16)/(d))&0x0ffffff0)
+#define PM3VideoOverlayZoomXDelta                               0x3160
+        #define PM3VideoOverlayZoomXDelta_NONE                  (1<<16)
+        #define PM3VideoOverlayZoomXDelta_DELTA(s,d)            \
+                ((((s)<<16)/(d))&0x0001fff0)
+#define PM3VideoOverlayYDelta                                   0x3168
+        #define PM3VideoOverlayYDelta_NONE                      (1<<16)
+        #define PM3VideoOverlayYDelta_DELTA(s,d)                        \
+                ((((s)<<16)/(d))&0x0ffffff0)
+#define PM3VideoOverlayFieldOffset				0x3170
+#define PM3VideoOverlayStatus					0x3178
+
+/**********************************************
+*  GLINT Permedia3 RAMDAC Registers (0x4000)  *
+***********************************************/
+/* Direct Registers */
+#define PM3RD_PaletteWriteAddress				0x4000
+#define PM3RD_PaletteData					0x4008
+#define PM3RD_PixelMask						0x4010
+#define PM3RD_PaletteReadAddress				0x4018
+
+#define PM3RD_IndexLow						0x4020
+#define PM3RD_IndexHigh						0x4028
+#define PM3RD_IndexedData					0x4030
+#define PM3RD_IndexControl					0x4038
+	#define PM3RD_IndexControl_AUTOINCREMENT_ENABLE		(1<<0)
+	#define PM3RD_IndexControl_AUTOINCREMENT_DISABLE	(0<<0)
+
+/* Indirect Registers */
+#define PM3RD_MiscControl					0x000
+	#define PM3RD_MiscControl_HIGHCOLOR_RES_DISABLE		(0<<0)
+	#define PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE		(1<<0)
+	#define PM3RD_MiscControl_PIXELDOUBLE_DISABLE		(0<<1)
+	#define PM3RD_MiscControl_PIXELDOUBLE_ENABLE		(1<<1)
+	#define PM3RD_MiscControl_LASTREAD_ADDR_DISABLE		(0<<2)
+	#define PM3RD_MiscControl_LASTREAD_ADDR_ENABLE		(1<<2)
+	#define PM3RD_MiscControl_DIRECTCOLOR_DISABLE		(0<<3)
+	#define PM3RD_MiscControl_DIRECTCOLOR_ENABLE		(1<<3)
+	#define PM3RD_MiscControl_OVERLAY_DISABLE		(0<<4)
+	#define PM3RD_MiscControl_OVERLAY_ENABLE		(1<<4)
+	#define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_DISABLE	(0<<5)
+	#define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_ENABLE	(1<<5)
+	#define PM3RD_MiscControl_VSB_OUTPUT_DISABLE		(0<<6)
+	#define PM3RD_MiscControl_VSB_OUTPUT_ENABLE		(1<<6)
+	#define PM3RD_MiscControl_STEREODOUBLE_BUFFER_DISABLE	(0<<7)
+	#define PM3RD_MiscControl_STEREODOUBLE_BUFFER_ENABLE	(1<<7)
+#define PM3RD_SyncControl					0x001
+	#define PM3RD_SyncControl_HSYNC_ACTIVE_LOW		(0<<0)
+	#define PM3RD_SyncControl_HSYNC_ACTIVE_HIGH		(1<<0)
+	#define PM3RD_SyncControl_HSYNC_FORCE_ACTIVE		(3<<0)
+	#define PM3RD_SyncControl_HSYNC_FORCE_INACTIVE		(4<<0)
+	#define PM3RD_SyncControl_HSYNC_TRI_STATE		(2<<0)
+	#define PM3RD_SyncControl_VSYNC_ACTIVE_LOW		(0<<3)
+	#define PM3RD_SyncControl_VSYNC_ACTIVE_HIGH		(1<<3)
+	#define PM3RD_SyncControl_VSYNC_TRI_STATE		(2<<3)
+	#define PM3RD_SyncControl_VSYNC_FORCE_ACTIVE		(3<<3)
+	#define PM3RD_SyncControl_VSYNC_FORCE_INACTIVE		(4<<3)
+	#define PM3RD_SyncControl_HSYNC_OVERRIDE_SETBY_HSYNC	(0<<6)
+	#define PM3RD_SyncControl_HSYNC_OVERRIDE_FORCE_HIGH	(1<<6)
+	#define PM3RD_SyncControl_VSYNC_OVERRIDE_SETBY_VSYNC	(0<<7)
+	#define PM3RD_SyncControl_VSYNC_OVERRIDE_FORCE_HIGH	(1<<7)
+#define PM3RD_DACControl					0x002
+	#define PM3RD_DACControl_DAC_POWER_ON			(0<<0)
+	#define PM3RD_DACControl_DAC_POWER_OFF			(1<<0)
+	#define PM3RD_DACControl_SYNC_ON_GREEN_DISABLE		(0<<3)
+	#define PM3RD_DACControl_SYNC_ON_GREEN_ENABLE		(1<<3)
+	#define PM3RD_DACControl_BLANK_RED_DAC_DISABLE		(0<<4)
+	#define PM3RD_DACControl_BLANK_RED_DAC_ENABLE		(1<<4)
+	#define PM3RD_DACControl_BLANK_GREEN_DAC_DISABLE	(0<<5)
+	#define PM3RD_DACControl_BLANK_GREEN_DAC_ENABLE		(1<<5)
+	#define PM3RD_DACControl_BLANK_BLUE_DAC_DISABLE		(0<<6)
+	#define PM3RD_DACControl_BLANK_BLUE_DAC_ENABLE		(1<<6)
+	#define PM3RD_DACControl_BLANK_PEDESTAL_DISABLE		(0<<7)
+	#define PM3RD_DACControl_BLANK_PEDESTAL_ENABLE		(1<<7)
+#define PM3RD_PixelSize						0x003
+	#define PM3RD_PixelSize_24_BIT_PIXELS			(4<<0)
+	#define PM3RD_PixelSize_32_BIT_PIXELS			(2<<0)
+	#define PM3RD_PixelSize_16_BIT_PIXELS			(1<<0)
+	#define PM3RD_PixelSize_8_BIT_PIXELS			(0<<0)
+#define PM3RD_ColorFormat					0x004
+	#define PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE	(1<<6)
+	#define PM3RD_ColorFormat_LINEAR_COLOR_EXT_DISABLE	(0<<6)
+	#define PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW		(1<<5)
+	#define PM3RD_ColorFormat_COLOR_ORDER_RED_LOW		(0<<5)
+	#define PM3RD_ColorFormat_COLOR_FORMAT_MASK		(0x1f<<0)
+	#define PM3RD_ColorFormat_8888_COLOR			(0<<0)
+	#define PM3RD_ColorFormat_5551_FRONT_COLOR		(1<<0)
+	#define PM3RD_ColorFormat_4444_COLOR			(2<<0)
+	#define PM3RD_ColorFormat_332_FRONT_COLOR		(5<<0)
+	#define PM3RD_ColorFormat_332_BACK_COLOR		(6<<0)
+	#define PM3RD_ColorFormat_2321_FRONT_COLOR		(9<<0)
+	#define PM3RD_ColorFormat_2321_BACK_COLOR		(10<<0)
+	#define PM3RD_ColorFormat_232_FRONTOFF_COLOR		(11<<0)
+	#define PM3RD_ColorFormat_232_BACKOFF_COLOR		(12<<0)
+	#define PM3RD_ColorFormat_5551_BACK_COLOR		(13<<0)
+	#define PM3RD_ColorFormat_CI8_COLOR			(14<<0)
+	#define PM3RD_ColorFormat_565_FRONT_COLOR		(16<<0)
+	#define PM3RD_ColorFormat_565_BACK_COLOR		(17<<0)
+#define PM3RD_CursorMode					0x005
+	#define PM3RD_CursorMode_CURSOR_DISABLE			(0<<0)
+	#define PM3RD_CursorMode_CURSOR_ENABLE			(1<<0)
+	#define PM3RD_CursorMode_FORMAT_64x64_2BPE_P0123	(0<<2)
+	#define PM3RD_CursorMode_FORMAT_32x32_2BPE_P0		(1<<2)
+	#define PM3RD_CursorMode_FORMAT_32x32_2BPE_P1		(2<<2)
+	#define PM3RD_CursorMode_FORMAT_32x32_2BPE_P2		(3<<2)
+	#define PM3RD_CursorMode_FORMAT_32x32_2BPE_P3		(4<<2)
+	#define PM3RD_CursorMode_FORMAT_32x32_4BPE_P01		(5<<2)
+	#define PM3RD_CursorMode_FORMAT_32x32_4BPE_P23		(6<<2)
+	#define PM3RD_CursorMode_TYPE_MS			(0<<4)
+	#define PM3RD_CursorMode_TYPE_X				(1<<4)
+	#define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_DISABLE	(0<<6)
+	#define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_ENABLE	(1<<6)
+	#define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_3_COLOR	(2<<6)
+	#define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_15_COLOR	(3<<6)
+#define PM3RD_CursorControl					0x006
+	#define PM3RD_CursorControl_DOUBLE_X_DISABLED		(0<<0)
+	#define PM3RD_CursorControl_DOUBLE_X_ENABLED		(1<<0)
+	#define PM3RD_CursorControl_DOUBLE_Y_DISABLED		(0<<1)
+	#define PM3RD_CursorControl_DOUBLE_Y_ENABLED		(1<<1)
+	#define PM3RD_CursorControl_READBACK_POS_DISABLED	(0<<2)
+	#define PM3RD_CursorControl_READBACK_POS_ENABLED	(1<<2)
+
+#define PM3RD_CursorXLow					0x007
+#define PM3RD_CursorXHigh					0x008
+#define PM3RD_CursorYLow					0x009
+#define PM3RD_CursorYHigh					0x00a
+#define PM3RD_CursorHotSpotX					0x00b
+#define PM3RD_CursorHotSpotY					0x00c
+#define PM3RD_OverlayKey					0x00d
+#define PM3RD_Pan						0x00e
+	#define PM3RD_Pan_DISABLE				(0<<0)
+	#define PM3RD_Pan_ENABLE				(1<<0)
+	#define PM3RD_Pan_GATE_DISABLE				(0<<1)
+	#define PM3RD_Pan_GATE_ENABLE				(1<<1)
+#define PM3RD_Sense						0x00f
+
+#define PM3RD_CheckControl					0x018
+	#define PM3RD_CheckControl_PIXEL_DISABLED		(0<<0)
+	#define PM3RD_CheckControl_PIXEL_ENABLED		(1<<0)
+	#define PM3RD_CheckControl_LUT_DISABLED			(0<<1)
+	#define PM3RD_CheckControl_LUT_ENABLED			(1<<1)
+#define PM3RD_CheckPixelRed					0x019
+#define PM3RD_CheckPixelGreen					0x01a
+#define PM3RD_CheckPixelBlue					0x01b
+#define PM3RD_CheckLUTRed					0x01c
+#define PM3RD_CheckLUTGreen					0x01d
+#define PM3RD_CheckLUTBlue					0x01e
+#define PM3RD_Scratch						0x01f
+
+#define PM3RD_VideoOverlayControl				0x020
+        #define PM3RD_VideoOverlayControl_DISABLE               (0<<0)
+        #define PM3RD_VideoOverlayControl_ENABLE                (1<<0)
+        #define PM3RD_VideoOverlayControl_MODE_MASK             (3<<1)
+        #define PM3RD_VideoOverlayControl_MODE_MAINKEY          (0<<1)
+        #define PM3RD_VideoOverlayControl_MODE_OVERLAYKEY       (1<<1)
+        #define PM3RD_VideoOverlayControl_MODE_ALWAYS           (2<<1)
+        #define PM3RD_VideoOverlayControl_MODE_BLEND            (3<<1)
+        #define PM3RD_VideoOverlayControl_DIRECTCOLOR_DISABLED  (0<<3)
+        #define PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED   (1<<3)
+        #define PM3RD_VideoOverlayControl_BLENDSRC_MAIN         (0<<4)
+        #define PM3RD_VideoOverlayControl_BLENDSRC_REGISTER     (1<<4)
+        #define PM3RD_VideoOverlayControl_KEY_COLOR             (0<<5)
+        #define PM3RD_VideoOverlayControl_KEY_ALPHA             (1<<5)
+#define PM3RD_VideoOverlayXStartLow				0x021
+#define PM3RD_VideoOverlayXStartHigh				0x022
+#define PM3RD_VideoOverlayYStartLow				0x023
+#define PM3RD_VideoOverlayYStartHigh				0x024
+#define PM3RD_VideoOverlayXEndLow				0x025
+#define PM3RD_VideoOverlayXEndHigh				0x026
+#define PM3RD_VideoOverlayYEndLow				0x027
+#define PM3RD_VideoOverlayYEndHigh				0x028
+#define PM3RD_VideoOverlayKeyR					0x029
+#define PM3RD_VideoOverlayKeyG					0x02a
+#define PM3RD_VideoOverlayKeyB					0x02b
+#define PM3RD_VideoOverlayBlend					0x02c
+        #define PM3RD_VideoOverlayBlend_FACTOR_0_PERCENT        (0<<6)
+        #define PM3RD_VideoOverlayBlend_FACTOR_25_PERCENT       (1<<6)
+        #define PM3RD_VideoOverlayBlend_FACTOR_75_PERCENT       (2<<6)
+        #define PM3RD_VideoOverlayBlend_FACTOR_100_PERCENT      (3<<6)
+
+#define PM3RD_DClkSetup1					0x1f0
+#define PM3RD_DClkSetup2					0x1f1
+#define PM3RD_KClkSetup1					0x1f2
+#define PM3RD_KClkSetup2					0x1f3
+
+#define PM3RD_DClkControl					0x200
+	#define PM3RD_DClkControl_SOURCE_PLL			(0<<4)
+	#define PM3RD_DClkControl_SOURCE_VSA			(1<<4)
+	#define PM3RD_DClkControl_SOURCE_VSB			(2<<4)
+	#define PM3RD_DClkControl_SOURCE_EXT			(3<<4)
+	#define PM3RD_DClkControl_STATE_RUN			(2<<2)
+	#define PM3RD_DClkControl_STATE_HIGH			(1<<2)
+	#define PM3RD_DClkControl_STATE_LOW			(0<<2)
+	#define PM3RD_DClkControl_LOCKED			(1<<1)
+	#define PM3RD_DClkControl_NOT_LOCKED			(0<<1)
+	#define PM3RD_DClkControl_ENABLE			(1<<0)
+	#define PM3RD_DClkControl_DISABLE			(0<<0)
+#define PM3RD_DClk0PreScale					0x201
+#define PM3RD_DClk0FeedbackScale				0x202
+#define PM3RD_DClk0PostScale					0x203
+        #define PM3_REF_CLOCK                                   14318
+#define PM3RD_DClk1PreScale					0x204
+#define PM3RD_DClk1FeedbackScale				0x205
+#define PM3RD_DClk1PostScale					0x206
+#define PM3RD_DClk2PreScale					0x207
+#define PM3RD_DClk2FeedbackScale				0x208
+#define PM3RD_DClk2PostScale					0x209
+#define PM3RD_DClk3PreScale					0x20a
+#define PM3RD_DClk3FeedbackScale				0x20b
+#define PM3RD_DClk3PostScale					0x20c
+#define PM3RD_KClkControl					0x20d
+	#define PM3RD_KClkControl_DISABLE			(0<<0)
+	#define PM3RD_KClkControl_ENABLE			(1<<0)
+	#define PM3RD_KClkControl_NOT_LOCKED			(0<<1)
+	#define PM3RD_KClkControl_LOCKED			(1<<1)
+	#define PM3RD_KClkControl_STATE_LOW			(0<<2)
+	#define PM3RD_KClkControl_STATE_HIGH			(1<<2)
+	#define PM3RD_KClkControl_STATE_RUN			(2<<2)
+	#define PM3RD_KClkControl_STATE_LOW_POWER		(3<<2)
+	#define PM3RD_KClkControl_SOURCE_PCLK			(0<<4)
+	#define PM3RD_KClkControl_SOURCE_HALF_PCLK		(1<<4)
+	#define PM3RD_KClkControl_SOURCE_PLL			(2<<4)
+#define PM3RD_KClkPreScale					0x20e
+#define PM3RD_KClkFeedbackScale					0x20f
+#define PM3RD_KClkPostScale					0x210
+#define PM3RD_MClkControl					0x211
+	#define PM3RD_MClkControl_DISABLE			(0<<0)
+	#define PM3RD_MClkControl_ENABLE			(1<<0)
+	#define PM3RD_MClkControl_NOT_LOCKED			(0<<1)
+	#define PM3RD_MClkControl_LOCKED			(1<<1)
+	#define PM3RD_MClkControl_STATE_LOW			(0<<2)
+	#define PM3RD_MClkControl_STATE_HIGH			(1<<2)
+	#define PM3RD_MClkControl_STATE_RUN			(2<<2)
+	#define PM3RD_MClkControl_STATE_LOW_POWER		(3<<2)
+	#define PM3RD_MClkControl_SOURCE_PCLK			(0<<4)
+	#define PM3RD_MClkControl_SOURCE_HALF_PCLK		(1<<4)
+	#define PM3RD_MClkControl_SOURCE_HALF_EXT		(3<<4)
+	#define PM3RD_MClkControl_SOURCE_EXT			(4<<4)
+	#define PM3RD_MClkControl_SOURCE_HALF_KCLK		(5<<4)
+	#define PM3RD_MClkControl_SOURCE_KCLK			(6<<4)
+#define PM3RD_MClkPreScale					0x212
+#define PM3RD_MClkFeedbackScale					0x213
+#define PM3RD_MClkPostScale					0x214
+#define PM3RD_SClkControl					0x215
+	#define PM3RD_SClkControl_DISABLE			(0<<0)
+	#define PM3RD_SClkControl_ENABLE			(1<<0)
+	#define PM3RD_SClkControl_NOT_LOCKED			(0<<1)
+	#define PM3RD_SClkControl_LOCKED			(1<<1)
+	#define PM3RD_SClkControl_STATE_LOW			(0<<2)
+	#define PM3RD_SClkControl_STATE_HIGH			(1<<2)
+	#define PM3RD_SClkControl_STATE_RUN			(2<<2)
+	#define PM3RD_SClkControl_STATE_LOW_POWER		(3<<2)
+	#define PM3RD_SClkControl_SOURCE_PCLK			(0<<4)
+	#define PM3RD_SClkControl_SOURCE_HALF_PCLK		(1<<4)
+	#define PM3RD_SClkControl_SOURCE_HALF_EXT		(3<<4)
+	#define PM3RD_SClkControl_SOURCE_EXT			(4<<4)
+	#define PM3RD_SClkControl_SOURCE_HALF_KCLK		(5<<4)
+	#define PM3RD_SClkControl_SOURCE_KCLK			(6<<4)
+#define PM3RD_SClkPreScale					0x216
+#define PM3RD_SClkFeedbackScale					0x217
+#define PM3RD_SClkPostScale					0x218
+
+#define PM3RD_CursorPalette(p)					(0x303+(p))
+#define PM3RD_CursorPattern(p)					(0x400+(p))
+/******************************************************
+*  GLINT Permedia3 Video Streaming Registers (0x5000) *
+*******************************************************/
+
+#define PM3VSConfiguration					0x5800
+
+/**********************************************
+*  GLINT Permedia3 Core Registers (0x8000+)   *
+***********************************************/
+#define PM3AALineWidth						0x94c0
+#define PM3AAPointsize						0x94a0
+#define PM3AlphaBlendAlphaMode					0xafa8
+#define PM3AlphaBlendAlphaModeAnd				0xad30
+#define PM3AlphaBlendAlphaModeOr				0xad38
+#define PM3AlphaBlendColorMode					0xafa0
+#define PM3AlphaBlendColorModeAnd				0xacb0
+#define PM3AlphaBlendColorModeOr				0xacb8
+#define PM3AlphaDestColor					0xaf88
+#define PM3AlphaSourceColor					0xaf80
+#define PM3AlphaTestMode					0x8800
+#define PM3AlphaTestModeAnd					0xabf0
+#define PM3AlphaTestModeOr					0xabf8
+#define PM3AntialiasMode					0x8808
+#define PM3AntialiasModeAnd					0xac00
+#define PM3AntialiasModeOr					0xac08
+/* ... */
+#define PM3BackgroundColor					0xb0c8
+/* ... */
+#define PM3ColorDDAMode						0x87e0
+#define PM3ColorDDAModeAnd					0xabe0
+#define PM3ColorDDAModeOr					0xabe8
+#define PM3CommandInterrupt					0xa990
+#define PM3ConstantColorDDA					0xafb0
+	#define PM3ConstantColorDDA_R(r)		((r)&0xff)
+	#define PM3ConstantColorDDA_G(g)		(((g)&0xff)<<8)
+	#define PM3ConstantColorDDA_B(b)		(((b)&0xff)<<16)
+	#define PM3ConstantColorDDA_A(a)		(((a)&0xff)<<24)
+#define PM3ContextData						0x8dd0
+#define PM3ContextDump						0x8dc0
+#define PM3ContextRestore					0x8dc8
+#define PM3Continue						0x8058
+#define PM3ContinueNewDom					0x8048
+#define PM3ContinueNewLine					0x8040
+#define PM3ContinueNewSub					0x8050
+#define PM3Count						0x8030
+/* ... */
+#define PM3DeltaControl						0x9350
+#define PM3DeltaControlAnd					0xab20
+#define PM3DeltaControlOr					0xab28
+#define PM3DeltaMode						0x9300
+#define PM3DeltaModeAnd						0xaad0
+#define PM3DeltaModeOr						0xaad8
+/* ... */
+#define PM3DitherMode						0x8818
+#define PM3DitherModeAnd					0xacd0
+#define PM3DitherModeOr						0xacd8
+/* ... */
+#define PM3dXDom						0x8008
+#define PM3dXSub						0x8018
+#define PM3dY							0x8028
+/* ... */
+#define PM3FBBlockColor						0x8ac8
+#define PM3FBBlockColor0					0xb060
+#define PM3FBBlockColor1					0xb068
+#define PM3FBBlockColor2					0xb070
+#define PM3FBBlockColor3					0xb078
+#define PM3FBBlockColorBack					0xb0a0
+#define PM3FBBlockColorBack0					0xb080
+#define PM3FBBlockColorBack1					0xb088
+#define PM3FBBlockColorBack2					0xb090
+#define PM3FBBlockColorBack3					0xb098
+#define PM3FBColor						0x8a98
+#define PM3FBDestReadBufferAddr0				0xae80
+#define PM3FBDestReadBufferAddr1				0xae88
+#define PM3FBDestReadBufferAddr2				0xae90
+#define PM3FBDestReadBufferAddr3				0xae98
+#define PM3FBDestReadBufferOffset0				0xaea0
+#define PM3FBDestReadBufferOffset1				0xaea8
+#define PM3FBDestReadBufferOffset2				0xaeb0
+#define PM3FBDestReadBufferOffset3				0xaeb8
+	#define PM3FBDestReadBufferOffset_XOffset(x)	((x)&0xffff)
+	#define PM3FBDestReadBufferOffset_YOffset(y)	(((y)&0xffff)<<16)
+#define PM3FBDestReadBufferWidth0				0xaec0
+#define PM3FBDestReadBufferWidth1				0xaec8
+#define PM3FBDestReadBufferWidth2				0xaed0
+#define PM3FBDestReadBufferWidth3				0xaed8
+	#define PM3FBDestReadBufferWidth_Width(w)	((w)&0x0fff)
+
+#define PM3FBDestReadEnables					0xaee8
+#define PM3FBDestReadEnablesAnd					0xad20
+#define PM3FBDestReadEnablesOr					0xad28
+	#define PM3FBDestReadEnables_E(e)		((e)&0xff)
+	#define PM3FBDestReadEnables_E0				1<<0
+	#define PM3FBDestReadEnables_E1				1<<1
+	#define PM3FBDestReadEnables_E2				1<<2
+	#define PM3FBDestReadEnables_E3				1<<3
+	#define PM3FBDestReadEnables_E4				1<<4
+	#define PM3FBDestReadEnables_E5				1<<5
+	#define PM3FBDestReadEnables_E6				1<<6
+	#define PM3FBDestReadEnables_E7				1<<7
+	#define PM3FBDestReadEnables_R(r)		(((r)&0xff)<<8)
+	#define PM3FBDestReadEnables_R0				1<<8
+	#define PM3FBDestReadEnables_R1				1<<9
+	#define PM3FBDestReadEnables_R2				1<<10
+	#define PM3FBDestReadEnables_R3				1<<11
+	#define PM3FBDestReadEnables_R4				1<<12
+	#define PM3FBDestReadEnables_R5				1<<13
+	#define PM3FBDestReadEnables_R6				1<<14
+	#define PM3FBDestReadEnables_R7				1<<15
+	#define PM3FBDestReadEnables_ReferenceAlpha(a)	(((a)&0xff)<<24)
+
+#define PM3FBDestReadMode					0xaee0
+#define PM3FBDestReadModeAnd					0xac90
+#define PM3FBDestReadModeOr					0xac98
+	#define PM3FBDestReadMode_ReadDisable			0<<0
+	#define PM3FBDestReadMode_ReadEnable			1<<0
+	#define PM3FBDestReadMode_StripePitch(sp)	(((sp)&0x7)<<2
+	#define PM3FBDestReadMode_StripeHeight(sh)	(((sh)&0x7)<<7
+	#define PM3FBDestReadMode_Enable0			1<<8
+	#define PM3FBDestReadMode_Enable1			1<<9
+	#define PM3FBDestReadMode_Enable2			1<<10
+	#define PM3FBDestReadMode_Enable3			1<<11
+	#define PM3FBDestReadMode_Layout0(l)		(((l)&0x3)<<12
+	#define PM3FBDestReadMode_Layout1(l)		(((l)&0x3)<<14
+	#define PM3FBDestReadMode_Layout2(l)		(((l)&0x3)<<16
+	#define PM3FBDestReadMode_Layout3(l)		(((l)&0x3)<<18
+	#define PM3FBDestReadMode_Origin0			1<<20
+	#define PM3FBDestReadMode_Origin1			1<<21
+	#define PM3FBDestReadMode_Origin2			1<<22
+	#define PM3FBDestReadMode_Origin3			1<<23
+	#define PM3FBDestReadMode_Blocking			1<<24
+	#define PM3FBDestReadMode_UseReadEnabled		1<<26
+	#define PM3FBDestReadMode_AlphaFiltering		1<<27
+
+#define PM3FBHardwareWriteMask					0x8ac0
+#define PM3FBSoftwareWriteMask					0x8820
+#define PM3FBData						0x8aa0
+#define PM3FBSourceData						0x8aa8
+#define PM3FBSourceReadBufferAddr				0xaf08
+#define PM3FBSourceReadBufferOffset				0xaf10
+	#define PM3FBSourceReadBufferOffset_XOffset(x)	((x)&0xffff)
+	#define PM3FBSourceReadBufferOffset_YOffset(y)	(((y)&0xffff)<<16)
+#define PM3FBSourceReadBufferWidth				0xaf18
+	#define PM3FBSourceReadBufferWidth_Width(w)	((w)&0x0fff)
+#define PM3FBSourceReadMode					0xaf00
+#define PM3FBSourceReadModeAnd					0xaca0
+#define PM3FBSourceReadModeOr					0xaca8
+	#define PM3FBSourceReadMode_ReadDisable			(0<<0)
+	#define PM3FBSourceReadMode_ReadEnable			(1<<0)
+	#define PM3FBSourceReadMode_StripePitch(sp)	(((sp)&0x7)<<2
+	#define PM3FBSourceReadMode_StripeHeight(sh)	(((sh)&0x7)<<7
+	#define PM3FBSourceReadMode_Layout(l)		(((l)&0x3)<<8
+	#define PM3FBSourceReadMode_Origin			1<<10
+	#define PM3FBSourceReadMode_Blocking			1<<11
+	#define PM3FBSourceReadMode_UserTexelCoord		1<<13
+	#define PM3FBSourceReadMode_WrapXEnable			1<<14
+	#define PM3FBSourceReadMode_WrapYEnable			1<<15
+	#define PM3FBSourceReadMode_WrapX(w)		(((w)&0xf)<<16
+	#define PM3FBSourceReadMode_WrapY(w)		(((w)&0xf)<<20
+	#define PM3FBSourceReadMode_ExternalSourceData		1<<24
+#define PM3FBWriteBufferAddr0                                   0xb000
+#define PM3FBWriteBufferAddr1                                   0xb008
+#define PM3FBWriteBufferAddr2                                   0xb010
+#define PM3FBWriteBufferAddr3                                   0xb018
+
+#define PM3FBWriteBufferOffset0                                 0xb020
+#define PM3FBWriteBufferOffset1                                 0xb028
+#define PM3FBWriteBufferOffset2                                 0xb030
+#define PM3FBWriteBufferOffset3                                 0xb038
+	#define PM3FBWriteBufferOffset_XOffset(x)		((x)&0xffff)
+	#define PM3FBWriteBufferOffset_YOffset(y)		(((y)&0xffff)<<16)
+
+#define PM3FBWriteBufferWidth0                                  0xb040
+#define PM3FBWriteBufferWidth1                                  0xb048
+#define PM3FBWriteBufferWidth2                                  0xb050
+#define PM3FBWriteBufferWidth3                                  0xb058
+	#define PM3FBWriteBufferWidth_Width(w)			((w)&0x0fff)
+
+#define PM3FBWriteMode                                          0x8ab8
+#define PM3FBWriteModeAnd                                       0xacf0
+#define PM3FBWriteModeOr                                        0xacf8
+	#define PM3FBWriteMode_WriteDisable                     0<<0
+	#define PM3FBWriteMode_WriteEnable                      1<<0
+	#define PM3FBWriteMode_Replicate                        1<<4
+	#define PM3FBWriteMode_OpaqueSpan                       1<<5
+	#define PM3FBWriteMode_StripePitch(p)            (((p)&0x7)<<6)
+	#define PM3FBWriteMode_StripeHeight(h)           (((h)&0x7)<<9)
+	#define PM3FBWriteMode_Enable0                          1<<12
+	#define PM3FBWriteMode_Enable1                          1<<13
+	#define PM3FBWriteMode_Enable2                          1<<14
+	#define PM3FBWriteMode_Enable3                          1<<15
+	#define PM3FBWriteMode_Layout0(l)               (((l)&0x3)<<16)
+	#define PM3FBWriteMode_Layout1(l)               (((l)&0x3)<<18)
+	#define PM3FBWriteMode_Layout2(l)               (((l)&0x3)<<20)
+	#define PM3FBWriteMode_Layout3(l)               (((l)&0x3)<<22)
+	#define PM3FBWriteMode_Origin0                          1<<24
+	#define PM3FBWriteMode_Origin1                          1<<25
+	#define PM3FBWriteMode_Origin2                          1<<26
+	#define PM3FBWriteMode_Origin3                          1<<27
+#define PM3ForegroundColor					0xb0c0
+/* ... */
+#define PM3GIDMode						0xb538
+#define PM3GIDModeAnd						0xb5b0
+#define PM3GIDModeOr						0xb5b8
+/* ... */
+#define PM3LBDestReadBufferAddr					0xb510
+#define PM3LBDestReadBufferOffset				0xb518
+#define PM3LBDestReadEnables					0xb508
+#define PM3LBDestReadEnablesAnd					0xb590
+#define PM3LBDestReadEnablesOr					0xb598
+#define PM3LBDestReadMode					0xb500
+#define PM3LBDestReadModeAnd					0xb580
+#define PM3LBDestReadModeOr					0xb588
+	#define PM3LBDestReadMode_Disable			0<<0
+	#define PM3LBDestReadMode_Enable			1<<0
+	#define PM3LBDestReadMode_StripePitch(p)		(((p)&0x7)<<2)
+	#define PM3LBDestReadMode_StripeHeight(h)		(((h)&0x7)<<5)
+	#define PM3LBDestReadMode_Layout			1<<8
+	#define PM3LBDestReadMode_Origin			1<<9
+	#define PM3LBDestReadMode_UserReadEnables		1<<10
+	#define PM3LBDestReadMode_Packed16			1<<11
+	#define PM3LBDestReadMode_Width(w)			(((w)&0xfff)<<12)
+#define PM3LBReadFormat						0x8888
+	#define PM3LBReadFormat_DepthWidth(w)			(((w)&0x3)<<0)
+	#define PM3LBReadFormat_StencilWidth(w)			(((w)&0xf)<<2)
+	#define PM3LBReadFormat_StencilPosition(p)		(((p)&0x1f)<<6)
+	#define PM3LBReadFormat_FCPWidth(w)			(((w)&0xf)<<11)
+	#define PM3LBReadFormat_FCPPosition(p)			(((p)&0x1f)<<15)
+	#define PM3LBReadFormat_GIDWidth(w)			(((w)&0x7)<<20)
+	#define PM3LBReadFormat_GIDPosition(p)			(((p)&0x1f)<<23)
+#define PM3LBSourceReadBufferAddr				0xb528
+#define PM3LBSourceReadBufferOffset				0xb530
+#define PM3LBSourceReadMode					0xb520
+#define PM3LBSourceReadModeAnd					0xb5a0
+#define PM3LBSourceReadModeOr					0xb5a8
+	#define PM3LBSourceReadMode_Enable			1<<0
+	#define PM3LBSourceReadMode_StripePitch(p)		(((p)&0x7)<<2)
+	#define PM3LBSourceReadMode_StripeHeight(h)		(((h)&0x7)<<5)
+	#define PM3LBSourceReadMode_Layout			1<<8
+	#define PM3LBSourceReadMode_Origin			1<<9
+	#define PM3LBSourceReadMode_Packed16			1<<10
+	#define PM3LBSourceReadMode_Width(w)			(((w)&0xfff)<<11)
+#define PM3LBStencil						0x88a8
+#define PM3LBWriteBufferAddr					0xb540
+#define PM3LBWriteBufferOffset					0xb548
+#define PM3LBWriteFormat					0x88c8
+	#define PM3LBWriteFormat_DepthWidth(w)			(((w)&0x3)<<0)
+	#define PM3LBWriteFormat_StencilWidth(w)		(((w)&0xf)<<2)
+	#define PM3LBWriteFormat_StencilPosition(p)		(((p)&0x1f)<<6)
+	#define PM3LBWriteFormat_GIDWidth(w)			(((w)&0x7)<<20)
+	#define PM3LBWriteFormat_GIDPosition(p)			(((p)&0x1f)<<23)
+#define PM3LBWriteMode						0x88c0
+#define PM3LBWriteModeAnd					0xac80
+#define PM3LBWriteModeOr					0xac88
+	#define PM3LBWriteMode_WriteDisable			0<<0
+	#define PM3LBWriteMode_WriteEnable			1<<0
+	#define PM3LBWriteMode_StripePitch(p)			(((p)&0x7)<<3)
+	#define PM3LBWriteMode_StripeHeight(h)			(((h)&0x7)<<6)
+	#define PM3LBWriteMode_Layout				1<<9
+	#define PM3LBWriteMode_Origin				1<<10
+	#define PM3LBWriteMode_Packed16				1<<11
+	#define PM3LBWriteMode_Width(w)				(((w)&0xfff)<<12)
+/* ... */
+#define PM3LineStippleMode					0x81a8
+#define PM3LineStippleModeAnd					0xabc0
+#define PM3LineStippleModeOr					0xabc8
+#define PM3LoadLineStippleCounters				0x81b0
+/* ... */
+#define PM3LogicalOpMode					0x8828
+#define PM3LogicalOpModeAnd					0xace0
+#define PM3LogicalOpModeOr					0xace8
+	#define PM3LogicalOpMode_Disable			(0<<0)
+	#define PM3LogicalOpMode_Enable				(1<<0)
+	#define PM3LogicalOpMode_LogicOp(op)			(((op)&0xf)<<1)
+	#define PM3LogicalOpMode_UseConstantWriteData_Disable	(0<<5)
+	#define PM3LogicalOpMode_UseConstantWriteData_Enable	(1<<5)
+	#define PM3LogicalOpMode_Background_Disable		(0<<6)
+	#define PM3LogicalOpMode_Background_Enable		(1<<6)
+	#define PM3LogicalOpMode_Background_LogicOp(op)		(((op)&0xf)<<7)
+	#define PM3LogicalOpMode_UseConstantSource_Disable	(0<<11)
+	#define PM3LogicalOpMode_UseConstantSource_Enable	(1<<11)
+
+/* ... */
+#define PM3LUT							0x8e80
+/* ... */
+#define PM3LUT							0x8e80
+#define PM3LUTAddress						0x84d0
+#define PM3LUTData						0x84c8
+#define PM3LUTIndex						0x84c0
+#define PM3LUTMode						0xb378
+#define PM3LUTModeAnd						0xad70
+#define PM3LUTModeOr						0xad78
+#define PM3LUTTransfer						0x84d8
+/* ... */
+#define PM3PixelSize						0x80c0
+	#define PM3PixelSize_GLOBAL_32BIT			(0<<0)
+	#define PM3PixelSize_GLOBAL_16BIT			(1<<0)
+	#define PM3PixelSize_GLOBAL_8BIT			(2<<0)
+	#define PM3PixelSize_RASTERIZER_32BIT			(0<<2)
+	#define PM3PixelSize_RASTERIZER_16BIT			(1<<2)
+	#define PM3PixelSize_RASTERIZER_8BIT			(2<<2)
+	#define PM3PixelSize_SCISSOR_AND_STIPPLE_32BIT		(0<<4)
+	#define PM3PixelSize_SCISSOR_AND_STIPPLE_16BIT		(1<<4)
+	#define PM3PixelSize_SCISSOR_AND_STIPPLE_8BIT		(2<<4)
+	#define PM3PixelSize_TEXTURE_32BIT			(0<<6)
+	#define PM3PixelSize_TEXTURE_16BIT			(1<<6)
+	#define PM3PixelSize_TEXTURE_8BIT			(2<<6)
+	#define PM3PixelSize_LUT_32BIT				(0<<8)
+	#define PM3PixelSize_LUT_16BIT				(1<<8)
+	#define PM3PixelSize_LUT_8BIT				(2<<8)
+	#define PM3PixelSize_FRAMEBUFFER_32BIT			(0<<10)
+	#define PM3PixelSize_FRAMEBUFFER_16BIT			(1<<10)
+	#define PM3PixelSize_FRAMEBUFFER_8BIT			(2<<10)
+	#define PM3PixelSize_LOGICAL_OP_32BIT			(0<<12)
+	#define PM3PixelSize_LOGICAL_OP_16BIT			(1<<12)
+	#define PM3PixelSize_LOGICAL_OP_8BIT			(2<<12)
+	#define PM3PixelSize_LOCALBUFFER_32BIT			(0<<14)
+	#define PM3PixelSize_LOCALBUFFER_16BIT			(1<<14)
+	#define PM3PixelSize_LOCALBUFFER_8BIT			(2<<14)
+	#define PM3PixelSize_SETUP_32BIT			(0<<16)
+	#define PM3PixelSize_SETUP_16BIT			(1<<16)
+	#define PM3PixelSize_SETUP_8BIT				(2<<16)
+	#define PM3PixelSize_GLOBAL				(0<<31)
+	#define PM3PixelSize_INDIVIDUAL				(1<<31)
+/* ... */
+#define PM3Render						0x8038
+	#define PM3Render_AreaStipple_Disable			(0<<0)
+	#define PM3Render_AreaStipple_Enable			(1<<0)
+	#define PM3Render_LineStipple_Disable			(0<<1)
+	#define PM3Render_LineStipple_Enable			(1<<1)
+	#define PM3Render_ResetLine_Disable			(0<<2)
+	#define PM3Render_ResetLine_Enable			(1<<2)
+	#define PM3Render_FastFill_Disable			(0<<3)
+	#define PM3Render_FastFill_Enable			(1<<3)
+	#define PM3Render_Primitive_Line			(0<<6)
+	#define PM3Render_Primitive_Trapezoid			(1<<6)
+	#define PM3Render_Primitive_Point			(2<<6)
+	#define PM3Render_Antialias_Disable			(0<<8)
+	#define PM3Render_Antialias_Enable			(1<<8)
+	#define PM3Render_Antialias_SubPixelRes_4x4		(0<<9)
+	#define PM3Render_Antialias_SubPixelRes_8x8		(1<<9)
+	#define PM3Render_UsePointTable_Disable			(0<<10)
+	#define PM3Render_UsePointTable_Enable			(1<<10)
+	#define PM3Render_SyncOnbitMask_Disable			(0<<11)
+	#define PM3Render_SyncOnBitMask_Enable			(1<<11)
+	#define PM3Render_SyncOnHostData_Disable		(0<<12)
+	#define PM3Render_SyncOnHostData_Enable			(1<<12)
+	#define PM3Render_Texture_Disable			(0<<13)
+	#define PM3Render_Texture_Enable			(1<<13)
+	#define PM3Render_Fog_Disable				(0<<14)
+	#define PM3Render_Fog_Enable				(1<<14)
+	#define PM3Render_Coverage_Disable			(0<<15)
+	#define PM3Render_Coverage_Enable			(1<<15)
+	#define PM3Render_SubPixelCorrection_Disable		(0<<16)
+	#define PM3Render_SubPixelCorrection_Enable		(1<<16)
+	#define PM3Render_SpanOperation_Disable			(0<<18)
+	#define PM3Render_SpanOperation_Enable			(1<<18)
+	#define PM3Render_FBSourceRead_Disable			(0<<27)
+	#define PM3Render_FBSourceRead_Enable			(1<<27)
+#define PM3RasterizerMode					0x80a0
+#define PM3RasterizerModeAnd					0xaba0
+#define PM3RasterizerModeOr					0xabb8
+#define PM3RectangleHeight					0x94e0
+#define PM3Render						0x8038
+#define PM3RepeatLine						0x9328
+#define PM3ResetPickResult					0x8c20
+#define PM3RLEMask						0x8c48
+#define PM3RouterMode						0x8840
+#define PM3RStart						0x8780
+#define PM3S1Start						0x8400
+#define PM3aveLineStippleCounters				0x81c0
+#define PM3ScissorMaxXY						0x8190
+#define PM3ScissorMinXY						0x8188
+#define PM3ScissorMode						0x8180
+#define PM3ScissorModeAnd					0xabb0
+#define PM3ScissorModeOr					0xabb8
+#define PM3ScreenSize						0x8198
+#define PM3Security						0x8908
+#define PM3SetLogicalTexturePage				0xb360
+#define PM3SizeOfFramebuffer					0xb0a8
+#define PM3SStart						0x8388
+#define PM3StartXDom						0x8000
+#define PM3StartXSub						0x8010
+#define PM3StartY						0x8020
+/* ... */
+#define PM3SpanColorMask					0x8168
+/* ... */
+#define PM3TextureApplicationMode				0x8680
+#define PM3TextureApplicationModeAnd				0xac50
+#define PM3TextureApplicationModeOr				0xac58
+#define PM3TextureBaseAddr					0x8500
+#define PM3TextureCacheControl					0x8490
+#define PM3TextureChromaLower0					0x84f0
+#define PM3TextureChromaLower1					0x8608
+#define PM3TextureChromaUpper0					0x84e8
+#define PM3TextureChromaUpper1					0x8600
+#define PM3TextureCompositeAlphaMode0				0xb310
+#define PM3TextureCompositeAlphaMode0And			0xb390
+#define PM3TextureCompositeAlphaMode0Or				0xb398
+#define PM3TextureCompositeAlphaMode1				0xb320
+#define PM3TextureCompositeAlphaMode1And			0xb3b0
+#define PM3TextureCompositeAlphaMode1Or				0xb3b8
+#define PM3TextureCompositeColorMode0				0xb308
+#define PM3TextureCompositeColorMode0And			0xb380
+#define PM3TextureCompositeColorMode0Or				0xb388
+#define PM3TextureCompositeColorMode1				0xb318
+#define PM3TextureCompositeColorMode1And			0xb3a0
+#define PM3TextureCompositeColorMode1Or				0xb3a8
+#define PM3TextureCompositeFactor0				0xb328
+#define PM3TextureCompositeFactor1				0xb330
+#define PM3TextureCompositeMode					0xb300
+#define PM3TextureCoordMode					0x8380
+#define PM3TextureCoordModeAnd					0xac20
+#define PM3TextureCoordModeOr					0xac28
+#define PM3TextureData						0x88e8
+/*
+#define PM3TextureDownloadControl				0x0108
+*/
+#define PM3TextureDownloadOffset				0x88f0
+#define PM3TextureEnvColor					0x8688
+#define PM3TextureFilterMode					0x84e0
+#define PM3TextureFilterModeAnd					0xad50
+#define PM3TextureFilterModeOr					0xad58
+#define PM3TextureIndexMode0					0xb338
+#define PM3TextureIndexMode0And					0xb3c0
+#define PM3TextureIndexMode0Or					0xb3c8
+#define PM3TextureIndexMode1					0xb340
+#define PM3TextureIndexMode1And					0xb3d0
+#define PM3TextureIndexMode1Or					0xb3d8
+/* ... */
+#define PM3TextureMapSize                                       0xb428
+#define PM3TextureMapWidth0                                     0x8580
+#define PM3TextureMapWidth1                                     0x8588
+        #define PM3TextureMapWidth_Width(w)             ((w&0xfff)<<0)
+        #define PM3TextureMapWidth_BorderLayout                 (1<<12)
+        #define PM3TextureMapWidth_Layout_Linear                (0<<13)
+        #define PM3TextureMapWidth_Layout_Patch64               (1<<13)
+        #define PM3TextureMapWidth_Layout_Patch32_2             (2<<13)
+        #define PM3TextureMapWidth_Layout_Patch2                (3<<13)
+        #define PM3TextureMapWidth_HostTexture                  (1<<15)
+#define PM3TextureReadMode0                                     0xb400
+#define PM3TextureReadMode0And                                  0xac30
+#define PM3TextureReadMode0Or                                   0xac38
+#define PM3TextureReadMode1                                     0xb408
+#define PM3TextureReadMode1And                                  0xad40
+#define PM3TextureReadMode1Or                                   0xad48
+/* ... */
+#define PM3WaitForCompletion					0x80b8
+#define PM3Window						0x8980
+	#define PM3Window_ForceLBUpdate				1<<3
+	#define PM3Window_LBUpdateSource			1<<4
+	#define PM3Window_FrameCount(c)				(((c)&0xff)<<9
+	#define PM3Window_StencilFCP				1<<17
+	#define PM3Window_DepthFCP				1<<18
+	#define PM3Window_OverrideWriteFiltering		1<<19
+#define PM3WindowAnd						0xab80
+#define PM3WindowOr						0xab88
+#define PM3WindowOrigin						0x81c8
+#define PM3XBias						0x9480
+#define PM3YBias						0x9488
+#define PM3YLimits						0x80a8
+#define PM3UVMode						0x8f00
+#define PM3ZFogBias						0x86b8
+#define PM3ZStart						0xadd8
+#define PM3ZStartL						0x89b8
+#define PM3ZStartU						0x89b0
+
+
+/**********************************************
+*  GLINT Permedia3 2D setup Unit              *
+***********************************************/
+#define PM3Config2D						0xb618
+	#define PM3Config2D_OpaqueSpan				1<<0
+	#define PM3Config2D_MultiRXBlit				1<<1
+	#define PM3Config2D_UserScissorEnable			1<<2
+	#define PM3Config2D_FBDestReadEnable			1<<3
+	#define PM3Config2D_AlphaBlendEnable			1<<4
+	#define PM3Config2D_DitherEnable			1<<5
+	#define PM3Config2D_ForegroundROPEnable			1<<6
+	#define PM3Config2D_ForegroundROP(rop)		(((rop)&0xf)<<7)
+	#define PM3Config2D_BackgroundROPEnable			1<<11
+	#define PM3Config2D_BackgroundROP(rop)		(((rop)&0xf)<<12)
+	#define PM3Config2D_UseConstantSource			1<<16
+	#define PM3Config2D_FBWriteEnable			1<<17
+	#define PM3Config2D_Blocking				1<<18
+	#define PM3Config2D_ExternalSourceData			1<<19
+	#define PM3Config2D_LUTModeEnable			1<<20
+#define PM3DownloadGlyphwidth					0xb658
+	#define PM3DownloadGlyphwidth_GlyphWidth(gw)	((gw)&0xffff)
+#define PM3DownloadTarget					0xb650
+	#define PM3DownloadTarget_TagName(tag)		((tag)&0x1fff)
+#define PM3GlyphData						0xb660
+#define PM3GlyphPosition					0xb608
+	#define PM3GlyphPosition_XOffset(x)		((x)&0xffff)
+	#define PM3GlyphPosition_YOffset(y)		(((y)&0xffff)<<16)
+#define PM3Packed4Pixels					0xb668
+#define PM3Packed8Pixels					0xb630
+#define PM3Packed16Pixels					0xb638
+#define PM3RectanglePosition					0xb600
+	#define PM3RectanglePosition_XOffset(x)		((x)&0xffff)
+	#define PM3RectanglePosition_YOffset(y)		(((y)&0xffff)<<16)
+#define PM3Render2D						0xb640
+	#define PM3Render2D_Width(w)			((w)&0x0fff)
+	#define PM3Render2D_Operation_Normal			0<<12
+	#define PM3Render2D_Operation_SyncOnHostData		1<<12
+	#define PM3Render2D_Operation_SyncOnBitMask		2<<12
+	#define PM3Render2D_Operation_PatchOrderRendering	3<<12
+	#define PM3Render2D_FBSourceReadEnable			1<<14
+	#define PM3Render2D_SpanOperation			1<<15
+	#define PM3Render2D_Height(h)			(((h)&0x0fff)<<16)
+	#define PM3Render2D_XPositive				1<<28
+	#define PM3Render2D_YPositive				1<<29
+	#define PM3Render2D_AreaStippleEnable			1<<30
+	#define PM3Render2D_TextureEnable			1<<31
+#define PM3Render2DGlyph					0xb648
+	#define PM3Render2DGlyph_Width(w)		((w)&0x7f)
+	#define PM3Render2DGlyph_Height(h)		(((h)&0x7f)<<7)
+	#define PM3Render2DGlyph_XOffset(x)		(((x)&0x1ff)<<14)
+	#define PM3Render2DGlyph_YOffset(y)		(((y)&0x1ff)<<23)
+#define PM3RenderPatchOffset					0xb610
+	#define PM3RenderPatchOffset_XOffset(x)		((x)&0xffff)
+	#define PM3RenderPatchOffset_YOffset(y)		(((y)&0xffff)<<16)
+#define PM3RLCount						0xb678
+	#define PM3RLCount_Count(c)			((c)&0x0fff)
+#define PM3RLData						0xb670
+
+/**********************************************
+*  GLINT Permedia3 Alias Register             *
+***********************************************/
+#define PM3FillBackgroundColor                                  0x8330
+#define PM3FillConfig2D0                                        0x8338
+#define PM3FillConfig2D1                                        0x8360
+	#define PM3FillConfig2D_OpaqueSpan                      1<<0
+	#define PM3FillConfig2D_MultiRXBlit                     1<<1
+	#define PM3FillConfig2D_UserScissorEnable               1<<2
+	#define PM3FillConfig2D_FBDestReadEnable                1<<3
+	#define PM3FillConfig2D_AlphaBlendEnable                1<<4
+	#define PM3FillConfig2D_DitherEnable                    1<<5
+	#define PM3FillConfig2D_ForegroundROPEnable             1<<6
+	#define PM3FillConfig2D_ForegroundROP(rop)              (((rop)&0xf)<<7)
+	#define PM3FillConfig2D_BackgroundROPEnable             1<<11
+	#define PM3FillConfig2D_BackgroundROP(rop)              (((rop)&0xf)<<12)
+	#define PM3FillConfig2D_UseConstantSource               1<<16
+	#define PM3FillConfig2D_FBWriteEnable                   1<<17
+	#define PM3FillConfig2D_Blocking                        1<<18
+	#define PM3FillConfig2D_ExternalSourceData              1<<19
+	#define PM3FillConfig2D_LUTModeEnable                   1<<20
+#define PM3FillFBDestReadBufferAddr                             0x8310
+#define PM3FillFBSourceReadBufferAddr                           0x8308
+#define PM3FillFBSourceReadBufferOffset                         0x8340
+	#define PM3FillFBSourceReadBufferOffset_XOffset(x)     ((x)&0xffff)
+	#define PM3FillFBSourceReadBufferOffset_YOffset(y)      (((y)&0xffff)<<16)
+#define PM3FillFBWriteBufferAddr                                0x8300
+#define PM3FillForegroundColor0                                 0x8328
+#define PM3FillForegroundColor1                                 0x8358
+#define PM3FillGlyphPosition                                    0x8368
+        #define PM3FillGlyphPosition_XOffset(x)                        ((x)&0xffff)
+	#define PM3FillGlyphPosition_YOffset(y)                        (((y)&0xffff)<<16)
+#define PM3FillRectanglePosition                                0x8348
+	#define PM3FillRectanglePosition_XOffset(x)            ((x)&0xffff)
+	#define PM3FillRectanglePosition_YOffset(y)            (((y)&0xffff)<<16)
+
+#define PM3_REGS_SIZE           0x10000
+#define PM3_MAX_PIXCLOCK        300000
+/* a few more useful registers & regs value... */
+#define PM3Sync 0x8c40
+        #define PM3Sync_Tag 0x188
+#define PM3FilterMode 0x8c00
+        #define PM3FilterModeSync 0x400
+#define PM3OutputFifo 0x2000
+#define PM3StatisticMode 0x8c08
+#define PM3AreaStippleMode 0x81a0
+        #define AreaStipplePattern0					(0x8200)
+        #define AreaStipplePattern1					(0x8208)
+        #define AreaStipplePattern2					(0x8210)
+        #define AreaStipplePattern3					(0x8218)
+        #define AreaStipplePattern4					(0x8220)
+        #define AreaStipplePattern5					(0x8228)
+        #define AreaStipplePattern6					(0x8230)
+        #define AreaStipplePattern7					(0x8238)
+        #define AreaStipplePattern8					(0x8240)
+        #define AreaStipplePattern9					(0x8248)
+        #define AreaStipplePattern10					(0x8250)
+        #define AreaStipplePattern11					(0x8258)
+        #define AreaStipplePattern12					(0x8260)
+        #define AreaStipplePattern13					(0x8268)
+        #define AreaStipplePattern14					(0x8270)
+        #define AreaStipplePattern15					(0x8278)
+        #define AreaStipplePattern16					(0x8280)
+        #define AreaStipplePattern17					(0x8288)
+        #define AreaStipplePattern18					(0x8290)
+        #define AreaStipplePattern19					(0x8298)
+        #define AreaStipplePattern20					(0x82a0)
+        #define AreaStipplePattern21					(0x82a8)
+        #define AreaStipplePattern22					(0x82b0)
+        #define AreaStipplePattern23					(0x82b8)
+        #define AreaStipplePattern24					(0x82c0)
+        #define AreaStipplePattern25					(0x82c8)
+        #define AreaStipplePattern26					(0x82d0)
+        #define AreaStipplePattern27					(0x82d8)
+        #define AreaStipplePattern28					(0x82eo)
+        #define AreaStipplePattern29					(0x82e8)
+        #define AreaStipplePattern30					(0x82f0)
+        #define AreaStipplePattern31					(0x82f8)
+        #define AreaStipplePattern_indexed(i)             (0x8200 + ((i) * 0x8))
+
+#define PM3DepthMode 0x89a0
+#define PM3StencilMode 0x8988
+#define PM3StencilData 0x8990
+#define PM3TextureReadMode 0x8670
+#define PM3FogMode 0x8690
+#define PM3ChromaTestMode 0x8f18
+#define PM3YUVMode 0x8f00
+#define PM3BitMaskPattern 0x8068
+
+/* ***************************** */
+/* ***** pm3fb IOCTL const ***** */
+/* ***************************** */
+/* debug-only IOCTL */
+#define PM3FBIO_CLEARMEMORY 0x504D3300 /* 'PM3\000' */
+#define PM3FBIO_CLEARCMAP   0x504D3301 /* 'PM3\001' */
+/* common use IOCTL */
+#define PM3FBIO_RESETCHIP   0x504D33FF /* 'PM3\377' */
+
+/* ***************************************** */
+/* ***** pm3fb useful define and macro ***** */
+/* ***************************************** */
+
+/* kernel -specific definitions */
+/* what kernel is this ? */
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)))
+#define KERNEL_2_5
+#endif
+
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)))
+#define KERNEL_2_4
+#endif
+
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))) 
+#define KERNEL_2_2
+/* pci_resource_start, available in 2.2.18 */
+#include <linux/kcomp.h>
+#ifdef CONFIG_FB_OF
+#define SUPPORT_FB_OF
+#endif
+#endif
+
+#if (!defined(KERNEL_2_2)) && (!defined(KERNEL_2_4)) && (!defined(KERNEL_2_5))
+#error "Only kernel 2.2.x, kernel 2.4.y and kernel 2.5.z might work"
+#endif
+
+/* not sure if/why it's needed. doesn't work without on my PowerMac... */
+#ifdef __BIG_ENDIAN
+#define MUST_BYTESWAP
+#endif
+
+/* for compatibility between 2.5, 2.4 and 2.2 */
+#ifndef B_FREE
+#define B_FREE   -1
+#endif
+
+/* permedia3 -specific definitions */
+#define PM3_SCALE_TO_CLOCK(pr, fe, po) ((2 * PM3_REF_CLOCK * fe) / (pr * (1 << (po))))
+
+/* in case it's not in linux/pci.h */
+#ifndef PCI_DEVICE_ID_3DLABS_PERMEDIA3
+#define PCI_DEVICE_ID_3DLABS_PERMEDIA3 0x000a
+#endif
+
+/* max number of simultaneous board */
+/* warning : make sure module array def's are coherent with PM3_MAX_BOARD */
+#define PM3_MAX_BOARD 4
+#define PM3_MAX_BOARD_MODULE_ARRAY_SHORT "1-4h"
+#define PM3_MAX_BOARD_MODULE_ARRAY_STRING "1-4s"
+
+/* max size of options */
+#define PM3_OPTIONS_SIZE 256
+
+/* max size of font name */
+#define PM3_FONTNAME_SIZE 40
+
+/* do we want accelerated console  */
+#define PM3FB_USE_ACCEL 1
+
+/* useful ? */
+#define CHAR_IS_NUM(a)  ((((a) >= '0') && ((a) <= '9')) ? 1 : 0)
+
+/* for driver debugging ONLY */
+/* 0 = assert only, 1 = error, 2 = info, 3+ = verbose */
+/* define PM3FB_MASTER_DEBUG 1 */
+#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 3)
+#define PM3FB_TRACE
+#endif /* defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 3) */
+
+#ifdef PM3FB_MASTER_DEBUG
+#define DPRINTK(l,a,b...) do { if ((l) <= PM3FB_MASTER_DEBUG) printk("pm3fb: %s: " a, __FUNCTION__ , ## b); } while (0)
+#define DASSERT(t,a,b...) do { if (!(t)) printk("pm3fb: _assert failed: %s: " a, __FUNCTION__ , ## b); } while (0)
+#ifdef PM3FB_TRACE
+#define DTRACE printk("pm3fb: _enter %s\n", __FUNCTION__)
+#else /* PM3FB_TRACE */
+#define DTRACE
+#endif /* PM3FB_TRACE */
+#else /* PM3FB_MASTER_DEBUG */
+#define DPRINTK(l,a,b...)
+#define DASSERT(t,a,b...)
+#define DTRACE
+#endif /* PM3FB_MASTER_DEBUG */
+
+#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2)
+#define PM3_SHOW_CUR_MODE pm3fb_show_cur_mode(l_fb_info)
+#else
+#define PM3_SHOW_CUR_MODE /* pm3fb_show_cur_mode() */
+#endif
+
+/* ******************************************** */
+/* ***** A bunch of register-access macro ***** */
+/* ******************************************** */
+#ifdef KERNEL_2_2
+#ifdef MUST_BYTESWAP /* we are writing big_endian to big_endian through a little_endian macro */
+#define PM3_READ_REG(r) __swab32(readl((l_fb_info->vIOBase + r)))
+#define PM3_WRITE_REG(r, v) writel(__swab32(v), (l_fb_info->vIOBase + r))
+#else /* MUST_BYTESWAP */
+#define PM3_WRITE_REG(r, v) writel(v, (l_fb_info->vIOBase + r))
+#define PM3_READ_REG(r) readl((l_fb_info->vIOBase + r))
+#endif /* MUST_BYTESWAP */
+#endif /* KERNEL_2_2 */
+#if (defined KERNEL_2_4) || (defined KERNEL_2_5) /* native-endian access */
+#define PM3_WRITE_REG(r, v) fb_writel(v, (l_fb_info->vIOBase + r))
+#define PM3_READ_REG(r) fb_readl((l_fb_info->vIOBase + r))
+#endif /* KERNEL_2_4 or KERNEL_2_5 */
+
+
+#define depth2bpp(d) ((d + 7L) & ~7L)
+#define depth2ByPP(d) (depth2bpp(d) / 8)
+
+#define depth_supported(d) ((d == 8) || (d == 12) || (d == 15) || (d == 16) || (d==32))
+
+
+#define PM3_WAIT(n) \
+do{ \
+	while(PM3_READ_REG(PM3InFIFOSpace)<(n)); \
+} while(0)
+
+#define PM3_DELAY(x) do { \
+        int delay = x; \
+        unsigned char tmp; \
+        while(delay--){tmp = PM3_READ_REG(PM3InFIFOSpace);}; \
+} while(0)
+
+#define PM3_SLOW_WRITE_REG(r,v)	\
+do{                             \
+    DASSERT((l_fb_info->vIOBase != (unsigned char*)(-1)), "l_fb_info->vIOBase mapped in slow write\n"); \
+	mb();                   \
+	PM3_WAIT(1);            \
+	mb();                   \
+    PM3_WRITE_REG(r,v);     \
+} while(0)
+
+#define PM3_SET_INDEX(index) \
+do{ \
+	PM3_SLOW_WRITE_REG(PM3RD_IndexHigh,(((index)>>8)&0xff)); \
+	PM3_SLOW_WRITE_REG(PM3RD_IndexLow,((index)&0xff)); \
+} while(0)
+
+#define PM3_WRITE_DAC_REG(r, v) \
+do { \
+     DASSERT((l_fb_info->vIOBase != (unsigned char*)(-1)), "l_fb_info->vIOBase mapped in write dac reg\n"); \
+     PM3_SET_INDEX(r); \
+     mb(); \
+     PM3_WRITE_REG(PM3RD_IndexedData, v); \
+} while (0)
+
+/* next one is really a function, added as a macro to be consistent */
+#define PM3_READ_DAC_REG(r) pm3fb_read_dac_reg(l_fb_info, r)
+
+
+#define PM3_COLOR(c) \
+do { \
+  if (l_fb_info->current_par->depth == 8) \
+    { \
+      c = (c & 0xFF); \
+      c = c | (c << 8); \
+    } \
+  if ((l_fb_info->current_par->depth == 8) || (depth2bpp(l_fb_info->current_par->depth) == 16)) \
+    { \
+      c = (c & 0xFFFF); \
+      c = c | (c << 16); \
+    } \
+} while (0)
+
+#endif /* PM3FB_H */
diff -Nru a/include/video/pmag-ba-fb.h b/include/video/pmag-ba-fb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/pmag-ba-fb.h	Wed Feb 12 11:08:13 2003
@@ -0,0 +1,24 @@
+/*
+ *      linux/drivers/video/pmag-ba-fb.h
+ *
+ *      TurboChannel PMAG-BA framebuffer card support,
+ *      Copyright (C) 1999,2000,2001 by
+ *      Michael Engel <engel@unix-ag.org>,
+ *      Karsten Merker <merker@linuxtag.org>
+ *      This file is subject to the terms and conditions of the GNU General
+ *      Public License.  See the file COPYING in the main directory of this
+ *      archive for more details.
+ */
+
+/*
+ * Bt459 RAM DAC register base offset (rel. to TC slot base address)
+ */
+
+#define PMAG_BA_BT459_OFFSET                    0x00200000
+
+/*
+ * Begin of PMAG-BA framebuffer memory relative to TC slot address,
+ * resolution is 1024x864x8
+ */
+
+#define PMAG_BA_ONBOARD_FBMEM_OFFSET    0x00000000
diff -Nru a/include/video/pmagb-b-fb.h b/include/video/pmagb-b-fb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/pmagb-b-fb.h	Wed Feb 12 11:08:46 2003
@@ -0,0 +1,32 @@
+/*
+ *      linux/drivers/video/pmagb-b-fb.h
+ *
+ *      TurboChannel PMAGB-B framebuffer card support,
+ *      Copyright (C) 1999, 2000, 2001 by
+ *      Michael Engel <engel@unix-ag.org> and 
+ *      Karsten Merker <merker@linuxtag.org>
+ *      This file is subject to the terms and conditions of the GNU General
+ *      Public License.  See the file COPYING in the main directory of this
+ *      archive for more details.
+ */
+
+
+/*
+ * Bt459 RAM DAC register base offset (rel. to TC slot base address)
+ */
+#define PMAGB_B_BT459_OFFSET			0x001C0000
+
+/*
+ * Begin of PMAGB-B framebuffer memory, resolution is configurable:
+ * 1024x864x8 or 1280x1024x8, settable by jumper on the card
+ */
+#define PMAGB_B_ONBOARD_FBMEM_OFFSET	0x00201000
+
+/*
+ * Bt459 register offsets, byte-wide registers
+ */
+
+#define BT459_ADR_LOW			BT459_OFFSET + 0x00	/* addr. low */
+#define BT459_ADR_HIGH			BT459_OFFSET + 0x04	/* addr. high */
+#define BT459_DATA			BT459_OFFSET + 0x08	/* r/w data */
+#define BT459_CMAP			BT459_OFFSET + 0x0C	/* color map */
diff -Nru a/include/video/sisfb.h b/include/video/sisfb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/sisfb.h	Wed Mar  5 09:22:37 2003
@@ -0,0 +1,191 @@
+#ifndef _LINUX_SISFB
+#define _LINUX_SISFB
+
+#include <linux/spinlock.h>
+
+#include <asm/ioctl.h>
+#include <asm/types.h>
+
+#define DISPTYPE_CRT1       0x00000008L
+#define DISPTYPE_CRT2       0x00000004L
+#define DISPTYPE_LCD        0x00000002L
+#define DISPTYPE_TV         0x00000001L
+#define DISPTYPE_DISP1      DISPTYPE_CRT1
+#define DISPTYPE_DISP2      (DISPTYPE_CRT2 | DISPTYPE_LCD | DISPTYPE_TV)
+#define DISPMODE_SINGLE	    0x00000020L
+#define DISPMODE_MIRROR	    0x00000010L
+#define DISPMODE_DUALVIEW   0x00000040L
+
+#define HASVB_NONE      	0x00
+#define HASVB_301       	0x01
+#define HASVB_LVDS      	0x02
+#define HASVB_TRUMPION  	0x04
+#define HASVB_LVDS_CHRONTEL	0x10
+#define HASVB_302       	0x20
+#define HASVB_303       	0x40
+#define HASVB_CHRONTEL  	0x80
+
+/* TW: *Never* change the order of the following enum */
+typedef enum _SIS_CHIP_TYPE {
+	SIS_VGALegacy = 0,
+	SIS_300,
+	SIS_630,
+	SIS_540,
+	SIS_730, 
+	SIS_315H,
+	SIS_315,
+	SIS_315PRO,
+	SIS_550,
+	SIS_650,
+	SIS_740,
+	SIS_330,
+	MAX_SIS_CHIP
+} SIS_CHIP_TYPE;
+
+typedef enum _VGA_ENGINE {
+	UNKNOWN_VGA = 0,
+	SIS_300_VGA,
+	SIS_315_VGA,
+} VGA_ENGINE;
+
+typedef enum _TVTYPE {
+	TVMODE_NTSC = 0,
+	TVMODE_PAL,
+	TVMODE_HIVISION,
+	TVMODE_TOTAL
+} SIS_TV_TYPE;
+
+typedef enum _TVPLUGTYPE {
+	TVPLUG_Legacy = 0,
+	TVPLUG_COMPOSITE,
+	TVPLUG_SVIDEO,
+	TVPLUG_SCART,
+	TVPLUG_TOTAL
+} SIS_TV_PLUG;
+
+struct sis_memreq {
+	unsigned long offset;
+	unsigned long size;
+};
+
+struct mode_info {
+	int    bpp;
+	int    xres;
+	int    yres;
+	int    v_xres;
+	int    v_yres;
+	int    org_x;
+	int    org_y;
+	unsigned int  vrate;
+};
+
+struct ap_data {
+	struct mode_info minfo;
+	unsigned long iobase;
+	unsigned int  mem_size;
+	unsigned long disp_state;    	
+	SIS_CHIP_TYPE chip;
+	unsigned char hasVB;
+	SIS_TV_TYPE TV_type;
+	SIS_TV_PLUG TV_plug;
+	unsigned long version;
+	char reserved[256];
+};
+
+struct video_info {
+	int           chip_id;
+	unsigned int  video_size;
+	unsigned long video_base;
+	char  *       video_vbase;
+	unsigned long mmio_base;
+	char  *       mmio_vbase;
+	unsigned long vga_base;
+	unsigned long mtrr;
+	unsigned long heapstart;
+
+	int    video_bpp;
+	int    video_cmap_len;
+	int    video_width;
+	int    video_height;
+	int    video_vwidth;
+	int    video_vheight;
+	int    org_x;
+	int    org_y;
+	int    video_linelength;
+	unsigned int refresh_rate;
+
+	unsigned long disp_state;
+	unsigned char hasVB;
+	unsigned char TV_type;
+	unsigned char TV_plug;
+
+	SIS_CHIP_TYPE chip;
+	unsigned char revision_id;
+
+        unsigned short DstColor;		/* TW: For 2d acceleration */
+	unsigned long  SiS310_AccelDepth;
+	unsigned long  CommandReg;
+
+	spinlock_t     lockaccel;
+
+        unsigned int   pcibus;
+	unsigned int   pcislot;
+	unsigned int   pcifunc;
+
+	int 	       accel;
+
+	unsigned short subsysvendor;
+	unsigned short subsysdevice;
+
+	char reserved[236];
+};
+
+
+/* TW: Addtional IOCTL for communication sisfb <> X driver                 */
+/*     If changing this, vgatypes.h must also be changed (for X driver)    */
+
+/* TW: ioctl for identifying and giving some info (esp. memory heap start) */
+#define SISFB_GET_INFO	  	_IOR('n',0xF8,sizeof(__u32))
+
+#define SISFB_GET_VBRSTATUS  	_IOR('n',0xF9,sizeof(__u32))
+
+/* TW: Structure argument for SISFB_GET_INFO ioctl  */
+typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
+
+struct _SISFB_INFO {
+	unsigned long sisfb_id;         /* for identifying sisfb */
+#ifndef SISFB_ID
+#define SISFB_ID	  0x53495346    /* Identify myself with 'SISF' */
+#endif
+ 	int    chip_id;			/* PCI ID of detected chip */
+	int    memory;			/* video memory in KB which sisfb manages */
+	int    heapstart;               /* heap start (= sisfb "mem" argument) in KB */
+	unsigned char fbvidmode;	/* current sisfb mode */
+	
+	unsigned char sisfb_version;
+	unsigned char sisfb_revision;
+	unsigned char sisfb_patchlevel;
+
+	unsigned char sisfb_caps;	/* Sisfb capabilities */
+
+	int    sisfb_tqlen;		/* turbo queue length (in KB) */
+
+	unsigned int sisfb_pcibus;      /* The card's PCI ID */
+	unsigned int sisfb_pcislot;
+	unsigned int sisfb_pcifunc;
+
+	unsigned char sisfb_lcdpdc;	/* PanelDelayCompensation */
+	
+	unsigned char sisfb_lcda;	/* Detected status of LCDA for low res/text modes */
+
+	char reserved[235]; 		/* for future use */
+};
+
+#ifdef __KERNEL__
+extern struct video_info ivideo;
+
+extern void sis_malloc(struct sis_memreq *req);
+extern void sis_free(unsigned long base);
+extern void sis_dispinfo(struct ap_data *rec);
+#endif
+#endif
diff -Nru a/include/video/sstfb.h b/include/video/sstfb.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/sstfb.h	Wed Feb 12 11:09:27 2003
@@ -0,0 +1,355 @@
+/*
+ * linux/drivers/video/sstfb.h -- voodoo graphics frame buffer
+ *
+ *     Copyright (c) 2000,2001 Ghozlane Toumi <gtoumi@messel.emse.fr>
+ *
+ *     Created 28 Aug 2001 by Ghozlane Toumi
+ */
+
+
+#ifndef _SSTFB_H_
+#define _SSTFB_H_
+
+/*
+ *
+ *  Debug Stuff
+ *
+ */
+
+#ifdef SST_DEBUG
+#  define dprintk(X...)		printk("sstfb: " X)
+#else
+#  define dprintk(X...)
+#  undef SST_DEBUG_REG
+#  undef SST_DEBUG_FUNC
+#  undef SST_DEBUG_VAR
+#endif
+
+#if (SST_DEBUG_REG > 0)
+#  define r_dprintk(X...)	dprintk(X)
+#else
+#  define r_dprintk(X...)
+#endif
+#if (SST_DEBUG_REG > 1)
+#  define r_ddprintk(X...)	dprintk(" " X)
+#else
+#  define r_ddprintk(X...)
+#endif
+
+#if (SST_DEBUG_FUNC > 0)
+#  define f_dprintk(X...)	dprintk(X)
+#else
+#  define f_dprintk(X...)
+#endif
+#if (SST_DEBUG_FUNC > 1)
+#  define f_ddprintk(X...)	dprintk(" " X)
+#else
+#  define f_ddprintk(X...)
+#endif
+#if (SST_DEBUG_FUNC > 2)
+#  define f_dddprintk(X...)	dprintk(" " X)
+#else
+#  define f_dddprintk(X...)
+#endif
+
+#if (SST_DEBUG_VAR > 0)
+#  define v_dprintk(X...)	dprintk(X)
+#  define print_var(V, X...)	\
+   {				\
+     dprintk(X);		\
+     printk(" :\n");		\
+     sst_dbg_print_var(V);	\
+   }
+#else
+#  define v_dprintk(X...)
+#  define print_var(X,Y...)
+#endif
+
+#define eprintk(X...)	printk(KERN_ERR "sstfb: " X)
+#define iprintk(X...)	printk(KERN_INFO "sstfb: " X)
+#define wprintk(X...)	printk(KERN_WARNING "sstfb: " X)
+
+#define BIT(x)		(1ul<<(x))
+#define POW2(x)		(1ul<<(x))
+
+#ifndef ABS
+# define ABS(x)		(((x)<0)?-(x):(x))
+#endif
+
+/*
+ *
+ *  Const
+ *
+ */
+
+/* pci stuff */
+#define PCI_INIT_ENABLE		0x40
+#  define PCI_EN_INIT_WR	  BIT(0)
+#  define PCI_EN_FIFO_WR	  BIT(1)
+#  define PCI_REMAP_DAC		  BIT(2)
+#define PCI_VCLK_ENABLE		0xc0	/* enable video */
+#define PCI_VCLK_DISABLE	0xe0
+
+/* register offsets from memBaseAddr */
+#define STATUS			0x0000
+#  define STATUS_FBI_BUSY	  BIT(7)
+#define FBZMODE			0x0110
+#  define EN_CLIPPING		  BIT(0)	/* enable clipping */
+#  define EN_RGB_WRITE		  BIT(9)	/* enable writes to rgb area */
+#  define EN_ALPHA_WRITE	  BIT(10)
+#  define ENGINE_INVERT_Y	  BIT(17)	/* invert Y origin (pipe) */
+#define LFBMODE			0x0114
+#  define LFB_565		  0		/* bits 3:0 .16 bits RGB */
+#  define LFB_888		  4		/* 24 bits RGB */
+#  define LFB_8888		  5		/* 32 bits ARGB */
+#  define WR_BUFF_FRONT		  0		/* write buf select (front) */
+#  define WR_BUFF_BACK		  (1 << 4)	/* back */
+#  define RD_BUFF_FRONT		  0		/* read buff select (front) */
+#  define RD_BUFF_BACK		  (1 << 6)	/* back */
+#  define EN_PXL_PIPELINE	  BIT(8)	/* pixel pipeline (clip..)*/
+#  define LFB_WORD_SWIZZLE_WR	  BIT(11)	/* enable write-wordswap (big-endian) */
+#  define LFB_BYTE_SWIZZLE_WR	  BIT(12)	/* enable write-byteswap (big-endian) */
+#  define LFB_INVERT_Y		  BIT(13)	/* invert Y origin (LFB) */
+#  define LFB_WORD_SWIZZLE_RD	  BIT(15)	/* enable read-wordswap (big-endian) */
+#  define LFB_BYTE_SWIZZLE_RD	  BIT(16)	/* enable read-byteswap (big-endian) */
+#define CLIP_LEFT_RIGHT		0x0118
+#define CLIP_LOWY_HIGHY		0x011c
+#define NOPCMD			0x0120
+#define FASTFILLCMD		0x0124
+#define SWAPBUFFCMD		0x0128
+#define FBIINIT4		0x0200		/* misc controls */
+#  define FAST_PCI_READS	  0		/* 1 waitstate */
+#  define SLOW_PCI_READS	  BIT(0)	/* 2 ws */
+#  define LFB_READ_AHEAD	  BIT(1)
+#define BACKPORCH		0x0208
+#define VIDEODIMENSIONS		0x020c
+#define FBIINIT0		0x0210		/* misc+fifo  controls */
+#  define EN_VGA_PASSTHROUGH	  BIT(0)
+#  define FBI_RESET		  BIT(1)
+#  define FIFO_RESET		  BIT(2)
+#define FBIINIT1		0x0214		/* PCI + video controls */
+#  define VIDEO_MASK		  0x8080010f	/* masks video related bits V1+V2*/
+#  define FAST_PCI_WRITES	  0		/* 0 ws */
+#  define SLOW_PCI_WRITES	  BIT(1)	/* 1 ws */
+#  define EN_LFB_READ		  BIT(3)
+#  define TILES_IN_X_SHIFT	  4
+#  define VIDEO_RESET		  BIT(8)
+#  define EN_BLANKING		  BIT(12)
+#  define EN_DATA_OE		  BIT(13)
+#  define EN_BLANK_OE		  BIT(14)
+#  define EN_HVSYNC_OE		  BIT(15)
+#  define EN_DCLK_OE		  BIT(16)
+#  define SEL_INPUT_VCLK_2X	  0		/* bit 17 */
+#  define SEL_INPUT_VCLK_SLAVE	  BIT(17)
+#  define SEL_SOURCE_VCLK_SLAVE	  0		/* bits 21:20 */
+#  define SEL_SOURCE_VCLK_2X_DIV2 (0x01 << 20)
+#  define SEL_SOURCE_VCLK_2X_SEL  (0x02 << 20)
+#  define EN_24BPP		  BIT(22)
+#  define TILES_IN_X_MSB_SHIFT	  24		/* v2 */
+#  define VCLK_2X_SEL_DEL_SHIFT	  27		/* vclk out delay 0,4,6,8ns */
+#  define VCLK_DEL_SHIFT	  29		/* vclk in delay */
+#define FBIINIT2		0x0218		/* Dram controls */
+#  define EN_FAST_RAS_READ	  BIT(5)
+#  define EN_DRAM_OE		  BIT(6)
+#  define EN_FAST_RD_AHEAD_WR	  BIT(7)
+#  define VIDEO_OFFSET_SHIFT	  11		/* unit: #rows tile 64x16/2 */
+#  define SWAP_DACVSYNC		  0
+#  define SWAP_DACDATA0		  (1 << 9)
+#  define SWAP_FIFO_STALL	  (2 << 9)
+#  define EN_RD_AHEAD_FIFO	  BIT(21)
+#  define EN_DRAM_REFRESH	  BIT(22)
+#  define DRAM_REFRESH_16	  (0x30 << 23)	/* dram 16 ms */
+#define DAC_READ		FBIINIT2	/* in remap mode */
+#define FBIINIT3		0x021c		/* fbi controls */
+#  define DISABLE_TEXTURE	  BIT(6)
+#  define Y_SWAP_ORIGIN_SHIFT	  22		/* Y swap substraction value */
+#define HSYNC			0x0220
+#define VSYNC			0x0224
+#define DAC_DATA		0x022c
+#  define DAC_READ_CMD		  BIT(11)	/* set read dacreg mode */
+#define FBIINIT5		0x0244		/* v2 specific */
+#  define FBIINIT5_MASK		  0xfa40ffff    /* mask video bits*/
+#  define HDOUBLESCAN		  BIT(20)
+#  define VDOUBLESCAN		  BIT(21)
+#  define HSYNC_HIGH 		  BIT(23)
+#  define VSYNC_HIGH 		  BIT(24)
+#  define INTERLACE		  BIT(26)
+#define FBIINIT6		0x0248		/* v2 specific */
+#  define TILES_IN_X_LSB_SHIFT	  30		/* v2 */
+#define FBIINIT7		0x024c		/* v2 specific */
+
+#define BLTSRCBASEADDR		0x02c0	/* BitBLT Source base address */
+#define BLTDSTBASEADDR		0x02c4	/* BitBLT Destination base address */
+#define BLTXYSTRIDES		0x02c8	/* BitBLT Source and Destination strides */
+#define BLTSRCCHROMARANGE	0x02cc	/* BitBLT Source Chroma key range */
+#define BLTDSTCHROMARANGE	0x02d0	/* BitBLT Destination Chroma key range */
+#define BLTCLIPX		0x02d4	/* BitBLT Min/Max X clip values */
+#define BLTCLIPY		0x02d8	/* BitBLT Min/Max Y clip values */
+#define BLTSRCXY		0x02e0	/* BitBLT Source starting XY coordinates */
+#define BLTDSTXY		0x02e4	/* BitBLT Destination starting XY coordinates */
+#define BLTSIZE			0x02e8	/* BitBLT width and height */
+#define BLTROP			0x02ec	/* BitBLT Raster operations */
+#  define BLTROP_COPY		  0x0cccc
+#  define BLTROP_INVERT		  0x05555
+#  define BLTROP_XOR		  0x06666
+#define BLTCOLOR		0x02f0	/* BitBLT and foreground background colors */
+#define BLTCOMMAND		0x02f8	/* BitBLT command mode (v2 specific) */
+# define BLT_SCR2SCR_BITBLT	  0	  /* Screen-to-Screen BitBLT */
+# define BLT_CPU2SCR_BITBLT	  1	  /* CPU-to-screen BitBLT */
+# define BLT_RECFILL_BITBLT	  2	  /* BitBLT Rectangle Fill */
+# define BLT_16BPP_FMT		  2	  /* 16 BPP (5-6-5 RGB) */
+#define BLTDATA			0x02fc	/* BitBLT data for CPU-to-Screen BitBLTs */
+#  define LAUNCH_BITBLT		  BIT(31) /* Launch BitBLT in BltCommand, bltDstXY or bltSize */
+
+/* Dac Registers */
+#define DACREG_WMA		0x0	/* pixel write mode address */
+#define DACREG_LUT		0x01	/* color value */
+#define DACREG_RMR		0x02	/* pixel mask */
+#define DACREG_RMA		0x03	/* pixel read mode address */
+/*Dac registers in indexed mode (TI, ATT dacs) */
+#define DACREG_ADDR_I		DACREG_WMA
+#define DACREG_DATA_I		DACREG_RMR
+#define DACREG_RMR_I		0x00
+#define DACREG_CR0_I		0x01
+#  define DACREG_CR0_EN_INDEXED	  BIT(0)	/* enable indexec mode */
+#  define DACREG_CR0_8BIT	  BIT(1)	/* set dac to 8 bits/read */
+#  define DACREG_CR0_PWDOWN	  BIT(3)	/* powerdown dac */
+#  define DACREG_CR0_16BPP	  0x30		/* mode 3 */
+#  define DACREG_CR0_24BPP	  0x50		/* mode 5 */
+#define	DACREG_CR1_I		0x05
+#define DACREG_CC_I		0x06
+#  define DACREG_CC_CLKA	  BIT(7)	/* clk A controled by regs */
+#  define DACREG_CC_CLKA_C	  (2<<4)	/* clk A uses reg C */
+#  define DACREG_CC_CLKB	  BIT(3)	/* clk B controled by regs */
+#  define DACREG_CC_CLKB_D	  3		/* clkB uses reg D */
+#define DACREG_AC0_I		0x48		/* clock A reg C */
+#define DACREG_AC1_I		0x49
+#define DACREG_BD0_I		0x6c		/* clock B reg D */
+#define DACREG_BD1_I		0x6d
+
+/* identification constants */
+#define DACREG_MIR_TI		0x97
+#define DACREG_DIR_TI		0x09
+#define DACREG_MIR_ATT		0x84
+#define DACREG_DIR_ATT		0x09
+/* ics dac specific registers */
+#define DACREG_ICS_PLLWMA	0x04	/* PLL write mode address */
+#define DACREG_ICS_PLLDATA	0x05	/* PLL data /parameter */
+#define DACREG_ICS_CMD		0x06	/* command */
+#  define DACREG_ICS_CMD_16BPP	  0x50	/* ics color mode 6 (16bpp bypass)*/
+#  define DACREG_ICS_CMD_24BPP	  0x70	/* ics color mode 7 (24bpp bypass)*/
+#  define DACREG_ICS_CMD_PWDOWN BIT(0)	/* powerdown dac */
+#define DACREG_ICS_PLLRMA	0x07	/* PLL read mode address */
+/*
+ * pll parameter register:
+ * indexed : write addr to PLLWMA, write data in PLLDATA.
+ * for reads use PLLRMA .
+ * 8 freq registers (0-7) for video clock (CLK0)
+ * 2 freq registers (a-b) for graphic clock (CLK1)
+ */
+#define DACREG_ICS_PLL_CLK0_1_INI 0x55	/* initial pll M value for freq f1  */
+#define DACREG_ICS_PLL_CLK0_7_INI 0x71	/* f7 */
+#define DACREG_ICS_PLL_CLK1_B_INI 0x79	/* fb */
+#define DACREG_ICS_PLL_CTRL	0x0e
+#  define DACREG_ICS_CLK0	  BIT(5)
+#  define DACREG_ICS_CLK0_0	  0
+#  define DACREG_ICS_CLK1_A	  0	/* bit4 */
+
+/* sst default init registers */
+#define FBIINIT0_DEFAULT EN_VGA_PASSTHROUGH
+
+#define FBIINIT1_DEFAULT 	\
+	(			\
+	  FAST_PCI_WRITES	\
+/*	  SLOW_PCI_WRITES*/	\
+	| VIDEO_RESET		\
+	| 10 << TILES_IN_X_SHIFT\
+	| SEL_SOURCE_VCLK_2X_SEL\
+	| EN_LFB_READ		\
+	)
+
+#define FBIINIT2_DEFAULT	\
+	(			\
+	 SWAP_DACVSYNC		\
+	| EN_DRAM_OE		\
+	| DRAM_REFRESH_16	\
+	| EN_DRAM_REFRESH	\
+	| EN_FAST_RAS_READ	\
+	| EN_RD_AHEAD_FIFO	\
+	| EN_FAST_RD_AHEAD_WR	\
+	)
+
+#define FBIINIT3_DEFAULT 	\
+	( DISABLE_TEXTURE )
+
+#define FBIINIT4_DEFAULT	\
+	(			\
+	  FAST_PCI_READS	\
+/*	  SLOW_PCI_READS*/	\
+	| LFB_READ_AHEAD	\
+	)
+/* Careful with this one : writing back the data just read will trash the DAC
+   reading some fields give logic value on pins, but setting this field will
+   set the source signal driving the pin. conclusion : just use the default
+   as a base before writing back .
+*/
+#define FBIINIT6_DEFAULT	(0x0)
+
+/*
+ *
+ * Misc Const
+ *
+ */
+
+/* used to know witch clock to set */
+enum {
+	VID_CLOCK=0,
+	GFX_CLOCK=1,
+};
+
+/* freq max */
+#define DAC_FREF	14318	/* DAC reference freq (Khz) */
+#define VCO_MAX		260000
+
+/*
+ *  driver structs
+ */
+
+struct pll_timing {
+	unsigned int m;
+	unsigned int n;
+	unsigned int p;
+};
+
+struct dac_switch {
+	char * name;
+	int (*detect) (struct fb_info *info);
+	int (*set_pll) (struct fb_info *info, const struct pll_timing *t, const int clock);
+	void (*set_vidmod) (struct fb_info *info, const int bpp);
+};
+
+struct sst_spec {
+	char * name;
+	int default_gfx_clock;	/* 50000 for voodoo1, 75000 for voodoo2 */
+	int max_gfxclk; 	/* ! in Mhz ie 60 for voodoo 1 */
+};
+
+struct sstfb_par {
+	unsigned int yDim;
+	unsigned int hSyncOn;	/* hsync_len */
+	unsigned int hSyncOff;	/* left_margin + xres + right_margin */
+	unsigned int hBackPorch;/* left_margin */
+	unsigned int vSyncOn;
+	unsigned int vSyncOff;
+	unsigned int vBackPorch;
+	struct pll_timing pll;
+	unsigned int tiles_in_X;/* num of tiles in X res */
+	unsigned long mmio_vbase;
+	struct dac_switch 	dac_sw;	/* dac specific functions */
+	struct pci_dev		*dev;
+	int	type;
+	u8	revision;
+	int	gfx_clock;	/* status */
+};
+
+#endif /* _SSTFB_H_ */
diff -Nru a/include/video/vga.h b/include/video/vga.h
--- a/include/video/vga.h	Fri Dec  6 12:36:21 2002
+++ b/include/video/vga.h	Mon Feb 24 13:47:01 2003
@@ -28,10 +28,10 @@
  * Ugh, we don't have PCI space, so map readb() and friends to use Zorro space
  * for MMIO accesses. This should make clgenfb work again on Amiga
  */
-#define inb(port)	0
-#define inw(port)	0
-#define outb(port, val)	do { } while (0)
-#define outw(port, val)	do { } while (0)
+#define inb_p(port)	0
+#define inw_p(port)	0
+#define outb_p(port, val)	do { } while (0)
+#define outw(port, val)		do { } while (0)
 #define readb		z_readb
 #define writeb		z_writeb
 #define writew		z_writew
@@ -197,9 +197,9 @@
 
 struct vgastate {
 	caddr_t vgabase;	/* mmio base, if supported 		   */
-	__u32 flags;		/* what state[s] to save (see VGA_SAVE_*)  */
-	__u32 membase;		/* VGA window base, 0 for default - 0xA000 */
+	unsigned long membase;	/* VGA window base, 0 for default - 0xA000 */
 	__u32 memsize;		/* VGA window size, 0 for default 64K	   */
+	__u32 flags;		/* what state[s] to save (see VGA_SAVE_*)  */
 	__u32 depth;		/* current fb depth, not important	   */
 	__u32 num_attr;		/* number of att registers, 0 for default  */
 	__u32 num_crtc;		/* number of crt registers, 0 for default  */
@@ -217,18 +217,18 @@
  
 static inline unsigned char vga_io_r (unsigned short port)
 {
-	return inb (port);
+	return inb_p(port);
 }
 
 static inline void vga_io_w (unsigned short port, unsigned char val)
 {
-	outb (val, port);
+	outb_p(val, port);
 }
 
 static inline void vga_io_w_fast (unsigned short port, unsigned char reg,
 				  unsigned char val)
 {
-	outw (VGA_OUT16VAL (val, reg), port);
+	outw(VGA_OUT16VAL (val, reg), port);
 }
 
 static inline unsigned char vga_mm_r (caddr_t regbase, unsigned short port)
@@ -379,8 +379,6 @@
 #endif /* VGA_OUTW_WRITE */
 }
 
-
-
 /*
  * VGA graphics controller register read/write
  */
@@ -473,8 +471,5 @@
         vga_mm_w (regbase, VGA_ATT_IW, reg);
         vga_mm_w (regbase, VGA_ATT_W, val);
 }
-
-
-
 
 #endif /* __linux_video_vga_h__ */
diff -Nru a/init/do_mounts.c b/init/do_mounts.c
--- a/init/do_mounts.c	Thu Mar  6 16:27:25 2003
+++ b/init/do_mounts.c	Sat Mar 22 22:14:13 2003
@@ -245,6 +245,7 @@
 {
 	char *fs_names = __getname();
 	char *p;
+	char b[BDEVNAME_SIZE];
 
 	get_fs_names(fs_names);
 retry:
@@ -263,12 +264,13 @@
 		 * Allow the user to distinguish between failed open
 		 * and bad superblock on root device.
 		 */
+		__bdevname(ROOT_DEV, b);
 		printk("VFS: Cannot open root device \"%s\" or %s\n",
-			root_device_name, __bdevname(ROOT_DEV));
+				root_device_name, b);
 		printk("Please append a correct \"root=\" boot option\n");
-		panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV));
+		panic("VFS: Unable to mount root fs on %s", b);
 	}
-	panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV));
+	panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b));
 out:
 	putname(fs_names);
 }
diff -Nru a/kernel/cpufreq.c b/kernel/cpufreq.c
--- a/kernel/cpufreq.c	Sat Mar  8 01:39:17 2003
+++ b/kernel/cpufreq.c	Wed Mar 19 11:22:30 2003
@@ -46,7 +46,7 @@
 static DECLARE_RWSEM		(cpufreq_notifier_rwsem);
 
 
-LIST_HEAD(cpufreq_governor_list);
+static LIST_HEAD(cpufreq_governor_list);
 static DECLARE_MUTEX		(cpufreq_governor_sem);
 
 static struct device_interface cpufreq_interface;
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c	Mon Mar 10 22:34:31 2003
+++ b/kernel/fork.c	Sat Mar 22 22:14:57 2003
@@ -736,7 +736,7 @@
 	p->flags = new_flags;
 }
 
-asmlinkage int sys_set_tid_address(int *tidptr)
+asmlinkage long sys_set_tid_address(int *tidptr)
 {
 	current->clear_child_tid = tidptr;
 
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Wed Mar 12 11:10:29 2003
+++ b/kernel/ksyms.c	Fri Mar 21 20:05:21 2003
@@ -175,6 +175,7 @@
 EXPORT_SYMBOL(d_path);
 EXPORT_SYMBOL(mark_buffer_dirty);
 EXPORT_SYMBOL(end_buffer_io_sync);
+EXPORT_SYMBOL(end_buffer_async_write);
 EXPORT_SYMBOL(__mark_inode_dirty);
 EXPORT_SYMBOL(get_empty_filp);
 EXPORT_SYMBOL(open_private_file);
@@ -202,8 +203,6 @@
 EXPORT_SYMBOL(set_blocksize);
 EXPORT_SYMBOL(sb_set_blocksize);
 EXPORT_SYMBOL(sb_min_blocksize);
-EXPORT_SYMBOL(cdget);
-EXPORT_SYMBOL(cdput);
 EXPORT_SYMBOL(bdget);
 EXPORT_SYMBOL(bdput);
 EXPORT_SYMBOL(bd_claim);
diff -Nru a/kernel/posix-timers.c b/kernel/posix-timers.c
--- a/kernel/posix-timers.c	Sun Mar  9 18:48:02 2003
+++ b/kernel/posix-timers.c	Sun Mar 23 16:00:00 2003
@@ -1,15 +1,14 @@
 /*
  * linux/kernel/posix_timers.c
  *
- * 
+ *
  * 2002-10-15  Posix Clocks & timers by George Anzinger
  *			     Copyright (C) 2002 by MontaVista Software.
  */
 
-/* These are all the functions necessary to implement 
+/* These are all the functions necessary to implement
  * POSIX clocks & timers
  */
-
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
@@ -23,6 +22,7 @@
 #include <linux/compiler.h>
 #include <linux/idr.h>
 #include <linux/posix-timers.h>
+#include <linux/wait.h>
 
 #ifndef div_long_long_rem
 #include <asm/div64.h>
@@ -32,32 +32,32 @@
 		       *remainder = do_div(result,divisor); \
 		       result; })
 
-#endif				/* ifndef div_long_long_rem */
+#endif
 
 /*
  * Management arrays for POSIX timers.	 Timers are kept in slab memory
  * Timer ids are allocated by an external routine that keeps track of the
  * id and the timer.  The external interface is:
  *
- *void *idr_find(struct idr *idp, int id);           to find timer_id <id>
- *int idr_get_new(struct idr *idp, void *ptr);       to get a new id and 
- *                                                  related it to <ptr>
- *void idr_remove(struct idr *idp, int id);          to release <id>
- *void idr_init(struct idr *idp);                    to initialize <idp>
- *                                                  which we supply.
+ * void *idr_find(struct idr *idp, int id);           to find timer_id <id>
+ * int idr_get_new(struct idr *idp, void *ptr);       to get a new id and
+ *                                                    related it to <ptr>
+ * void idr_remove(struct idr *idp, int id);          to release <id>
+ * void idr_init(struct idr *idp);                    to initialize <idp>
+ *                                                    which we supply.
  * The idr_get_new *may* call slab for more memory so it must not be
  * called under a spin lock.  Likewise idr_remore may release memory
  * (but it may be ok to do this under a lock...).
  * idr_find is just a memory look up and is quite fast.  A zero return
  * indicates that the requested id does not exist.
-
  */
+
 /*
-   * Lets keep our timers in a slab cache :-)
+ * Lets keep our timers in a slab cache :-)
  */
 static kmem_cache_t *posix_timers_cache;
-struct idr posix_timers_id;
-spinlock_t idr_lock = SPIN_LOCK_UNLOCKED;
+static struct idr posix_timers_id;
+static spinlock_t idr_lock = SPIN_LOCK_UNLOCKED;
 
 /*
  * Just because the timer is not in the timer list does NOT mean it is
@@ -65,24 +65,28 @@
  */
 #define TIMER_INACTIVE 1
 #define TIMER_RETRY 1
+
 #ifdef CONFIG_SMP
-#define timer_active(tmr) (tmr->it_timer.entry.prev != (void *)TIMER_INACTIVE)
-#define set_timer_inactive(tmr) tmr->it_timer.entry.prev = (void *)TIMER_INACTIVE
+# define timer_active(tmr) \
+		((tmr)->it_timer.entry.prev != (void *)TIMER_INACTIVE)
+# define set_timer_inactive(tmr) \
+		do { \
+			(tmr)->it_timer.entry.prev = (void *)TIMER_INACTIVE; \
+		} while (0)
 #else
-#define timer_active(tmr) BARFY	// error to use outside of SMP
-#define set_timer_inactive(tmr)
+# define timer_active(tmr) BARFY	// error to use outside of SMP
+# define set_timer_inactive(tmr) do { } while (0)
 #endif
 /*
  * The timer ID is turned into a timer address by idr_find().
  * Verifying a valid ID consists of:
- * 
+ *
  * a) checking that idr_find() returns other than zero.
  * b) checking that the timer id matches the one in the timer itself.
  * c) that the timer owner is in the callers thread group.
  */
 
-
-/* 
+/*
  * CLOCKs: The POSIX standard calls for a couple of clocks and allows us
  *	    to implement others.  This structure defines the various
  *	    clocks and allows the possibility of adding others.	 We
@@ -90,7 +94,7 @@
  *	    the "arch" code to add at least one clock that is high
  *	    resolution.	 Here we define the standard CLOCK_REALTIME as a
  *	    1/HZ resolution clock.
-
+ *
  * CPUTIME & THREAD_CPUTIME: We are not, at this time, definding these
  *	    two clocks (and the other process related clocks (Std
  *	    1003.1d-1999).  The way these should be supported, we think,
@@ -98,7 +102,7 @@
  *	    pinned to the executing process and to use -pid for clocks
  *	    pinned to particular pids.	Calls which supported these clock
  *	    ids would split early in the function.
- 
+ *
  * RESOLUTION: Clock resolution is used to round up timer and interval
  *	    times, NOT to report clock times, which are reported with as
  *	    much resolution as the system can muster.  In some cases this
@@ -106,7 +110,7 @@
  *	    may not be quantifiable until run time, and only then is the
  *	    necessary code is written.	The standard says we should say
  *	    something about this issue in the documentation...
-
+ *
  * FUNCTIONS: The CLOCKs structure defines possible functions to handle
  *	    various clock functions.  For clocks that use the standard
  *	    system timer code these entries should be NULL.  This will
@@ -116,7 +120,7 @@
  *	    ENOSYS.  The standard POSIX timer management code assumes the
  *	    following: 1.) The k_itimer struct (sched.h) is used for the
  *	    timer.  2.) The list, it_lock, it_clock, it_id and it_process
- *	    fields are not modified by timer code. 
+ *	    fields are not modified by timer code.
  *
  *          At this time all functions EXCEPT clock_nanosleep can be
  *          redirected by the CLOCKS structure.  Clock_nanosleep is in
@@ -130,39 +134,31 @@
  *	    which we beg off on and pass to do_sys_settimeofday().
  */
 
-struct k_clock posix_clocks[MAX_CLOCKS];
+static struct k_clock posix_clocks[MAX_CLOCKS];
 
-#define if_clock_do(clock_fun, alt_fun,parms)	(! clock_fun)? alt_fun parms :\
-							      clock_fun parms
+#define if_clock_do(clock_fun,alt_fun,parms) \
+		(!clock_fun) ? alt_fun parms : clock_fun parms
 
-#define p_timer_get( clock,a,b) if_clock_do((clock)->timer_get, \
-					     do_timer_gettime,	 \
-					     (a,b))
-
-#define p_nsleep( clock,a,b,c) if_clock_do((clock)->nsleep,   \
-					    do_nsleep,	       \
-					    (a,b,c))
-
-#define p_timer_del( clock,a) if_clock_do((clock)->timer_del, \
-					   do_timer_delete,    \
-					   (a))
+#define p_timer_get(clock,a,b) \
+	       	if_clock_do((clock)->timer_get,do_timer_gettime, (a,b))
 
-void register_posix_clock(int clock_id, struct k_clock *new_clock);
+#define p_nsleep(clock,a,b,c) \
+		if_clock_do((clock)->nsleep, do_nsleep, (a,b,c))
 
-static int do_posix_gettime(struct k_clock *clock, struct timespec *tp);
+#define p_timer_del(clock,a) \
+		if_clock_do((clock)->timer_del, do_timer_delete, (a))
 
+void register_posix_clock(int clock_id, struct k_clock *new_clock);
+static int do_posix_gettime(struct k_clock *clock, struct timespec *tp);
 int do_posix_clock_monotonic_gettime(struct timespec *tp);
-
 int do_posix_clock_monotonic_settime(struct timespec *tp);
 static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags);
 static inline void unlock_timer(struct k_itimer *timr, unsigned long flags);
 
-/* 
+/*
  * Initialize everything, well, just everything in Posix clocks/timers ;)
  */
-
-static __init int
-init_posix_timers(void)
+static __init int init_posix_timers(void)
 {
 	struct k_clock clock_realtime = {.res = NSEC_PER_SEC / HZ };
 	struct k_clock clock_monotonic = {.res = NSEC_PER_SEC / HZ,
@@ -174,16 +170,15 @@
 	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
 
 	posix_timers_cache = kmem_cache_create("posix_timers_cache",
-					       sizeof (struct k_itimer), 0, 0,
-					       0, 0);
+					sizeof (struct k_itimer), 0, 0, 0, 0);
 	idr_init(&posix_timers_id);
+
 	return 0;
 }
 
 __initcall(init_posix_timers);
 
-static inline int
-tstojiffie(struct timespec *tp, int res, unsigned long *jiff)
+static void tstojiffie(struct timespec *tp, int res, u64 *jiff)
 {
 	unsigned long sec = tp->tv_sec;
 	long nsec = tp->tv_nsec + res - 1;
@@ -201,47 +196,42 @@
 	 * unsigned int/2).  Times beyond this will be truncated back to
 	 * this value.   This is done in the absolute adjustment code,
 	 * below.  Here it is enough to just discard the high order
-	 * bits.  
+	 * bits.
 	 */
-	*jiff = HZ * sec;
+	*jiff = (u64)sec * HZ;
 	/*
-	 * Do the res thing. (Don't forget the add in the declaration of nsec) 
+	 * Do the res thing. (Don't forget the add in the declaration of nsec)
 	 */
 	nsec -= nsec % res;
 	/*
 	 * Split to jiffie and sub jiffie
 	 */
 	*jiff += nsec / (NSEC_PER_SEC / HZ);
-	/*
-	 * We trust that the optimizer will use the remainder from the 
-	 * above div in the following operation as long as they are close. 
-	 */
-	return 0;
 }
-static void
-tstotimer(struct itimerspec *time, struct k_itimer *timer)
+
+static void tstotimer(struct itimerspec *time, struct k_itimer *timer)
 {
+	u64 result;
 	int res = posix_clocks[timer->it_clock].res;
-	tstojiffie(&time->it_value, res, &timer->it_timer.expires);
-	tstojiffie(&time->it_interval, res, &timer->it_incr);
+
+	tstojiffie(&time->it_value, res, &result);
+	timer->it_timer.expires = (unsigned long)result;
+	tstojiffie(&time->it_interval, res, &result);
+	timer->it_incr = (unsigned long)result;
 }
 
-static void
-schedule_next_timer(struct k_itimer *timr)
+static void schedule_next_timer(struct k_itimer *timr)
 {
 	struct now_struct now;
 
 	/* Set up the timer for the next interval (if there is one) */
-	if (timr->it_incr == 0) {
-		{
-			set_timer_inactive(timr);
-			return;
-		}
+	if (!timr->it_incr) {
+		set_timer_inactive(timr);
+		return;
 	}
 	posix_get_now(&now);
-	while (posix_time_before(&timr->it_timer, &now)) {
+	while (posix_time_before(&timr->it_timer, &now))
 		posix_bump_timer(timr);
-	};
 	timr->it_overrun_last = timr->it_overrun;
 	timr->it_overrun = -1;
 	timr->it_requeue_pending = 0;
@@ -249,7 +239,6 @@
 }
 
 /*
-
  * This function is exported for use by the signal deliver code.  It is
  * called just prior to the info block being released and passes that
  * block to us.  It's function is to update the overrun entry AND to
@@ -259,12 +248,9 @@
  *
  * To protect aginst the timer going away while the interrupt is queued,
  * we require that the it_requeue_pending flag be set.
-
  */
-void
-do_schedule_next_timer(struct siginfo *info)
+void do_schedule_next_timer(struct siginfo *info)
 {
-
 	struct k_itimer *timr;
 	unsigned long flags;
 
@@ -275,13 +261,12 @@
 
 	schedule_next_timer(timr);
 	info->si_overrun = timr->it_overrun_last;
-      exit:
+exit:
 	if (timr)
 		unlock_timer(timr, flags);
 }
 
-/* 
-
+/*
  * Notify the task and set up the timer for the next expiration (if
  * applicable).  This function requires that the k_itimer structure
  * it_lock is taken.  This code will requeue the timer only if we get
@@ -289,11 +274,9 @@
  * indicating that the signal was either not queued or was queued
  * without an info block.  In this case, we will not get a call back to
  * do_schedule_next_timer() so we do it here.  This should be rare...
-
  */
 
-static void
-timer_notify_task(struct k_itimer *timr)
+static void timer_notify_task(struct k_itimer *timr)
 {
 	struct siginfo info;
 	int ret;
@@ -306,11 +289,11 @@
 	info.si_code = SI_TIMER;
 	info.si_tid = timr->it_id;
 	info.si_value = timr->it_sigev_value;
-	if (timr->it_incr == 0) {
+	if (!timr->it_incr)
 		set_timer_inactive(timr);
-	} else {
+	else
 		timr->it_requeue_pending = info.si_sys_private = 1;
-	}
+
 	ret = send_sig_info(info.si_signo, &info, timr->it_process);
 	switch (ret) {
 
@@ -325,11 +308,11 @@
 		 * signal was not sent because of sig_ignor or,
 		 * possibly no queue memory OR will be sent but,
 		 * we will not get a call back to restart it AND
-		 * it should be restarted. 
+		 * it should be restarted.
 		 */
 		schedule_next_timer(timr);
 	case 0:
-		/* 
+		/*
 		 * all's well new signal queued
 		 */
 		break;
@@ -337,14 +320,11 @@
 }
 
 /*
-
  * This function gets called when a POSIX.1b interval timer expires.  It
  * is used as a callback from the kernel internal timer.  The
  * run_timer_list code ALWAYS calls with interrutps on.
-
  */
-static void
-posix_timer_fn(unsigned long __data)
+static void posix_timer_fn(unsigned long __data)
 {
 	struct k_itimer *timr = (struct k_itimer *) __data;
 	unsigned long flags;
@@ -355,8 +335,8 @@
 }
 
 /*
- * For some reason mips/mips64 define the SIGEV constants plus 128.  
- * Here we define a mask to get rid of the common bits.	 The 
+ * For some reason mips/mips64 define the SIGEV constants plus 128.
+ * Here we define a mask to get rid of the common bits.	 The
  * optimizer should make this costless to all but mips.
  */
 #if (ARCH == mips) || (ARCH == mips64)
@@ -368,30 +348,26 @@
 #define MIPS_SIGEV (int)-1
 #endif
 
-static inline struct task_struct *
-good_sigevent(sigevent_t * event)
+static inline struct task_struct * good_sigevent(sigevent_t * event)
 {
 	struct task_struct *rtn = current;
 
-	if (event->sigev_notify & SIGEV_THREAD_ID & MIPS_SIGEV) {
-		if (!(rtn =
-		      find_task_by_pid(event->sigev_notify_thread_id)) ||
-		    rtn->tgid != current->tgid) {
-			return NULL;
-		}
-	}
-	if (event->sigev_notify & SIGEV_SIGNAL & MIPS_SIGEV) {
-		if ((unsigned) (event->sigev_signo > SIGRTMAX))
-			return NULL;
-	}
-	if (event->sigev_notify & ~(SIGEV_SIGNAL | SIGEV_THREAD_ID)) {
+	if ((event->sigev_notify & SIGEV_THREAD_ID & MIPS_SIGEV) &&
+		(!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) ||
+			rtn->tgid != current->tgid))
 		return NULL;
-	}
+
+	if ((event->sigev_notify & SIGEV_SIGNAL & MIPS_SIGEV) &&
+			((unsigned) (event->sigev_signo > SIGRTMAX)))
+		return NULL;
+
+	if (event->sigev_notify & ~(SIGEV_SIGNAL | SIGEV_THREAD_ID))
+		return NULL;
+
 	return rtn;
 }
 
-void
-register_posix_clock(int clock_id, struct k_clock *new_clock)
+void register_posix_clock(int clock_id, struct k_clock *new_clock)
 {
 	if ((unsigned) clock_id >= MAX_CLOCKS) {
 		printk("POSIX clock register failed for clock_id %d\n",
@@ -401,19 +377,18 @@
 	posix_clocks[clock_id] = *new_clock;
 }
 
-static struct k_itimer *
-alloc_posix_timer(void)
+static struct k_itimer * alloc_posix_timer(void)
 {
 	struct k_itimer *tmr;
 	tmr = kmem_cache_alloc(posix_timers_cache, GFP_KERNEL);
 	memset(tmr, 0, sizeof (struct k_itimer));
-	return (tmr);
+
+	return tmr;
 }
 
-static void
-release_posix_timer(struct k_itimer *tmr)
+static void release_posix_timer(struct k_itimer *tmr)
 {
-	if (tmr->it_id != -1){
+	if (tmr->it_id != -1) {
 		spin_lock_irq(&idr_lock);
 		idr_remove(&posix_timers_id, tmr->it_id);
 		spin_unlock_irq(&idr_lock);
@@ -423,7 +398,7 @@
 
 /* Create a POSIX.1b interval timer. */
 
-asmlinkage int
+asmlinkage long
 sys_timer_create(clockid_t which_clock,
 		 struct sigevent *timer_event_spec, timer_t * created_timer_id)
 {
@@ -434,28 +409,29 @@
 	sigevent_t event;
 
 	if ((unsigned) which_clock >= MAX_CLOCKS ||
-	    !posix_clocks[which_clock].res) return -EINVAL;
+				!posix_clocks[which_clock].res)
+		return -EINVAL;
 
 	new_timer = alloc_posix_timer();
-	if (unlikely (new_timer == NULL))
+	if (unlikely(!new_timer))
 		return -EAGAIN;
 
 	spin_lock_init(&new_timer->it_lock);
 	do {
-		if ( unlikely ( !idr_pre_get(&posix_timers_id))){
+		if (unlikely(!idr_pre_get(&posix_timers_id))) {
 			error = -EAGAIN;
 			new_timer_id = (timer_t)-1;
-			goto out;			
+			goto out;
 		}
 		spin_lock_irq(&idr_lock);
-		new_timer_id = (timer_t) idr_get_new(
-			&posix_timers_id, (void *) new_timer);
+		new_timer_id = (timer_t) idr_get_new(&posix_timers_id,
+							(void *) new_timer);
 		spin_unlock_irq(&idr_lock);
-	}while( unlikely (new_timer_id == -1));
+	} while (unlikely(new_timer_id == -1));
 
 	new_timer->it_id = new_timer_id;
 	/*
-	 * return the timer_id now.  The next step is hard to 
+	 * return the timer_id now.  The next step is hard to
 	 * back out if there is an error.
 	 */
 	if (copy_to_user(created_timer_id,
@@ -471,13 +447,12 @@
 		read_lock(&tasklist_lock);
 		if ((process = good_sigevent(&event))) {
 			/*
-
 			 * We may be setting up this process for another
-			 * thread.  It may be exitiing.  To catch this
+			 * thread.  It may be exiting.  To catch this
 			 * case the we check the PF_EXITING flag.  If
 			 * the flag is not set, the task_lock will catch
 			 * him before it is too late (in exit_itimers).
-
+			 *
 			 * The exec case is a bit more invloved but easy
 			 * to code.  If the process is in our thread
 			 * group (and it must be or we would not allow
@@ -485,7 +460,6 @@
 			 * us to be killed.  In this case it will wait
 			 * for us to die which means we can finish this
 			 * linkage with our last gasp. I.e. no code :)
-
 			 */
 			task_lock(process);
 			if (!(process->flags & PF_EXITING)) {
@@ -528,11 +502,10 @@
 	 * Once we set the process, it can be found so do it last...
 	 */
 	new_timer->it_process = process;
-
-      out:
-	if (error) {
+out:
+	if (error)
 		release_posix_timer(new_timer);
-	}
+
 	return error;
 }
 
@@ -544,43 +517,36 @@
  * Arguments:
  * ts	     : Pointer to the timespec structure to check
  *
- * Return value: 
+ * Return value:
  * If a NULL pointer was passed in, or the tv_nsec field was less than 0
  * or greater than NSEC_PER_SEC, or the tv_sec field was less than 0,
  * this function returns 0. Otherwise it returns 1.
-
  */
-
-static int
-good_timespec(const struct timespec *ts)
+static int good_timespec(const struct timespec *ts)
 {
-	if ((ts == NULL) ||
-	    (ts->tv_sec < 0) ||
-	    ((unsigned) ts->tv_nsec >= NSEC_PER_SEC)) return 0;
+	if ((!ts) || (ts->tv_sec < 0) ||
+			((unsigned) ts->tv_nsec >= NSEC_PER_SEC))
+		return 0;
 	return 1;
 }
 
-static inline void
-unlock_timer(struct k_itimer *timr, unsigned long flags)
+static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
 {
 	spin_unlock_irqrestore(&timr->it_lock, flags);
 }
 
 /*
-
  * Locking issues: We need to protect the result of the id look up until
  * we get the timer locked down so it is not deleted under us.  The
  * removal is done under the idr spinlock so we use that here to bridge
  * the find to the timer lock.  To avoid a dead lock, the timer id MUST
  * be release with out holding the timer lock.
-
  */
-static struct k_itimer *
-lock_timer(timer_t timer_id, unsigned long *flags)
+static struct k_itimer * lock_timer(timer_t timer_id, unsigned long *flags)
 {
 	struct k_itimer *timr;
 	/*
-	 * Watch out here.  We do a irqsave on the idr_lock and pass the 
+	 * Watch out here.  We do a irqsave on the idr_lock and pass the
 	 * flags part over to the timer lock.  Must not let interrupts in
 	 * while we are moving the lock.
 	 */
@@ -591,35 +557,32 @@
 		spin_lock(&timr->it_lock);
 		spin_unlock(&idr_lock);
 
-		if ( (timr->it_id != timer_id) || !(timr->it_process) ||
-		     timr->it_process->tgid != current->tgid) {
+		if ((timr->it_id != timer_id) || !(timr->it_process) ||
+				timr->it_process->tgid != current->tgid) {
 			unlock_timer(timr, *flags);
 			timr = NULL;
 		}
-	} else {
+	} else
 		spin_unlock_irqrestore(&idr_lock, *flags);
-	}
 
 	return timr;
 }
 
-/* 
-
+/*
  * Get the time remaining on a POSIX.1b interval timer.  This function
  * is ALWAYS called with spin_lock_irq on the timer, thus it must not
  * mess with irq.
-
+ *
  * We have a couple of messes to clean up here.  First there is the case
  * of a timer that has a requeue pending.  These timers should appear to
  * be in the timer list with an expiry as if we were to requeue them
  * now.
-
+ *
  * The second issue is the SIGEV_NONE timer which may be active but is
  * not really ever put in the timer list (to save system resources).
  * This timer may be expired, and if so, we will do it here.  Otherwise
  * it is the same as a requeue pending timer WRT to what we should
  * report.
-
  */
 void inline
 do_timer_gettime(struct k_itimer *timr, struct itimerspec *cur_setting)
@@ -628,31 +591,25 @@
 	unsigned long expires;
 	struct now_struct now;
 
-	do {
+	do
 		expires = timr->it_timer.expires;
-	} while ((volatile long) (timr->it_timer.expires) != expires);
+	while ((volatile long) (timr->it_timer.expires) != expires);
 
 	posix_get_now(&now);
 
-	if (expires && (timr->it_sigev_notify & SIGEV_NONE) && !timr->it_incr) {
-		if (posix_time_before(&timr->it_timer, &now)) {
-			timr->it_timer.expires = expires = 0;
-		}
-	}
+	if (expires && (timr->it_sigev_notify & SIGEV_NONE) && !timr->it_incr &&
+			posix_time_before(&timr->it_timer, &now))
+		timr->it_timer.expires = expires = 0;
 	if (expires) {
 		if (timr->it_requeue_pending ||
-		    (timr->it_sigev_notify & SIGEV_NONE)) {
-			while (posix_time_before(&timr->it_timer, &now)) {
+		    (timr->it_sigev_notify & SIGEV_NONE))
+			while (posix_time_before(&timr->it_timer, &now))
 				posix_bump_timer(timr);
-			};
-		} else {
-			if (!timer_pending(&timr->it_timer)) {
+		else
+			if (!timer_pending(&timr->it_timer))
 				sub_expires = expires = 0;
-			}
-		}
-		if (expires) {
+		if (expires)
 			expires -= now.jiffies;
-		}
 	}
 	jiffies_to_timespec(expires, &cur_setting->it_value);
 	jiffies_to_timespec(timr->it_incr, &cur_setting->it_interval);
@@ -662,8 +619,9 @@
 		cur_setting->it_value.tv_sec = 0;
 	}
 }
+
 /* Get the time remaining on a POSIX.1b interval timer. */
-asmlinkage int
+asmlinkage long
 sys_timer_gettime(timer_t timer_id, struct itimerspec *setting)
 {
 	struct k_itimer *timr;
@@ -684,7 +642,6 @@
 	return 0;
 }
 /*
-
  * Get the number of overruns of a POSIX.1b interval timer.  This is to
  * be the overrun of the timer last delivered.  At the same time we are
  * accumulating overruns on the next timer.  The overrun is frozen when
@@ -692,10 +649,9 @@
  * is not queued) or at the actual delivery time (as we are informed by
  * the call back to do_schedule_next_timer().  So all we need to do is
  * to pick up the frozen overrun.
-
  */
 
-asmlinkage int
+asmlinkage long
 sys_timer_getoverrun(timer_t timer_id)
 {
 	struct k_itimer *timr;
@@ -711,8 +667,9 @@
 
 	return overrun;
 }
-/* Adjust for absolute time */
 /*
+ * Adjust for absolute time
+ *
  * If absolute time is given and it is not CLOCK_MONOTONIC, we need to
  * adjust for the offset between the timer clock (CLOCK_MONOTONIC) and
  * what ever clock he is using.
@@ -720,26 +677,23 @@
  * If it is relative time, we need to add the current (CLOCK_MONOTONIC)
  * time to it to get the proper time for the timer.
  */
-static int
-adjust_abs_time(struct k_clock *clock, struct timespec *tp, int abs)
+static int adjust_abs_time(struct k_clock *clock, struct timespec *tp, int abs)
 {
 	struct timespec now;
 	struct timespec oc;
 	do_posix_clock_monotonic_gettime(&now);
 
-	if (abs &&
-	    (posix_clocks[CLOCK_MONOTONIC].clock_get == clock->clock_get)) {
-	} else {
-
-		if (abs) {
+	if (!abs || (posix_clocks[CLOCK_MONOTONIC].clock_get !=
+							clock->clock_get)) {
+		if (abs)
 			do_posix_gettime(clock, &oc);
-		} else {
+		else
 			oc.tv_nsec = oc.tv_sec = 0;
-		}
+
 		tp->tv_sec += now.tv_sec - oc.tv_sec;
 		tp->tv_nsec += now.tv_nsec - oc.tv_nsec;
 
-		/* 
+		/*
 		 * Normalize...
 		 */
 		if ((tp->tv_nsec - NSEC_PER_SEC) >= 0) {
@@ -762,18 +716,16 @@
 		if ((unsigned) tp->tv_sec < now.tv_sec) {
 			tp->tv_sec = now.tv_sec;
 			tp->tv_nsec = now.tv_nsec;
-		} else {
-			// tp->tv_sec = now.tv_sec + (MAX_JIFFY_OFFSET / HZ);
+		} else
 			/*
 			 * This is a considered response, not exactly in
 			 * line with the standard (in fact it is silent on
-			 * possible overflows).  We assume such a large 
+			 * possible overflows).  We assume such a large
 			 * value is ALMOST always a programming error and
 			 * try not to compound it by setting a really dumb
 			 * value.
 			 */
 			return -EINVAL;
-		}
 	}
 	return 0;
 }
@@ -786,28 +738,27 @@
 {
 	struct k_clock *clock = &posix_clocks[timr->it_clock];
 
-	if (old_setting) {
+	if (old_setting)
 		do_timer_gettime(timr, old_setting);
-	}
 
 	/* disable the timer */
 	timr->it_incr = 0;
-	/* 
+	/*
 	 * careful here.  If smp we could be in the "fire" routine which will
 	 * be spinning as we hold the lock.  But this is ONLY an SMP issue.
 	 */
 #ifdef CONFIG_SMP
-	if (timer_active(timr) && !del_timer(&timr->it_timer)) {
+	if (timer_active(timr) && !del_timer(&timr->it_timer))
 		/*
 		 * It can only be active if on an other cpu.  Since
 		 * we have cleared the interval stuff above, it should
 		 * clear once we release the spin lock.  Of course once
-		 * we do that anything could happen, including the 
-		 * complete melt down of the timer.  So return with 
+		 * we do that anything could happen, including the
+		 * complete melt down of the timer.  So return with
 		 * a "retry" exit status.
 		 */
 		return TIMER_RETRY;
-	}
+
 	set_timer_inactive(timr);
 #else
 	del_timer(&timr->it_timer);
@@ -815,22 +766,21 @@
 	timr->it_requeue_pending = 0;
 	timr->it_overrun_last = 0;
 	timr->it_overrun = -1;
-	/* 
-	 *switch off the timer when it_value is zero 
+	/*
+	 *switch off the timer when it_value is zero
 	 */
-	if ((new_setting->it_value.tv_sec == 0) &&
-	    (new_setting->it_value.tv_nsec == 0)) {
+	if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec) {
 		timr->it_timer.expires = 0;
 		return 0;
 	}
 
 	if ((flags & TIMER_ABSTIME) &&
-	    (clock->clock_get != do_posix_clock_monotonic_gettime)) {
-	}
+	    (clock->clock_get != do_posix_clock_monotonic_gettime))
+		// FIXME: what is this?
+		;
 	if (adjust_abs_time(clock,
-			    &new_setting->it_value, flags & TIMER_ABSTIME)) {
+			    &new_setting->it_value, flags & TIMER_ABSTIME))
 		return -EINVAL;
-	}
 	tstotimer(new_setting, timr);
 
 	/*
@@ -839,16 +789,16 @@
 	 * We do not even queue SIGEV_NONE timers!
 	 */
 	if (!(timr->it_sigev_notify & SIGEV_NONE)) {
-		if (timr->it_timer.expires == jiffies) {
+		if (timr->it_timer.expires == jiffies)
 			timer_notify_task(timr);
-		} else
+		else
 			add_timer(&timr->it_timer);
 	}
 	return 0;
 }
 
 /* Set a POSIX.1b interval timer */
-asmlinkage int
+asmlinkage long
 sys_timer_settime(timer_t timer_id, int flags,
 		  const struct itimerspec *new_setting,
 		  struct itimerspec *old_setting)
@@ -859,62 +809,54 @@
 	long flag;
 	struct itimerspec *rtn = old_setting ? &old_spec : NULL;
 
-	if (new_setting == NULL) {
+	if (!new_setting)
 		return -EINVAL;
-	}
 
-	if (copy_from_user(&new_spec, new_setting, sizeof (new_spec))) {
+	if (copy_from_user(&new_spec, new_setting, sizeof (new_spec)))
 		return -EFAULT;
-	}
 
 	if ((!good_timespec(&new_spec.it_interval)) ||
-	    (!good_timespec(&new_spec.it_value))) {
+	    (!good_timespec(&new_spec.it_value)))
 		return -EINVAL;
-	}
-      retry:
+retry:
 	timr = lock_timer(timer_id, &flag);
 	if (!timr)
 		return -EINVAL;
 
-	if (!posix_clocks[timr->it_clock].timer_set) {
+	if (!posix_clocks[timr->it_clock].timer_set)
 		error = do_timer_settime(timr, flags, &new_spec, rtn);
-	} else {
+	else
 		error = posix_clocks[timr->it_clock].timer_set(timr,
 							       flags,
 							       &new_spec, rtn);
-	}
 	unlock_timer(timr, flag);
 	if (error == TIMER_RETRY) {
 		rtn = NULL;	// We already got the old time...
 		goto retry;
 	}
 
-	if (old_setting && !error) {
-		if (copy_to_user(old_setting, &old_spec, sizeof (old_spec))) {
-			error = -EFAULT;
-		}
-	}
+	if (old_setting && !error && copy_to_user(old_setting,
+						  &old_spec, sizeof (old_spec)))
+		error = -EFAULT;
 
 	return error;
 }
 
-static inline int
-do_timer_delete(struct k_itimer *timer)
+static inline int do_timer_delete(struct k_itimer *timer)
 {
 	timer->it_incr = 0;
 #ifdef CONFIG_SMP
 	if (timer_active(timer) &&
-	    !del_timer(&timer->it_timer) && !timer->it_requeue_pending) {
+	    !del_timer(&timer->it_timer) && !timer->it_requeue_pending)
 		/*
 		 * It can only be active if on an other cpu.  Since
 		 * we have cleared the interval stuff above, it should
 		 * clear once we release the spin lock.  Of course once
-		 * we do that anything could happen, including the 
-		 * complete melt down of the timer.  So return with 
+		 * we do that anything could happen, including the
+		 * complete melt down of the timer.  So return with
 		 * a "retry" exit status.
 		 */
 		return TIMER_RETRY;
-	}
 #else
 	del_timer(&timer->it_timer);
 #endif
@@ -922,7 +864,7 @@
 }
 
 /* Delete a POSIX.1b interval timer. */
-asmlinkage int
+asmlinkage long
 sys_timer_delete(timer_t timer_id)
 {
 	struct k_itimer *timer;
@@ -930,9 +872,8 @@
 
 #ifdef CONFIG_SMP
 	int error;
-      retry_delete:
+retry_delete:
 #endif
-
 	timer = lock_timer(timer_id, &flags);
 	if (!timer)
 		return -EINVAL;
@@ -947,13 +888,9 @@
 #else
 	p_timer_del(&posix_clocks[timer->it_clock], timer);
 #endif
-
 	task_lock(timer->it_process);
-
 	list_del(&timer->list);
-
 	task_unlock(timer->it_process);
-
 	/*
 	 * This keeps any tasks waiting on the spin lock from thinking
 	 * they got something (see the lock code above).
@@ -964,20 +901,17 @@
 	return 0;
 }
 /*
- * return  timer owned by the process, used by exit_itimers
+ * return timer owned by the process, used by exit_itimers
  */
-static inline void
-itimer_delete(struct k_itimer *timer)
+static inline void itimer_delete(struct k_itimer *timer)
 {
-	if (sys_timer_delete(timer->it_id)) {
+	if (sys_timer_delete(timer->it_id))
 		BUG();
-	}
 }
 /*
  * This is exported to exit and exec
  */
-void
-exit_itimers(struct task_struct *tsk)
+void exit_itimers(struct task_struct *tsk)
 {
 	struct k_itimer *tmr;
 
@@ -993,18 +927,15 @@
 
 /*
  * And now for the "clock" calls
-
+ *
  * These functions are called both from timer functions (with the timer
  * spin_lock_irq() held and from clock calls with no locking.	They must
  * use the save flags versions of locks.
  */
-static int
-do_posix_gettime(struct k_clock *clock, struct timespec *tp)
+static int do_posix_gettime(struct k_clock *clock, struct timespec *tp)
 {
-
-	if (clock->clock_get) {
+	if (clock->clock_get)
 		return clock->clock_get(tp);
-	}
 
 	do_gettimeofday((struct timeval *) tp);
 	tp->tv_nsec *= NSEC_PER_USEC;
@@ -1014,24 +945,24 @@
 /*
  * We do ticks here to avoid the irq lock ( they take sooo long).
  * The seqlock is great here.  Since we a reader, we don't really care
- * if we are interrupted since we don't take lock that will stall us or 
+ * if we are interrupted since we don't take lock that will stall us or
  * any other cpu. Voila, no irq lock is needed.
-
+ *
  * Note also that the while loop assures that the sub_jiff_offset
  * will be less than a jiffie, thus no need to normalize the result.
  * Well, not really, if called with ints off :(
+ *
+ * HELP, this code should make an attempt at resolution beyond the
+ * jiffie.  Trouble is this is "arch" dependent...
  */
 
-int
-do_posix_clock_monotonic_gettime(struct timespec *tp)
+int do_posix_clock_monotonic_gettime(struct timespec *tp)
 {
 	long sub_sec;
 	u64 jiffies_64_f;
 
 #if (BITS_PER_LONG > 32)
-
 	jiffies_64_f = jiffies_64;
-
 #else
 	unsigned int seq;
 
@@ -1039,75 +970,74 @@
 		seq = read_seqbegin(&xtime_lock);
 		jiffies_64_f = jiffies_64;
 
-	}while(  read_seqretry(&xtime_lock, seq));
-
+	} while (read_seqretry(&xtime_lock, seq));
 #endif
 	tp->tv_sec = div_long_long_rem(jiffies_64_f, HZ, &sub_sec);
-
 	tp->tv_nsec = sub_sec * (NSEC_PER_SEC / HZ);
+
 	return 0;
 }
 
-int
-do_posix_clock_monotonic_settime(struct timespec *tp)
+int do_posix_clock_monotonic_settime(struct timespec *tp)
 {
 	return -EINVAL;
 }
 
-asmlinkage int
+asmlinkage long
 sys_clock_settime(clockid_t which_clock, const struct timespec *tp)
 {
 	struct timespec new_tp;
 
 	if ((unsigned) which_clock >= MAX_CLOCKS ||
-	    !posix_clocks[which_clock].res) return -EINVAL;
+					!posix_clocks[which_clock].res)
+		return -EINVAL;
 	if (copy_from_user(&new_tp, tp, sizeof (*tp)))
 		return -EFAULT;
-	if (posix_clocks[which_clock].clock_set) {
+	if (posix_clocks[which_clock].clock_set)
 		return posix_clocks[which_clock].clock_set(&new_tp);
-	}
+
 	new_tp.tv_nsec /= NSEC_PER_USEC;
 	return do_sys_settimeofday((struct timeval *) &new_tp, NULL);
 }
-asmlinkage int
+
+asmlinkage long
 sys_clock_gettime(clockid_t which_clock, struct timespec *tp)
 {
 	struct timespec rtn_tp;
 	int error = 0;
 
 	if ((unsigned) which_clock >= MAX_CLOCKS ||
-	    !posix_clocks[which_clock].res) return -EINVAL;
+					!posix_clocks[which_clock].res)
+		return -EINVAL;
 
 	error = do_posix_gettime(&posix_clocks[which_clock], &rtn_tp);
 
-	if (!error) {
-		if (copy_to_user(tp, &rtn_tp, sizeof (rtn_tp))) {
-			error = -EFAULT;
-		}
-	}
+	if (!error && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp)))
+		error = -EFAULT;
+
 	return error;
 
 }
-asmlinkage int
+
+asmlinkage long
 sys_clock_getres(clockid_t which_clock, struct timespec *tp)
 {
 	struct timespec rtn_tp;
 
 	if ((unsigned) which_clock >= MAX_CLOCKS ||
-	    !posix_clocks[which_clock].res) return -EINVAL;
+					!posix_clocks[which_clock].res)
+		return -EINVAL;
 
 	rtn_tp.tv_sec = 0;
 	rtn_tp.tv_nsec = posix_clocks[which_clock].res;
-	if (tp) {
-		if (copy_to_user(tp, &rtn_tp, sizeof (rtn_tp))) {
-			return -EFAULT;
-		}
-	}
+	if (tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp)))
+		return -EFAULT;
+
 	return 0;
 
 }
-static void
-nanosleep_wake_up(unsigned long __data)
+
+static void nanosleep_wake_up(unsigned long __data)
 {
 	struct task_struct *p = (struct task_struct *) __data;
 
@@ -1117,41 +1047,27 @@
 /*
  * The standard says that an absolute nanosleep call MUST wake up at
  * the requested time in spite of clock settings.  Here is what we do:
- * For each nanosleep call that needs it (only absolute and not on 
+ * For each nanosleep call that needs it (only absolute and not on
  * CLOCK_MONOTONIC* (as it can not be set)) we thread a little structure
  * into the "nanosleep_abs_list".  All we need is the task_struct pointer.
  * When ever the clock is set we just wake up all those tasks.	 The rest
  * is done by the while loop in clock_nanosleep().
-
- * On locking, clock_was_set() is called from update_wall_clock which 
- * holds (or has held for it) a write_lock_irq( xtime_lock) and is 
+ *
+ * On locking, clock_was_set() is called from update_wall_clock which
+ * holds (or has held for it) a write_lock_irq( xtime_lock) and is
  * called from the timer bh code.  Thus we need the irq save locks.
  */
-spinlock_t nanosleep_abs_list_lock = SPIN_LOCK_UNLOCKED;
-
-struct list_head nanosleep_abs_list = LIST_HEAD_INIT(nanosleep_abs_list);
 
-struct abs_struct {
-	struct list_head list;
-	struct task_struct *t;
-};
+static DECLARE_WAIT_QUEUE_HEAD(nanosleep_abs_wqueue);
 
-void
-clock_was_set(void)
+void clock_was_set(void)
 {
-	struct list_head *pos;
-	unsigned long flags;
-
-	spin_lock_irqsave(&nanosleep_abs_list_lock, flags);
-	list_for_each(pos, &nanosleep_abs_list) {
-		wake_up_process(list_entry(pos, struct abs_struct, list)->t);
-	}
-	spin_unlock_irqrestore(&nanosleep_abs_list_lock, flags);
+	wake_up_all(&nanosleep_abs_wqueue);
 }
 
 long clock_nanosleep_restart(struct restart_block *restart_block);
 
-extern long do_clock_nanosleep(clockid_t which_clock, int flags, 
+extern long do_clock_nanosleep(clockid_t which_clock, int flags,
 			       struct timespec *t);
 
 #ifdef FOLD_NANO_SLEEP_INTO_CLOCK_NANO_SLEEP
@@ -1170,9 +1086,9 @@
 
 	ret = do_clock_nanosleep(CLOCK_REALTIME, 0, &t);
 
-	if (ret == -ERESTART_RESTARTBLOCK && rmtp && 
-	    copy_to_user(rmtp, &t, sizeof (t)))
-			return -EFAULT;
+	if (ret == -ERESTART_RESTARTBLOCK && rmtp &&
+					copy_to_user(rmtp, &t, sizeof (t)))
+		return -EFAULT;
 	return ret;
 }
 #endif				// ! FOLD_NANO_SLEEP_INTO_CLOCK_NANO_SLEEP
@@ -1185,7 +1101,8 @@
 	int ret;
 
 	if ((unsigned) which_clock >= MAX_CLOCKS ||
-	    !posix_clocks[which_clock].res) return -EINVAL;
+					!posix_clocks[which_clock].res)
+		return -EINVAL;
 
 	if (copy_from_user(&t, rqtp, sizeof (struct timespec)))
 		return -EFAULT;
@@ -1195,11 +1112,10 @@
 
 	ret = do_clock_nanosleep(which_clock, flags, &t);
 
-	if ((ret == -ERESTART_RESTARTBLOCK) && rmtp && 
-	    copy_to_user(rmtp, &t, sizeof (t)))
-			return -EFAULT;
+	if ((ret == -ERESTART_RESTARTBLOCK) && rmtp &&
+					copy_to_user(rmtp, &t, sizeof (t)))
+		return -EFAULT;
 	return ret;
-
 }
 
 long
@@ -1207,13 +1123,14 @@
 {
 	struct timespec t;
 	struct timer_list new_timer;
-	struct abs_struct abs_struct = { .list = { .next = 0 } };
+	DECLARE_WAITQUEUE(abs_wqueue, current);
+	u64 rq_time = 0;
+	s64 left;
 	int abs;
-	int rtn = 0;
-	int active;
 	struct restart_block *restart_block =
 	    &current_thread_info()->restart_block;
 
+	abs_wqueue.flags = 0;
 	init_timer(&new_timer);
 	new_timer.expires = 0;
 	new_timer.data = (unsigned long) current;
@@ -1226,54 +1143,48 @@
 		 * time and continue.
 		 */
 		restart_block->fn = do_no_restart_syscall;
-		if (!restart_block->arg2)
-			return -EINTR;
 
-		new_timer.expires = restart_block->arg2;
-		if (time_before(new_timer.expires, jiffies))
-			return 0;
+		rq_time = restart_block->arg3;
+		rq_time = (rq_time << 32) + restart_block->arg2;
+		if (!rq_time)
+			return -EINTR;
+		left = rq_time - get_jiffies_64();
+		if (left <= 0LL)
+			return 0;	/* Already passed */
 	}
 
 	if (abs && (posix_clocks[which_clock].clock_get !=
-		    posix_clocks[CLOCK_MONOTONIC].clock_get)) {
-		spin_lock_irq(&nanosleep_abs_list_lock);
-		list_add(&abs_struct.list, &nanosleep_abs_list);
-		abs_struct.t = current;
-		spin_unlock_irq(&nanosleep_abs_list_lock);
-	}
+			    posix_clocks[CLOCK_MONOTONIC].clock_get))
+		add_wait_queue(&nanosleep_abs_wqueue, &abs_wqueue);
+
 	do {
 		t = *tsave;
-		if ((abs || !new_timer.expires) &&
-		    !(rtn = adjust_abs_time(&posix_clocks[which_clock],
-					    &t, abs))) {
-			/*
-			 * On error, we don't set up the timer so
-			 * we don't arm the timer so
-			 * del_timer_sync() will return 0, thus
-			 * active is zero... and so it goes.
-			 */
-
-			tstojiffie(&t,
-				   posix_clocks[which_clock].res,
-				   &new_timer.expires);
+		if (abs || !rq_time) {
+			adjust_abs_time(&posix_clocks[which_clock], &t, abs);
+			tstojiffie(&t, posix_clocks[which_clock].res, &rq_time);
 		}
-		if (new_timer.expires) {
-			current->state = TASK_INTERRUPTIBLE;
-			add_timer(&new_timer);
 
-			schedule();
-		}
-	}
-	while ((active = del_timer_sync(&new_timer)) &&
-	       !test_thread_flag(TIF_SIGPENDING));
+		left = rq_time - get_jiffies_64();
+		if (left >= MAX_JIFFY_OFFSET)
+			left = MAX_JIFFY_OFFSET;
+		if (left < 0)
+			break;
 
-	if (abs_struct.list.next) {
-		spin_lock_irq(&nanosleep_abs_list_lock);
-		list_del(&abs_struct.list);
-		spin_unlock_irq(&nanosleep_abs_list_lock);
-	}
-	if (active) {
-		long jiffies_left;
+		new_timer.expires = jiffies + left;
+		__set_current_state(TASK_INTERRUPTIBLE);
+		add_timer(&new_timer);
+
+		schedule();
+
+		del_timer_sync(&new_timer);
+		left = rq_time - get_jiffies_64();
+	} while (left > 0 && !test_thread_flag(TIF_SIGPENDING));
+
+	if (abs_wqueue.task_list.next)
+		finish_wait(&nanosleep_abs_wqueue, &abs_wqueue);
+
+	if (left > 0) {
+		unsigned long rmd;
 
 		/*
 		 * Always restart abs calls from scratch to pick up any
@@ -1282,29 +1193,19 @@
 		if (abs)
 			return -ERESTARTNOHAND;
 
-		jiffies_left = new_timer.expires - jiffies;
-
-		if (jiffies_left < 0)
-			return 0;
-
-		jiffies_to_timespec(jiffies_left, tsave);
+		tsave->tv_sec = div_long_long_rem(left, HZ, &rmd);
+		tsave->tv_nsec = rmd * (NSEC_PER_SEC / HZ);
 
-		while (tsave->tv_nsec < 0) {
-			tsave->tv_nsec += NSEC_PER_SEC;
-			tsave->tv_sec--;
-		}
-		if (tsave->tv_sec < 0) {
-			tsave->tv_sec = 0;
-			tsave->tv_nsec = 1;
-		}
 		restart_block->fn = clock_nanosleep_restart;
 		restart_block->arg0 = which_clock;
 		restart_block->arg1 = (unsigned long)tsave;
-		restart_block->arg2 = new_timer.expires;
+		restart_block->arg2 = rq_time & 0xffffffffLL;
+		restart_block->arg3 = rq_time >> 32;
+
 		return -ERESTART_RESTARTBLOCK;
 	}
 
-	return rtn;
+	return 0;
 }
 /*
  * This will restart either clock_nanosleep or clock_nanosleep
@@ -1315,8 +1216,8 @@
 	struct timespec t;
 	int ret = do_clock_nanosleep(restart_block->arg0, 0, &t);
 
-	if ((ret == -ERESTART_RESTARTBLOCK) && restart_block->arg1 && 
-	    copy_to_user((struct timespec *)(restart_block->arg1), &t, 
+	if ((ret == -ERESTART_RESTARTBLOCK) && restart_block->arg1 &&
+	    copy_to_user((struct timespec *)(restart_block->arg1), &t,
 			 sizeof (t)))
 		return -EFAULT;
 	return ret;
diff -Nru a/kernel/ptrace.c b/kernel/ptrace.c
--- a/kernel/ptrace.c	Sat Feb 15 19:30:17 2003
+++ b/kernel/ptrace.c	Sat Mar 22 13:30:19 2003
@@ -336,5 +336,8 @@
 	/*
 	 * Signals sent while we were stopped might set TIF_SIGPENDING.
 	 */
+
+	spin_lock_irq(&current->sighand->siglock);
 	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
 }
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	Sun Mar 16 16:00:00 2003
+++ b/kernel/sched.c	Sun Mar 23 16:56:04 2003
@@ -778,7 +778,7 @@
 		spin_unlock(&rq2->lock);
 }
 
-#if CONFIG_NUMA
+#ifdef CONFIG_NUMA
 /*
  * If dest_cpu is allowed for this process, migrate the task to it.
  * This is accomplished by forcing the cpu_allowed mask to only
@@ -1104,7 +1104,7 @@
 #define IDLE_NODE_REBALANCE_TICK (IDLE_REBALANCE_TICK * 5)
 #define BUSY_NODE_REBALANCE_TICK (BUSY_REBALANCE_TICK * 100)
 
-#if CONFIG_NUMA
+#ifdef CONFIG_NUMA
 static void balance_node(runqueue_t *this_rq, int idle, int this_cpu)
 {
 	int node = find_busiest_node(cpu_to_node(this_cpu));
@@ -1121,7 +1121,7 @@
 
 static void rebalance_tick(runqueue_t *this_rq, int idle)
 {
-#if CONFIG_NUMA
+#ifdef CONFIG_NUMA
 	int this_cpu = smp_processor_id();
 #endif
 	unsigned long j = jiffies;
@@ -1135,7 +1135,7 @@
 	 * are not balanced.)
 	 */
 	if (idle) {
-#if CONFIG_NUMA
+#ifdef CONFIG_NUMA
 		if (!(j % IDLE_NODE_REBALANCE_TICK))
 			balance_node(this_rq, idle, this_cpu);
 #endif
@@ -1146,7 +1146,7 @@
 		}
 		return;
 	}
-#if CONFIG_NUMA
+#ifdef CONFIG_NUMA
 	if (!(j % BUSY_NODE_REBALANCE_TICK))
 		balance_node(this_rq, idle, this_cpu);
 #endif
@@ -1902,7 +1902,7 @@
  * @len: length in bytes of the bitmask pointed to by user_mask_ptr
  * @user_mask_ptr: user-space pointer to the new cpu mask
  */
-asmlinkage int sys_sched_setaffinity(pid_t pid, unsigned int len,
+asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len,
 				      unsigned long *user_mask_ptr)
 {
 	unsigned long new_mask;
@@ -1954,7 +1954,7 @@
  * @len: length in bytes of the bitmask pointed to by user_mask_ptr
  * @user_mask_ptr: user-space pointer to hold the current cpu mask
  */
-asmlinkage int sys_sched_getaffinity(pid_t pid, unsigned int len,
+asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len,
 				      unsigned long *user_mask_ptr)
 {
 	unsigned int real_len;
@@ -2268,7 +2268,7 @@
 	local_irq_restore(flags);
 
 	/* Set the preempt count _outside_ the spinlocks! */
-#if CONFIG_PREEMPT
+#ifdef CONFIG_PREEMPT
 	idle->thread_info->preempt_count = (idle->lock_depth >= 0);
 #else
 	idle->thread_info->preempt_count = 0;
diff -Nru a/kernel/signal.c b/kernel/signal.c
--- a/kernel/signal.c	Sun Mar 16 18:37:50 2003
+++ b/kernel/signal.c	Sat Mar 22 22:14:57 2003
@@ -2254,7 +2254,7 @@
 
 #ifndef HAVE_ARCH_SYS_PAUSE
 
-asmlinkage int
+asmlinkage long
 sys_pause(void)
 {
 	current->state = TASK_INTERRUPTIBLE;
diff -Nru a/kernel/suspend.c b/kernel/suspend.c
--- a/kernel/suspend.c	Mon Feb 24 10:29:52 2003
+++ b/kernel/suspend.c	Sat Mar 22 22:14:58 2003
@@ -65,7 +65,7 @@
 #include <asm/pgtable.h>
 #include <asm/io.h>
 
-extern int sys_sync(void);
+extern long sys_sync(void);
 
 unsigned char software_suspend_enabled = 0;
 
@@ -1152,13 +1152,15 @@
 	union diskpage *cur;
 	unsigned long scratch_page = 0;
 	int error;
+	char b[BDEVNAME_SIZE];
 
 	resume_device = name_to_dev_t(specialfile);
 	scratch_page = get_zeroed_page(GFP_ATOMIC);
 	cur = (void *) scratch_page;
 	if (cur) {
 		struct block_device *bdev;
-		printk("Resuming from device %s\n", __bdevname(resume_device));
+		printk("Resuming from device %s\n",
+				__bdevname(resume_device, b));
 		bdev = bdget(resume_device);
 		if (!bdev) {
 			printk("No such block device ?!\n");
diff -Nru a/kernel/sys.c b/kernel/sys.c
--- a/kernel/sys.c	Mon Mar 10 10:49:27 2003
+++ b/kernel/sys.c	Thu Mar 20 00:55:30 2003
@@ -209,6 +209,23 @@
 cond_syscall(sys_swapoff)
 cond_syscall(sys_init_module)
 cond_syscall(sys_delete_module)
+cond_syscall(sys_socketpair)
+cond_syscall(sys_bind)
+cond_syscall(sys_listen)
+cond_syscall(sys_accept)
+cond_syscall(sys_connect)
+cond_syscall(sys_getsockname)
+cond_syscall(sys_getpeername)
+cond_syscall(sys_sendto)
+cond_syscall(sys_send)
+cond_syscall(sys_recvfrom)
+cond_syscall(sys_recv)
+cond_syscall(sys_setsockopt)
+cond_syscall(sys_getsockopt)
+cond_syscall(sys_shutdown)
+cond_syscall(sys_sendmsg)
+cond_syscall(sys_recvmsg)
+cond_syscall(sys_socketcall)
 
 static int set_one_prio(struct task_struct *p, int niceval, int error)
 {
diff -Nru a/kernel/sysctl.c b/kernel/sysctl.c
--- a/kernel/sysctl.c	Fri Jan 17 06:49:15 2003
+++ b/kernel/sysctl.c	Sun Mar 23 01:40:12 2003
@@ -20,6 +20,7 @@
 
 #include <linux/config.h>
 #include <linux/mm.h>
+#include <linux/swap.h>
 #include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
diff -Nru a/kernel/timer.c b/kernel/timer.c
--- a/kernel/timer.c	Mon Feb 24 23:13:09 2003
+++ b/kernel/timer.c	Sun Mar 23 01:40:12 2003
@@ -24,6 +24,7 @@
 #include <linux/percpu.h>
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <linux/swap.h>
 #include <linux/notifier.h>
 #include <linux/thread_info.h>
 #include <linux/time.h>
@@ -44,16 +45,13 @@
 #define TVR_MASK (TVR_SIZE - 1)
 
 typedef struct tvec_s {
-	int index;
 	struct list_head vec[TVN_SIZE];
 } tvec_t;
 
 typedef struct tvec_root_s {
-	int index;
 	struct list_head vec[TVR_SIZE];
 } tvec_root_t;
 
-
 struct tvec_t_base_s {
 	spinlock_t lock;
 	unsigned long timer_jiffies;
@@ -67,6 +65,14 @@
 
 typedef struct tvec_t_base_s tvec_base_t;
 
+static inline void set_running_timer(tvec_base_t *base,
+					struct timer_list *timer)
+{
+#ifdef CONFIG_SMP
+	base->running_timer = timer;
+#endif
+}
+
 /* Fake initialization */
 static DEFINE_PER_CPU(tvec_base_t, tvec_bases) = { SPIN_LOCK_UNLOCKED };
 
@@ -94,7 +100,8 @@
 		check_timer_failed(timer);
 }
 
-static inline void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
+
+static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
 {
 	unsigned long expires = timer->expires;
 	unsigned long idx = expires - base->timer_jiffies;
@@ -117,7 +124,7 @@
 		 * Can happen if you add a timer with expires == jiffies,
 		 * or you set a timer to go off in the past
 		 */
-		vec = base->tv1.vec + base->tv1.index;
+		vec = base->tv1.vec + (base->timer_jiffies & TVR_MASK);
 	} else if (idx <= 0xffffffffUL) {
 		int i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
 		vec = base->tv5.vec + i;
@@ -351,12 +358,12 @@
 #endif
 
 
-static int cascade(tvec_base_t *base, tvec_t *tv)
+static int cascade(tvec_base_t *base, tvec_t *tv, int index)
 {
 	/* cascade all the timers from tv up one level */
-	struct list_head *head, *curr, *next;
+	struct list_head *head, *curr;
 
-	head = tv->vec + tv->index;
+	head = tv->vec + index;
 	curr = head->next;
 	/*
 	 * We are removing _all_ timers from the list, so we don't  have to
@@ -366,15 +373,13 @@
 		struct timer_list *tmp;
 
 		tmp = list_entry(curr, struct timer_list, entry);
-		if (tmp->base != base)
-			BUG();
-		next = curr->next;
+		BUG_ON(tmp->base != base);
+		curr = curr->next;
 		internal_add_timer(base, tmp);
-		curr = next;
 	}
 	INIT_LIST_HEAD(head);
 
-	return tv->index = (tv->index + 1) & TVN_MASK;
+	return index;
 }
 
 /***
@@ -384,51 +389,46 @@
  * This function cascades all vectors and executes all expired timer
  * vectors.
  */
+#define INDEX(N) (base->timer_jiffies >> (TVR_BITS + N * TVN_BITS)) & TVN_MASK
+
 static inline void __run_timers(tvec_base_t *base)
 {
-	spin_lock_irq(&base->lock);
-	while ((long)(jiffies - base->timer_jiffies) >= 0) {
-		struct list_head *head, *curr;
+	struct timer_list *timer;
 
+	spin_lock_irq(&base->lock);
+	while (time_after_eq(jiffies, base->timer_jiffies)) {
+		struct list_head *head;
+ 		int index = base->timer_jiffies & TVR_MASK;
+ 
 		/*
 		 * Cascade timers:
 		 */
-		if (!base->tv1.index &&
-			(cascade(base, &base->tv2) == 1) &&
-				(cascade(base, &base->tv3) == 1) &&
-					cascade(base, &base->tv4) == 1)
-			cascade(base, &base->tv5);
+		if (!index &&
+			(!cascade(base, &base->tv2, INDEX(0))) &&
+				(!cascade(base, &base->tv3, INDEX(1))) &&
+					!cascade(base, &base->tv4, INDEX(2)))
+			cascade(base, &base->tv5, INDEX(3));
+		++base->timer_jiffies; 
 repeat:
-		head = base->tv1.vec + base->tv1.index;
-		curr = head->next;
-		if (curr != head) {
+		head = base->tv1.vec + index;
+		if (!list_empty(head)) {
 			void (*fn)(unsigned long);
 			unsigned long data;
-			struct timer_list *timer;
 
-			timer = list_entry(curr, struct timer_list, entry);
+			timer = list_entry(head->next,struct timer_list,entry);
  			fn = timer->function;
  			data = timer->data;
 
 			list_del(&timer->entry);
 			timer->base = NULL;
-#if CONFIG_SMP
-			base->running_timer = timer;
-#endif
+			set_running_timer(base, timer);
 			spin_unlock_irq(&base->lock);
-			if (!fn)
-				printk("Bad: timer %p has NULL fn. (data: %08lx)\n", timer, data);
-			else
-				fn(data);
+			fn(data);
 			spin_lock_irq(&base->lock);
 			goto repeat;
 		}
-		++base->timer_jiffies; 
-		base->tv1.index = (base->tv1.index + 1) & TVR_MASK;
 	}
-#if CONFIG_SMP
-	base->running_timer = NULL;
-#endif
+	set_running_timer(base, NULL);
 	spin_unlock_irq(&base->lock);
 }
 
@@ -775,7 +775,7 @@
 {
 	tvec_base_t *base = &per_cpu(tvec_bases, smp_processor_id());
 
-	if ((long)(jiffies - base->timer_jiffies) >= 0)
+	if (time_after_eq(jiffies, base->timer_jiffies))
 		__run_timers(base);
 }
 
@@ -1181,12 +1181,7 @@
 	for (j = 0; j < TVR_SIZE; j++)
 		INIT_LIST_HEAD(base->tv1.vec + j);
 
-	base->timer_jiffies = INITIAL_JIFFIES;
-	base->tv1.index = INITIAL_JIFFIES & TVR_MASK;
-	base->tv2.index = (INITIAL_JIFFIES >> TVR_BITS) & TVN_MASK;
-	base->tv3.index = (INITIAL_JIFFIES >> (TVR_BITS+TVN_BITS)) & TVN_MASK;
-	base->tv4.index = (INITIAL_JIFFIES >> (TVR_BITS+2*TVN_BITS)) & TVN_MASK;
-	base->tv5.index = (INITIAL_JIFFIES >> (TVR_BITS+3*TVN_BITS)) & TVN_MASK;
+	base->timer_jiffies = jiffies;
 }
 	
 static int __devinit timer_cpu_notify(struct notifier_block *self, 
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c	Sat Mar  8 14:50:29 2003
+++ b/mm/filemap.c	Sun Mar 23 01:40:12 2003
@@ -17,6 +17,7 @@
 #include <linux/aio.h>
 #include <linux/kernel_stat.h>
 #include <linux/mm.h>
+#include <linux/swap.h>
 #include <linux/mman.h>
 #include <linux/pagemap.h>
 #include <linux/file.h>
@@ -88,7 +89,7 @@
 	page->mapping = NULL;
 
 	mapping->nrpages--;
-	dec_page_state(nr_pagecache);
+	pagecache_acct(-1);
 }
 
 void remove_from_page_cache(struct page *page)
@@ -1195,7 +1196,7 @@
 static int filemap_populate(struct vm_area_struct *vma,
 			unsigned long addr,
 			unsigned long len,
-			unsigned long prot,
+			pgprot_t prot,
 			unsigned long pgoff,
 			int nonblock)
 {
@@ -1206,6 +1207,10 @@
 	struct mm_struct *mm = vma->vm_mm;
 	struct page *page;
 	int err;
+
+	if (!nonblock)
+		do_page_cache_readahead(mapping, vma->vm_file,
+					pgoff, len >> PAGE_CACHE_SHIFT);
 
 repeat:
 	size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
diff -Nru a/mm/fremap.c b/mm/fremap.c
--- a/mm/fremap.c	Thu Feb 20 08:38:13 2003
+++ b/mm/fremap.c	Sun Mar 23 01:40:12 2003
@@ -7,6 +7,7 @@
  */
 
 #include <linux/mm.h>
+#include <linux/swap.h>
 #include <linux/file.h>
 #include <linux/mman.h>
 #include <linux/pagemap.h>
@@ -16,12 +17,12 @@
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
-static inline void zap_pte(struct mm_struct *mm, pte_t *ptep)
+static inline int zap_pte(struct mm_struct *mm, pte_t *ptep)
 {
 	pte_t pte = *ptep;
 
 	if (pte_none(pte))
-		return;
+		return 0;
 	if (pte_present(pte)) {
 		unsigned long pfn = pte_pfn(pte);
 
@@ -36,9 +37,12 @@
 				mm->rss--;
 			}
 		}
+		return 1;
 	} else {
-		free_swap_and_cache(pte_to_swp_entry(pte));
+		if (!pte_file(pte))
+			free_swap_and_cache(pte_to_swp_entry(pte));
 		pte_clear(ptep);
+		return 0;
 	}
 }
 
@@ -47,9 +51,9 @@
  * previously existing mapping.
  */
 int install_page(struct mm_struct *mm, struct vm_area_struct *vma,
-		unsigned long addr, struct page *page, unsigned long prot)
+		unsigned long addr, struct page *page, pgprot_t prot)
 {
-	int err = -ENOMEM;
+	int err = -ENOMEM, flush;
 	pte_t *pte, entry;
 	pgd_t *pgd;
 	pmd_t *pmd;
@@ -69,18 +73,17 @@
 	if (!pte)
 		goto err_unlock;
 
-	zap_pte(mm, pte);
+	flush = zap_pte(mm, pte);
 
 	mm->rss++;
 	flush_page_to_ram(page);
 	flush_icache_page(vma, page);
-	entry = mk_pte(page, protection_map[prot]);
-	if (prot & PROT_WRITE)
-		entry = pte_mkwrite(pte_mkdirty(entry));
+	entry = mk_pte(page, prot);
 	set_pte(pte, entry);
 	pte_chain = page_add_rmap(page, pte, pte_chain);
 	pte_unmap(pte);
-	flush_tlb_page(vma, addr);
+	if (flush)
+		flush_tlb_page(vma, addr);
 
 	spin_unlock(&mm->page_table_lock);
 	pte_chain_free(pte_chain);
@@ -104,26 +107,38 @@
  *
  * this syscall works purely via pagetables, so it's the most efficient
  * way to map the same (large) file into a given virtual window. Unlike
- * mremap()/mmap() it does not create any new vmas.
+ * mmap()/mremap() it does not create any new vmas. The new mappings are
+ * also safe across swapout.
  *
- * The new mappings do not live across swapout, so either use MAP_LOCKED
- * or use PROT_NONE in the original linear mapping and add a special
- * SIGBUS pagefault handler to reinstall zapped mappings.
+ * NOTE: the 'prot' parameter right now is ignored, and the vma's default
+ * protection is used. Arbitrary protections might be implemented in the
+ * future.
  */
-int sys_remap_file_pages(unsigned long start, unsigned long size,
-	unsigned long prot, unsigned long pgoff, unsigned long flags)
+long sys_remap_file_pages(unsigned long start, unsigned long size,
+	unsigned long __prot, unsigned long pgoff, unsigned long flags)
 {
 	struct mm_struct *mm = current->mm;
 	unsigned long end = start + size;
 	struct vm_area_struct *vma;
 	int err = -EINVAL;
 
+	if (__prot)
+		return err;
 	/*
 	 * Sanitize the syscall parameters:
 	 */
-	start = PAGE_ALIGN(start);
-	size = PAGE_ALIGN(size);
-	prot &= 0xf;
+	start = start & PAGE_MASK;
+	size = size & PAGE_MASK;
+
+	/* Does the address range wrap, or is the span zero-sized? */
+	if (start + size <= start)
+		return err;
+
+	/* Can we represent this offset inside this architecture's pte's? */
+#if PTE_FILE_MAX_BITS < BITS_PER_LONG
+	if (pgoff + (size >> PAGE_SHIFT) >= (1UL << PTE_FILE_MAX_BITS))
+		return err;
+#endif
 
 	down_read(&mm->mmap_sem);
 
@@ -136,15 +151,9 @@
 	if (vma && (vma->vm_flags & VM_SHARED) &&
 		vma->vm_ops && vma->vm_ops->populate &&
 			end > start && start >= vma->vm_start &&
-				end <= vma->vm_end) {
-		/*
-		 * Change the default protection to PROT_NONE:
-		 */
-		if (pgprot_val(vma->vm_page_prot) != pgprot_val(__S000))
-			vma->vm_page_prot = __S000;
-		err = vma->vm_ops->populate(vma, start, size, prot,
-						pgoff, flags & MAP_NONBLOCK);
-	}
+				end <= vma->vm_end)
+		err = vma->vm_ops->populate(vma, start, size, vma->vm_page_prot,
+				pgoff, flags & MAP_NONBLOCK);
 
 	up_read(&mm->mmap_sem);
 
diff -Nru a/mm/highmem.c b/mm/highmem.c
--- a/mm/highmem.c	Mon Feb  3 23:46:47 2003
+++ b/mm/highmem.c	Sun Mar 23 01:40:12 2003
@@ -17,6 +17,7 @@
  */
 
 #include <linux/mm.h>
+#include <linux/swap.h>
 #include <linux/bio.h>
 #include <linux/pagemap.h>
 #include <linux/mempool.h>
@@ -120,7 +121,7 @@
 		{
 			DECLARE_WAITQUEUE(wait, current);
 
-			current->state = TASK_UNINTERRUPTIBLE;
+			__set_current_state(TASK_UNINTERRUPTIBLE);
 			add_wait_queue(&pkmap_map_wait, &wait);
 			spin_unlock(&kmap_lock);
 			schedule();
diff -Nru a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c	Sun Mar 16 22:33:14 2003
+++ b/mm/memory.c	Sat Mar 22 22:06:03 2003
@@ -281,7 +281,8 @@
 					goto cont_copy_pte_range_noset;
 				/* pte contains position in swap, so copy. */
 				if (!pte_present(pte)) {
-					swap_duplicate(pte_to_swp_entry(pte));
+					if (!pte_file(pte))
+						swap_duplicate(pte_to_swp_entry(pte));
 					set_pte(dst_pte, pte);
 					goto cont_copy_pte_range_noset;
 				}
@@ -415,7 +416,8 @@
 				}
 			}
 		} else {
-			free_swap_and_cache(pte_to_swp_entry(pte));
+			if (!pte_file(pte))
+				free_swap_and_cache(pte_to_swp_entry(pte));
 			pte_clear(ptep);
 		}
 	}
@@ -1393,6 +1395,41 @@
 }
 
 /*
+ * Fault of a previously existing named mapping. Repopulate the pte
+ * from the encoded file_pte if possible. This enables swappable
+ * nonlinear vmas.
+ */
+static int do_file_page(struct mm_struct * mm, struct vm_area_struct * vma,
+	unsigned long address, int write_access, pte_t *pte, pmd_t *pmd)
+{
+	unsigned long pgoff;
+	int err;
+
+	BUG_ON(!vma->vm_ops || !vma->vm_ops->nopage);
+	/*
+	 * Fall back to the linear mapping if the fs does not support
+	 * ->populate:
+	 */
+	if (!vma->vm_ops || !vma->vm_ops->populate || 
+			(write_access && !(vma->vm_flags & VM_SHARED))) {
+		pte_clear(pte);
+		return do_no_page(mm, vma, address, write_access, pte, pmd);
+	}
+
+	pgoff = pte_to_pgoff(*pte);
+
+	pte_unmap(pte);
+	spin_unlock(&mm->page_table_lock);
+
+	err = vma->vm_ops->populate(vma, address & PAGE_MASK, PAGE_SIZE, vma->vm_page_prot, pgoff, 0);
+	if (err == -ENOMEM)
+		return VM_FAULT_OOM;
+	if (err)
+		return VM_FAULT_SIGBUS;
+	return VM_FAULT_MAJOR;
+}
+
+/*
  * These routines also need to handle stuff like marking pages dirty
  * and/or accessed for architectures that don't do it in hardware (most
  * RISC architectures).  The early dirtying is also good on the i386.
@@ -1428,6 +1465,8 @@
 		 */
 		if (pte_none(entry))
 			return do_no_page(mm, vma, address, write_access, pte, pmd);
+		if (pte_file(entry))
+			return do_file_page(mm, vma, address, write_access, pte, pmd);
 		return do_swap_page(mm, vma, address, pte, pmd, entry, write_access);
 	}
 
@@ -1453,7 +1492,7 @@
 	pgd_t *pgd;
 	pmd_t *pmd;
 
-	current->state = TASK_RUNNING;
+	__set_current_state(TASK_RUNNING);
 	pgd = pgd_offset(mm, address);
 
 	inc_page_state(pgfault);
diff -Nru a/mm/mlock.c b/mm/mlock.c
--- a/mm/mlock.c	Tue Sep 17 11:05:14 2002
+++ b/mm/mlock.c	Fri Mar 21 03:28:02 2003
@@ -111,16 +111,8 @@
 	lock_limit >>= PAGE_SHIFT;
 
 	/* check against resource limits */
-	if (locked > lock_limit)
-		goto out;
-
-	/* we may lock at most half of physical memory... */
-	/* (this check is pretty bogus, but doesn't hurt) */
-	if (locked > num_physpages/2)
-		goto out;
-
-	error = do_mlock(start, len, 1);
-out:
+	if (locked <= lock_limit)
+		error = do_mlock(start, len, 1);
 	up_write(&current->mm->mmap_sem);
 	return error;
 }
@@ -178,15 +170,8 @@
 	lock_limit >>= PAGE_SHIFT;
 
 	ret = -ENOMEM;
-	if (current->mm->total_vm > lock_limit)
-		goto out;
-
-	/* we may lock at most half of physical memory... */
-	/* (this check is pretty bogus, but doesn't hurt) */
-	if (current->mm->total_vm > num_physpages/2)
-		goto out;
-
-	ret = do_mlockall(flags);
+	if (current->mm->total_vm <= lock_limit)
+		ret = do_mlockall(flags);
 out:
 	up_write(&current->mm->mmap_sem);
 	return ret;
diff -Nru a/mm/mmap.c b/mm/mmap.c
--- a/mm/mmap.c	Sat Mar  8 14:50:32 2003
+++ b/mm/mmap.c	Tue Mar 18 03:24:48 2003
@@ -53,11 +53,6 @@
 int sysctl_overcommit_ratio = 50;	/* default is 50% */
 atomic_t vm_committed_space = ATOMIC_INIT(0);
 
-inline void vm_unacct_memory(long pages)
-{	
-	atomic_sub(pages, &vm_committed_space);
-}
-
 /*
  * Check that a process has enough memory to allocate a new virtual
  * mapping. 1 means there is enough memory for the allocation to
@@ -73,7 +68,7 @@
 {
 	unsigned long free, allowed;
 
-	atomic_add(pages, &vm_committed_space);
+	vm_acct_memory(pages);
 
         /*
 	 * Sometimes we want to use more memory than we have
diff -Nru a/mm/nommu.c b/mm/nommu.c
--- a/mm/nommu.c	Tue Nov 26 07:32:56 2002
+++ b/mm/nommu.c	Mon Mar 17 21:32:09 2003
@@ -130,6 +130,11 @@
 	return kmalloc(size, gfp_mask & ~__GFP_HIGHMEM);
 }
 
+struct page * vmalloc_to_page(void *addr)
+{
+	return virt_to_page(addr);
+}
+
 long vread(char *buf, char *addr, unsigned long count)
 {
 	memcpy(buf, addr, count);
@@ -544,6 +549,17 @@
 struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr)
 {
 	return NULL;
+}
+
+struct page * follow_page(struct mm_struct *mm, unsigned long addr, int write)
+{
+	return NULL;
+}
+
+int remap_page_range(struct vm_area_struct *vma, unsigned long from,
+		unsigned long to, unsigned long size, pgprot_t prot)
+{
+	return -EPERM;
 }
 
 unsigned long get_unmapped_area(struct file *file, unsigned long addr,
diff -Nru a/mm/oom_kill.c b/mm/oom_kill.c
--- a/mm/oom_kill.c	Mon Feb 24 23:13:24 2003
+++ b/mm/oom_kill.c	Thu Mar 20 10:43:25 2003
@@ -51,7 +51,7 @@
  * 3) we don't kill anything innocent of eating tons of memory
  * 4) we want to kill the minimum amount of processes (one)
  * 5) we try to kill the process the user expects us to kill, this
- *    algorithm has been meticulously tuned to meet the priniciple
+ *    algorithm has been meticulously tuned to meet the principle
  *    of least surprise ... (be careful when you change it)
  */
 
diff -Nru a/mm/page-writeback.c b/mm/page-writeback.c
--- a/mm/page-writeback.c	Sun Mar 16 22:33:14 2003
+++ b/mm/page-writeback.c	Sun Mar 23 01:40:12 2003
@@ -15,6 +15,7 @@
 #include <linux/spinlock.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/swap.h>
 #include <linux/slab.h>
 #include <linux/pagemap.h>
 #include <linux/writeback.h>
diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c
--- a/mm/page_alloc.c	Wed Feb  5 20:05:13 2003
+++ b/mm/page_alloc.c	Sat Mar 22 22:14:49 2003
@@ -804,6 +804,11 @@
 DEFINE_PER_CPU(struct page_state, page_states) = {0};
 EXPORT_PER_CPU_SYMBOL(page_states);
 
+atomic_t nr_pagecache = ATOMIC_INIT(0);
+#ifdef CONFIG_SMP
+DEFINE_PER_CPU(long, nr_pagecache_local) = 0;
+#endif
+
 void __get_page_state(struct page_state *ret, int nr)
 {
 	int cpu = 0;
@@ -857,14 +862,6 @@
 	}
 }
 
-unsigned long get_page_cache_size(void)
-{
-	struct page_state ps;
-
-	get_page_state(&ps);
-	return ps.nr_pagecache;
-}
-
 void si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
@@ -1434,7 +1431,6 @@
 static char *vmstat_text[] = {
 	"nr_dirty",
 	"nr_writeback",
-	"nr_pagecache",
 	"nr_page_table_pages",
 	"nr_reverse_maps",
 	"nr_mapped",
diff -Nru a/mm/rmap.c b/mm/rmap.c
--- a/mm/rmap.c	Sun Jan  5 07:28:46 2003
+++ b/mm/rmap.c	Sun Mar 23 01:40:12 2003
@@ -22,6 +22,7 @@
  */
 #include <linux/mm.h>
 #include <linux/pagemap.h>
+#include <linux/swap.h>
 #include <linux/swapops.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -365,11 +366,28 @@
 	pte = ptep_get_and_clear(ptep);
 	flush_tlb_page(vma, address);
 
-	/* Store the swap location in the pte. See handle_pte_fault() ... */
 	if (PageSwapCache(page)) {
+		/*
+		 * Store the swap location in the pte.
+		 * See handle_pte_fault() ...
+		 */
 		swp_entry_t entry = { .val = page->index };
 		swap_duplicate(entry);
 		set_pte(ptep, swp_entry_to_pte(entry));
+		BUG_ON(pte_file(*ptep));
+	} else {
+		unsigned long pgidx;
+		/*
+		 * If a nonlinear mapping then store the file page offset
+		 * in the pte.
+		 */
+		pgidx = (address - vma->vm_start) >> PAGE_SHIFT;
+		pgidx += vma->vm_pgoff;
+		pgidx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT;
+		if (page->index != pgidx) {
+			set_pte(ptep, pgoff_to_pte(page->index));
+			BUG_ON(!pte_file(*ptep));
+		}
 	}
 
 	/* Move the dirty bit to the physical page now the pte is gone. */
diff -Nru a/mm/shmem.c b/mm/shmem.c
--- a/mm/shmem.c	Sun Jan  5 07:28:48 2003
+++ b/mm/shmem.c	Sat Mar 22 07:38:04 2003
@@ -945,7 +945,7 @@
 
 static int shmem_populate(struct vm_area_struct *vma,
 	unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long pgoff, int nonblock)
+	pgprot_t prot, unsigned long pgoff, int nonblock)
 {
 	struct inode *inode = vma->vm_file->f_dentry->d_inode;
 	struct mm_struct *mm = vma->vm_mm;
@@ -1882,7 +1882,7 @@
 		goto out2;
 	}
 #ifdef CONFIG_TMPFS
-	devfs_mk_dir(NULL, "shm", NULL);
+	devfs_mk_dir("shm");
 #endif
 	shm_mnt = kern_mount(&tmpfs_fs_type);
 	if (IS_ERR(shm_mnt)) {
diff -Nru a/mm/slab.c b/mm/slab.c
--- a/mm/slab.c	Tue Mar 11 07:15:44 2003
+++ b/mm/slab.c	Thu Mar 20 03:11:47 2003
@@ -344,8 +344,20 @@
 
 #endif
 
-/* maximum size of an obj (in 2^order pages) */
+/*
+ * Maximum size of an obj (in 2^order pages)
+ * and absolute limit for the gfp order.
+ */
+#if defined(CONFIG_LARGE_ALLOCS)
+#define	MAX_OBJ_ORDER	13	/* up to 32Mb */
+#define	MAX_GFP_ORDER	13	/* up to 32Mb */
+#elif defined(CONFIG_MMU)
 #define	MAX_OBJ_ORDER	5	/* 32 pages */
+#define	MAX_GFP_ORDER	5	/* 32 pages */
+#else
+#define	MAX_OBJ_ORDER	8	/* up to 1Mb */
+#define	MAX_GFP_ORDER	8	/* up to 1Mb */
+#endif
 
 /*
  * Do not go above this order unless 0 objects fit into the slab.
@@ -354,12 +366,6 @@
 #define	BREAK_GFP_ORDER_LO	1
 static int slab_break_gfp_order = BREAK_GFP_ORDER_LO;
 
-/*
- * Absolute limit for the gfp order
- */
-#define	MAX_GFP_ORDER	5	/* 32 pages */
-
-
 /* Macros for storing/retrieving the cachep and or slab from the
  * global 'mem_map'. These are used to find the slab an obj belongs to.
  * With kfree(), these are used to find the cache which an obj belongs to.
@@ -399,6 +405,18 @@
 	{ 32768,	NULL, NULL},
 	{ 65536,	NULL, NULL},
 	{131072,	NULL, NULL},
+#ifndef CONFIG_MMU
+	{262144,	NULL, NULL},
+	{524288,	NULL, NULL},
+	{1048576,	NULL, NULL},
+#ifdef CONFIG_LARGE_ALLOCS
+	{2097152,	NULL, NULL},
+	{4194304,	NULL, NULL},
+	{8388608,	NULL, NULL},
+	{16777216,	NULL, NULL},
+	{33554432,	NULL, NULL},
+#endif /* CONFIG_LARGE_ALLOCS */
+#endif /* CONFIG_MMU */
 	{     0,	NULL, NULL}
 };
 /* Must match cache_sizes above. Out of line to keep cache footprint low. */
@@ -427,7 +445,19 @@
 	CN("size-16384"),
 	CN("size-32768"),
 	CN("size-65536"),
-	CN("size-131072")
+	CN("size-131072"),
+#ifndef CONFIG_MMU
+	CN("size-262144"),
+	CN("size-524288"),
+	CN("size-1048576"),
+#ifdef CONFIG_LARGE_ALLOCS
+	CN("size-2097152"),
+	CN("size-4194304"),
+	CN("size-8388608"),
+	CN("size-16777216"),
+	CN("size-33554432"),
+#endif /* CONFIG_LARGE_ALLOCS */
+#endif /* CONFIG_MMU */
 }; 
 #undef CN
 
@@ -2145,7 +2175,9 @@
 	 * The numbers are guessed, we should auto-tune as described by
 	 * Bonwick.
 	 */
-	if (cachep->objsize > PAGE_SIZE)
+	if (cachep->objsize > 131072)
+		limit = 1;
+	else if (cachep->objsize > PAGE_SIZE)
 		limit = 8;
 	else if (cachep->objsize > 1024)
 		limit = 54;
@@ -2162,7 +2194,7 @@
 	if (limit > 32)
 		limit = 32;
 #endif
-	err = do_tune_cpucache(cachep, limit, limit/2);
+	err = do_tune_cpucache(cachep, limit, (limit+1)/2);
 	if (err)
 		printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n",
 					cachep->name, -err);
diff -Nru a/mm/swap.c b/mm/swap.c
--- a/mm/swap.c	Sun Mar  2 18:14:31 2003
+++ b/mm/swap.c	Tue Mar 18 01:44:12 2003
@@ -16,6 +16,7 @@
 #include <linux/mm.h>
 #include <linux/kernel_stat.h>
 #include <linux/swap.h>
+#include <linux/mman.h>
 #include <linux/pagemap.h>
 #include <linux/pagevec.h>
 #include <linux/init.h>
@@ -346,6 +347,32 @@
 	pvec->nr = find_get_pages(mapping, start, nr_pages, pvec->pages);
 	return pagevec_count(pvec);
 }
+
+
+#ifdef CONFIG_SMP
+/*
+ * We tolerate a little inaccuracy to avoid ping-ponging the counter between
+ * CPUs
+ */
+#define ACCT_THRESHOLD	max(16, NR_CPUS * 2)
+
+static DEFINE_PER_CPU(long, committed_space) = 0;
+
+void vm_acct_memory(long pages)
+{
+	long *local;
+
+	preempt_disable();
+	local = &__get_cpu_var(committed_space);
+	*local += pages;
+	if (*local > ACCT_THRESHOLD || *local < -ACCT_THRESHOLD) {
+		atomic_add(*local, &vm_committed_space);
+		*local = 0;
+	}
+	preempt_enable();
+}
+#endif
+
 
 /*
  * Perform any setup for the swap system
diff -Nru a/mm/swapfile.c b/mm/swapfile.c
--- a/mm/swapfile.c	Sun Jan  5 07:28:47 2003
+++ b/mm/swapfile.c	Sat Mar 22 22:06:03 2003
@@ -384,6 +384,8 @@
 {
 	pte_t pte = *dir;
 
+	if (pte_file(pte))
+		return;
 	if (likely(pte_to_swp_entry(pte).val != entry.val))
 		return;
 	if (unlikely(pte_none(pte) || pte_present(pte)))
@@ -736,8 +738,7 @@
 		 * interactive performance.  Interruptible check on
 		 * signal_pending() would be nice, but changes the spec?
 		 */
-		if (need_resched())
-			schedule();
+		cond_resched();
 	}
 
 	mmput(start_mm);
diff -Nru a/net/8021q/vlan.c b/net/8021q/vlan.c
--- a/net/8021q/vlan.c	Wed Nov 20 12:31:08 2002
+++ b/net/8021q/vlan.c	Wed Mar 19 21:17:02 2003
@@ -433,7 +433,6 @@
 	/* set up method calls */
 	new_dev->init = vlan_dev_init;
 	new_dev->destructor = vlan_dev_destruct;
-	new_dev->features |= NETIF_F_DYNALLOC ; 
 	    
 	/* new_dev->ifindex = 0;  it will be set when added to
 	 * the global list.
diff -Nru a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
--- a/net/8021q/vlan_dev.c	Wed Nov 20 12:31:08 2002
+++ b/net/8021q/vlan_dev.c	Wed Mar 19 21:17:02 2003
@@ -785,6 +785,7 @@
 			kfree(dev->priv);
 			dev->priv = NULL;
 		}
+		kfree(dev);
 	}
 }
 
diff -Nru a/net/Makefile b/net/Makefile
--- a/net/Makefile	Thu Mar  6 11:06:44 2003
+++ b/net/Makefile	Thu Mar 20 00:55:30 2003
@@ -5,7 +5,9 @@
 # Rewritten to use lists instead of if-statements.
 #
 
-obj-y	:= socket.o core/
+obj-y	:= nonet.o
+
+obj-$(CONFIG_NET)		:= socket.o core/
 
 obj-$(CONFIG_COMPAT)		+= compat.o
 
diff -Nru a/net/atm/pppoatm.c b/net/atm/pppoatm.c
--- a/net/atm/pppoatm.c	Thu Jul 18 23:16:19 2002
+++ b/net/atm/pppoatm.c	Thu Mar 20 00:45:11 2003
@@ -231,7 +231,7 @@
 		kfree_skb(skb);
 		return 1;
 	}
-	atomic_add(skb->truesize, &ATM_SKB(skb)->vcc->tx_inuse);
+	atomic_add(skb->truesize, &ATM_SKB(skb)->vcc->sk->wmem_alloc);
 	ATM_SKB(skb)->iovcnt = 0;
 	ATM_SKB(skb)->atm_options = ATM_SKB(skb)->vcc->atm_options;
 	DPRINTK("(unit %d): atm_skb(%p)->vcc(%p)->dev(%p)\n",
diff -Nru a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c
--- a/net/bridge/netfilter/ebt_ip.c	Mon Mar  3 04:41:09 2003
+++ b/net/bridge/netfilter/ebt_ip.c	Wed Mar 19 23:57:11 2003
@@ -86,7 +86,7 @@
 	if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK)
 		return -EINVAL;
 	if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) {
-		if (!(info->bitmask & EBT_IPROTO))
+		if (info->bitmask & EBT_IPROTO)
 			return -EINVAL;
 		if (info->protocol != IPPROTO_TCP &&
 		    info->protocol != IPPROTO_UDP)
diff -Nru a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
--- a/net/bridge/netfilter/ebtable_broute.c	Mon Mar  3 04:41:09 2003
+++ b/net/bridge/netfilter/ebtable_broute.c	Sun Mar 23 04:46:53 2003
@@ -49,6 +49,7 @@
 	.valid_hooks	= 1 << NF_BR_BROUTING,
 	.lock		= RW_LOCK_UNLOCKED,
 	.check		= check,
+	.me		= THIS_MODULE,
 };
 
 static int ebt_broute(struct sk_buff **pskb)
diff -Nru a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
--- a/net/bridge/netfilter/ebtable_filter.c	Mon Mar  3 04:41:09 2003
+++ b/net/bridge/netfilter/ebtable_filter.c	Sun Mar 23 04:46:53 2003
@@ -57,6 +57,7 @@
 	.valid_hooks	= FILTER_VALID_HOOKS, 
 	.lock		= RW_LOCK_UNLOCKED,
 	.check		= check,
+	.me		= THIS_MODULE,
 };
 
 static unsigned int
diff -Nru a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
--- a/net/bridge/netfilter/ebtable_nat.c	Mon Mar  3 04:41:09 2003
+++ b/net/bridge/netfilter/ebtable_nat.c	Sun Mar 23 04:46:53 2003
@@ -56,6 +56,7 @@
 	.valid_hooks	= NAT_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.check		= check,
+	.me		= THIS_MODULE,
 };
 
 static unsigned int
diff -Nru a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
--- a/net/bridge/netfilter/ebtables.c	Mon Mar  3 04:41:09 2003
+++ b/net/bridge/netfilter/ebtables.c	Sun Mar 23 04:46:53 2003
@@ -969,8 +969,10 @@
 		goto free_counterstmp;
 
 	t = find_table_lock(tmp.name, &ret, &ebt_mutex);
-	if (!t)
+	if (!t) {
+		ret = -ENOENT;
 		goto free_iterate;
+	}
 
 	/* the table doesn't like it */
 	if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
@@ -984,6 +986,12 @@
 
 	/* we have the mutex lock, so no danger in reading this pointer */
 	table = t->private;
+	/* make sure the table can only be rmmod'ed if it contains no rules */
+	if (!table->nentries && newinfo->nentries && !try_module_get(t->me)) {
+		ret = -ENOENT;
+		goto free_unlock;
+	} else if (table->nentries && !newinfo->nentries)
+		module_put(t->me);
 	/* we need an atomic snapshot of the counters */
 	write_lock_bh(&t->lock);
 	if (tmp.num_counters)
@@ -1168,6 +1176,11 @@
 		goto free_unlock;
 	}
 
+	/* Hold a reference count if the chains aren't empty */
+	if (newinfo->nentries && !try_module_get(table->me)) {
+		ret = -ENOENT;
+		goto free_unlock;
+	}
 	list_prepend(&ebt_tables, table);
 	up(&ebt_mutex);
 	return 0;
@@ -1196,8 +1209,6 @@
 	down(&ebt_mutex);
 	LIST_DELETE(&ebt_tables, table);
 	up(&ebt_mutex);
-	EBT_ENTRY_ITERATE(table->private->entries,
-	   table->private->entries_size, ebt_cleanup_entry, NULL);
 	if (table->private->entries)
 		vfree(table->private->entries);
 	if (table->private->chainstack) {
diff -Nru a/net/compat.c b/net/compat.c
--- a/net/compat.c	Thu Mar  6 11:02:18 2003
+++ b/net/compat.c	Sun Mar 23 22:47:02 2003
@@ -25,15 +25,10 @@
 #include <net/scm.h>
 #include <net/sock.h>
 #include <asm/uaccess.h>
-#include <net/compat_socket.h>
+#include <net/compat.h>
 
-#define A(__x)		((unsigned long)(__x))
 #define AA(__x)		((unsigned long)(__x))
 
-extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
-				       void * optval, int *optlen);
-
-
 static inline int iov_from_user_compat_to_kern(struct iovec *kiov,
 					  struct compat_iovec *uiov32,
 					  int niov)
@@ -41,7 +36,8 @@
 	int tot_len = 0;
 
 	while(niov > 0) {
-		u32 len, buf;
+		compat_uptr_t buf;
+		compat_size_t len;
 
 		if(get_user(len, &uiov32->iov_len) ||
 		   get_user(buf, &uiov32->iov_base)) {
@@ -49,7 +45,7 @@
 			break;
 		}
 		tot_len += len;
-		kiov->iov_base = (void *)A(buf);
+		kiov->iov_base = compat_ptr(buf);
 		kiov->iov_len = (__kernel_size_t) len;
 		uiov32++;
 		kiov++;
@@ -58,27 +54,23 @@
 	return tot_len;
 }
 
-int msghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct compat_msghdr *umsg)
+int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr *umsg)
 {
-	u32 tmp1, tmp2, tmp3;
-	int err;
-
-	err = get_user(tmp1, &umsg->msg_name);
-	err |= __get_user(tmp2, &umsg->msg_iov);
-	err |= __get_user(tmp3, &umsg->msg_control);
-	if (err)
-		return -EFAULT;
+	compat_uptr_t tmp1, tmp2, tmp3;
 
-	kmsg->msg_name = (void *)A(tmp1);
-	kmsg->msg_iov = (struct iovec *)A(tmp2);
-	kmsg->msg_control = (void *)A(tmp3);
-
-	err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
-	err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
-	err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
-	err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
-	
-	return err;
+	if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) ||
+	    __get_user(tmp1, &umsg->msg_name) ||
+	    __get_user(kmsg->msg_namelen, &umsg->msg_namelen) ||
+	    __get_user(tmp2, &umsg->msg_iov) ||
+	    __get_user(kmsg->msg_iovlen, &umsg->msg_iovlen) ||
+	    __get_user(tmp3, &umsg->msg_control) ||
+	    __get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
+	    __get_user(kmsg->msg_flags, &umsg->msg_flags))
+		return -EFAULT;
+	kmsg->msg_name = compat_ptr(tmp1);
+	kmsg->msg_iov = compat_ptr(tmp2);
+	kmsg->msg_control = compat_ptr(tmp3);
+	return 0;
 }
 
 /* I've named the args so it is easy to tell whose space the pointers are in. */
@@ -117,6 +109,34 @@
 	return tot_len;
 }
 
+/* Bleech... */
+#define CMSG_COMPAT_ALIGN(len)	ALIGN((len), sizeof(s32))
+
+#define CMSG_COMPAT_DATA(cmsg)				\
+	((void *)((char *)(cmsg) + CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr))))
+#define CMSG_COMPAT_SPACE(len)				\
+	(CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)) + CMSG_COMPAT_ALIGN(len))
+#define CMSG_COMPAT_LEN(len)				\
+	(CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)) + (len))
+
+#define CMSG_COMPAT_FIRSTHDR(msg)			\
+	(((msg)->msg_controllen) >= sizeof(struct compat_cmsghdr) ?	\
+	 (struct compat_cmsghdr *)((msg)->msg_control) :		\
+	 (struct compat_cmsghdr *)NULL)
+
+static inline struct compat_cmsghdr *cmsg_compat_nxthdr(struct msghdr *msg,
+		struct compat_cmsghdr *cmsg, int cmsg_len)
+{
+	struct compat_cmsghdr *ptr;
+
+	ptr = (struct compat_cmsghdr *)(((unsigned char *)cmsg) +
+			CMSG_COMPAT_ALIGN(cmsg_len));
+	if ((unsigned long)((char *)(ptr + 1) - (char *)msg->msg_control) >
+			msg->msg_controllen)
+		return NULL;
+	return ptr;
+}
+
 /* There is a lot of hair here because the alignment rules (and
  * thus placement) of cmsg headers and length are different for
  * 32-bit apps.  -DaveM
@@ -147,7 +167,7 @@
 		tmp = ((ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg))) +
 		       CMSG_ALIGN(sizeof(struct cmsghdr)));
 		kcmlen += tmp;
-		ucmsg = CMSG_COMPAT_NXTHDR(kmsg, ucmsg, ucmlen);
+		ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
 	}
 	if(kcmlen == 0)
 		return -EINVAL;
@@ -181,7 +201,7 @@
 
 		/* Advance. */
 		kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
-		ucmsg = CMSG_COMPAT_NXTHDR(kmsg, ucmsg, ucmlen);
+		ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
 	}
 
 	/* Ok, looks like we made it.  Hook it up and return success. */
@@ -304,7 +324,7 @@
  *		IPV6_RTHDR	ipv6 routing exthdr	32-bit clean
  *		IPV6_AUTHHDR	ipv6 auth exthdr	32-bit clean
  */
-void cmsg_compat_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
+static void cmsg_compat_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
 {
 	unsigned char *workbuf, *wp;
 	unsigned long bufsz, space_avail;
@@ -365,112 +385,133 @@
 	kmsg->msg_control = (void *) orig_cmsg_uptr;
 }
 
-extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
+int put_compat_msg_controllen(struct msghdr *msg_sys,
+		struct compat_msghdr *msg_compat, unsigned long cmsg_ptr)
+{
+	unsigned long ucmsg_ptr;
+	compat_size_t uclen;
+
+	if ((unsigned long)msg_sys->msg_control != cmsg_ptr)
+		cmsg_compat_recvmsg_fixup(msg_sys, cmsg_ptr);
+	ucmsg_ptr = ((unsigned long)msg_sys->msg_control);
+	uclen = (compat_size_t) (ucmsg_ptr - cmsg_ptr);
+	return __put_user(uclen, &msg_compat->msg_controllen);
+}
+
+extern asmlinkage long sys_setsockopt(int fd, int level, int optname,
 				     char *optval, int optlen);
 
+/*
+ * For now, we assume that the compatibility and native version
+ * of struct ipt_entry are the same - sfr.  FIXME
+ */
+struct compat_ipt_replace {
+	char			name[IPT_TABLE_MAXNAMELEN];
+	u32			valid_hooks;
+	u32			num_entries;
+	u32			size;
+	u32			hook_entry[NF_IP_NUMHOOKS];
+	u32			underflow[NF_IP_NUMHOOKS];
+	u32			num_counters;
+	compat_uptr_t		counters;	/* struct ipt_counters * */
+	struct ipt_entry	entries[0];
+};
+
 static int do_netfilter_replace(int fd, int level, int optname,
 				char *optval, int optlen)
 {
-	struct ipt_replace32 {
-		char name[IPT_TABLE_MAXNAMELEN];
-		__u32 valid_hooks;
-		__u32 num_entries;
-		__u32 size;
-		__u32 hook_entry[NF_IP_NUMHOOKS];
-		__u32 underflow[NF_IP_NUMHOOKS];
-		__u32 num_counters;
-		__u32 counters;
-		struct ipt_entry entries[0];
-	} *repl32 = (struct ipt_replace32 *)optval;
+	struct compat_ipt_replace *urepl = (struct compat_ipt_replace *)optval;
 	struct ipt_replace *krepl;
-	struct ipt_counters *counters32;
-	__u32 origsize;
-	unsigned int kreplsize, kcountersize;
+	u32 origsize;
+	unsigned int kreplsize;
 	mm_segment_t old_fs;
 	int ret;
+	int i;
+	compat_uptr_t ucntrs;
 
-	if (optlen < sizeof(repl32))
-		return -EINVAL;
-
-	if (copy_from_user(&origsize,
-			&repl32->size,
-			sizeof(origsize)))
+	if (get_user(origsize, &urepl->size))
 		return -EFAULT;
 
-	kreplsize = sizeof(*krepl) + origsize;
-	kcountersize = krepl->num_counters * sizeof(struct ipt_counters);
-
 	/* Hack: Causes ipchains to give correct error msg --RR */
-	if (optlen != kreplsize)
+	if (optlen != sizeof(*urepl) + origsize)
 		return -ENOPROTOOPT;
 
+	/* XXX Assumes that size of ipt_entry is the same both in
+	 *     native and compat environments.
+	 */
+	kreplsize = sizeof(*krepl) + origsize;
 	krepl = (struct ipt_replace *)kmalloc(kreplsize, GFP_KERNEL);
 	if (krepl == NULL)
 		return -ENOMEM;
 
-	if (copy_from_user(krepl, optval, kreplsize)) {
-		kfree(krepl);
-		return -EFAULT;
+	ret = -EFAULT;
+	krepl->size = origsize;
+	if (!access_ok(VERIFY_READ, urepl, optlen) ||
+	    __copy_from_user(krepl->name, urepl->name, sizeof(urepl->name)) ||
+	    __get_user(krepl->valid_hooks, &urepl->valid_hooks) ||
+	    __get_user(krepl->num_entries, &urepl->num_entries) ||
+	    __get_user(krepl->num_counters, &urepl->num_counters) ||
+	    __get_user(ucntrs, &urepl->counters) ||
+	    __copy_from_user(krepl->entries, &urepl->entries, origsize))
+		goto out_free;
+	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
+		if (__get_user(krepl->hook_entry[i], &urepl->hook_entry[i]) ||
+		    __get_user(krepl->underflow[i], &urepl->underflow[i]))
+			goto out_free;
 	}
 
-	counters32 = (struct ipt_counters *)AA(
-		((struct ipt_replace32 *)krepl)->counters);
-
-	kcountersize = krepl->num_counters * sizeof(struct ipt_counters);
-	krepl->counters = (struct ipt_counters *)kmalloc(
-					kcountersize, GFP_KERNEL);
-	if (krepl->counters == NULL) {
-		kfree(krepl);
-		return -ENOMEM;
-	}
+	/*
+	 * Since struct ipt_counters just contains two u_int64_t members
+	 * we can just do the access_ok check here and pass the (converted)
+	 * pointer into the standard syscall.  We hope that the pointer is
+	 * not misaligned ...
+	 */
+	krepl->counters = compat_ptr(ucntrs);
+	if (!access_ok(VERIFY_WRITE, krepl->counters,
+			krepl->num_counters * sizeof(struct ipt_counters)))
+		goto out_free;
 
 	old_fs = get_fs();
 	set_fs(KERNEL_DS);
-	ret = sys_setsockopt(fd, level, optname,
-			     (char *)krepl, kreplsize);
+	ret = sys_setsockopt(fd, level, optname, (char *)krepl, kreplsize);
 	set_fs(old_fs);
 
-	if (ret == 0 &&
-		copy_to_user(counters32, krepl->counters, kcountersize))
-			ret = -EFAULT;
-
-	kfree(krepl->counters);
+out_free:
 	kfree(krepl);
-
 	return ret;
 }
 
+/*
+ * A struct sock_filter is architecture independent.
+ */
+struct compat_sock_fprog {
+	u16		len;
+	compat_uptr_t	filter;		/* struct sock_filter * */
+};
+
 static int do_set_attach_filter(int fd, int level, int optname,
 				char *optval, int optlen)
 {
-	struct sock_fprog32 {
-		__u16 len;
-		__u32 filter;
-	} *fprog32 = (struct sock_fprog32 *)optval;
+	struct compat_sock_fprog *fprog32 = (struct compat_sock_fprog *)optval;
 	struct sock_fprog kfprog;
-	struct sock_filter *kfilter;
-	unsigned int fsize;
 	mm_segment_t old_fs;
-	__u32 uptr;
+	compat_uptr_t uptr;
 	int ret;
 
-	if (get_user(kfprog.len, &fprog32->len) ||
+	if (!access_ok(VERIFY_READ, fprog32, sizeof(*fprog32)) ||
+	    __get_user(kfprog.len, &fprog32->len) ||
 	    __get_user(uptr, &fprog32->filter))
 		return -EFAULT;
 
-	kfprog.filter = (struct sock_filter *)A(uptr);
-	fsize = kfprog.len * sizeof(struct sock_filter);
-
-	kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
-	if (kfilter == NULL)
-		return -ENOMEM;
-
-	if (copy_from_user(kfilter, kfprog.filter, fsize)) {
-		kfree(kfilter);
+	kfprog.filter = compat_ptr(uptr);
+	/*
+	 * Since struct sock_filter is architecure independent,
+	 * we can just do the access_ok check and pass the
+	 * same pointer to the real syscall.
+	 */
+	if (!access_ok(VERIFY_READ, kfprog.filter,
+			kfprog.len * sizeof(struct sock_filter)))
 		return -EFAULT;
-	}
-
-	kfprog.filter = kfilter;
 
 	old_fs = get_fs();
 	set_fs(KERNEL_DS);
@@ -478,8 +519,6 @@
 			     (char *)&kfprog, sizeof(kfprog));
 	set_fs(old_fs);
 
-	kfree(kfilter);
-
 	return ret;
 }
 
@@ -490,10 +529,11 @@
 	mm_segment_t old_fs;
 	int ret, i;
 
+	if (optlen < sizeof(kfilter))
+		return -EINVAL;
 	if (copy_from_user(&kfilter, optval, sizeof(kfilter)))
 		return -EFAULT;
 
-
 	for (i = 0; i < 8; i += 2) {
 		u32 tmp = kfilter.data[i];
 
@@ -519,7 +559,8 @@
 
 	if (optlen < sizeof(*up))
 		return -EINVAL;
-	if (get_user(ktime.tv_sec, &up->tv_sec) ||
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+	    __get_user(ktime.tv_sec, &up->tv_sec) ||
 	    __get_user(ktime.tv_usec, &up->tv_usec))
 		return -EFAULT;
 	old_fs = get_fs();
@@ -530,7 +571,7 @@
 	return err;
 }
 
-asmlinkage int compat_sys_setsockopt(int fd, int level, int optname,
+asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
 				char *optval, int optlen)
 {
 	if (optname == IPT_SO_SET_REPLACE)
@@ -548,7 +589,11 @@
 	return sys_setsockopt(fd, level, optname, optval, optlen);
 }
 
-static int do_get_sock_timeout(int fd, int level, int optname, char *optval, int *optlen)
+extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
+				       void * optval, int *optlen);
+
+static int do_get_sock_timeout(int fd, int level, int optname, char *optval,
+		int *optlen)
 {
 	struct compat_timeval *up = (struct compat_timeval *) optval;
 	struct timeval ktime;
@@ -567,7 +612,8 @@
 
 	if (!err) {
 		if (put_user(sizeof(*up), optlen) ||
-		    put_user(ktime.tv_sec, &up->tv_sec) ||
+		    !access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+		    __put_user(ktime.tv_sec, &up->tv_sec) ||
 		    __put_user(ktime.tv_usec, &up->tv_usec))
 			err = -EFAULT;
 	}
@@ -589,27 +635,21 @@
 				AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
 #undef AL
 
-extern asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
-extern asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr,
-				  int addrlen);
-extern asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr,
-				 int *upeer_addrlen); 
-extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr,
-				      int *usockaddr_len);
-extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr,
-				      int *usockaddr_len);
-extern asmlinkage long sys_send(int fd, void *buff, size_t len, unsigned flags);
-extern asmlinkage long sys_sendto(int fd, u32 buff, compat_size_t len,
-				   unsigned flags, u32 addr, int addr_len);
-extern asmlinkage long sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
-extern asmlinkage long sys_recvfrom(int fd, u32 ubuf, compat_size_t size,
-				     unsigned flags, u32 addr, u32 addr_len);
-extern asmlinkage long sys_socket(int family, int type, int protocol);
-extern asmlinkage long sys_socketpair(int family, int type, int protocol,
-				     int usockvec[2]);
-extern asmlinkage long sys_shutdown(int fd, int how);
-extern asmlinkage long sys_listen(int fd, int backlog);
-
+extern asmlinkage long sys_bind(int, struct sockaddr *, int);
+extern asmlinkage long sys_connect(int, struct sockaddr *, int);
+extern asmlinkage long sys_accept(int, struct sockaddr *, int *); 
+extern asmlinkage long sys_getsockname(int, struct sockaddr *, int *);
+extern asmlinkage long sys_getpeername(int, struct sockaddr *, int *);
+extern asmlinkage long sys_send(int, void *, size_t, unsigned);
+extern asmlinkage long sys_sendto(int, void *, size_t, unsigned,
+		struct sockaddr *, int);
+extern asmlinkage long sys_recv(int, void *, size_t, unsigned);
+extern asmlinkage long sys_recvfrom(int, void *, size_t, unsigned,
+		struct sockaddr *, int *);
+extern asmlinkage long sys_socket(int, int, int);
+extern asmlinkage long sys_socketpair(int, int, int, int [2]);
+extern asmlinkage long sys_shutdown(int, int);
+extern asmlinkage long sys_listen(int, int);
 
 asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr *msg, unsigned flags)
 {
@@ -639,58 +679,54 @@
 		ret = sys_socket(a0, a1, a[2]);
 		break;
 	case SYS_BIND:
-		ret = sys_bind(a0, (struct sockaddr *)A(a1), a[2]);
+		ret = sys_bind(a0, compat_ptr(a1), a[2]);
 		break;
 	case SYS_CONNECT:
-		ret = sys_connect(a0, (struct sockaddr *)A(a1), a[2]);
+		ret = sys_connect(a0, compat_ptr(a1), a[2]);
 		break;
 	case SYS_LISTEN:
 		ret = sys_listen(a0, a1);
 		break;
 	case SYS_ACCEPT:
-		ret = sys_accept(a0, (struct sockaddr *)A(a1), (int *)A(a[2]));
+		ret = sys_accept(a0, compat_ptr(a1), compat_ptr(a[2]));
 		break;
 	case SYS_GETSOCKNAME:
-		ret = sys_getsockname(a0, (struct sockaddr *)A(a1),
-				       (int *)A(a[2]));
+		ret = sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]));
 		break;
 	case SYS_GETPEERNAME:
-		ret = sys_getpeername(a0, (struct sockaddr *)A(a1),
-				       (int *)A(a[2]));
+		ret = sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2]));
 		break;
 	case SYS_SOCKETPAIR:
-		ret = sys_socketpair(a0, a1, a[2], (int *)A(a[3]));
+		ret = sys_socketpair(a0, a1, a[2], compat_ptr(a[3]));
 		break;
 	case SYS_SEND:
-		ret = sys_send(a0, (void *)A(a1), a[2], a[3]);
+		ret = sys_send(a0, compat_ptr(a1), a[2], a[3]);
 		break;
 	case SYS_SENDTO:
-		ret = sys_sendto(a0, a1, a[2], a[3], a[4], a[5]);
+		ret = sys_sendto(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), a[5]);
 		break;
 	case SYS_RECV:
-		ret = sys_recv(a0, (void *)A(a1), a[2], a[3]);
+		ret = sys_recv(a0, compat_ptr(a1), a[2], a[3]);
 		break;
 	case SYS_RECVFROM:
-		ret = sys_recvfrom(a0, a1, a[2], a[3], a[4], a[5]);
+		ret = sys_recvfrom(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), compat_ptr(a[5]));
 		break;
 	case SYS_SHUTDOWN:
 		ret = sys_shutdown(a0,a1);
 		break;
 	case SYS_SETSOCKOPT:
-		ret = compat_sys_setsockopt(a0, a1, a[2], (char *)A(a[3]),
-				      a[4]);
+		ret = compat_sys_setsockopt(a0, a1, a[2],
+				compat_ptr(a[3]), a[4]);
 		break;
 	case SYS_GETSOCKOPT:
-		ret = compat_sys_getsockopt(a0, a1, a[2], (char *)(u64)a[3],
-					    (int *)(u64)a[4]);
+		ret = compat_sys_getsockopt(a0, a1, a[2],
+				compat_ptr(a[3]), compat_ptr(a[4]));
 		break;
 	case SYS_SENDMSG:
-		ret = compat_sys_sendmsg(a0, (struct compat_msghdr *)A(a1),
-				         a[2]);
+		ret = compat_sys_sendmsg(a0, compat_ptr(a1), a[2]);
 		break;
 	case SYS_RECVMSG:
-		ret = compat_sys_recvmsg(a0, (struct compat_msghdr *)A(a1),
-				         a[2]);
+		ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]);
 		break;
 	default:
 		ret = -EINVAL;
diff -Nru a/net/core/datagram.c b/net/core/datagram.c
--- a/net/core/datagram.c	Thu Jul 18 23:16:19 2002
+++ b/net/core/datagram.c	Tue Mar 11 23:12:12 2003
@@ -68,11 +68,9 @@
 static int wait_for_packet(struct sock *sk, int *err, long *timeo_p)
 {
 	int error;
+	DEFINE_WAIT(wait);
 
-	DECLARE_WAITQUEUE(wait, current);
-
-	__set_current_state(TASK_INTERRUPTIBLE);
-	add_wait_queue_exclusive(sk->sleep, &wait);
+	prepare_to_wait_exclusive(sk->sleep, &wait, TASK_INTERRUPTIBLE);
 
 	/* Socket errors? */
 	error = sock_error(sk);
@@ -101,8 +99,7 @@
 	error = 0;
 	*timeo_p = schedule_timeout(*timeo_p);
 out:
-	current->state = TASK_RUNNING;
-	remove_wait_queue(sk->sleep, &wait);
+	finish_wait(sk->sleep, &wait);
 	return error;
 interrupted:
 	error = sock_intr_errno(*timeo_p);
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	Tue Feb 25 19:23:02 2003
+++ b/net/core/dev.c	Wed Mar 19 21:17:02 2003
@@ -547,6 +547,50 @@
 }
 
 /**
+ *	dev_get_by_flags - find any device with given flags
+ *	@if_flags: IFF_* values
+ *	@mask: bitmask of bits in if_flags to check
+ *
+ *	Search for any interface with the given flags. Returns NULL if a device
+ *	is not found or a pointer to the device. The device returned has 
+ *	had a reference added and the pointer is safe until the user calls
+ *	dev_put to indicate they have finished with it.
+ */
+
+struct net_device * dev_get_by_flags(unsigned short if_flags, unsigned short mask)
+{
+	struct net_device *dev;
+
+	read_lock(&dev_base_lock);
+	dev = __dev_get_by_flags(if_flags, mask);
+	if (dev)
+		dev_hold(dev);
+	read_unlock(&dev_base_lock);
+	return dev;
+}
+
+/**
+ *	__dev_get_by_flags - find any device with given flags
+ *	@if_flags: IFF_* values
+ *	@mask: bitmask of bits in if_flags to check
+ *
+ *	Search for any interface with the given flags. Returns NULL if a device
+ *	is not found or a pointer to the device. The caller must hold either
+ *	the RTNL semaphore or @dev_base_lock.
+ */
+
+struct net_device *__dev_get_by_flags(unsigned short if_flags, unsigned short mask)
+{
+	struct net_device *dev;
+
+	for (dev = dev_base; dev != NULL; dev = dev->next) {
+		if (((dev->flags ^ if_flags) & mask) == 0)
+			return dev;
+	}
+	return NULL;
+}
+
+/**
  *	dev_alloc_name - allocate a name for a device
  *	@dev: device
  *	@name: name format string
@@ -2595,12 +2639,10 @@
 	}
 #ifdef NET_REFCNT_DEBUG
 	printk(KERN_DEBUG "netdev_finish_unregister: %s%s.\n", dev->name,
-	       (dev->features & NETIF_F_DYNALLOC)?"":", old style");
+	       (dev->destructor != NULL)?"":", old style");
 #endif
 	if (dev->destructor)
 		dev->destructor(dev);
-	if (dev->features & NETIF_F_DYNALLOC)
-		kfree(dev);
 	return 0;
 }
 
@@ -2680,7 +2722,7 @@
 	free_divert_blk(dev);
 #endif
 
-	if (dev->features & NETIF_F_DYNALLOC) {
+	if (dev->destructor != NULL) {
 #ifdef NET_REFCNT_DEBUG
 		if (atomic_read(&dev->refcnt) != 1)
 			printk(KERN_DEBUG "unregister_netdevice: holding %s "
diff -Nru a/net/core/dst.c b/net/core/dst.c
--- a/net/core/dst.c	Wed Nov  6 17:27:58 2002
+++ b/net/core/dst.c	Wed Mar 19 21:17:02 2003
@@ -228,7 +228,7 @@
 				   _race_ _condition_.
 				 */
 				if (event!=NETDEV_DOWN &&
-				    !(dev->features & NETIF_F_DYNALLOC) &&
+				    dev->destructor == NULL &&
 				    dst->output == dst_blackhole) {
 					dst->dev = &loopback_dev;
 					dev_put(dev);
diff -Nru a/net/core/neighbour.c b/net/core/neighbour.c
--- a/net/core/neighbour.c	Thu Nov 14 09:20:05 2002
+++ b/net/core/neighbour.c	Thu Mar 20 10:46:44 2003
@@ -550,7 +550,7 @@
 	write_lock(&tbl->lock);
 
 	/*
-	 *	periodicly recompute ReachableTime from random function
+	 *	periodically recompute ReachableTime from random function
 	 */
 
 	if (now - tbl->last_rand > 300 * HZ) {
diff -Nru a/net/core/scm.c b/net/core/scm.c
--- a/net/core/scm.c	Thu Mar  6 11:06:44 2003
+++ b/net/core/scm.c	Sun Mar 23 22:06:53 2003
@@ -30,6 +30,7 @@
 #include <net/protocol.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
+#include <net/compat.h>
 #include <net/scm.h>
 
 
diff -Nru a/net/core/skbuff.c b/net/core/skbuff.c
--- a/net/core/skbuff.c	Mon Mar  3 08:51:51 2003
+++ b/net/core/skbuff.c	Wed Mar 19 19:52:56 2003
@@ -208,6 +208,7 @@
 	skb->len	  = 0;
 	skb->data_len	  = 0;
 	skb->csum	  = 0;
+	skb->local_df	  = 0;
 	skb->cloned	  = 0;
 	skb->pkt_type	  = PACKET_HOST;	/* Default type */
 	skb->ip_summed	  = 0;
@@ -375,6 +376,7 @@
 	C(len);
 	C(data_len);
 	C(csum);
+	C(local_df);
 	n->cloned = 1;
 	C(pkt_type);
 	C(ip_summed);
@@ -438,6 +440,7 @@
 	new->mac.raw	= old->mac.raw + offset;
 	memcpy(new->cb, old->cb, sizeof(old->cb));
 	atomic_set(&new->users, 1);
+	new->local_df	= old->local_df;
 	new->pkt_type	= old->pkt_type;
 	new->stamp	= old->stamp;
 	new->destructor = NULL;
diff -Nru a/net/core/sock.c b/net/core/sock.c
--- a/net/core/sock.c	Sat Mar  8 11:39:01 2003
+++ b/net/core/sock.c	Tue Mar 11 23:12:12 2003
@@ -746,17 +746,16 @@
  */
 static long sock_wait_for_wmem(struct sock * sk, long timeo)
 {
-	DECLARE_WAITQUEUE(wait, current);
+	DEFINE_WAIT(wait);
 
 	clear_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
-	add_wait_queue(sk->sleep, &wait);
 	for (;;) {
 		if (!timeo)
 			break;
 		if (signal_pending(current))
 			break;
 		set_bit(SOCK_NOSPACE, &sk->socket->flags);
-		set_current_state(TASK_INTERRUPTIBLE);
+		prepare_to_wait(sk->sleep, &wait, TASK_INTERRUPTIBLE);
 		if (atomic_read(&sk->wmem_alloc) < sk->sndbuf)
 			break;
 		if (sk->shutdown & SEND_SHUTDOWN)
@@ -765,8 +764,7 @@
 			break;
 		timeo = schedule_timeout(timeo);
 	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(sk->sleep, &wait);
+	finish_wait(sk->sleep, &wait);
 	return timeo;
 }
 
@@ -860,19 +858,18 @@
 
 void __lock_sock(struct sock *sk)
 {
-	DECLARE_WAITQUEUE(wait, current);
+	DEFINE_WAIT(wait);
 
-	add_wait_queue_exclusive(&sk->lock.wq, &wait);
 	for(;;) {
-		current->state = TASK_UNINTERRUPTIBLE;
+		prepare_to_wait_exclusive(&sk->lock.wq, &wait,
+					TASK_UNINTERRUPTIBLE);
 		spin_unlock_bh(&sk->lock.slock);
 		schedule();
 		spin_lock_bh(&sk->lock.slock);
 		if(!sock_owned_by_user(sk))
 			break;
 	}
-	current->state = TASK_RUNNING;
-	remove_wait_queue(&sk->lock.wq, &wait);
+	finish_wait(&sk->lock.wq, &wait);
 }
 
 void __release_sock(struct sock *sk)
diff -Nru a/net/ipv4/Makefile b/net/ipv4/Makefile
--- a/net/ipv4/Makefile	Wed Jan  8 23:59:17 2003
+++ b/net/ipv4/Makefile	Sun Mar 23 02:21:28 2003
@@ -22,4 +22,4 @@
 obj-$(CONFIG_NETFILTER)	+= netfilter/
 obj-$(CONFIG_XFRM_USER) += xfrm_user.o
 
-obj-y += xfrm_policy.o xfrm_state.o xfrm_input.o xfrm_algo.o
+obj-y += xfrm_policy.o xfrm4_policy.o xfrm_state.o xfrm4_state.o xfrm_input.o xfrm4_input.o xfrm_algo.o
diff -Nru a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
--- a/net/ipv4/af_inet.c	Thu Mar  6 11:06:44 2003
+++ b/net/ipv4/af_inet.c	Tue Mar 11 23:12:12 2003
@@ -562,10 +562,9 @@
 
 static long inet_wait_for_connect(struct sock *sk, long timeo)
 {
-	DECLARE_WAITQUEUE(wait, current);
+	DEFINE_WAIT(wait);
 
-	__set_current_state(TASK_INTERRUPTIBLE);
-	add_wait_queue(sk->sleep, &wait);
+	prepare_to_wait(sk->sleep, &wait, TASK_INTERRUPTIBLE);
 
 	/* Basic assumption: if someone sets sk->err, he _must_
 	 * change state of the socket from TCP_SYN_*.
@@ -578,10 +577,9 @@
 		lock_sock(sk);
 		if (signal_pending(current) || !timeo)
 			break;
-		set_current_state(TASK_INTERRUPTIBLE);
+		prepare_to_wait(sk->sleep, &wait, TASK_INTERRUPTIBLE);
 	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(sk->sleep, &wait);
+	finish_wait(sk->sleep, &wait);
 	return timeo;
 }
 
diff -Nru a/net/ipv4/ah.c b/net/ipv4/ah.c
--- a/net/ipv4/ah.c	Thu Mar  6 16:16:15 2003
+++ b/net/ipv4/ah.c	Sun Mar 23 02:21:28 2003
@@ -68,8 +68,10 @@
 		char 		buf[60];
 	} tmp_iph;
 
-	if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL)
-		return -EINVAL;
+	if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
+		err = -EINVAL;
+		goto error_nolock;
+	}
 
 	spin_lock_bh(&x->lock);
 	if ((err = xfrm_state_check_expire(x)) != 0)
@@ -90,8 +92,8 @@
 		top_iph->ttl = 0;
 		top_iph->protocol = IPPROTO_AH;
 		top_iph->check = 0;
-		top_iph->saddr = x->props.saddr.xfrm4_addr;
-		top_iph->daddr = x->id.daddr.xfrm4_addr;
+		top_iph->saddr = x->props.saddr.a4;
+		top_iph->daddr = x->id.daddr.a4;
 		ah = (struct ip_auth_hdr*)(top_iph+1);
 		ah->nexthdr = IPPROTO_IPIP;
 	} else {
@@ -139,8 +141,10 @@
 	x->curlft.bytes += skb->len;
 	x->curlft.packets++;
 	spin_unlock_bh(&x->lock);
-	if ((skb->dst = dst_pop(dst)) == NULL)
+	if ((skb->dst = dst_pop(dst)) == NULL) {
+		err = -EHOSTUNREACH;
 		goto error_nolock;
+	}
 	return NET_XMIT_BYPASS;
 
 error:
@@ -228,7 +232,7 @@
 	    skb->h.icmph->code != ICMP_FRAG_NEEDED)
 		return;
 
-	x = xfrm4_state_lookup(iph->daddr, ah->spi, IPPROTO_AH);
+	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET);
 	if (!x)
 		return;
 	printk(KERN_DEBUG "pmtu discvovery on SA AH/%08x/%08x\n",
@@ -334,13 +338,13 @@
 static int __init ah4_init(void)
 {
 	SET_MODULE_OWNER(&ah_type);
-	if (xfrm_register_type(&ah_type) < 0) {
+	if (xfrm_register_type(&ah_type, AF_INET) < 0) {
 		printk(KERN_INFO "ip ah init: can't add xfrm type\n");
 		return -EAGAIN;
 	}
 	if (inet_add_protocol(&ah4_protocol, IPPROTO_AH) < 0) {
 		printk(KERN_INFO "ip ah init: can't add protocol\n");
-		xfrm_unregister_type(&ah_type);
+		xfrm_unregister_type(&ah_type, AF_INET);
 		return -EAGAIN;
 	}
 	return 0;
@@ -350,7 +354,7 @@
 {
 	if (inet_del_protocol(&ah4_protocol, IPPROTO_AH) < 0)
 		printk(KERN_INFO "ip ah close: can't remove protocol\n");
-	if (xfrm_unregister_type(&ah_type) < 0)
+	if (xfrm_unregister_type(&ah_type, AF_INET) < 0)
 		printk(KERN_INFO "ip ah close: can't remove xfrm type\n");
 }
 
diff -Nru a/net/ipv4/arp.c b/net/ipv4/arp.c
--- a/net/ipv4/arp.c	Sun Jan 12 08:52:15 2003
+++ b/net/ipv4/arp.c	Wed Mar 19 19:34:17 2003
@@ -510,11 +510,11 @@
 	 */
 	
 	skb = alloc_skb(sizeof(struct arphdr)+ 2*(dev->addr_len+4)
-				+ dev->hard_header_len + 15, GFP_ATOMIC);
+				+ LL_RESERVED_SPACE(dev), GFP_ATOMIC);
 	if (skb == NULL)
 		return;
 
-	skb_reserve(skb, (dev->hard_header_len+15)&~15);
+	skb_reserve(skb, LL_RESERVED_SPACE(dev));
 	skb->nh.raw = skb->data;
 	arp = (struct arphdr *) skb_put(skb,sizeof(struct arphdr) + 2*(dev->addr_len+4));
 	skb->dev = dev;
diff -Nru a/net/ipv4/esp.c b/net/ipv4/esp.c
--- a/net/ipv4/esp.c	Thu Mar  6 16:16:15 2003
+++ b/net/ipv4/esp.c	Sun Mar 23 02:21:28 2003
@@ -32,8 +32,10 @@
 	} tmp_iph;
 
 	/* First, if the skb is not checksummed, complete checksum. */
-	if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL)
-		return -EINVAL;
+	if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
+		err = -EINVAL;
+		goto error_nolock;
+	}
 
 	spin_lock_bh(&x->lock);
 	if ((err = xfrm_state_check_expire(x)) != 0)
@@ -89,8 +91,8 @@
 		top_iph->ttl = iph->ttl;	/* TTL disclosed */
 		top_iph->protocol = IPPROTO_ESP;
 		top_iph->check = 0;
-		top_iph->saddr = x->props.saddr.xfrm4_addr;
-		top_iph->daddr = x->id.daddr.xfrm4_addr;
+		top_iph->saddr = x->props.saddr.a4;
+		top_iph->daddr = x->id.daddr.a4;
 		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
 	} else {
 		esph = (struct ip_esp_hdr*)skb_push(skb, x->props.header_len);
@@ -143,8 +145,10 @@
 	x->curlft.bytes += skb->len;
 	x->curlft.packets++;
 	spin_unlock_bh(&x->lock);
-	if ((skb->dst = dst_pop(dst)) == NULL)
+	if ((skb->dst = dst_pop(dst)) == NULL) {
+		err = -EHOSTUNREACH;
 		goto error_nolock;
+	}
 	return NET_XMIT_BYPASS;
 
 error:
@@ -259,7 +263,7 @@
 	if (esp->conf.padlen)
 		mtu = (mtu + esp->conf.padlen-1)&~(esp->conf.padlen-1);
 
-	return mtu + x->props.header_len + esp->auth.icv_full_len;
+	return mtu + x->props.header_len + esp->auth.icv_trunc_len;
 }
 
 void esp4_err(struct sk_buff *skb, u32 info)
@@ -272,7 +276,7 @@
 	    skb->h.icmph->code != ICMP_FRAG_NEEDED)
 		return;
 
-	x = xfrm4_state_lookup(iph->daddr, esph->spi, IPPROTO_ESP);
+	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET);
 	if (!x)
 		return;
 	printk(KERN_DEBUG "pmtu discvovery on SA ESP/%08x/%08x\n",
@@ -365,6 +369,7 @@
 	if (x->props.mode)
 		x->props.header_len += 20;
 	x->data = esp;
+	x->props.trailer_len = esp4_get_max_size(x, 0) - x->props.header_len;
 	return 0;
 
 error:
@@ -400,13 +405,13 @@
 int __init esp4_init(void)
 {
 	SET_MODULE_OWNER(&esp_type);
-	if (xfrm_register_type(&esp_type) < 0) {
+	if (xfrm_register_type(&esp_type, AF_INET) < 0) {
 		printk(KERN_INFO "ip esp init: can't add xfrm type\n");
 		return -EAGAIN;
 	}
 	if (inet_add_protocol(&esp4_protocol, IPPROTO_ESP) < 0) {
 		printk(KERN_INFO "ip esp init: can't add protocol\n");
-		xfrm_unregister_type(&esp_type);
+		xfrm_unregister_type(&esp_type, AF_INET);
 		return -EAGAIN;
 	}
 	return 0;
@@ -416,7 +421,7 @@
 {
 	if (inet_del_protocol(&esp4_protocol, IPPROTO_ESP) < 0)
 		printk(KERN_INFO "ip esp close: can't remove protocol\n");
-	if (xfrm_unregister_type(&esp_type) < 0)
+	if (xfrm_unregister_type(&esp_type, AF_INET) < 0)
 		printk(KERN_INFO "ip esp close: can't remove xfrm type\n");
 }
 
diff -Nru a/net/ipv4/igmp.c b/net/ipv4/igmp.c
--- a/net/ipv4/igmp.c	Mon Mar 10 17:08:59 2003
+++ b/net/ipv4/igmp.c	Wed Mar 19 19:34:17 2003
@@ -211,7 +211,7 @@
 		return -1;
 	}
 
-	skb=alloc_skb(IGMP_SIZE+dev->hard_header_len+15, GFP_ATOMIC);
+	skb=alloc_skb(IGMP_SIZE+LL_RESERVED_SPACE(dev), GFP_ATOMIC);
 	if (skb == NULL) {
 		ip_rt_put(rt);
 		return -1;
@@ -219,7 +219,7 @@
 
 	skb->dst = &rt->u.dst;
 
-	skb_reserve(skb, (dev->hard_header_len+15)&~15);
+	skb_reserve(skb, LL_RESERVED_SPACE(dev));
 
 	skb->nh.iph = iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr)+4);
 
diff -Nru a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
--- a/net/ipv4/ip_forward.c	Tue Nov  5 07:17:12 2002
+++ b/net/ipv4/ip_forward.c	Sun Mar 23 02:21:28 2003
@@ -60,7 +60,7 @@
 	struct rtable *rt;	/* Route we use */
 	struct ip_options * opt	= &(IPCB(skb)->opt);
 
-	if (!xfrm_policy_check(NULL, XFRM_POLICY_FWD, skb))
+	if (!xfrm4_policy_check(NULL, XFRM_POLICY_FWD, skb))
 		goto drop;
 
 	if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb))
@@ -82,7 +82,7 @@
 	if (iph->ttl <= 1)
                 goto too_many_hops;
 
-	if (!xfrm_route_forward(skb))
+	if (!xfrm4_route_forward(skb))
 		goto drop;
 
 	iph = skb->nh.iph;
@@ -92,7 +92,7 @@
 		goto sr_failed;
 
 	/* We are about to mangle packet. Copy it! */
-	if (skb_cow(skb, rt->u.dst.dev->hard_header_len+rt->u.dst.header_len))
+	if (skb_cow(skb, LL_RESERVED_SPACE(rt->u.dst.dev)+rt->u.dst.header_len))
 		goto drop;
 	iph = skb->nh.iph;
 
diff -Nru a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
--- a/net/ipv4/ip_gre.c	Sat Feb 15 13:10:57 2003
+++ b/net/ipv4/ip_gre.c	Wed Mar 19 21:17:02 2003
@@ -273,7 +273,6 @@
 	nt = (struct ip_tunnel*)dev->priv;
 	nt->dev = dev;
 	dev->init = ipgre_tunnel_init;
-	dev->features |= NETIF_F_DYNALLOC;
 	memcpy(&nt->parms, parms, sizeof(*parms));
 	nt->parms.name[IFNAMSIZ-1] = '\0';
 	strcpy(dev->name, nt->parms.name);
@@ -305,6 +304,7 @@
 static void ipgre_tunnel_destructor(struct net_device *dev)
 {
 	if (dev != &ipgre_fb_tunnel_dev) {
+		kfree(dev);
 		MOD_DEC_USE_COUNT;
 	}
 }
@@ -824,7 +824,7 @@
 
 	skb->h.raw = skb->nh.raw;
 
-	max_headroom = ((tdev->hard_header_len+15)&~15)+ gre_hlen;
+	max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen;
 
 	if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
 		struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
diff -Nru a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
--- a/net/ipv4/ip_input.c	Wed Feb 19 13:55:33 2003
+++ b/net/ipv4/ip_input.c	Sun Mar 23 02:21:28 2003
@@ -236,7 +236,7 @@
 			int ret;
 
 			if (!ipprot->no_policy &&
-			    !xfrm_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+			    !xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
 				kfree_skb(skb);
 				return 0;
 			}
@@ -248,7 +248,7 @@
 			IP_INC_STATS_BH(IpInDelivers);
 		} else {
 			if (!raw_sk) {
-				if (xfrm_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+				if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
 					IP_INC_STATS_BH(IpInUnknownProtos);
 					icmp_send(skb, ICMP_DEST_UNREACH,
 						  ICMP_PROT_UNREACH, 0);
diff -Nru a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
--- a/net/ipv4/ip_output.c	Mon Feb 10 14:44:43 2003
+++ b/net/ipv4/ip_output.c	Wed Mar 19 19:52:56 2003
@@ -162,13 +162,13 @@
 	struct dst_entry *dst = skb->dst;
 	struct hh_cache *hh = dst->hh;
 	struct net_device *dev = dst->dev;
+	int hh_len = LL_RESERVED_SPACE(dev);
 
 	/* Be paranoid, rather than too clever. */
-	if (unlikely(skb_headroom(skb) < dev->hard_header_len
-		     && dev->hard_header)) {
+	if (unlikely(skb_headroom(skb) < hh_len && dev->hard_header)) {
 		struct sk_buff *skb2;
 
-		skb2 = skb_realloc_headroom(skb, (dev->hard_header_len&~15) + 16);
+		skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev));
 		if (skb2 == NULL) {
 			kfree_skb(skb);
 			return -ENOMEM;
@@ -440,7 +440,7 @@
 
 	iph = skb->nh.iph;
 
-	if (unlikely(iph->frag_off & htons(IP_DF))) {
+	if (unlikely((iph->frag_off & htons(IP_DF)) && !skb->local_df)) {
 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
 			  htonl(dst_pmtu(&rt->u.dst)));
 		kfree_skb(skb);
@@ -572,7 +572,7 @@
 		 *	Allocate buffer.
 		 */
 
-		if ((skb2 = alloc_skb(len+hlen+rt->u.dst.dev->hard_header_len+16,GFP_ATOMIC)) == NULL) {
+		if ((skb2 = alloc_skb(len+hlen+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
 			NETDEBUG(printk(KERN_INFO "IP: frag: no memory for new fragment!\n"));
 			err = -ENOMEM;
 			goto fail;
@@ -583,7 +583,7 @@
 		 */
 
 		ip_copy_metadata(skb2, skb);
-		skb_reserve(skb2, (rt->u.dst.dev->hard_header_len&~15)+16);
+		skb_reserve(skb2, LL_RESERVED_SPACE(rt->u.dst.dev));
 		skb_put(skb2, len + hlen);
 		skb2->nh.raw = skb2->data;
 		skb2->h.raw = skb2->data + hlen;
@@ -771,7 +771,7 @@
 		exthdrlen = 0;
 		mtu = inet->cork.fragsize;
 	}
-	hh_len = (rt->u.dst.dev->hard_header_len&~15) + 16;
+	hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
 
 	fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
 	maxfraglen = ((mtu-fragheaderlen) & ~7) + fragheaderlen;
@@ -793,6 +793,19 @@
 
 	inet->cork.length += length;
 
+	/* So, what's going on in the loop below?
+	 *
+	 * We use calculated fragment length to generate chained skb,
+	 * each of segments is IP fragment ready for sending to network after
+	 * adding appropriate IP header.
+	 *
+	 * Mistake is:
+	 *
+	 *    If mtu-fragheaderlen is not 0 modulo 8, we generate additional
+	 *    small fragment of length (mtu-fragheaderlen)%8, even though
+	 *    it is not necessary. Not a big bug, but needs a fix.
+	 */
+
 	if ((skb = skb_peek_tail(&sk->write_queue)) == NULL)
 		goto alloc_new_skb;
 
@@ -815,6 +828,15 @@
 				alloclen = maxfraglen;
 			else
 				alloclen = datalen + fragheaderlen;
+
+			/* The last fragment gets additional space at tail.
+			 * Note, with MSG_MORE we overallocate on fragments,
+			 * because we have no idea what fragment will be
+			 * the last.
+			 */
+			if (datalen == length)
+				alloclen += rt->u.dst.trailer_len;
+
 			if (transhdrlen) {
 				skb = sock_alloc_send_skb(sk, 
 						alloclen + hh_len + 15,
@@ -967,7 +989,7 @@
 	if (!(rt->u.dst.dev->features&NETIF_F_SG))
 		return -EOPNOTSUPP;
 
-	hh_len = (rt->u.dst.dev->hard_header_len&~15)+16;
+	hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
 	mtu = inet->cork.fragsize;
 
 	fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
@@ -1088,6 +1110,16 @@
 #endif
 	}
 
+	/* Unless user demanded real pmtu discovery (IP_PMTUDISC_DO), we allow
+	 * to fragment the frame generated here. No matter, what transforms
+	 * how transforms change size of the packet, it will come out.
+	 */
+	if (inet->pmtudisc != IP_PMTUDISC_DO)
+		skb->local_df = 1;
+
+	/* DF bit is set when we want to see DF on outgoing frames.
+	 * If local_df is set too, we still allow to fragment this frame
+	 * locally. */
 	if (inet->pmtudisc == IP_PMTUDISC_DO ||
 	    (!skb_shinfo(skb)->frag_list && ip_dont_fragment(sk, &rt->u.dst)))
 		df = htons(IP_DF);
diff -Nru a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
--- a/net/ipv4/ipconfig.c	Tue Feb 18 10:38:27 2003
+++ b/net/ipv4/ipconfig.c	Wed Mar 19 19:34:17 2003
@@ -656,7 +656,7 @@
 	struct net_device *dev = d->dev;
 	struct sk_buff *skb;
 	struct bootp_pkt *b;
-	int hh_len = (dev->hard_header_len + 15) & ~15;
+	int hh_len = LL_RESERVED_SPACE(dev);
 	struct iphdr *h;
 
 	/* Allocate packet */
diff -Nru a/net/ipv4/ipip.c b/net/ipv4/ipip.c
--- a/net/ipv4/ipip.c	Sat Feb 15 13:11:22 2003
+++ b/net/ipv4/ipip.c	Wed Mar 19 21:17:02 2003
@@ -242,7 +242,6 @@
 	nt = (struct ip_tunnel*)dev->priv;
 	nt->dev = dev;
 	dev->init = ipip_tunnel_init;
-	dev->features |= NETIF_F_DYNALLOC;
 	memcpy(&nt->parms, parms, sizeof(*parms));
 	nt->parms.name[IFNAMSIZ-1] = '\0';
 	strcpy(dev->name, nt->parms.name);
@@ -274,6 +273,7 @@
 static void ipip_tunnel_destructor(struct net_device *dev)
 {
 	if (dev != &ipip_fb_tunnel_dev) {
+		kfree(dev);
 		MOD_DEC_USE_COUNT;
 	}
 }
@@ -616,7 +616,7 @@
 	/*
 	 * Okay, now see if we can stuff it in the buffer as-is.
 	 */
-	max_headroom = (((tdev->hard_header_len+15)&~15)+sizeof(struct iphdr));
+	max_headroom = (LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr));
 
 	if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
 		struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
diff -Nru a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
--- a/net/ipv4/ipmr.c	Wed Feb 19 13:55:33 2003
+++ b/net/ipv4/ipmr.c	Wed Mar 19 21:17:02 2003
@@ -182,6 +182,11 @@
 	return (struct net_device_stats*)dev->priv;
 }
 
+static void vif_dev_destructor(struct net_device *dev)
+{
+	kfree(dev);
+}
+
 static
 struct net_device *ipmr_reg_vif(struct vifctl *v)
 {
@@ -205,7 +210,7 @@
 	dev->flags		= IFF_NOARP;
 	dev->hard_start_xmit	= reg_vif_xmit;
 	dev->get_stats		= reg_vif_get_stats;
-	dev->features		|= NETIF_F_DYNALLOC;
+	dev->destructor		= vif_dev_destructor;
 
 	if (register_netdevice(dev)) {
 		kfree(dev);
@@ -1178,7 +1183,7 @@
 		return;
 	}
 
-	encap += dev->hard_header_len;
+	encap += LL_RESERVED_SPACE(dev);
 
 	if (skb_headroom(skb) < encap || skb_cloned(skb) || !last)
 		skb2 = skb_realloc_headroom(skb, (encap + 15)&~15);
diff -Nru a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
--- a/net/ipv4/netfilter/arp_tables.c	Mon Mar  3 01:15:36 2003
+++ b/net/ipv4/netfilter/arp_tables.c	Fri Mar 21 04:25:13 2003
@@ -912,19 +912,25 @@
 		goto free_newinfo_counters_untrans_unlock;
 	}
 
+	/* Get a reference in advance, we're not allowed fail later */
+	if (!try_module_get(t->me)) {
+		ret = -EBUSY;
+		goto free_newinfo_counters_untrans_unlock;
+	}
+
 	oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret);
 	if (!oldinfo)
-		goto free_newinfo_counters_untrans_unlock;
+		goto put_module;
 
 	/* Update module usage count based on number of rules */
 	duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n",
 		oldinfo->number, oldinfo->initial_entries, newinfo->number);
-	if (t->me && (oldinfo->number <= oldinfo->initial_entries) &&
- 	    (newinfo->number > oldinfo->initial_entries))
-		__MOD_INC_USE_COUNT(t->me);
-	else if (t->me && (oldinfo->number > oldinfo->initial_entries) &&
-	 	 (newinfo->number <= oldinfo->initial_entries))
-		__MOD_DEC_USE_COUNT(t->me);
+	if ((oldinfo->number > oldinfo->initial_entries) || 
+	    (newinfo->number <= oldinfo->initial_entries)) 
+		module_put(t->me);
+	if ((oldinfo->number > oldinfo->initial_entries) &&
+	    (newinfo->number <= oldinfo->initial_entries))
+		module_put(t->me);
 
 	/* Get the old counters. */
 	get_counters(oldinfo, counters);
@@ -938,6 +944,8 @@
 	up(&arpt_mutex);
 	return 0;
 
+ put_module:
+	module_put(t->me);
  free_newinfo_counters_untrans_unlock:
 	up(&arpt_mutex);
  free_newinfo_counters_untrans:
@@ -1205,14 +1213,24 @@
 }
 
 /* The built-in targets: standard (NULL) and error. */
-static struct arpt_target arpt_standard_target
-= { { NULL, NULL }, ARPT_STANDARD_TARGET, NULL, NULL, NULL };
-static struct arpt_target arpt_error_target
-= { { NULL, NULL }, ARPT_ERROR_TARGET, arpt_error, NULL, NULL };
-
-static struct nf_sockopt_ops arpt_sockopts
-= { { NULL, NULL }, PF_INET, ARPT_BASE_CTL, ARPT_SO_SET_MAX+1, do_arpt_set_ctl,
-    ARPT_BASE_CTL, ARPT_SO_GET_MAX+1, do_arpt_get_ctl, 0, NULL  };
+static struct arpt_target arpt_standard_target = {
+	.name		= ARPT_STANDARD_TARGET,
+};
+
+static struct arpt_target arpt_error_target = {
+	.name		= ARPT_ERROR_TARGET,
+	.target		= arpt_error,
+};
+
+static struct nf_sockopt_ops arpt_sockopts = {
+	.pf		= PF_INET,
+	.set_optmin	= ARPT_BASE_CTL,
+	.set_optmax	= ARPT_SO_SET_MAX+1,
+	.set		= do_arpt_set_ctl,
+	.get_optmin	= ARPT_BASE_CTL,
+	.get_optmax	= ARPT_SO_GET_MAX+1,
+	.get		= do_arpt_get_ctl,
+};
 
 #ifdef CONFIG_PROC_FS
 static inline int print_name(const struct arpt_table *t,
diff -Nru a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
--- a/net/ipv4/netfilter/ip_conntrack_core.c	Mon Mar  3 01:25:39 2003
+++ b/net/ipv4/netfilter/ip_conntrack_core.c	Thu Mar 20 00:42:26 2003
@@ -1339,11 +1339,12 @@
 	return -ENOENT;
 }
 
-static struct nf_sockopt_ops so_getorigdst
-= { { NULL, NULL }, PF_INET,
-    0, 0, NULL, /* Setsockopts */
-    SO_ORIGINAL_DST, SO_ORIGINAL_DST+1, &getorigdst,
-    0, NULL };
+static struct nf_sockopt_ops so_getorigdst = {
+	.pf		= PF_INET,
+	.get_optmin	= SO_ORIGINAL_DST,
+	.get_optmax	= SO_ORIGINAL_DST+1,
+	.get		= &getorigdst,
+};
 
 #define NET_IP_CONNTRACK_MAX 2089
 #define NET_IP_CONNTRACK_MAX_NAME "ip_conntrack_max"
@@ -1367,7 +1368,6 @@
 	{
 		.ctl_name	= NET_IPV4,
 		.procname	= "ipv4",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= ip_conntrack_table
 	},
@@ -1378,7 +1378,6 @@
 	{
 		.ctl_name	= CTL_NET,
 		.procname	= "net",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= ip_conntrack_dir_table
 	},
diff -Nru a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
--- a/net/ipv4/netfilter/ip_queue.c	Wed Feb 12 21:50:47 2003
+++ b/net/ipv4/netfilter/ip_queue.c	Thu Mar 20 00:42:26 2003
@@ -555,9 +555,7 @@
 }
 
 static struct notifier_block ipq_dev_notifier = {
-	ipq_rcv_dev_event,
-	NULL,
-	0
+	.notifier_call	= ipq_rcv_dev_event,
 };
 
 static int
@@ -577,9 +575,7 @@
 }
 
 static struct notifier_block ipq_nl_notifier = {
-	ipq_rcv_nl_event,
-	NULL,
-	0
+	.notifier_call	= ipq_rcv_nl_event,
 };
 
 static int sysctl_maxlen = IPQ_QMAX_DEFAULT;
@@ -601,7 +597,6 @@
 	{
 		.ctl_name	= NET_IPV4,
 		.procname	= "ipv4",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= ipq_table
 	},
@@ -612,7 +607,6 @@
 	{
 		.ctl_name	= CTL_NET,
 		.procname	= "net",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= ipq_dir_table
 	},
diff -Nru a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
--- a/net/ipv4/netfilter/ip_tables.c	Mon Mar  3 01:21:27 2003
+++ b/net/ipv4/netfilter/ip_tables.c	Fri Mar 21 04:26:12 2003
@@ -1106,19 +1106,26 @@
 		goto free_newinfo_counters_untrans_unlock;
 	}
 
+	/* Get a reference in advance, we're not allowed fail later */
+	if (!try_module_get(t->me)) {
+		ret = -EBUSY;
+		goto free_newinfo_counters_untrans_unlock;
+	}
+
+
 	oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret);
 	if (!oldinfo)
-		goto free_newinfo_counters_untrans_unlock;
+		goto put_module;
 
 	/* Update module usage count based on number of rules */
 	duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n",
 		oldinfo->number, oldinfo->initial_entries, newinfo->number);
-	if (t->me && (oldinfo->number <= oldinfo->initial_entries) &&
- 	    (newinfo->number > oldinfo->initial_entries))
-		__MOD_INC_USE_COUNT(t->me);
-	else if (t->me && (oldinfo->number > oldinfo->initial_entries) &&
-	 	 (newinfo->number <= oldinfo->initial_entries))
-		__MOD_DEC_USE_COUNT(t->me);
+	if ((oldinfo->number > oldinfo->initial_entries) || 
+	    (newinfo->number <= oldinfo->initial_entries)) 
+		module_put(t->me);
+	if ((oldinfo->number > oldinfo->initial_entries) &&
+	    (newinfo->number <= oldinfo->initial_entries))
+		module_put(t->me);
 
 	/* Get the old counters. */
 	get_counters(oldinfo, counters);
@@ -1132,6 +1139,8 @@
 	up(&ipt_mutex);
 	return 0;
 
+ put_module:
+	module_put(t->me);
  free_newinfo_counters_untrans_unlock:
 	up(&ipt_mutex);
  free_newinfo_counters_untrans:
@@ -1663,21 +1672,42 @@
 }
 
 /* The built-in targets: standard (NULL) and error. */
-static struct ipt_target ipt_standard_target
-= { { NULL, NULL }, IPT_STANDARD_TARGET, NULL, NULL, NULL };
-static struct ipt_target ipt_error_target
-= { { NULL, NULL }, IPT_ERROR_TARGET, ipt_error, NULL, NULL };
-
-static struct nf_sockopt_ops ipt_sockopts
-= { { NULL, NULL }, PF_INET, IPT_BASE_CTL, IPT_SO_SET_MAX+1, do_ipt_set_ctl,
-    IPT_BASE_CTL, IPT_SO_GET_MAX+1, do_ipt_get_ctl, 0, NULL  };
-
-static struct ipt_match tcp_matchstruct
-= { { NULL, NULL }, "tcp", &tcp_match, &tcp_checkentry, NULL };
-static struct ipt_match udp_matchstruct
-= { { NULL, NULL }, "udp", &udp_match, &udp_checkentry, NULL };
-static struct ipt_match icmp_matchstruct
-= { { NULL, NULL }, "icmp", &icmp_match, &icmp_checkentry, NULL };
+static struct ipt_target ipt_standard_target = {
+	.name		= IPT_STANDARD_TARGET,
+};
+
+static struct ipt_target ipt_error_target = {
+	.name		= IPT_ERROR_TARGET,
+	.target		= ipt_error,
+};
+
+static struct nf_sockopt_ops ipt_sockopts = {
+	.pf		= PF_INET,
+	.set_optmin	= IPT_BASE_CTL,
+	.set_optmax	= IPT_SO_SET_MAX+1,
+	.set		= do_ipt_set_ctl,
+	.get_optmin	= IPT_BASE_CTL,
+	.get_optmax	= IPT_SO_GET_MAX+1,
+	.get		= do_ipt_get_ctl,
+};
+
+static struct ipt_match tcp_matchstruct = {
+	.name		= "tcp",
+	.match		= &tcp_match,
+	.checkentry	= &tcp_checkentry,
+};
+
+static struct ipt_match udp_matchstruct = {
+	.name		= "udp",
+	.match		= &udp_match,
+	.checkentry	= &udp_checkentry,
+};
+
+static struct ipt_match icmp_matchstruct = {
+	.name		= "icmp",
+	.match		= &icmp_match,
+	.checkentry	= &icmp_checkentry,
+};
 
 #ifdef CONFIG_PROC_FS
 static inline int print_name(const struct ipt_table *t,
diff -Nru a/net/ipv4/netfilter/ipfwadm_core.c b/net/ipv4/netfilter/ipfwadm_core.c
--- a/net/ipv4/netfilter/ipfwadm_core.c	Mon Mar  3 01:06:54 2003
+++ b/net/ipv4/netfilter/ipfwadm_core.c	Thu Mar 20 00:42:26 2003
@@ -1315,9 +1315,7 @@
 }
 
 static struct notifier_block ipfw_dev_notifier={
-	ipfw_device_event,
-	NULL,
-	0
+	.notifier_call	= ipfw_device_event,
 };
 
 #endif
diff -Nru a/net/ipv4/netfilter/ipt_DSCP.c b/net/ipv4/netfilter/ipt_DSCP.c
--- a/net/ipv4/netfilter/ipt_DSCP.c	Mon Aug 19 11:48:13 2002
+++ b/net/ipv4/netfilter/ipt_DSCP.c	Thu Mar 20 00:42:26 2003
@@ -88,8 +88,12 @@
 	return 1;
 }
 
-static struct ipt_target ipt_dscp_reg
-= { { NULL, NULL }, "DSCP", target, checkentry, NULL, THIS_MODULE };
+static struct ipt_target ipt_dscp_reg = {
+	.name		= "DSCP",
+	.target		= target,
+	.checkentry	= checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
--- a/net/ipv4/netfilter/ipt_ECN.c	Fri Jan 10 01:05:48 2003
+++ b/net/ipv4/netfilter/ipt_ECN.c	Thu Mar 20 00:42:26 2003
@@ -164,8 +164,12 @@
 	return 1;
 }
 
-static struct ipt_target ipt_ecn_reg
-= { { NULL, NULL }, "ECN", target, checkentry, NULL, THIS_MODULE };
+static struct ipt_target ipt_ecn_reg = {
+	.name		= "ECN",
+	.target		= target,
+	.checkentry	= checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
--- a/net/ipv4/netfilter/ipt_LOG.c	Mon Oct 28 05:06:31 2002
+++ b/net/ipv4/netfilter/ipt_LOG.c	Thu Mar 20 00:42:26 2003
@@ -350,9 +350,12 @@
 	return 1;
 }
 
-static struct ipt_target ipt_log_reg
-= { { NULL, NULL }, "LOG", ipt_log_target, ipt_log_checkentry, NULL, 
-    THIS_MODULE };
+static struct ipt_target ipt_log_reg = {
+	.name		= "LOG",
+	.target		= ipt_log_target,
+	.checkentry	= ipt_log_checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_MARK.c b/net/ipv4/netfilter/ipt_MARK.c
--- a/net/ipv4/netfilter/ipt_MARK.c	Mon Feb  4 23:49:27 2002
+++ b/net/ipv4/netfilter/ipt_MARK.c	Thu Mar 20 00:42:26 2003
@@ -46,8 +46,12 @@
 	return 1;
 }
 
-static struct ipt_target ipt_mark_reg
-= { { NULL, NULL }, "MARK", target, checkentry, NULL, THIS_MODULE };
+static struct ipt_target ipt_mark_reg = {
+	.name		= "MARK",
+	.target		= target,
+	.checkentry	= checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c	Fri Oct 11 16:07:30 2002
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c	Thu Mar 20 00:42:26 2003
@@ -167,20 +167,19 @@
 }
 
 static struct notifier_block masq_dev_notifier = {
-	masq_device_event,
-	NULL,
-	0
+	.notifier_call	= masq_device_event,
 };
 
 static struct notifier_block masq_inet_notifier = {
-	masq_inet_event,
-	NULL,
-	0
+	.notifier_call	= masq_inet_event,
 };
 
-static struct ipt_target masquerade
-= { { NULL, NULL }, "MASQUERADE", masquerade_target, masquerade_check, NULL,
-    THIS_MODULE };
+static struct ipt_target masquerade = {
+	.name		= "MASQUERADE",
+	.target		= masquerade_target,
+	.checkentry	= masquerade_check,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_MIRROR.c b/net/ipv4/netfilter/ipt_MIRROR.c
--- a/net/ipv4/netfilter/ipt_MIRROR.c	Fri Oct 11 16:07:30 2002
+++ b/net/ipv4/netfilter/ipt_MIRROR.c	Thu Mar 20 00:42:26 2003
@@ -157,9 +157,12 @@
 	return 1;
 }
 
-static struct ipt_target ipt_mirror_reg
-= { { NULL, NULL }, "MIRROR", ipt_mirror_target, ipt_mirror_checkentry, NULL,
-    THIS_MODULE };
+static struct ipt_target ipt_mirror_reg = {
+	.name		= "MIRROR",
+	.target		= ipt_mirror_target,
+	.checkentry	= ipt_mirror_checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
--- a/net/ipv4/netfilter/ipt_REDIRECT.c	Tue Feb  5 07:24:40 2002
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c	Thu Mar 20 00:42:27 2003
@@ -96,9 +96,12 @@
 	return ip_nat_setup_info(ct, &newrange, hooknum);
 }
 
-static struct ipt_target redirect_reg
-= { { NULL, NULL }, "REDIRECT", redirect_target, redirect_check, NULL,
-    THIS_MODULE };
+static struct ipt_target redirect_reg = {
+	.name		= "REDIRECT",
+	.target		= redirect_target,
+	.checkentry	= redirect_check,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
--- a/net/ipv4/netfilter/ipt_REJECT.c	Fri Jan 10 01:01:00 2003
+++ b/net/ipv4/netfilter/ipt_REJECT.c	Thu Mar 20 00:42:27 2003
@@ -386,8 +386,12 @@
 	return 1;
 }
 
-static struct ipt_target ipt_reject_reg
-= { { NULL, NULL }, "REJECT", reject, check, NULL, THIS_MODULE };
+static struct ipt_target ipt_reject_reg = {
+	.name		= "REJECT",
+	.target		= reject,
+	.checkentry	= check,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_TCPMSS.c b/net/ipv4/netfilter/ipt_TCPMSS.c
--- a/net/ipv4/netfilter/ipt_TCPMSS.c	Sun Nov 10 16:20:05 2002
+++ b/net/ipv4/netfilter/ipt_TCPMSS.c	Thu Mar 20 00:42:27 2003
@@ -238,9 +238,12 @@
 	return 0;
 }
 
-static struct ipt_target ipt_tcpmss_reg
-= { { NULL, NULL }, "TCPMSS",
-    ipt_tcpmss_target, ipt_tcpmss_checkentry, NULL, THIS_MODULE };
+static struct ipt_target ipt_tcpmss_reg = {
+	.name		= "TCPMSS",
+	.target		= ipt_tcpmss_target,
+	.checkentry	= ipt_tcpmss_checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c
--- a/net/ipv4/netfilter/ipt_TOS.c	Tue Feb  5 07:23:43 2002
+++ b/net/ipv4/netfilter/ipt_TOS.c	Thu Mar 20 00:42:27 2003
@@ -76,8 +76,12 @@
 	return 1;
 }
 
-static struct ipt_target ipt_tos_reg
-= { { NULL, NULL }, "TOS", target, checkentry, NULL, THIS_MODULE };
+static struct ipt_target ipt_tos_reg = {
+	.name		= "TOS",
+	.target		= target,
+	.checkentry	= checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
--- a/net/ipv4/netfilter/ipt_ULOG.c	Fri Jan 10 00:57:03 2003
+++ b/net/ipv4/netfilter/ipt_ULOG.c	Thu Mar 20 00:42:27 2003
@@ -304,9 +304,11 @@
 	return 1;
 }
 
-static struct ipt_target ipt_ulog_reg =
-    { {NULL, NULL}, "ULOG", ipt_ulog_target, ipt_ulog_checkentry, NULL,
-THIS_MODULE
+static struct ipt_target ipt_ulog_reg = {
+	.name		= "ULOG",
+	.target		= ipt_ulog_target,
+	.checkentry	= ipt_ulog_checkentry,
+	.me		= THIS_MODULE,
 };
 
 static int __init init(void)
diff -Nru a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c
--- a/net/ipv4/netfilter/ipt_ah.c	Wed Feb 19 12:23:15 2003
+++ b/net/ipv4/netfilter/ipt_ah.c	Thu Mar 20 00:42:27 2003
@@ -87,8 +87,12 @@
 	return 1;
 }
 
-static struct ipt_match ah_match
-= { { NULL, NULL }, "ah", &match, &checkentry, NULL, THIS_MODULE };
+static struct ipt_match ah_match = {
+	.name		= "ah",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_conntrack.c b/net/ipv4/netfilter/ipt_conntrack.c
--- a/net/ipv4/netfilter/ipt_conntrack.c	Mon Mar  3 01:15:36 2003
+++ b/net/ipv4/netfilter/ipt_conntrack.c	Thu Mar 20 00:42:27 2003
@@ -100,8 +100,12 @@
 	return 1;
 }
 
-static struct ipt_match conntrack_match
-= { { NULL, NULL }, "conntrack", &match, &check, NULL, THIS_MODULE };
+static struct ipt_match conntrack_match = {
+	.name		= "conntrack",
+	.match		= &match,
+	.checkentry	= &check,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_dscp.c b/net/ipv4/netfilter/ipt_dscp.c
--- a/net/ipv4/netfilter/ipt_dscp.c	Mon Aug 19 11:48:13 2002
+++ b/net/ipv4/netfilter/ipt_dscp.c	Thu Mar 20 00:42:27 2003
@@ -40,8 +40,12 @@
 	return 1;
 }
 
-static struct ipt_match dscp_match = { { NULL, NULL }, "dscp", &match,
-		&checkentry, NULL, THIS_MODULE };
+static struct ipt_match dscp_match = {
+	.name		= "dscp",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c
--- a/net/ipv4/netfilter/ipt_ecn.c	Mon Aug 19 11:48:13 2002
+++ b/net/ipv4/netfilter/ipt_ecn.c	Thu Mar 20 00:42:27 2003
@@ -101,8 +101,12 @@
 	return 1;
 }
 
-static struct ipt_match ecn_match = { { NULL, NULL }, "ecn", &match,
-		&checkentry, NULL, THIS_MODULE };
+static struct ipt_match ecn_match = {
+	.name		= "ecn",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_esp.c b/net/ipv4/netfilter/ipt_esp.c
--- a/net/ipv4/netfilter/ipt_esp.c	Wed Feb 19 12:23:13 2003
+++ b/net/ipv4/netfilter/ipt_esp.c	Thu Mar 20 00:42:27 2003
@@ -87,8 +87,12 @@
 	return 1;
 }
 
-static struct ipt_match esp_match
-= { { NULL, NULL }, "esp", &match, &checkentry, NULL, THIS_MODULE };
+static struct ipt_match esp_match = {
+	.name		= "esp",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c
--- a/net/ipv4/netfilter/ipt_helper.c	Mon Mar  3 01:15:36 2003
+++ b/net/ipv4/netfilter/ipt_helper.c	Thu Mar 20 00:42:27 2003
@@ -89,8 +89,12 @@
 	return 1;
 }
 
-static struct ipt_match helper_match
-= { { NULL, NULL }, "helper", &match, &check, NULL, THIS_MODULE };
+static struct ipt_match helper_match = {
+	.name		= "helper",
+	.match		= &match,
+	.checkentry	= &check,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_length.c b/net/ipv4/netfilter/ipt_length.c
--- a/net/ipv4/netfilter/ipt_length.c	Mon Feb  4 23:54:00 2002
+++ b/net/ipv4/netfilter/ipt_length.c	Thu Mar 20 00:42:27 2003
@@ -38,8 +38,12 @@
 	return 1;
 }
 
-static struct ipt_match length_match
-= { { NULL, NULL }, "length", &match, &checkentry, NULL, THIS_MODULE };
+static struct ipt_match length_match = {
+	.name		= "length",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_limit.c b/net/ipv4/netfilter/ipt_limit.c
--- a/net/ipv4/netfilter/ipt_limit.c	Mon Feb  4 23:49:27 2002
+++ b/net/ipv4/netfilter/ipt_limit.c	Thu Mar 20 00:42:27 2003
@@ -115,9 +115,12 @@
 	return 1;
 }
 
-static struct ipt_match ipt_limit_reg
-= { { NULL, NULL }, "limit", ipt_limit_match, ipt_limit_checkentry, NULL,
-    THIS_MODULE };
+static struct ipt_match ipt_limit_reg = {
+	.name		= "limit",
+	.match		= ipt_limit_match,
+	.checkentry	= ipt_limit_checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_mac.c b/net/ipv4/netfilter/ipt_mac.c
--- a/net/ipv4/netfilter/ipt_mac.c	Mon Feb  4 23:49:35 2002
+++ b/net/ipv4/netfilter/ipt_mac.c	Thu Mar 20 00:42:27 2003
@@ -47,8 +47,12 @@
 	return 1;
 }
 
-static struct ipt_match mac_match
-= { { NULL, NULL }, "mac", &match, &ipt_mac_checkentry, NULL, THIS_MODULE };
+static struct ipt_match mac_match = {
+	.name		= "mac",
+	.match		= &match,
+	.checkentry	= &ipt_mac_checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_mark.c b/net/ipv4/netfilter/ipt_mark.c
--- a/net/ipv4/netfilter/ipt_mark.c	Mon Feb  4 23:49:27 2002
+++ b/net/ipv4/netfilter/ipt_mark.c	Thu Mar 20 00:42:27 2003
@@ -33,8 +33,12 @@
 	return 1;
 }
 
-static struct ipt_match mark_match
-= { { NULL, NULL }, "mark", &match, &checkentry, NULL, THIS_MODULE };
+static struct ipt_match mark_match = {
+	.name		= "mark",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_multiport.c b/net/ipv4/netfilter/ipt_multiport.c
--- a/net/ipv4/netfilter/ipt_multiport.c	Fri Jan 10 00:47:07 2003
+++ b/net/ipv4/netfilter/ipt_multiport.c	Thu Mar 20 00:42:27 2003
@@ -86,8 +86,12 @@
 		&& multiinfo->count <= IPT_MULTI_PORTS;
 }
 
-static struct ipt_match multiport_match
-= { { NULL, NULL }, "multiport", &match, &checkentry, NULL, THIS_MODULE };
+static struct ipt_match multiport_match = {
+	.name		= "multiport",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c
--- a/net/ipv4/netfilter/ipt_owner.c	Sat Sep 14 06:16:57 2002
+++ b/net/ipv4/netfilter/ipt_owner.c	Thu Mar 20 00:42:27 2003
@@ -176,8 +176,12 @@
 	return 1;
 }
 
-static struct ipt_match owner_match
-= { { NULL, NULL }, "owner", &match, &checkentry, NULL, THIS_MODULE };
+static struct ipt_match owner_match = {
+	.name		= "owner",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_physdev.c b/net/ipv4/netfilter/ipt_physdev.c
--- a/net/ipv4/netfilter/ipt_physdev.c	Sat Nov  2 02:10:40 2002
+++ b/net/ipv4/netfilter/ipt_physdev.c	Thu Mar 20 00:42:27 2003
@@ -63,8 +63,12 @@
 	return 1;
 }
 
-static struct ipt_match physdev_match
-= { { NULL, NULL }, "physdev", &match, &checkentry, NULL, THIS_MODULE };
+static struct ipt_match physdev_match = {
+	.name		= "physdev",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_pkttype.c b/net/ipv4/netfilter/ipt_pkttype.c
--- a/net/ipv4/netfilter/ipt_pkttype.c	Mon Aug 19 11:48:13 2002
+++ b/net/ipv4/netfilter/ipt_pkttype.c	Thu Mar 20 00:42:27 2003
@@ -42,8 +42,12 @@
 	return 1;
 }
 
-static struct ipt_match pkttype_match
-= { { NULL, NULL }, "pkttype", &match, &checkentry, NULL, THIS_MODULE };
+static struct ipt_match pkttype_match = {
+	.name		= "pkttype",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_state.c b/net/ipv4/netfilter/ipt_state.c
--- a/net/ipv4/netfilter/ipt_state.c	Mon Mar  3 01:15:36 2003
+++ b/net/ipv4/netfilter/ipt_state.c	Thu Mar 20 00:42:27 2003
@@ -41,8 +41,12 @@
 	return 1;
 }
 
-static struct ipt_match state_match
-= { { NULL, NULL }, "state", &match, &check, NULL, THIS_MODULE };
+static struct ipt_match state_match = {
+	.name		= "state",
+	.match		= &match,
+	.checkentry	= &check,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_tcpmss.c b/net/ipv4/netfilter/ipt_tcpmss.c
--- a/net/ipv4/netfilter/ipt_tcpmss.c	Mon Feb  4 23:49:27 2002
+++ b/net/ipv4/netfilter/ipt_tcpmss.c	Thu Mar 20 00:42:27 2003
@@ -91,8 +91,12 @@
 	return 1;
 }
 
-static struct ipt_match tcpmss_match
-= { { NULL, NULL }, "tcpmss", &match, &checkentry, NULL, THIS_MODULE };
+static struct ipt_match tcpmss_match = {
+	.name		= "tcpmss",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_tos.c b/net/ipv4/netfilter/ipt_tos.c
--- a/net/ipv4/netfilter/ipt_tos.c	Mon Feb  4 23:49:27 2002
+++ b/net/ipv4/netfilter/ipt_tos.c	Thu Mar 20 00:42:27 2003
@@ -34,8 +34,12 @@
 	return 1;
 }
 
-static struct ipt_match tos_match
-= { { NULL, NULL }, "tos", &match, &checkentry, NULL, THIS_MODULE };
+static struct ipt_match tos_match = {
+	.name		= "tos",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_ttl.c b/net/ipv4/netfilter/ipt_ttl.c
--- a/net/ipv4/netfilter/ipt_ttl.c	Mon Feb  4 23:54:00 2002
+++ b/net/ipv4/netfilter/ipt_ttl.c	Thu Mar 20 00:42:27 2003
@@ -57,8 +57,12 @@
 	return 1;
 }
 
-static struct ipt_match ttl_match = { { NULL, NULL }, "ttl", &match,
-		&checkentry, NULL, THIS_MODULE };
+static struct ipt_match ttl_match = {
+	.name		= "ttl",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/netfilter/ipt_unclean.c b/net/ipv4/netfilter/ipt_unclean.c
--- a/net/ipv4/netfilter/ipt_unclean.c	Wed Oct 23 04:09:45 2002
+++ b/net/ipv4/netfilter/ipt_unclean.c	Thu Mar 20 00:42:27 2003
@@ -580,8 +580,12 @@
 	return 1;
 }
 
-static struct ipt_match unclean_match
-= { { NULL, NULL }, "unclean", &match, &checkentry, NULL, THIS_MODULE };
+static struct ipt_match unclean_match = {
+	.name		= "unclean",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv4/raw.c b/net/ipv4/raw.c
--- a/net/ipv4/raw.c	Mon Mar  3 04:56:53 2003
+++ b/net/ipv4/raw.c	Sun Mar 23 02:21:28 2003
@@ -251,7 +251,7 @@
 
 int raw_rcv(struct sock *sk, struct sk_buff *skb)
 {
-	if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb)) {
+	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) {
 		kfree_skb(skb);
 		return NET_RX_DROP;
 	}
@@ -280,7 +280,7 @@
 	if (flags&MSG_PROBE)
 		goto out;
 
-	hh_len = (rt->u.dst.dev->hard_header_len&~15) + 16;
+	hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
 
 	skb = sock_alloc_send_skb(sk, length+hh_len+15,
 				  flags&MSG_DONTWAIT, &err);
diff -Nru a/net/ipv4/route.c b/net/ipv4/route.c
--- a/net/ipv4/route.c	Wed Mar  5 15:45:36 2003
+++ b/net/ipv4/route.c	Sun Mar 23 02:21:28 2003
@@ -1854,7 +1854,7 @@
 			goto out;
 
 		/* I removed check for oif == dev_out->oif here.
-		   It was wrong by three reasons:
+		   It was wrong for two reasons:
 		   1. ip_dev_find(saddr) can return wrong iface, if saddr is
 		      assigned to multiple interfaces.
 		   2. Moreover, we are allowed to send packets with saddr
@@ -2600,13 +2600,6 @@
 #endif /* CONFIG_PROC_FS */
 #endif /* CONFIG_NET_CLS_ROUTE */
 
-int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl)
-{
-        int err = 0;
-        err = __ip_route_output_key((struct rtable**)dst, fl);
-        return err;
-}
-
 int __init ip_rt_init(void)
 {
 	int i, order, goal, rc = 0;
@@ -2688,7 +2681,6 @@
 					ip_rt_gc_interval;
 	add_timer(&rt_periodic_timer);
 
-	xfrm_dst_lookup_register(xfrm_dst_lookup, AF_INET);
 #ifdef CONFIG_PROC_FS
 	if (rt_cache_proc_init())
 		goto out_enomem;
@@ -2698,6 +2690,7 @@
 #endif
 #endif
 	xfrm_init();
+	xfrm4_init();
 out:
 	return rc;
 out_enomem:
diff -Nru a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c	Mon Mar  3 04:56:53 2003
+++ b/net/ipv4/tcp.c	Tue Mar 11 23:12:12 2003
@@ -659,7 +659,7 @@
 {
 	struct tcp_opt *tp = tcp_sk(sk);
 	struct task_struct *tsk = current;
-	DECLARE_WAITQUEUE(wait, tsk);
+	DEFINE_WAIT(wait);
 
 	while ((1 << sk->state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) {
 		if (sk->err)
@@ -671,16 +671,14 @@
 		if (signal_pending(tsk))
 			return sock_intr_errno(*timeo_p);
 
-		__set_task_state(tsk, TASK_INTERRUPTIBLE);
-		add_wait_queue(sk->sleep, &wait);
+		prepare_to_wait(sk->sleep, &wait, TASK_INTERRUPTIBLE);
 		tp->write_pending++;
 
 		release_sock(sk);
 		*timeo_p = schedule_timeout(*timeo_p);
 		lock_sock(sk);
 
-		__set_task_state(tsk, TASK_RUNNING);
-		remove_wait_queue(sk->sleep, &wait);
+		finish_wait(sk->sleep, &wait);
 		tp->write_pending--;
 	}
 	return 0;
@@ -700,16 +698,15 @@
 	int err = 0;
 	long vm_wait = 0;
 	long current_timeo = *timeo;
-	DECLARE_WAITQUEUE(wait, current);
+	DEFINE_WAIT(wait);
 
 	if (tcp_memory_free(sk))
 		current_timeo = vm_wait = (net_random() % (HZ / 5)) + 2;
 
-	add_wait_queue(sk->sleep, &wait);
 	for (;;) {
 		set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
 
-		set_current_state(TASK_INTERRUPTIBLE);
+		prepare_to_wait(sk->sleep, &wait, TASK_INTERRUPTIBLE);
 
 		if (sk->err || (sk->shutdown & SEND_SHUTDOWN))
 			goto do_error;
@@ -740,8 +737,7 @@
 		*timeo = current_timeo;
 	}
 out:
-	current->state = TASK_RUNNING;
-	remove_wait_queue(sk->sleep, &wait);
+	finish_wait(sk->sleep, &wait);
 	return err;
 
 do_error:
@@ -1374,11 +1370,9 @@
 
 static long tcp_data_wait(struct sock *sk, long timeo)
 {
-	DECLARE_WAITQUEUE(wait, current);
+	DEFINE_WAIT(wait);
 
-	add_wait_queue(sk->sleep, &wait);
-
-	__set_current_state(TASK_INTERRUPTIBLE);
+	prepare_to_wait(sk->sleep, &wait, TASK_INTERRUPTIBLE);
 
 	set_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
 	release_sock(sk);
@@ -1389,8 +1383,7 @@
 	lock_sock(sk);
 	clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
 
-	remove_wait_queue(sk->sleep, &wait);
-	__set_current_state(TASK_RUNNING);
+	finish_wait(sk->sleep, &wait);
 	return timeo;
 }
 
@@ -2017,12 +2010,10 @@
 
 	if (timeout) {
 		struct task_struct *tsk = current;
-		DECLARE_WAITQUEUE(wait, current);
-
-		add_wait_queue(sk->sleep, &wait);
+		DEFINE_WAIT(wait);
 
 		do {
-			set_current_state(TASK_INTERRUPTIBLE);
+			prepare_to_wait(sk->sleep, &wait, TASK_INTERRUPTIBLE);
 			if (!closing(sk))
 				break;
 			release_sock(sk);
@@ -2030,8 +2021,7 @@
 			lock_sock(sk);
 		} while (!signal_pending(tsk) && timeout);
 
-		tsk->state = TASK_RUNNING;
-		remove_wait_queue(sk->sleep, &wait);
+		finish_wait(sk->sleep, &wait);
 	}
 
 adjudge_to_death:
@@ -2191,7 +2181,7 @@
 static int wait_for_connect(struct sock *sk, long timeo)
 {
 	struct tcp_opt *tp = tcp_sk(sk);
-	DECLARE_WAITQUEUE(wait, current);
+	DEFINE_WAIT(wait);
 	int err;
 
 	/*
@@ -2208,9 +2198,8 @@
 	 * our exclusiveness temporarily when we get woken up without
 	 * having to remove and re-insert us on the wait queue.
 	 */
-	add_wait_queue_exclusive(sk->sleep, &wait);
 	for (;;) {
-		current->state = TASK_INTERRUPTIBLE;
+		prepare_to_wait_exclusive(sk->sleep, &wait, TASK_INTERRUPTIBLE);
 		release_sock(sk);
 		if (!tp->accept_queue)
 			timeo = schedule_timeout(timeo);
@@ -2228,8 +2217,7 @@
 		if (!timeo)
 			break;
 	}
-	current->state = TASK_RUNNING;
-	remove_wait_queue(sk->sleep, &wait);
+	finish_wait(sk->sleep, &wait);
 	return err;
 }
 
diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c	Sat Mar  8 11:37:51 2003
+++ b/net/ipv4/tcp_ipv4.c	Sun Mar 23 02:21:28 2003
@@ -334,11 +334,11 @@
 	write_lock(&tcp_lhash_lock);
 
 	if (atomic_read(&tcp_lhash_users)) {
-		DECLARE_WAITQUEUE(wait, current);
+		DEFINE_WAIT(wait);
 
-		add_wait_queue_exclusive(&tcp_lhash_wait, &wait);
 		for (;;) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
+			prepare_to_wait_exclusive(&tcp_lhash_wait,
+						&wait, TASK_UNINTERRUPTIBLE);
 			if (!atomic_read(&tcp_lhash_users))
 				break;
 			write_unlock_bh(&tcp_lhash_lock);
@@ -346,8 +346,7 @@
 			write_lock_bh(&tcp_lhash_lock);
 		}
 
-		__set_current_state(TASK_RUNNING);
-		remove_wait_queue(&tcp_lhash_wait, &wait);
+		finish_wait(&tcp_lhash_wait, &wait);
 	}
 }
 
@@ -853,11 +852,7 @@
 	/* OK, now commit destination to socket.  */
 	__sk_dst_set(sk, &rt->u.dst);
 	tcp_v4_setup_caps(sk, &rt->u.dst);
-
-	/* DAVEM REDPEN: This used to sit above forced ext_header_len = 0
-	 *               above, it was real bug.  Is this one correct?
-	 */
-	tp->ext_header_len += rt->u.dst.header_len;
+	tp->ext2_header_len = rt->u.dst.header_len;
 
 	if (!tp->write_seq)
 		tp->write_seq = secure_tcp_sequence_number(inet->saddr,
@@ -868,6 +863,7 @@
 	inet->id = tp->write_seq ^ jiffies;
 
 	err = tcp_connect(sk);
+	rt = NULL;
 	if (err)
 		goto failure;
 
@@ -1611,7 +1607,7 @@
 	newtp->ext_header_len = 0;
 	if (newinet->opt)
 		newtp->ext_header_len = newinet->opt->optlen;
-	newtp->ext_header_len += dst->header_len;
+	newtp->ext2_header_len = dst->header_len;
 	newinet->id = newtp->write_seq ^ jiffies;
 
 	tcp_sync_mss(newsk, dst_pmtu(dst));
@@ -1802,7 +1798,7 @@
 	if (sk->state == TCP_TIME_WAIT)
 		goto do_time_wait;
 
-	if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb))
+	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
 		goto discard_and_relse;
 
 	if (sk_filter(sk, skb, 0))
@@ -1824,7 +1820,7 @@
 	return ret;
 
 no_tcp_socket:
-	if (!xfrm_policy_check(NULL, XFRM_POLICY_IN, skb))
+	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
 		goto discard_it;
 
 	if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) {
@@ -1844,7 +1840,7 @@
 	goto discard_it;
 
 do_time_wait:
-	if (!xfrm_policy_check(NULL, XFRM_POLICY_IN, skb))
+	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
 		goto discard_and_relse;
 
 	if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) {
diff -Nru a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
--- a/net/ipv4/tcp_output.c	Mon Mar  3 04:56:53 2003
+++ b/net/ipv4/tcp_output.c	Wed Mar 19 19:52:56 2003
@@ -570,7 +570,7 @@
 		mss_now = tp->mss_clamp;
 
 	/* Now subtract optional transport overhead */
-	mss_now -= tp->ext_header_len;
+	mss_now -= tp->ext_header_len + tp->ext2_header_len;
 
 	/* Then reserve room for full set of TCP options and 8 bytes of data */
 	if (mss_now < 48)
@@ -591,7 +591,7 @@
 		int large_mss;
 
 		large_mss = 65535 - tp->af_specific->net_header_len -
-			tp->ext_header_len - tp->tcp_header_len;
+			tp->ext_header_len - tp->ext2_header_len - tp->tcp_header_len;
 
 		if (tp->max_window && large_mss > (tp->max_window>>1))
 			large_mss = max((tp->max_window>>1), 68U - tp->tcp_header_len);
diff -Nru a/net/ipv4/udp.c b/net/ipv4/udp.c
--- a/net/ipv4/udp.c	Mon Mar  3 04:56:53 2003
+++ b/net/ipv4/udp.c	Sun Mar 23 02:21:28 2003
@@ -946,7 +946,7 @@
 	/*
 	 *	Charge it to the socket, dropping if the queue is full.
 	 */
-	if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb)) {
+	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) {
 		kfree_skb(skb);
 		return -1;
 	}
@@ -1077,7 +1077,7 @@
 		return 0;
 	}
 
-	if (!xfrm_policy_check(NULL, XFRM_POLICY_IN, skb))
+	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
 		goto drop;
 
 	/* No socket. Drop packet silently, if checksum is wrong */
diff -Nru a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv4/xfrm4_input.c	Sun Mar 23 02:21:03 2003
@@ -0,0 +1,129 @@
+/*
+ * xfrm4_input.c
+ *
+ * Changes:
+ *	YOSHIFUJI Hideaki @USAGI
+ *		Split up af-specific portion
+ * 	
+ */
+
+#include <net/ip.h>
+#include <net/xfrm.h>
+
+static kmem_cache_t *secpath_cachep;
+
+int xfrm4_rcv(struct sk_buff *skb)
+{
+	int err;
+	u32 spi, seq;
+	struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
+	struct xfrm_state *x;
+	int xfrm_nr = 0;
+	int decaps = 0;
+
+	if ((err = xfrm_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) != 0)
+		goto drop;
+
+	do {
+		struct iphdr *iph = skb->nh.iph;
+
+		if (xfrm_nr == XFRM_MAX_DEPTH)
+			goto drop;
+
+		x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, iph->protocol, AF_INET);
+		if (x == NULL)
+			goto drop;
+
+		spin_lock(&x->lock);
+		if (unlikely(x->km.state != XFRM_STATE_VALID))
+			goto drop_unlock;
+
+		if (x->props.replay_window && xfrm_replay_check(x, seq))
+			goto drop_unlock;
+
+		if (x->type->input(x, skb))
+			goto drop_unlock;
+
+		if (x->props.replay_window)
+			xfrm_replay_advance(x, seq);
+
+		x->curlft.bytes += skb->len;
+		x->curlft.packets++;
+
+		spin_unlock(&x->lock);
+
+		xfrm_vec[xfrm_nr++] = x;
+
+		iph = skb->nh.iph;
+
+		if (x->props.mode) {
+			if (iph->protocol != IPPROTO_IPIP)
+				goto drop;
+			skb->nh.raw = skb->data;
+			iph = skb->nh.iph;
+			memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+			decaps = 1;
+			break;
+		}
+
+		if ((err = xfrm_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) < 0)
+			goto drop;
+	} while (!err);
+
+	/* Allocate new secpath or COW existing one. */
+
+	if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
+		kmem_cache_t *pool = skb->sp ? skb->sp->pool : secpath_cachep;
+		struct sec_path *sp;
+		sp = kmem_cache_alloc(pool, SLAB_ATOMIC);
+		if (!sp)
+			goto drop;
+		if (skb->sp) {
+			memcpy(sp, skb->sp, sizeof(struct sec_path));
+			secpath_put(skb->sp);
+		} else {
+			sp->pool = pool;
+			sp->len = 0;
+		}
+		atomic_set(&sp->refcnt, 1);
+		skb->sp = sp;
+	}
+	if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
+		goto drop;
+
+	memcpy(skb->sp->xvec+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(void*));
+	skb->sp->len += xfrm_nr;
+
+	if (decaps) {
+		if (!(skb->dev->flags&IFF_LOOPBACK)) {
+			dst_release(skb->dst);
+			skb->dst = NULL;
+		}
+		netif_rx(skb);
+		return 0;
+	} else {
+		return -skb->nh.iph->protocol;
+	}
+
+drop_unlock:
+	spin_unlock(&x->lock);
+	xfrm_state_put(x);
+drop:
+	while (--xfrm_nr >= 0)
+		xfrm_state_put(xfrm_vec[xfrm_nr]);
+	kfree_skb(skb);
+	return 0;
+}
+
+
+void __init xfrm4_input_init(void)
+{
+	secpath_cachep = kmem_cache_create("secpath4_cache",
+					   sizeof(struct sec_path),
+					   0, SLAB_HWCACHE_ALIGN,
+					   NULL, NULL);
+
+	if (!secpath_cachep)
+		panic("IP: failed to allocate secpath4_cache\n");
+}
+
diff -Nru a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv4/xfrm4_policy.c	Sun Mar 23 02:21:17 2003
@@ -0,0 +1,277 @@
+/* 
+ * xfrm4_policy.c
+ *
+ * Changes:
+ *	Kazunori MIYAZAWA @USAGI
+ * 	YOSHIFUJI Hideaki @USAGI
+ *		Split up af-specific portion
+ * 	
+ */
+
+#include <linux/config.h>
+#include <net/xfrm.h>
+#include <net/ip.h>
+
+extern struct dst_ops xfrm4_dst_ops;
+extern struct xfrm_policy_afinfo xfrm4_policy_afinfo;
+
+static struct xfrm_type_map xfrm4_type_map = { .lock = RW_LOCK_UNLOCKED };
+
+static int xfrm4_dst_lookup(struct xfrm_dst **dst, struct flowi *fl)
+{
+	return __ip_route_output_key((struct rtable**)dst, fl);
+}
+
+/* Check that the bundle accepts the flow and its components are
+ * still valid.
+ */
+
+static int __xfrm4_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl)
+{
+	do {
+		if (xdst->u.dst.ops != &xfrm4_dst_ops)
+			return 1;
+
+		if (!xfrm_selector_match(&xdst->u.dst.xfrm->sel, fl, AF_INET))
+			return 0;
+		if (xdst->u.dst.xfrm->km.state != XFRM_STATE_VALID ||
+		    xdst->u.dst.path->obsolete > 0)
+			return 0;
+		xdst = (struct xfrm_dst*)xdst->u.dst.child;
+	} while (xdst);
+	return 0;
+}
+
+static struct dst_entry *
+__xfrm4_find_bundle(struct flowi *fl, struct rtable *rt, struct xfrm_policy *policy)
+{
+	struct dst_entry *dst;
+
+	if (!fl->fl4_src)
+		fl->fl4_src = rt->rt_src;
+	if (!fl->fl4_dst)
+		fl->fl4_dst = rt->rt_dst;
+	read_lock_bh(&policy->lock);
+	for (dst = policy->bundles; dst; dst = dst->next) {
+		struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
+		if (xdst->u.rt.fl.oif == fl->oif &&	/*XXX*/
+		    xdst->u.rt.fl.fl4_dst == fl->fl4_dst &&
+	    	    xdst->u.rt.fl.fl4_src == fl->fl4_src &&
+		    __xfrm4_bundle_ok(xdst, fl)) {
+			dst_clone(dst);
+			break;
+		}
+	}
+	read_unlock_bh(&policy->lock);
+	return dst;
+}
+
+/* Allocate chain of dst_entry's, attach known xfrm's, calculate
+ * all the metrics... Shortly, bundle a bundle.
+ */
+
+static int
+__xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
+		      struct flowi *fl, struct dst_entry **dst_p)
+{
+	struct dst_entry *dst, *dst_prev;
+	struct rtable *rt0 = (struct rtable*)(*dst_p);
+	struct rtable *rt = rt0;
+	u32 remote = fl->fl4_dst;
+	u32 local  = fl->fl4_src;
+	int i;
+	int err;
+	int header_len = 0;
+	int trailer_len = 0;
+
+	dst = dst_prev = NULL;
+
+	for (i = 0; i < nx; i++) {
+		struct dst_entry *dst1 = dst_alloc(&xfrm4_dst_ops);
+
+		if (unlikely(dst1 == NULL)) {
+			err = -ENOBUFS;
+			goto error;
+		}
+
+		dst1->xfrm = xfrm[i];
+		if (!dst)
+			dst = dst1;
+		else {
+			dst_prev->child = dst1;
+			dst1->flags |= DST_NOHASH;
+			dst_clone(dst1);
+		}
+		dst_prev = dst1;
+		if (xfrm[i]->props.mode) {
+			remote = xfrm[i]->id.daddr.a4;
+			local  = xfrm[i]->props.saddr.a4;
+		}
+		header_len += xfrm[i]->props.header_len;
+		trailer_len += xfrm[i]->props.trailer_len;
+	}
+
+	if (remote != fl->fl4_dst) {
+		struct flowi fl_tunnel = { .nl_u = { .ip4_u =
+						     { .daddr = remote,
+						       .saddr = local }
+					           }
+				         };
+		err = xfrm_dst_lookup((struct xfrm_dst**)&rt, &fl_tunnel, AF_INET);
+		if (err)
+			goto error;
+	} else {
+		dst_hold(&rt->u.dst);
+	}
+	dst_prev->child = &rt->u.dst;
+	for (dst_prev = dst; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
+		struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
+		x->u.rt.fl = *fl;
+
+		dst_prev->dev = rt->u.dst.dev;
+		if (rt->u.dst.dev)
+			dev_hold(rt->u.dst.dev);
+		dst_prev->obsolete	= -1;
+		dst_prev->flags	       |= DST_HOST;
+		dst_prev->lastuse	= jiffies;
+		dst_prev->header_len	= header_len;
+		dst_prev->trailer_len	= trailer_len;
+		memcpy(&dst_prev->metrics, &rt->u.dst.metrics, sizeof(dst_prev->metrics));
+		dst_prev->path		= &rt->u.dst;
+
+		/* Copy neighbout for reachability confirmation */
+		dst_prev->neighbour	= neigh_clone(rt->u.dst.neighbour);
+		dst_prev->input		= rt->u.dst.input;
+		dst_prev->output	= dst_prev->xfrm->type->output;
+		if (rt->peer)
+			atomic_inc(&rt->peer->refcnt);
+		x->u.rt.peer = rt->peer;
+		/* Sheit... I remember I did this right. Apparently,
+		 * it was magically lost, so this code needs audit */
+		x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
+		x->u.rt.rt_type = rt->rt_type;
+		x->u.rt.rt_src = rt0->rt_src;
+		x->u.rt.rt_dst = rt0->rt_dst;
+		x->u.rt.rt_gateway = rt->rt_gateway;
+		x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
+		header_len -= x->u.dst.xfrm->props.header_len;
+		trailer_len -= x->u.dst.xfrm->props.trailer_len;
+	}
+	*dst_p = dst;
+	return 0;
+
+error:
+	if (dst)
+		dst_free(dst);
+	return err;
+}
+
+static void
+_decode_session4(struct sk_buff *skb, struct flowi *fl)
+{
+	struct iphdr *iph = skb->nh.iph;
+	u8 *xprth = skb->nh.raw + iph->ihl*4;
+
+	if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) {
+		switch (iph->protocol) {
+		case IPPROTO_UDP:
+		case IPPROTO_TCP:
+		case IPPROTO_SCTP:
+			if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
+				u16 *ports = (u16 *)xprth;
+
+				fl->uli_u.ports.sport = ports[0];
+				fl->uli_u.ports.dport = ports[1];
+			}
+			break;
+
+		case IPPROTO_ESP:
+			if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
+				u32 *ehdr = (u32 *)xprth;
+
+				fl->uli_u.spi = ehdr[0];
+			}
+			break;
+
+		case IPPROTO_AH:
+			if (pskb_may_pull(skb, xprth + 8 - skb->data)) {
+				u32 *ah_hdr = (u32*)xprth;
+
+				fl->uli_u.spi = ah_hdr[1];
+			}
+			break;
+
+		default:
+			fl->uli_u.spi = 0;
+			break;
+		};
+	} else {
+		memset(fl, 0, sizeof(struct flowi));
+	}
+	fl->proto = iph->protocol;
+	fl->fl4_dst = iph->daddr;
+	fl->fl4_src = iph->saddr;
+}
+
+static inline int xfrm4_garbage_collect(void)
+{
+	read_lock(&xfrm4_policy_afinfo.lock);
+	xfrm4_policy_afinfo.garbage_collect();
+	read_unlock(&xfrm4_policy_afinfo.lock);
+	return (atomic_read(&xfrm4_dst_ops.entries) > xfrm4_dst_ops.gc_thresh*2);
+}
+
+static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu)
+{
+	struct dst_entry *path = dst->path;
+
+	if (mtu < 68 + dst->header_len)
+		return;
+
+	path->ops->update_pmtu(path, mtu);
+}
+
+struct dst_ops xfrm4_dst_ops = {
+	.family =		AF_INET,
+	.protocol =		__constant_htons(ETH_P_IP),
+	.gc =			xfrm4_garbage_collect,
+	.update_pmtu =		xfrm4_update_pmtu,
+	.gc_thresh =		1024,
+	.entry_size =		sizeof(struct xfrm_dst),
+};
+
+struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
+	.family = 		AF_INET,
+	.lock = 		RW_LOCK_UNLOCKED,
+	.type_map = 		&xfrm4_type_map,
+	.dst_ops =		&xfrm4_dst_ops,
+	.dst_lookup =		xfrm4_dst_lookup,
+	.find_bundle = 		__xfrm4_find_bundle,
+	.bundle_create =	__xfrm4_bundle_create,
+	.decode_session =	_decode_session4,
+};
+
+void __init xfrm4_policy_init(void)
+{
+	xfrm_policy_register_afinfo(&xfrm4_policy_afinfo);
+}
+
+void __exit xfrm4_policy_fini(void)
+{
+	xfrm_policy_unregister_afinfo(&xfrm4_policy_afinfo);
+}
+
+void __init xfrm4_init(void)
+{
+	xfrm4_state_init();
+	xfrm4_policy_init();
+	xfrm4_input_init();
+}
+
+void __exit xfrm4_fini(void)
+{
+	//xfrm4_input_fini();
+	xfrm4_policy_fini();
+	xfrm4_state_fini();
+}
+
diff -Nru a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv4/xfrm4_state.c	Sun Mar 23 02:21:18 2003
@@ -0,0 +1,128 @@
+/*
+ * xfrm4_state.c
+ *
+ * Changes:
+ * 	YOSHIFUJI Hideaki @USAGI
+ * 		Split up af-specific portion
+ *
+ */
+
+#include <net/xfrm.h>
+#include <linux/pfkeyv2.h>
+#include <linux/ipsec.h>
+
+extern struct xfrm_state_afinfo xfrm4_state_afinfo;
+
+static void
+__xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
+		     struct xfrm_tmpl *tmpl,
+		     xfrm_address_t *daddr, xfrm_address_t *saddr)
+{
+	x->sel.daddr.a4 = fl->fl4_dst;
+	x->sel.saddr.a4 = fl->fl4_src;
+	x->sel.dport = fl->uli_u.ports.dport;
+	x->sel.dport_mask = ~0;
+	x->sel.sport = fl->uli_u.ports.sport;
+	x->sel.sport_mask = ~0;
+	x->sel.prefixlen_d = 32;
+	x->sel.prefixlen_s = 32;
+	x->sel.proto = fl->proto;
+	x->sel.ifindex = fl->oif;
+	x->id = tmpl->id;
+	if (x->id.daddr.a4 == 0)
+		x->id.daddr.a4 = daddr->a4;
+	x->props.saddr = tmpl->saddr;
+	if (x->props.saddr.a4 == 0)
+		x->props.saddr.a4 = saddr->a4;
+	x->props.mode = tmpl->mode;
+	x->props.reqid = tmpl->reqid;
+	x->props.family = AF_INET;
+}
+
+static struct xfrm_state *
+__xfrm4_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto)
+{
+	unsigned h = __xfrm4_spi_hash(daddr, spi, proto);
+	struct xfrm_state *x;
+
+	list_for_each_entry(x, xfrm4_state_afinfo.state_byspi+h, byspi) {
+		if (x->props.family == AF_INET &&
+		    spi == x->id.spi &&
+		    daddr->a4 == x->id.daddr.a4 &&
+		    proto == x->id.proto) {
+			atomic_inc(&x->refcnt);
+			return x;
+		}
+	}
+	return NULL;
+}
+
+static struct xfrm_state *
+__xfrm4_find_acq(u8 mode, u16 reqid, u8 proto, 
+		 xfrm_address_t *daddr, xfrm_address_t *saddr, 
+		 int create)
+{
+	struct xfrm_state *x, *x0;
+	unsigned h = __xfrm4_dst_hash(daddr);
+
+	x0 = NULL;
+
+	list_for_each_entry(x, xfrm4_state_afinfo.state_bydst+h, bydst) {
+		if (x->props.family == AF_INET &&
+		    daddr->a4 == x->id.daddr.a4 &&
+		    mode == x->props.mode &&
+		    proto == x->id.proto &&
+		    saddr->a4 == x->props.saddr.a4 &&
+		    reqid == x->props.reqid &&
+		    x->km.state == XFRM_STATE_ACQ) {
+			    if (!x0)
+				    x0 = x;
+			    if (x->id.spi)
+				    continue;
+			    x0 = x;
+			    break;
+		    }
+	}
+	if (x0) {
+		atomic_inc(&x0->refcnt);
+	} else if (create && (x0 = xfrm_state_alloc()) != NULL) {
+		x0->sel.daddr.a4 = daddr->a4;
+		x0->sel.saddr.a4 = saddr->a4;
+		x0->sel.prefixlen_d = 32;
+		x0->sel.prefixlen_s = 32;
+		x0->props.saddr.a4 = saddr->a4;
+		x0->km.state = XFRM_STATE_ACQ;
+		x0->id.daddr.a4 = daddr->a4;
+		x0->id.proto = proto;
+		x0->props.family = AF_INET;
+		x0->props.mode = mode;
+		x0->props.reqid = reqid;
+		x0->props.family = AF_INET;
+		x0->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
+		atomic_inc(&x0->refcnt);
+		mod_timer(&x0->timer, jiffies + XFRM_ACQ_EXPIRES*HZ);
+		atomic_inc(&x0->refcnt);
+		list_add_tail(&x0->bydst, xfrm4_state_afinfo.state_bydst+h);
+		wake_up(&km_waitq);
+	}
+	return x0;
+}
+
+static struct xfrm_state_afinfo xfrm4_state_afinfo = {
+	.family			= AF_INET,
+	.lock			= RW_LOCK_UNLOCKED,
+	.init_tempsel		= __xfrm4_init_tempsel,
+	.state_lookup		= __xfrm4_state_lookup,
+	.find_acq		= __xfrm4_find_acq,
+};
+
+void __init xfrm4_state_init(void)
+{
+	xfrm_state_register_afinfo(&xfrm4_state_afinfo);
+}
+
+void __exit xfrm4_state_fini(void)
+{
+	xfrm_state_unregister_afinfo(&xfrm4_state_afinfo);
+}
+
diff -Nru a/net/ipv4/xfrm_algo.c b/net/ipv4/xfrm_algo.c
--- a/net/ipv4/xfrm_algo.c	Thu Mar  6 16:16:15 2003
+++ b/net/ipv4/xfrm_algo.c	Sun Mar 23 02:09:10 2003
@@ -219,6 +219,36 @@
 },
 };
 
+static struct xfrm_algo_desc calg_list[] = {
+{
+	.name = "deflate",
+	.uinfo = {
+		.comp = {
+			.threshold = 90,
+		}
+	},
+	.desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
+},
+{
+	.name = "lzs",
+	.uinfo = {
+		.comp = {
+			.threshold = 90,
+		}
+	},
+	.desc = { .sadb_alg_id = SADB_X_CALG_LZS }
+},
+{
+	.name = "lzjh",
+	.uinfo = {
+		.comp = {
+			.threshold = 50,
+		}
+	},
+	.desc = { .sadb_alg_id = SADB_X_CALG_LZJH }
+},
+};
+
 static inline int aalg_entries(void)
 {
 	return sizeof(aalg_list) / sizeof(aalg_list[0]);
@@ -229,6 +259,12 @@
 	return sizeof(ealg_list) / sizeof(ealg_list[0]);
 }
 
+static inline int calg_entries(void)
+{
+	return sizeof(calg_list) / sizeof(calg_list[0]);
+}
+
+/* Todo: generic iterators */
 struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
 {
 	int i;
@@ -259,6 +295,21 @@
 	return NULL;
 }
 
+struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
+{
+	int i;
+
+	for (i = 0; i < calg_entries(); i++) {
+		if (calg_list[i].desc.sadb_alg_id == alg_id) {
+			if (calg_list[i].available)
+				return &calg_list[i];
+			else
+				break;
+		}
+	}
+	return NULL;
+}
+
 struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name)
 {
 	int i;
@@ -295,6 +346,24 @@
 	return NULL;
 }
 
+struct xfrm_algo_desc *xfrm_calg_get_byname(char *name)
+{
+	int i;
+
+	if (!name)
+		return NULL;
+
+	for (i=0; i < calg_entries(); i++) {
+		if (strcmp(name, calg_list[i].name) == 0) {
+			if (calg_list[i].available)
+				return &calg_list[i];
+			else
+				break;
+		}
+	}
+	return NULL;
+}
+
 struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
 {
 	if (idx >= aalg_entries())
@@ -311,6 +380,14 @@
 	return &ealg_list[idx];
 }
 
+struct xfrm_algo_desc *xfrm_calg_get_byidx(unsigned int idx)
+{
+	if (idx >= calg_entries())
+		return NULL;
+
+	return &calg_list[idx];
+}
+
 /*
  * Probe for the availability of crypto algorithms, and set the available
  * flag for any algorithms found on the system.  This is typically called by
@@ -333,6 +410,12 @@
 		status = crypto_alg_available(ealg_list[i].name, 0);
 		if (ealg_list[i].available != status)
 			ealg_list[i].available = status;
+	}
+	
+	for (i = 0; i < calg_entries(); i++) {
+		status = crypto_alg_available(calg_list[i].name, 0);
+		if (calg_list[i].available != status)
+			calg_list[i].available = status;
 	}
 #endif
 }
diff -Nru a/net/ipv4/xfrm_input.c b/net/ipv4/xfrm_input.c
--- a/net/ipv4/xfrm_input.c	Wed Mar  5 15:45:36 2003
+++ b/net/ipv4/xfrm_input.c	Sun Mar 23 23:23:35 2003
@@ -1,178 +1,26 @@
-/* Changes
+/*
+ * xfrm_input.c
  *
- *	Mitsuru KANDA @USAGI       : IPv6 Support 
- * 	Kazunori MIYAZAWA @USAGI   :
- * 	YOSHIFUJI Hideaki @USAGI   :
- * 	Kunihiro Ishiguro          :
+ * Changes:
+ * 	YOSHIFUJI Hideaki @USAGI
+ * 		Split up af-specific portion
  * 	
  */
 
 #include <net/ip.h>
-#include <net/ipv6.h>
 #include <net/xfrm.h>
 
-static kmem_cache_t *secpath_cachep;
-
 void __secpath_destroy(struct sec_path *sp)
 {
 	int i;
 	for (i = 0; i < sp->len; i++)
 		xfrm_state_put(sp->xvec[i]);
-	kmem_cache_free(secpath_cachep, sp);
-}
-
-/* Fetch spi and seq frpm ipsec header */
-
-static int xfrm_parse_spi(struct sk_buff *skb, u32 *spi, u32 *seq)
-{
-	int offset, offset_seq;
-
-	switch (skb->nh.iph->protocol) {
-	case IPPROTO_AH:
-		offset = offsetof(struct ip_auth_hdr, spi);
-		offset_seq = offsetof(struct ip_auth_hdr, seq_no);
-		break;
-	case IPPROTO_ESP:
-		offset = offsetof(struct ip_esp_hdr, spi);
-		offset_seq = offsetof(struct ip_esp_hdr, seq_no);
-		break;
-	case IPPROTO_COMP:
-		if (!pskb_may_pull(skb, 4))
-			return -EINVAL;
-		*spi = *(u16*)(skb->h.raw + 2);
-		*seq = 0;
-		return 0;
-	default:
-		return 1;
-	}
-
-	if (!pskb_may_pull(skb, 16))
-		return -EINVAL;
-
-	*spi = *(u32*)(skb->h.raw + offset);
-	*seq = *(u32*)(skb->h.raw + offset_seq);
-	return 0;
-}
-
-
-
-int xfrm4_rcv(struct sk_buff *skb)
-{
-	int err;
-	u32 spi, seq;
-	struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
-	struct xfrm_state *x;
-	int xfrm_nr = 0;
-	int decaps = 0;
-
-	if ((err = xfrm_parse_spi(skb, &spi, &seq)) != 0)
-		goto drop;
-
-	do {
-		struct iphdr *iph = skb->nh.iph;
-
-		if (xfrm_nr == XFRM_MAX_DEPTH)
-			goto drop;
-
-		x = xfrm4_state_lookup(iph->daddr, spi, iph->protocol);
-		if (x == NULL)
-			goto drop;
-
-		spin_lock(&x->lock);
-		if (unlikely(x->km.state != XFRM_STATE_VALID))
-			goto drop_unlock;
-
-		if (x->props.replay_window && xfrm_replay_check(x, seq))
-			goto drop_unlock;
-
-		if (x->type->input(x, skb))
-			goto drop_unlock;
-
-		if (x->props.replay_window)
-			xfrm_replay_advance(x, seq);
-
-		x->curlft.bytes += skb->len;
-		x->curlft.packets++;
-
-		spin_unlock(&x->lock);
-
-		xfrm_vec[xfrm_nr++] = x;
-
-		iph = skb->nh.iph;
-
-		if (x->props.mode) {
-			if (iph->protocol != IPPROTO_IPIP)
-				goto drop;
-			skb->nh.raw = skb->data;
-			iph = skb->nh.iph;
-			memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
-			decaps = 1;
-			break;
-		}
-
-		if ((err = xfrm_parse_spi(skb, &spi, &seq)) < 0)
-			goto drop;
-	} while (!err);
-
-	/* Allocate new secpath or COW existing one. */
-
-	if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
-		struct sec_path *sp;
-		sp = kmem_cache_alloc(secpath_cachep, SLAB_ATOMIC);
-		if (!sp)
-			goto drop;
-		if (skb->sp) {
-			memcpy(sp, skb->sp, sizeof(struct sec_path));
-			secpath_put(skb->sp);
-		} else
-			sp->len = 0;
-		atomic_set(&sp->refcnt, 1);
-		skb->sp = sp;
-	}
-	if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
-		goto drop;
-
-	memcpy(skb->sp->xvec+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(void*));
-	skb->sp->len += xfrm_nr;
-
-	if (decaps) {
-		if (!(skb->dev->flags&IFF_LOOPBACK)) {
-			dst_release(skb->dst);
-			skb->dst = NULL;
-		}
-		netif_rx(skb);
-		return 0;
-	} else {
-		return -skb->nh.iph->protocol;
-	}
-
-drop_unlock:
-	spin_unlock(&x->lock);
-	xfrm_state_put(x);
-drop:
-	while (--xfrm_nr >= 0)
-		xfrm_state_put(xfrm_vec[xfrm_nr]);
-	kfree_skb(skb);
-	return 0;
-}
-
-
-void __init xfrm_input_init(void)
-{
-	secpath_cachep = kmem_cache_create("secpath_cache",
-					   sizeof(struct sec_path),
-					   0, SLAB_HWCACHE_ALIGN,
-					   NULL, NULL);
-
-	if (!secpath_cachep)
-		panic("IP: failed to allocate secpath_cache\n");
+	kmem_cache_free(sp->pool, sp);
 }
 
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-
 /* Fetch spi and seq frpm ipsec header */
 
-static int xfrm6_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
+int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
 {
 	int offset, offset_seq;
 
@@ -188,7 +36,7 @@
 	case IPPROTO_COMP:
 		if (!pskb_may_pull(skb, 4))
 			return -EINVAL;
-		*spi = *(u16*)(skb->h.raw + 2);
+		*spi = ntohl(ntohs(*(u16*)(skb->h.raw + 2)));
 		*seq = 0;
 		return 0;
 	default:
@@ -202,253 +50,3 @@
 	*seq = *(u32*)(skb->h.raw + offset_seq);
 	return 0;
 }
-
-static int zero_out_mutable_opts(struct ipv6_opt_hdr *opthdr)
-{
-	u8 *opt = (u8 *)opthdr;
-	int len = ipv6_optlen(opthdr);
-	int off = 0;
-	int optlen = 0;
-
-	off += 2;
-	len -= 2;
-
-	while (len > 0) {
-
-		switch (opt[off]) {
-
-		case IPV6_TLV_PAD0:
-			optlen = 1;
-			break;
-		default:
-			if (len < 2) 
-				goto bad;
-			optlen = opt[off+1]+2;
-			if (len < optlen)
-				goto bad;
-			if (opt[off] & 0x20)
-				memset(&opt[off+2], 0, opt[off+1]);
-			break;
-		}
-
-		off += optlen;
-		len -= optlen;
-	}
-	if (len == 0)
-		return 1;
-
-bad:
-	return 0;
-}
-
-int xfrm6_clear_mutable_options(struct sk_buff *skb, u16 *nh_offset, int dir)
-{
-	u16 offset = sizeof(struct ipv6hdr);
-	struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
-	unsigned int packet_len = skb->tail - skb->nh.raw;
-	u8 nexthdr = skb->nh.ipv6h->nexthdr;
-	u8 nextnexthdr = 0;
-
-	*nh_offset = ((unsigned char *)&skb->nh.ipv6h->nexthdr) - skb->nh.raw;
-
-	while (offset + 1 <= packet_len) {
-
-		switch (nexthdr) {
-
-		case NEXTHDR_HOP:
-			*nh_offset = offset;
-			offset += ipv6_optlen(exthdr);
-			if (!zero_out_mutable_opts(exthdr)) {
-				if (net_ratelimit())
-					printk(KERN_WARNING "overrun hopopts\n"); 
-				return 0;
-			}
-			nexthdr = exthdr->nexthdr;
-			exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
-			break;
-
-		case NEXTHDR_ROUTING:
-			*nh_offset = offset;
-			offset += ipv6_optlen(exthdr);
-			((struct ipv6_rt_hdr*)exthdr)->segments_left = 0; 
-			nexthdr = exthdr->nexthdr;
-			exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
-			break;
-
-		case NEXTHDR_DEST:
-			*nh_offset = offset;
-			offset += ipv6_optlen(exthdr);
-			if (!zero_out_mutable_opts(exthdr))  {
-				if (net_ratelimit())
-					printk(KERN_WARNING "overrun destopt\n"); 
-				return 0;
-			}
-			nexthdr = exthdr->nexthdr;
-			exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
-			break;
-
-		case NEXTHDR_AUTH:
-			if (dir == XFRM_POLICY_OUT) {
-				memset(((struct ipv6_auth_hdr*)exthdr)->auth_data, 0, 
-				       (((struct ipv6_auth_hdr*)exthdr)->hdrlen - 1) << 2);
-			}
-			if (exthdr->nexthdr == NEXTHDR_DEST) {
-				offset += (((struct ipv6_auth_hdr*)exthdr)->hdrlen + 2) << 2;
-				exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
-				nextnexthdr = exthdr->nexthdr;
-				if (!zero_out_mutable_opts(exthdr)) {
-					if (net_ratelimit())
-						printk(KERN_WARNING "overrun destopt\n");
-					return 0;
-				}
-			}
-			return nexthdr;
-		default :
-			return nexthdr;
-		}
-	}
-
-	return nexthdr;
-}
-
-int xfrm6_rcv(struct sk_buff *skb)
-{
-	int err;
-	u32 spi, seq;
-	struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
-	struct xfrm_state *x;
-	int xfrm_nr = 0;
-	int decaps = 0;
-	struct ipv6hdr *hdr = skb->nh.ipv6h;
-	unsigned char *tmp_hdr = NULL;
-	int hdr_len = 0;
-	u16 nh_offset = 0;
-	u8 nexthdr = 0;
-
-	if (hdr->nexthdr == IPPROTO_AH || hdr->nexthdr == IPPROTO_ESP) {
-		nh_offset = ((unsigned char*)&skb->nh.ipv6h->nexthdr) - skb->nh.raw;
-		hdr_len = sizeof(struct ipv6hdr);
-	} else {
-		hdr_len = skb->h.raw - skb->nh.raw;
-	}
-
-	tmp_hdr = kmalloc(hdr_len, GFP_ATOMIC);
-	if (!tmp_hdr)
-		goto drop;
-	memcpy(tmp_hdr, skb->nh.raw, hdr_len);
-
-	nexthdr = xfrm6_clear_mutable_options(skb, &nh_offset, XFRM_POLICY_IN);
-	hdr->priority    = 0;
-	hdr->flow_lbl[0] = 0;
-	hdr->flow_lbl[1] = 0;
-	hdr->flow_lbl[2] = 0;
-	hdr->hop_limit   = 0;
-
-	if ((err = xfrm6_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
-		goto drop;
-	
-	do {
-		struct ipv6hdr *iph = skb->nh.ipv6h;
-
-		if (xfrm_nr == XFRM_MAX_DEPTH)
-			goto drop;
-
-		x = xfrm6_state_lookup(&iph->daddr, spi, nexthdr);
-		if (x == NULL)
-			goto drop;
-		spin_lock(&x->lock);
-		if (unlikely(x->km.state != XFRM_STATE_VALID))
-			goto drop_unlock;
-
-		if (x->props.replay_window && xfrm_replay_check(x, seq))
-			goto drop_unlock;
-
-		nexthdr = x->type->input(x, skb);
-		if (nexthdr <= 0)
-			goto drop_unlock;
-
-		if (x->props.replay_window)
-			xfrm_replay_advance(x, seq);
-
-		x->curlft.bytes += skb->len;
-		x->curlft.packets++;
-
-		spin_unlock(&x->lock);
-
-		xfrm_vec[xfrm_nr++] = x;
-
-		iph = skb->nh.ipv6h; /* ??? */ 
-
-		if (nexthdr == NEXTHDR_DEST) {
-			if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
-		    	!pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
-				err = -EINVAL;
-				goto drop;
-			}
-			nexthdr = skb->h.raw[0];
-			nh_offset = skb->h.raw - skb->nh.raw;
-			skb_pull(skb, (skb->h.raw[1]+1)<<3);
-			skb->h.raw = skb->data;
-		}
-
-		if (x->props.mode) { /* XXX */
-			if (iph->nexthdr != IPPROTO_IPV6)
-				goto drop;
-			skb->nh.raw = skb->data;
-			iph = skb->nh.ipv6h;
-			decaps = 1;
-			break;
-		}
-
-		if ((err = xfrm6_parse_spi(skb, nexthdr, &spi, &seq)) < 0)
-			goto drop;
-	} while (!err);
-
-	memcpy(skb->nh.raw, tmp_hdr, hdr_len);
-	skb->nh.raw[nh_offset] = nexthdr;
-	skb->nh.ipv6h->payload_len = htons(hdr_len + skb->len - sizeof(struct ipv6hdr));
-
-	/* Allocate new secpath or COW existing one. */
-	if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
-		struct sec_path *sp;
-		sp = kmem_cache_alloc(secpath_cachep, SLAB_ATOMIC);
-		if (!sp)
-			goto drop;
-		if (skb->sp) {
-			memcpy(sp, skb->sp, sizeof(struct sec_path));
-			secpath_put(skb->sp);
-		} else
-			sp->len = 0;
-		atomic_set(&sp->refcnt, 1);
-		skb->sp = sp;
-	}
-
-	if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
-		goto drop;
-
-	memcpy(skb->sp->xvec+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(void*));
-	skb->sp->len += xfrm_nr;
-
-	if (decaps) {
-		if (!(skb->dev->flags&IFF_LOOPBACK)) {
-			dst_release(skb->dst);
-			skb->dst = NULL;
-		}
-		netif_rx(skb);
-		return 0;
-	} else {
-		return -nexthdr;
-	}
-
-drop_unlock:
-	spin_unlock(&x->lock);
-	xfrm_state_put(x);
-drop:
-	if (tmp_hdr) kfree(tmp_hdr);
-	while (--xfrm_nr >= 0)
-		xfrm_state_put(xfrm_vec[xfrm_nr]);
-	kfree_skb(skb);
-	return 0;
-}
-
-#endif /* CONFIG_IPV6 || CONFIG_IPV6_MODULE */
diff -Nru a/net/ipv4/xfrm_policy.c b/net/ipv4/xfrm_policy.c
--- a/net/ipv4/xfrm_policy.c	Wed Mar  5 15:45:36 2003
+++ b/net/ipv4/xfrm_policy.c	Sun Mar 23 02:21:29 2003
@@ -1,16 +1,20 @@
-/* Changes
+/* 
+ * xfrm_policy.c
  *
- *	Mitsuru KANDA @USAGI       : IPv6 Support 
- * 	Kazunori MIYAZAWA @USAGI   :
- * 	Kunihiro Ishiguro          :
+ * Changes:
+ *	Mitsuru KANDA @USAGI
+ * 	Kazunori MIYAZAWA @USAGI
+ * 	Kunihiro Ishiguro
+ * 		IPv6 support
+ * 	Kazunori MIYAZAWA @USAGI
+ * 	YOSHIFUJI Hideaki
+ * 		Split up af-specific portion
  * 	
  */
 
 #include <linux/config.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
-#include <net/ipv6.h>
-#include <net/ip6_route.h>
 
 DECLARE_MUTEX(xfrm_cfg_sem);
 
@@ -19,12 +23,10 @@
 
 struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2];
 
-extern struct dst_ops xfrm4_dst_ops;
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-extern struct dst_ops xfrm6_dst_ops;
-#endif
+static rwlock_t xfrm_policy_afinfo_lock = RW_LOCK_UNLOCKED;
+static struct xfrm_policy_afinfo *xfrm_policy_afinfo[NPROTO];
 
-static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family);
+kmem_cache_t *xfrm_dst_cache;
 
 /* Limited flow cache. Its function now is to accelerate search for
  * policy rules.
@@ -49,40 +51,8 @@
 
 struct flow_entry **flow_table;
 
-#define FLOWCACHE_HASH_SIZE	1024
-
-static inline u32 flow_hash(struct flowi *fl)
-{
-	u32 hash = fl->fl4_src ^ fl->uli_u.ports.sport;
-
-	hash = ((hash & 0xF0F0F0F0) >> 4) | ((hash & 0x0F0F0F0F) << 4);
-
-	hash ^= fl->fl4_dst ^ fl->uli_u.ports.dport;
-	hash ^= (hash >> 10);
-	hash ^= (hash >> 20);
-	return hash & (FLOWCACHE_HASH_SIZE-1);
-}
-
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-static inline u32 flow_hash6(struct flowi *fl)
-{
-	u32 hash = fl->fl6_src->s6_addr32[2] ^
-		   fl->fl6_src->s6_addr32[3] ^ 
-		   fl->uli_u.ports.sport;
-
-	hash = ((hash & 0xF0F0F0F0) >> 4) | ((hash & 0x0F0F0F0F) << 4);
-
-	hash ^= fl->fl6_dst->s6_addr32[2] ^
-		fl->fl6_dst->s6_addr32[3] ^ 
-		fl->uli_u.ports.dport;
-	hash ^= (hash >> 10);
-	hash ^= (hash >> 20);
-	return hash & (FLOWCACHE_HASH_SIZE-1);
-}
-#endif
-
-static int flow_lwm = 2*FLOWCACHE_HASH_SIZE;
-static int flow_hwm = 4*FLOWCACHE_HASH_SIZE;
+static int flow_lwm = 2*XFRM_FLOWCACHE_HASH_SIZE;
+static int flow_hwm = 4*XFRM_FLOWCACHE_HASH_SIZE;
 
 static int flow_number[NR_CPUS] __cacheline_aligned;
 
@@ -92,11 +62,11 @@
 {
 	int i;
 	struct flow_entry *fle, **flp;
-	int shrink_to = flow_lwm/FLOWCACHE_HASH_SIZE;
+	int shrink_to = flow_lwm/XFRM_FLOWCACHE_HASH_SIZE;
 
-	for (i=0; i<FLOWCACHE_HASH_SIZE; i++) {
+	for (i=0; i<XFRM_FLOWCACHE_HASH_SIZE; i++) {
 		int k = 0;
-		flp = &flow_table[cpu*FLOWCACHE_HASH_SIZE+i];
+		flp = &flow_table[cpu*XFRM_FLOWCACHE_HASH_SIZE+i];
 		while ((fle=*flp) != NULL && k<shrink_to) {
 			k++;
 			flp = &fle->next;
@@ -118,23 +88,12 @@
 	u32 hash;
 	int cpu;
 
-	switch (family) {
-	case AF_INET:
-		hash = flow_hash(fl);
-		break;
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-	case AF_INET6:
-		hash = flow_hash6(fl);
-		break;
-#endif
-	default:
-		return NULL;
-	}
+	hash = flow_hash(fl, family);
 
 	local_bh_disable();
 	cpu = smp_processor_id();
 
-	for (fle = flow_table[cpu*FLOWCACHE_HASH_SIZE+hash];
+	for (fle = flow_table[cpu*XFRM_FLOWCACHE_HASH_SIZE+hash];
 	     fle; fle = fle->next) {
 		if (memcmp(fl, &fle->fl, sizeof(fle->fl)) == 0 &&
 		    fle->dir == dir) {
@@ -172,8 +131,8 @@
 			fle->pol = pol;
 			if (pol)
 				atomic_inc(&pol->refcnt);
-			fle->next = flow_table[cpu*FLOWCACHE_HASH_SIZE+hash];
-			flow_table[cpu*FLOWCACHE_HASH_SIZE+hash] = fle;
+			fle->next = flow_table[cpu*XFRM_FLOWCACHE_HASH_SIZE+hash];
+			flow_table[cpu*XFRM_FLOWCACHE_HASH_SIZE+hash] = fle;
 		}
 	}
 	local_bh_enable();
@@ -193,7 +152,7 @@
 		panic("NET: failed to allocate flow cache slab\n");
 
 	for (order = 0;
-	     (PAGE_SIZE<<order) < (NR_CPUS*sizeof(struct flow_entry *)*FLOWCACHE_HASH_SIZE);
+	     (PAGE_SIZE<<order) < (NR_CPUS*sizeof(struct flow_entry *)*XFRM_FLOWCACHE_HASH_SIZE);
 	     order++)
 		/* NOTHING */;
 
@@ -205,130 +164,82 @@
 	memset(flow_table, 0, PAGE_SIZE<<order);
 }
 
-static struct xfrm_type *xfrm_type_map[256];
-static rwlock_t xfrm_type_lock = RW_LOCK_UNLOCKED;
-
-int xfrm_register_type(struct xfrm_type *type)
+int xfrm_register_type(struct xfrm_type *type, unsigned short family)
 {
+	struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
+	struct xfrm_type_map *typemap;
 	int err = 0;
 
-	write_lock(&xfrm_type_lock);
-	if (xfrm_type_map[type->proto] == NULL)
-		xfrm_type_map[type->proto] = type;
+	if (unlikely(afinfo == NULL))
+		return -EAFNOSUPPORT;
+	typemap = afinfo->type_map;
+
+	write_lock(&typemap->lock);
+	if (likely(typemap->map[type->proto] == NULL))
+		typemap->map[type->proto] = type;
 	else
 		err = -EEXIST;
-	write_unlock(&xfrm_type_lock);
+	write_unlock(&typemap->lock);
+	xfrm_policy_put_afinfo(afinfo);
 	return err;
 }
 
-int xfrm_unregister_type(struct xfrm_type *type)
+int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
 {
+	struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
+	struct xfrm_type_map *typemap;
 	int err = 0;
 
-	write_lock(&xfrm_type_lock);
-	if (xfrm_type_map[type->proto] != type)
+	if (unlikely(afinfo == NULL))
+		return -EAFNOSUPPORT;
+	typemap = afinfo->type_map;
+
+	write_lock(&typemap->lock);
+	if (unlikely(typemap->map[type->proto] != type))
 		err = -ENOENT;
 	else
-		xfrm_type_map[type->proto] = NULL;
-	write_unlock(&xfrm_type_lock);
+		typemap->map[type->proto] = NULL;
+	write_unlock(&typemap->lock);
+	xfrm_policy_put_afinfo(afinfo);
 	return err;
 }
 
-struct xfrm_type *xfrm_get_type(u8 proto)
+struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
 {
+	struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
+	struct xfrm_type_map *typemap;
 	struct xfrm_type *type;
 
-	read_lock(&xfrm_type_lock);
-	type = xfrm_type_map[proto];
-	if (type && !try_module_get(type->owner))
+	if (unlikely(afinfo == NULL))
+		return NULL;
+	typemap = afinfo->type_map;
+
+	read_lock(&typemap->lock);
+	type = typemap->map[proto];
+	if (unlikely(type && !try_module_get(type->owner)))
 		type = NULL;
-	read_unlock(&xfrm_type_lock);
+	read_unlock(&typemap->lock);
+	xfrm_policy_put_afinfo(afinfo);
 	return type;
 }
 
-static  xfrm_dst_lookup_t *__xfrm_dst_lookup[AF_MAX];
-rwlock_t xdl_lock = RW_LOCK_UNLOCKED;
-
-int xfrm_dst_lookup_register(xfrm_dst_lookup_t *dst_lookup, 
-			     unsigned short family)
+int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, 
+		    unsigned short family)
 {
+	struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
 	int err = 0;
 
-	write_lock(&xdl_lock);
-	if (__xfrm_dst_lookup[family])
-		err = -ENOBUFS;
-	else { 
-		__xfrm_dst_lookup[family] = dst_lookup;
-	}
-	write_unlock(&xdl_lock);
-
-	return err;
-}
-
-void xfrm_dst_lookup_unregister(unsigned short family)
-{
-	write_lock(&xdl_lock);
-	if (__xfrm_dst_lookup[family])
-		__xfrm_dst_lookup[family] = 0;
-	write_unlock(&xdl_lock);
-}
+	if (unlikely(afinfo == NULL))
+		return -EAFNOSUPPORT;
 
-static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, 
-				  unsigned short family)
-{
-	int err = 0;
-	read_lock(&xdl_lock);
-	if (__xfrm_dst_lookup[family])
-		err = __xfrm_dst_lookup[family](dst, fl);
+	if (likely(afinfo->dst_lookup != NULL))
+		err = afinfo->dst_lookup(dst, fl);
 	else
 		err = -EINVAL;
-	read_unlock(&xdl_lock);
+	xfrm_policy_put_afinfo(afinfo);
 	return err;
 }
 
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-static struct xfrm_type *xfrm6_type_map[256];
-static rwlock_t xfrm6_type_lock = RW_LOCK_UNLOCKED;
-
-int xfrm6_register_type(struct xfrm_type *type)
-{
-	int err = 0;
-
-	write_lock(&xfrm6_type_lock);
-	if (xfrm6_type_map[type->proto] == NULL)
-		xfrm6_type_map[type->proto] = type;
-	else
-		err = -EEXIST;
-	write_unlock(&xfrm6_type_lock);
-	return err;
-}
-
-int xfrm6_unregister_type(struct xfrm_type *type)
-{
-	int err = 0;
-
-	write_lock(&xfrm6_type_lock);
-	if (xfrm6_type_map[type->proto] != type)
-		err = -ENOENT;
-	else
-		xfrm6_type_map[type->proto] = NULL;
-	write_unlock(&xfrm6_type_lock);
-	return err;
-}
-
-struct xfrm_type *xfrm6_get_type(u8 proto)
-{
-	struct xfrm_type *type;
-
-	read_lock(&xfrm6_type_lock);
-	type = xfrm6_type_map[proto];
-	if (type && !try_module_get(type->owner))
-		type = NULL;
-	read_unlock(&xfrm6_type_lock);
-	return type;
-}
-#endif /* CONFIG_IPV6 || CONFIG_IPV6_MODULE */
-
 void xfrm_put_type(struct xfrm_type *type)
 {
 	module_put(type->owner);
@@ -347,6 +258,7 @@
 	struct xfrm_policy *xp = (struct xfrm_policy*)data;
 	unsigned long now = (unsigned long)xtime.tv_sec;
 	long next = LONG_MAX;
+	u32 index;
 
 	if (xp->dead)
 		goto out;
@@ -368,10 +280,11 @@
 	return;
 
 expired:
+	index = xp->index;
 	xfrm_pol_put(xp);
 
 	/* Not 100% correct. id can be recycled in theory */
-	xp = xfrm_policy_byid(0, xp->index, 1);
+	xp = xfrm_policy_byid(0, index, 1);
 	if (xp) {
 		xfrm_policy_kill(xp);
 		xfrm_pol_put(xp);
@@ -606,18 +519,7 @@
 		if (pol->family != family)
 			continue;
 
-		switch (family) {
-		case AF_INET:
-			match = xfrm4_selector_match(sel, fl);
-			break;
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-		case AF_INET6:
-			match = xfrm6_selector_match(sel, fl);
-			break;
-#endif
-		default:
-			match = 0;
-		}
+		match = xfrm_selector_match(sel, fl, family);
 		if (match) {
 			atomic_inc(&pol->refcnt);
 			break;
@@ -635,18 +537,7 @@
 	if ((pol = sk->policy[dir]) != NULL) {
 		int match;
 
-		switch (sk->family) {
-		case AF_INET:
-			match = xfrm4_selector_match(&pol->selector, fl);
-			break;
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-		case AF_INET6:
-			match = xfrm6_selector_match(&pol->selector, fl);
-			break;
-#endif
-		default:
-			match = 0;
-		}
+		match = xfrm_selector_match(&pol->selector, fl, sk->family);
 		if (match)
 			atomic_inc(&pol->refcnt);
 		else
@@ -748,26 +639,27 @@
 /* Resolve list of templates for the flow, given policy. */
 
 static int
-xfrm4_tmpl_resolve(struct xfrm_policy *policy, struct flowi *fl,
-		   struct xfrm_state **xfrm)
+xfrm_tmpl_resolve(struct xfrm_policy *policy, struct flowi *fl,
+		  struct xfrm_state **xfrm,
+		  unsigned short family)
 {
 	int nx;
 	int i, error;
-	u32 daddr = fl->fl4_dst;
-	u32 saddr = fl->fl4_src;
+	xfrm_address_t *daddr = xfrm_flowi_daddr(fl, family);
+	xfrm_address_t *saddr = xfrm_flowi_saddr(fl, family);
 
 	for (nx=0, i = 0; i < policy->xfrm_nr; i++) {
 		struct xfrm_state *x;
-		u32 remote = daddr;
-		u32 local = saddr;
+		xfrm_address_t *remote = daddr;
+		xfrm_address_t *local  = saddr;
 		struct xfrm_tmpl *tmpl = &policy->xfrm_vec[i];
 
 		if (tmpl->mode) {
-			remote = tmpl->id.daddr.xfrm4_addr;
-			local = tmpl->saddr.xfrm4_addr;
+			remote = &tmpl->id.daddr;
+			local = &tmpl->saddr;
 		}
 
-		x = xfrm4_state_find(remote, local, fl, tmpl, policy, &error);
+		x = xfrm_state_find(remote, local, fl, tmpl, policy, &error, family);
 
 		if (x && x->km.state == XFRM_STATE_VALID) {
 			xfrm[nx++] = x;
@@ -792,91 +684,21 @@
 	return error;
 }
 
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-static int
-xfrm6_tmpl_resolve(struct xfrm_policy *policy, struct flowi *fl,
-		  struct xfrm_state **xfrm)
-{
-	int nx;
-	int i, error;
-	struct in6_addr *daddr = fl->fl6_dst;
-	struct in6_addr *saddr = fl->fl6_src;
-
-	for (nx=0, i = 0; i < policy->xfrm_nr; i++) {
-		struct xfrm_state *x=NULL;
-		struct in6_addr *remote = daddr;
-		struct in6_addr *local = saddr;
-		struct xfrm_tmpl *tmpl = &policy->xfrm_vec[i];
-
-		if (tmpl->mode) {
-			remote = (struct in6_addr*)&tmpl->id.daddr;
-			local = (struct in6_addr*)&tmpl->saddr;
-		}
-
-		x = xfrm6_state_find(remote, local, fl, tmpl, policy, &error);
-
-		if (x && x->km.state == XFRM_STATE_VALID) {
-			xfrm[nx++] = x;
-			daddr = remote;
-			saddr = local;
-			continue;
-		}
-		if (x) {
-			error = (x->km.state == XFRM_STATE_ERROR ?
-				 -EINVAL : -EAGAIN);
-			xfrm_state_put(x);
-		}
-
-		if (!tmpl->optional)
-			goto fail;
-	}
-	return nx;
-
-fail:
-	for (nx--; nx>=0; nx--)
-		xfrm_state_put(xfrm[nx]);
-	return error;
-}
-#endif
-
 /* Check that the bundle accepts the flow and its components are
  * still valid.
  */
 
-static int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl)
-{
-	do {
-		if (xdst->u.dst.ops != &xfrm4_dst_ops)
-			return 1;
-
-		if (!xfrm4_selector_match(&xdst->u.dst.xfrm->sel, fl))
-			return 0;
-		if (xdst->u.dst.xfrm->km.state != XFRM_STATE_VALID ||
-		    xdst->u.dst.path->obsolete > 0)
-			return 0;
-		xdst = (struct xfrm_dst*)xdst->u.dst.child;
-	} while (xdst);
-	return 0;
-}
-
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-static int xfrm6_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl)
+static struct dst_entry *
+xfrm_find_bundle(struct flowi *fl, struct rtable *rt, struct xfrm_policy *policy, unsigned short family)
 {
-	do {
-		if (xdst->u.dst.ops != &xfrm6_dst_ops)
-			return 1;
-
-		if (!xfrm6_selector_match(&xdst->u.dst.xfrm->sel, fl))
-			return 0;
-		if (xdst->u.dst.xfrm->km.state != XFRM_STATE_VALID ||
-		    xdst->u.dst.path->obsolete > 0)
-			return 0;
-		xdst = (struct xfrm_dst*)xdst->u.dst.child;
-	} while (xdst);
-	return 0;
+	struct dst_entry *x;
+	struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
+	if (unlikely(afinfo == NULL))
+		return ERR_PTR(-EINVAL);
+	x = afinfo->find_bundle(fl, rt, policy);
+	xfrm_policy_put_afinfo(afinfo);
+	return x;
 }
-#endif
-
 
 /* Allocate chain of dst_entry's, attach known xfrm's, calculate
  * all the metrics... Shortly, bundle a bundle.
@@ -884,187 +706,18 @@
 
 static int
 xfrm_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
-		   struct flowi *fl, struct dst_entry **dst_p)
+		   struct flowi *fl, struct dst_entry **dst_p,
+		   unsigned short family)
 {
-	struct dst_entry *dst, *dst_prev;
-	struct rtable *rt0 = (struct rtable*)(*dst_p);
-	struct rtable *rt = rt0;
-	u32 remote = fl->fl4_dst;
-	u32 local  = fl->fl4_src;
-	int i;
 	int err;
-	int header_len = 0;
-
-	dst = dst_prev = NULL;
-
-	for (i = 0; i < nx; i++) {
-		struct dst_entry *dst1 = dst_alloc(&xfrm4_dst_ops);
-
-		if (unlikely(dst1 == NULL)) {
-			err = -ENOBUFS;
-			goto error;
-		}
-
-		dst1->xfrm = xfrm[i];
-		if (!dst)
-			dst = dst1;
-		else {
-			dst_prev->child = dst1;
-			dst1->flags |= DST_NOHASH;
-			dst_hold(dst1);
-		}
-		dst_prev = dst1;
-		if (xfrm[i]->props.mode) {
-			remote = xfrm[i]->id.daddr.xfrm4_addr;
-			local  = xfrm[i]->props.saddr.xfrm4_addr;
-		}
-		header_len += xfrm[i]->props.header_len;
-	}
-
-	if (remote != fl->fl4_dst) {
-		struct flowi fl_tunnel = { .nl_u = { .ip4_u =
-						     { .daddr = remote,
-						       .saddr = local }
-					           }
-				         };
-		err = xfrm_dst_lookup((struct xfrm_dst**)&rt, &fl_tunnel, AF_INET);
-		if (err)
-			goto error;
-	} else {
-		dst_hold(&rt->u.dst);
-	}
-	dst_prev->child = &rt->u.dst;
-	for (dst_prev = dst; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
-		struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
-		x->u.rt.fl = *fl;
-
-		dst_prev->dev = rt->u.dst.dev;
-		if (rt->u.dst.dev)
-			dev_hold(rt->u.dst.dev);
-		dst_prev->obsolete	= -1;
-		dst_prev->flags	       |= DST_HOST;
-		dst_prev->lastuse	= jiffies;
-		dst_prev->header_len	= header_len;
-		memcpy(&dst_prev->metrics, &rt->u.dst.metrics, sizeof(dst_prev->metrics));
-		dst_prev->path		= &rt->u.dst;
-
-		/* Copy neighbout for reachability confirmation */
-		dst_prev->neighbour	= neigh_clone(rt->u.dst.neighbour);
-		dst_prev->input		= rt->u.dst.input;
-		dst_prev->output	= dst_prev->xfrm->type->output;
-		if (rt->peer)
-			atomic_inc(&rt->peer->refcnt);
-		x->u.rt.peer = rt->peer;
-		/* Sheit... I remember I did this right. Apparently,
-		 * it was magically lost, so this code needs audit */
-		x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
-		x->u.rt.rt_type = rt->rt_type;
-		x->u.rt.rt_src = rt0->rt_src;
-		x->u.rt.rt_dst = rt0->rt_dst;
-		x->u.rt.rt_gateway = rt->rt_gateway;
-		x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
-		header_len -= x->u.dst.xfrm->props.header_len;
-	}
-	*dst_p = dst;
-	return 0;
-
-error:
-	if (dst)
-		dst_free(dst);
+	struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
+	if (unlikely(afinfo == NULL))
+		return -EINVAL;
+	err = afinfo->bundle_create(policy, xfrm, nx, fl, dst_p);
+	xfrm_policy_put_afinfo(afinfo);
 	return err;
 }
 
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-static int
-xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
-		   struct flowi *fl, struct dst_entry **dst_p)
-{
-	struct dst_entry *dst, *dst_prev;
-	struct rt6_info *rt0 = (struct rt6_info*)(*dst_p);
-	struct rt6_info *rt  = rt0;
-	struct in6_addr *remote = fl->fl6_dst;
-	struct in6_addr *local  = fl->fl6_src;
-	int i;
-	int err = 0;
-	int header_len = 0;
-
-	dst = dst_prev = NULL;
-
-	for (i = 0; i < nx; i++) {
-		struct dst_entry *dst1 = dst_alloc(&xfrm6_dst_ops);
-
-		if (unlikely(dst1 == NULL)) {
-			err = -ENOBUFS;
-			goto error;
-		}
-
-		dst1->xfrm = xfrm[i];
-		if (!dst)
-			dst = dst1;
-		else {
-			dst_prev->child = dst1;
-			dst1->flags |= DST_NOHASH;
-			dst_clone(dst1);
-		}
-		dst_prev = dst1;
-		if (xfrm[i]->props.mode) {
-			remote = (struct in6_addr*)&xfrm[i]->id.daddr;
-			local  = (struct in6_addr*)&xfrm[i]->props.saddr;
-		}
-		header_len += xfrm[i]->props.header_len;
-	}
-
-	if (ipv6_addr_cmp(remote, fl->fl6_dst)) {
-		struct flowi fl_tunnel = { .nl_u = { .ip6_u =
-						     { .daddr = remote,
-						       .saddr = local }
-					           }
-				         };
-		err = xfrm_dst_lookup((struct xfrm_dst**)&dst, &fl_tunnel, AF_INET6);
-		if (err)
-			goto error;
-	} else {
-		dst_clone(&rt->u.dst);
-	}
-	dst_prev->child = &rt->u.dst;
-	for (dst_prev = dst; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
-		struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
-		x->u.rt.fl = *fl;
-
-		dst_prev->dev = rt->u.dst.dev;
-		if (rt->u.dst.dev)
-			dev_hold(rt->u.dst.dev);
-		dst_prev->obsolete	= -1;
-		dst_prev->flags	       |= DST_HOST;
-		dst_prev->lastuse	= jiffies;
-		dst_prev->header_len	= header_len;
-		memcpy(&dst_prev->metrics, &rt->u.dst.metrics, sizeof(dst_prev->metrics));
-		dst_prev->path		= &rt->u.dst;
-
-		/* Copy neighbout for reachability confirmation */
-		dst_prev->neighbour	= neigh_clone(rt->u.dst.neighbour);
-		dst_prev->input		= rt->u.dst.input;
-		dst_prev->output	= dst_prev->xfrm->type->output;
-		/* Sheit... I remember I did this right. Apparently,
-		 * it was magically lost, so this code needs audit */
-		x->u.rt6.rt6i_flags    = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
-		x->u.rt6.rt6i_metric   = rt0->rt6i_metric;
-		x->u.rt6.rt6i_node     = rt0->rt6i_node;
-		x->u.rt6.rt6i_hoplimit = rt0->rt6i_hoplimit;
-		x->u.rt6.rt6i_gateway  = rt0->rt6i_gateway;
-		memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway)); 
-		header_len -= x->u.dst.xfrm->props.header_len;
-	}
-	*dst_p = dst;
-	return 0;
-
-error:
-	if (dst)
-		dst_free(dst);
-	return err;
-}
-#endif
-
 /* Main function: finds/creates a bundle for given flow.
  *
  * At the moment we eat a raw IP route. Mostly to speed up lookups
@@ -1082,6 +735,18 @@
 	u32 genid;
 	u16 family = (*dst_p)->ops->family;
 
+	switch (family) {
+	case AF_INET:
+		if (!fl->fl4_src)
+			fl->fl4_src = rt->rt_src;
+		if (!fl->fl4_dst)
+			fl->fl4_dst = rt->rt_dst;
+	case AF_INET6:
+		/* Still not clear... */
+	default:
+		/* nothing */;
+	}
+
 restart:
 	genid = xfrm_policy_genid;
 	policy = NULL;
@@ -1119,48 +784,17 @@
 		 * LATER: help from flow cache. It is optional, this
 		 * is required only for output policy.
 		 */
-		if (family == AF_INET) {
-			fl->oif = rt->u.dst.dev->ifindex;
-			fl->fl4_src = rt->rt_src;
-			read_lock_bh(&policy->lock);
-			for (dst = policy->bundles; dst; dst = dst->next) {
-				struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
-				if (xdst->u.rt.fl.fl4_dst == fl->fl4_dst &&
-				    xdst->u.rt.fl.fl4_src == fl->fl4_src &&
-				    xdst->u.rt.fl.oif == fl->oif &&
-				    xfrm_bundle_ok(xdst, fl)) {
-					dst_clone(dst);
-					break;
-				}
-			}
-			read_unlock_bh(&policy->lock);
-			if (dst)
-				break;
-			nx = xfrm4_tmpl_resolve(policy, fl, xfrm);
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-		} else if (family == AF_INET6) {
-			read_lock_bh(&policy->lock);
-			for (dst = policy->bundles; dst; dst = dst->next) {
-				struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
-				if (!ipv6_addr_cmp(&xdst->u.rt6.rt6i_dst.addr, fl->fl6_dst) &&
-				    !ipv6_addr_cmp(&xdst->u.rt6.rt6i_src.addr, fl->fl6_src) &&
-				    xfrm6_bundle_ok(xdst, fl)) {
-					dst_clone(dst);
-					break;
-				}
-			}
-			read_unlock_bh(&policy->lock);
-			if (dst)
-				break;
-			nx = xfrm6_tmpl_resolve(policy, fl, xfrm);
-#endif
-		} else {
-			return -EINVAL;
+		dst = xfrm_find_bundle(fl, rt, policy, family);
+		if (IS_ERR(dst)) {
+			xfrm_pol_put(policy);
+			return PTR_ERR(dst);
 		}
 
 		if (dst)
 			break;
 
+		nx = xfrm_tmpl_resolve(policy, fl, xfrm, family);
+
 		if (unlikely(nx<0)) {
 			err = nx;
 			if (err == -EAGAIN) {
@@ -1171,18 +805,7 @@
 
 				__set_task_state(tsk, TASK_INTERRUPTIBLE);
 				add_wait_queue(&km_waitq, &wait);
-				switch (family) {
-				case AF_INET:
-					err = xfrm4_tmpl_resolve(policy, fl, xfrm);
-					break;
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-				case AF_INET6:
-					err = xfrm6_tmpl_resolve(policy, fl, xfrm);
-					break;
-#endif
-				default:
-					err = -EINVAL;
-				}
+				err = xfrm_tmpl_resolve(policy, fl, xfrm, family);
 				if (err == -EAGAIN)
 					schedule();
 				__set_task_state(tsk, TASK_RUNNING);
@@ -1205,19 +828,8 @@
 		}
 
 		dst = &rt->u.dst;
-		switch (family) {
-		case AF_INET:
-			err = xfrm_bundle_create(policy, xfrm, nx, fl, &dst);
-			break;
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-		case AF_INET6:
-			err = xfrm6_bundle_create(policy, xfrm, nx, fl, &dst);
-			break;
-#endif
-		default:
-			err = -EINVAL;
-		}
-			
+		err = xfrm_bundle_create(policy, xfrm, nx, fl, &dst, family);
+
 		if (unlikely(err)) {
 			int i;
 			for (i=0; i<nx; i++)
@@ -1262,137 +874,39 @@
  */
 
 static inline int
-xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x)
-{
-	return	x->id.proto == tmpl->id.proto &&
-		(x->id.spi == tmpl->id.spi || !tmpl->id.spi) &&
-		x->props.mode == tmpl->mode &&
-		(tmpl->aalgos & (1<<x->props.aalgo)) &&
-		(!x->props.mode || !tmpl->saddr.xfrm4_addr ||
-		 tmpl->saddr.xfrm4_addr == x->props.saddr.xfrm4_addr);
-}
-
-static inline int
-xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int idx)
-{
-	for (; idx < sp->len; idx++) {
-		if (xfrm_state_ok(tmpl, sp->xvec[idx]))
-			return ++idx;
-	}
-	return -1;
-}
-
-static void
-_decode_session4(struct sk_buff *skb, struct flowi *fl)
-{
-	struct iphdr *iph = skb->nh.iph;
-	u8 *xprth = skb->nh.raw + iph->ihl*4;
-
-	if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) {
-		switch (iph->protocol) {
-		case IPPROTO_UDP:
-		case IPPROTO_TCP:
-		case IPPROTO_SCTP:
-			if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
-				u16 *ports = (u16 *)xprth;
-
-				fl->uli_u.ports.sport = ports[0];
-				fl->uli_u.ports.dport = ports[1];
-			}
-			break;
-
-		case IPPROTO_ESP:
-			if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
-				u32 *ehdr = (u32 *)xprth;
-
-				fl->uli_u.spi = ehdr[0];
-			}
-			break;
-
-		case IPPROTO_AH:
-			if (pskb_may_pull(skb, xprth + 8 - skb->data)) {
-				u32 *ah_hdr = (u32*)xprth;
-
-				fl->uli_u.spi = ah_hdr[1];
-			}
-			break;
-
-		default:
-			fl->uli_u.spi = 0;
-			break;
-		};
-	} else {
-		memset(fl, 0, sizeof(struct flowi));
-	}
-	fl->proto = iph->protocol;
-	fl->fl4_dst = iph->daddr;
-	fl->fl4_src = iph->saddr;
-}
-
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-static inline int
-xfrm6_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x)
+xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x, 
+	      unsigned short family)
 {
 	return	x->id.proto == tmpl->id.proto &&
 		(x->id.spi == tmpl->id.spi || !tmpl->id.spi) &&
 		x->props.mode == tmpl->mode &&
 		(tmpl->aalgos & (1<<x->props.aalgo)) &&
-		(!x->props.mode || !ipv6_addr_any((struct in6_addr*)&x->props.saddr) ||
-		 !ipv6_addr_cmp((struct in6_addr *)&tmpl->saddr, (struct in6_addr*)&x->props.saddr));
+		!(x->props.mode && xfrm_state_addr_cmp(tmpl, x, family));
 }
 
 static inline int
-xfrm6_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int idx)
+xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int idx,
+	       unsigned short family)
 {
 	for (; idx < sp->len; idx++) {
-		if (xfrm6_state_ok(tmpl, sp->xvec[idx]))
+		if (xfrm_state_ok(tmpl, sp->xvec[idx], family))
 			return ++idx;
 	}
 	return -1;
 }
 
-static inline void
-_decode_session6(struct sk_buff *skb, struct flowi *fl)
+static int
+_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family)
 {
-	u16 offset = sizeof(struct ipv6hdr);
-	struct ipv6hdr *hdr = skb->nh.ipv6h;
-	struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
-	u8 nexthdr = skb->nh.ipv6h->nexthdr;
-
-	fl->fl6_dst = &hdr->daddr;
-	fl->fl6_src = &hdr->saddr;
-
-	while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) {
-		switch (nexthdr) {
-		case NEXTHDR_ROUTING:
-		case NEXTHDR_HOP:
-		case NEXTHDR_DEST:
-			offset += ipv6_optlen(exthdr);
-			nexthdr = exthdr->nexthdr;
-			exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
-			break;
+	struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
 
-		case IPPROTO_UDP:
-		case IPPROTO_TCP:
-		case IPPROTO_SCTP:
-			if (pskb_may_pull(skb, skb->nh.raw + offset + 4 - skb->data)) {
-				u16 *ports = (u16 *)exthdr;
+	if (unlikely(afinfo == NULL))
+		return -EAFNOSUPPORT;
 
-				fl->uli_u.ports.sport = ports[0];
-				fl->uli_u.ports.dport = ports[1];
-			}
-			return;
-
-		/* XXX Why are there these headers? */
-		case IPPROTO_AH:
-		case IPPROTO_ESP:
-		default:
-			fl->uli_u.spi = 0;
-			return;
-		};
-	}
+	afinfo->decode_session(skb, fl);
+	xfrm_policy_put_afinfo(afinfo);
+	return 0;
 }
-#endif
 
 int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, 
 			unsigned short family)
@@ -1400,38 +914,15 @@
 	struct xfrm_policy *pol;
 	struct flowi fl;
 
-	switch (family) {
-	case AF_INET:
-		_decode_session4(skb, &fl);
-		break;
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-	case AF_INET6:
-		_decode_session6(skb, &fl);
-		break;
-#endif
-	default :
+	if (_decode_session(skb, &fl, family) < 0)
 		return 0;
-	}
 
 	/* First, check used SA against their selectors. */
 	if (skb->sp) {
 		int i;
 
 		for (i=skb->sp->len-1; i>=0; i--) {
-			int match;
-			switch (family) {
-			case AF_INET:
-				match = xfrm4_selector_match(&skb->sp->xvec[i]->sel, &fl);
-				break;
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-			case AF_INET6:
-				match = xfrm6_selector_match(&skb->sp->xvec[i]->sel, &fl);
-				break;
-#endif
-			default:
-				match = 0;
-			}
-			if (!match)
+			if (!xfrm_selector_match(&skb->sp->xvec[i]->sel, &fl, family))
 				return 0;
 		}
 	}
@@ -1451,10 +942,11 @@
 	if (pol->action == XFRM_POLICY_ALLOW) {
 		if (pol->xfrm_nr != 0) {
 			struct sec_path *sp;
+			static struct sec_path dummy;
 			int i, k;
 
 			if ((sp = skb->sp) == NULL)
-				goto reject;
+				sp = &dummy;
 
 			/* For each tmpl search corresponding xfrm.
 			 * Order is _important_. Later we will implement
@@ -1462,18 +954,7 @@
 			 * are implied between each two transformations.
 			 */
 			for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) {
-				switch (family) {
-				case AF_INET:
-					k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k);
-					break;
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-				case AF_INET6:
-					k = xfrm6_policy_ok(pol->xfrm_vec+i, sp, k);
-					break;
-#endif
-				default:
-					k = -1;
-				}
+				k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k, family);
 				if (k < 0)
 					goto reject;
 			}
@@ -1491,18 +972,8 @@
 {
 	struct flowi fl;
 
-	switch (family) {
-	case AF_INET:
-		_decode_session4(skb, &fl);
-		break;
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-	case AF_INET6:
-		_decode_session6(skb, &fl);
-		break;
-#endif
-	default:
+	if (_decode_session(skb, &fl, family) < 0)
 		return 0;
-	}
 
 	return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0;
 }
@@ -1580,20 +1051,6 @@
 	}
 }
 
-static inline int xfrm4_garbage_collect(void)
-{
-	__xfrm_garbage_collect();
-	return (atomic_read(&xfrm4_dst_ops.entries) > xfrm4_dst_ops.gc_thresh*2);
-}
-
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-static inline int xfrm6_garbage_collect(void)
-{
-	__xfrm_garbage_collect();
-	return (atomic_read(&xfrm6_dst_ops.entries) > xfrm6_dst_ops.gc_thresh*2);
-}
-#endif
-
 static int bundle_depends_on(struct dst_entry *dst, struct xfrm_state *x)
 {
 	do {
@@ -1637,29 +1094,6 @@
 	return 0;
 }
 
- 
-static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu)
-{
-	struct dst_entry *path = dst->path;
-
-	if (mtu < 68 + dst->header_len)
-		return;
-
-	path->ops->update_pmtu(path, mtu);
-}
-
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu)
-{
-	struct dst_entry *path = dst->path;
-
-	if (mtu >= 1280 && mtu < dst_pmtu(dst))
-		return;
-
-	path->ops->update_pmtu(path, mtu);
-}
-#endif
-
 /* Well... that's _TASK_. We need to scan through transformation
  * list and figure out what mss tcp should generate in order to
  * final datagram fit to mtu. Mama mia... :-)
@@ -1700,52 +1134,99 @@
 	return res + dst->header_len;
 }
 
-struct dst_ops xfrm4_dst_ops = {
-	.family =		AF_INET,
-	.protocol =		__constant_htons(ETH_P_IP),
-	.gc =			xfrm4_garbage_collect,
-	.check =		xfrm_dst_check,
-	.destroy =		xfrm_dst_destroy,
-	.negative_advice =	xfrm_negative_advice,
-	.link_failure =		xfrm_link_failure,
-	.update_pmtu =		xfrm4_update_pmtu,
-	.get_mss =		xfrm_get_mss,
-	.gc_thresh =		1024,
-	.entry_size =		sizeof(struct xfrm_dst),
-};
+int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
+{
+	int err = 0;
+	if (unlikely(afinfo == NULL))
+		return -EINVAL;
+	if (unlikely(afinfo->family >= NPROTO))
+		return -EAFNOSUPPORT;
+	write_lock(&xfrm_policy_afinfo_lock);
+	if (unlikely(xfrm_policy_afinfo[afinfo->family] != NULL))
+		err = -ENOBUFS;
+	else {
+		struct dst_ops *dst_ops = afinfo->dst_ops;
+		if (likely(dst_ops->kmem_cachep == NULL))
+			dst_ops->kmem_cachep = xfrm_dst_cache;
+		if (likely(dst_ops->check == NULL))
+			dst_ops->check = xfrm_dst_check;
+		if (likely(dst_ops->destroy == NULL))
+			dst_ops->destroy = xfrm_dst_destroy;
+		if (likely(dst_ops->negative_advice == NULL))
+			dst_ops->negative_advice = xfrm_negative_advice;
+		if (likely(dst_ops->link_failure == NULL))
+			dst_ops->link_failure = xfrm_link_failure;
+		if (likely(dst_ops->get_mss == NULL))
+			dst_ops->get_mss = xfrm_get_mss;
+		if (likely(afinfo->garbage_collect == NULL))
+			afinfo->garbage_collect = __xfrm_garbage_collect;
+		xfrm_policy_afinfo[afinfo->family] = afinfo;
+	}
+	write_unlock(&xfrm_policy_afinfo_lock);
+	return err;
+}
 
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-struct dst_ops xfrm6_dst_ops = {
-	.family =		AF_INET6,
-	.protocol =		__constant_htons(ETH_P_IPV6),
-	.gc =			xfrm6_garbage_collect,
-	.check =		xfrm_dst_check,
-	.destroy =		xfrm_dst_destroy,
-	.negative_advice =	xfrm_negative_advice,
-	.link_failure =		xfrm_link_failure,
-	.update_pmtu =		xfrm6_update_pmtu,
-	.get_mss =		xfrm_get_mss,
-	.gc_thresh =		1024,
-	.entry_size =		sizeof(struct xfrm_dst),
-};
-#endif /* CONFIG_IPV6 || CONFIG_IPV6_MODULE */
+int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
+{
+	int err = 0;
+	if (unlikely(afinfo == NULL))
+		return -EINVAL;
+	if (unlikely(afinfo->family >= NPROTO))
+		return -EAFNOSUPPORT;
+	write_lock(&xfrm_policy_afinfo_lock);
+	if (likely(xfrm_policy_afinfo[afinfo->family] != NULL)) {
+		if (unlikely(xfrm_policy_afinfo[afinfo->family] != afinfo))
+			err = -EINVAL;
+		else {
+			struct dst_ops *dst_ops = afinfo->dst_ops;
+			xfrm_policy_afinfo[afinfo->family] = NULL;
+			dst_ops->kmem_cachep = NULL;
+			dst_ops->check = NULL;
+			dst_ops->destroy = NULL;
+			dst_ops->negative_advice = NULL;
+			dst_ops->link_failure = NULL;
+			dst_ops->get_mss = NULL;
+			afinfo->garbage_collect = NULL;
+		}
+	}
+	write_unlock(&xfrm_policy_afinfo_lock);
+	return err;
+}
 
-void __init xfrm_init(void)
+struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family)
 {
-	xfrm4_dst_ops.kmem_cachep = kmem_cache_create("xfrm4_dst_cache",
-						      sizeof(struct xfrm_dst),
-						      0, SLAB_HWCACHE_ALIGN,
-						      NULL, NULL);
-
-	if (!xfrm4_dst_ops.kmem_cachep)
-		panic("IP: failed to allocate xfrm4_dst_cache\n");
-
-#if defined (CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-	xfrm6_dst_ops.kmem_cachep = xfrm4_dst_ops.kmem_cachep;
-#endif
+	struct xfrm_policy_afinfo *afinfo;
+	if (unlikely(family >= NPROTO))
+		return NULL;
+	read_lock(&xfrm_policy_afinfo_lock);
+	afinfo = xfrm_policy_afinfo[family];
+	if (likely(afinfo != NULL))
+		read_lock(&afinfo->lock);
+	read_unlock(&xfrm_policy_afinfo_lock);
+	return afinfo;
+}
 
-	flow_cache_init();
+void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo)
+{
+	if (unlikely(afinfo == NULL))
+		return;
+	read_unlock(&afinfo->lock);
+}
+
+void __init xfrm_policy_init(void)
+{
+	xfrm_dst_cache = kmem_cache_create("xfrm_dst_cache",
+					   sizeof(struct xfrm_dst),
+					   0, SLAB_HWCACHE_ALIGN,
+					   NULL, NULL);
+	if (!xfrm_dst_cache)
+		panic("XFRM: failed to allocate xfrm_dst_cache\n");
+}
+
+void __init xfrm_init(void)
+{
 	xfrm_state_init();
-	xfrm_input_init();
+	flow_cache_init();
+	xfrm_policy_init();
 }
 
diff -Nru a/net/ipv4/xfrm_state.c b/net/ipv4/xfrm_state.c
--- a/net/ipv4/xfrm_state.c	Wed Mar  5 15:45:36 2003
+++ b/net/ipv4/xfrm_state.c	Sun Mar 23 02:54:40 2003
@@ -1,15 +1,19 @@
-/* Changes
+/*
+ * xfrm_state.c
  *
- *	Mitsuru KANDA @USAGI       : IPv6 Support 
- * 	Kazunori MIYAZAWA @USAGI   :
- * 	Kunihiro Ishiguro          :
+ * Changes:
+ *	Mitsuru KANDA @USAGI
+ * 	Kazunori MIYAZAWA @USAGI
+ * 	Kunihiro Ishiguro
+ * 		IPv6 support
+ * 	YOSHIFUJI Hideaki @USAGI
+ * 		Split up af-specific functions
  * 	
  */
 
 #include <net/xfrm.h>
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
-#include <net/ipv6.h>
 
 /* Each xfrm_state may be linked to two tables:
 
@@ -20,8 +24,6 @@
 
 static spinlock_t xfrm_state_lock = SPIN_LOCK_UNLOCKED;
 
-#define XFRM_DST_HSIZE		1024
-
 /* Hash table to find appropriate SA towards given target (endpoint
  * of tunnel or destination of transport mode) allowed by selector.
  *
@@ -33,7 +35,8 @@
 
 DECLARE_WAIT_QUEUE_HEAD(km_waitq);
 
-#define ACQ_EXPIRES 30
+static rwlock_t xfrm_state_afinfo_lock = RW_LOCK_UNLOCKED;
+static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO];
 
 static void __xfrm_state_delete(struct xfrm_state *x);
 
@@ -214,138 +217,37 @@
 	wake_up(&km_waitq);
 }
 
-struct xfrm_state *
-xfrm4_state_find(u32 daddr, u32 saddr, struct flowi *fl, struct xfrm_tmpl *tmpl,
-		 struct xfrm_policy *pol, int *err)
-{
-	unsigned h = ntohl(daddr);
-	struct xfrm_state *x;
-	int acquire_in_progress = 0;
-	int error = 0;
-	struct xfrm_state *best = NULL;
-
-	h = (h ^ (h>>16)) % XFRM_DST_HSIZE;
-
-	spin_lock_bh(&xfrm_state_lock);
-	list_for_each_entry(x, xfrm_state_bydst+h, bydst) {
-		if (x->props.family == AF_INET &&
-		    daddr == x->id.daddr.xfrm4_addr &&
-		    x->props.reqid == tmpl->reqid &&
-		    (saddr == x->props.saddr.xfrm4_addr || !saddr || !x->props.saddr.xfrm4_addr) &&
-		    tmpl->mode == x->props.mode &&
-		    tmpl->id.proto == x->id.proto) {
-			/* Resolution logic:
-			   1. There is a valid state with matching selector.
-			      Done.
-			   2. Valid state with inappropriate selector. Skip.
-
-			   Entering area of "sysdeps".
-
-			   3. If state is not valid, selector is temporary,
-			      it selects only session which triggered
-			      previous resolution. Key manager will do
-			      something to install a state with proper
-			      selector.
-			 */
-			if (x->km.state == XFRM_STATE_VALID) {
-				if (!xfrm4_selector_match(&x->sel, fl))
-					continue;
-				if (!best ||
-				    best->km.dying > x->km.dying ||
-				    (best->km.dying == x->km.dying &&
-				     best->curlft.add_time < x->curlft.add_time))
-					best = x;
-			} else if (x->km.state == XFRM_STATE_ACQ) {
-				acquire_in_progress = 1;
-			} else if (x->km.state == XFRM_STATE_ERROR ||
-				   x->km.state == XFRM_STATE_EXPIRED) {
-				if (xfrm4_selector_match(&x->sel, fl))
-					error = 1;
-			}
-		}
-	}
-
-	if (best) {
-		atomic_inc(&best->refcnt);
-		spin_unlock_bh(&xfrm_state_lock);
-		return best;
-	}
-
-	x = NULL;
-	if (!error && !acquire_in_progress &&
-	    ((x = xfrm_state_alloc()) != NULL)) {
-		/* Initialize temporary selector matching only
-		 * to current session. */
-
-		x->sel.daddr.xfrm4_addr = fl->fl4_dst;
-		x->sel.daddr.xfrm4_mask = ~0;
-		x->sel.saddr.xfrm4_addr = fl->fl4_src;
-		x->sel.saddr.xfrm4_mask = ~0;
-		x->sel.dport = fl->uli_u.ports.dport;
-		x->sel.dport_mask = ~0;
-		x->sel.sport = fl->uli_u.ports.sport;
-		x->sel.sport_mask = ~0;
-		x->sel.prefixlen_d = 32;
-		x->sel.prefixlen_s = 32;
-		x->sel.proto = fl->proto;
-		x->sel.ifindex = fl->oif;
-		x->id = tmpl->id;
-		if (x->id.daddr.xfrm4_addr == 0)
-			x->id.daddr.xfrm4_addr = daddr;
-		x->props.family = AF_INET;
-		x->props.saddr = tmpl->saddr;
-		if (x->props.saddr.xfrm4_addr == 0)
-			x->props.saddr.xfrm4_addr = saddr;
-		x->props.mode = tmpl->mode;
-		x->props.reqid = tmpl->reqid;
-		x->props.family = AF_INET;
-
-		if (km_query(x, tmpl, pol) == 0) {
-			x->km.state = XFRM_STATE_ACQ;
-			list_add_tail(&x->bydst, xfrm_state_bydst+h);
-			atomic_inc(&x->refcnt);
-			if (x->id.spi) {
-				h = ntohl(x->id.daddr.xfrm4_addr^x->id.spi^x->id.proto);
-				h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE;
-				list_add(&x->byspi, xfrm_state_byspi+h);
-				atomic_inc(&x->refcnt);
-			}
-			x->lft.hard_add_expires_seconds = ACQ_EXPIRES;
-			atomic_inc(&x->refcnt);
-			mod_timer(&x->timer, ACQ_EXPIRES*HZ);
-		} else {
-			x->km.state = XFRM_STATE_DEAD;
-			xfrm_state_put(x);
-			x = NULL;
-			error = 1;
-		}
-	}
-	spin_unlock_bh(&xfrm_state_lock);
-	if (!x)
-		*err = acquire_in_progress ? -EAGAIN :
-			(error ? -ESRCH : -ENOMEM);
-	return x;
+static int
+xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl,
+		  struct xfrm_tmpl *tmpl,
+		  xfrm_address_t *daddr, xfrm_address_t *saddr,
+		  unsigned short family)
+{
+	struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
+	if (!afinfo)
+		return -1;
+	afinfo->init_tempsel(x, fl, tmpl, daddr, saddr);
+	xfrm_state_put_afinfo(afinfo);
+	return 0;
 }
 
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 struct xfrm_state *
-xfrm6_state_find(struct in6_addr *daddr, struct in6_addr *saddr, struct flowi *fl, struct xfrm_tmpl *tmpl,
-		struct xfrm_policy *pol, int *err)
+xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, 
+		struct flowi *fl, struct xfrm_tmpl *tmpl,
+		struct xfrm_policy *pol, int *err,
+		unsigned short family)
 {
-	unsigned h = ntohl(daddr->s6_addr32[2]^daddr->s6_addr32[3]);
+	unsigned h = xfrm_dst_hash(daddr, family);
 	struct xfrm_state *x;
 	int acquire_in_progress = 0;
 	int error = 0;
 	struct xfrm_state *best = NULL;
 
-	h = (h ^ (h>>16)) % XFRM_DST_HSIZE;
-
 	spin_lock_bh(&xfrm_state_lock);
 	list_for_each_entry(x, xfrm_state_bydst+h, bydst) {
-		if (x->props.family == AF_INET6&&
-		    !ipv6_addr_cmp(daddr, (struct in6_addr *)&x->id.daddr) &&
+		if (x->props.family == family &&
 		    x->props.reqid == tmpl->reqid &&
-		    (!ipv6_addr_cmp(saddr, (struct in6_addr *)&x->props.saddr)|| ipv6_addr_any(saddr)) &&
+		    xfrm_state_addr_check(x, daddr, saddr, family) &&
 		    tmpl->mode == x->props.mode &&
 		    tmpl->id.proto == x->id.proto) {
 			/* Resolution logic:
@@ -362,7 +264,7 @@
 			      selector.
 			 */
 			if (x->km.state == XFRM_STATE_VALID) {
-				if (!xfrm6_selector_match(&x->sel, fl))
+				if (!xfrm_selector_match(&x->sel, fl, family))
 					continue;
 				if (!best ||
 				    best->km.dying > x->km.dying ||
@@ -373,7 +275,7 @@
 				acquire_in_progress = 1;
 			} else if (x->km.state == XFRM_STATE_ERROR ||
 				   x->km.state == XFRM_STATE_EXPIRED) {
-				if (xfrm6_selector_match(&x->sel, fl))
+				if (xfrm_selector_match(&x->sel, fl, family))
 					error = 1;
 			}
 		}
@@ -384,45 +286,26 @@
 		spin_unlock_bh(&xfrm_state_lock);
 		return best;
 	}
+
 	x = NULL;
 	if (!error && !acquire_in_progress &&
 	    ((x = xfrm_state_alloc()) != NULL)) {
 		/* Initialize temporary selector matching only
 		 * to current session. */
-		memcpy(&x->sel.daddr, fl->fl6_dst, sizeof(struct in6_addr));
-		memcpy(&x->sel.saddr, fl->fl6_src, sizeof(struct in6_addr));
-		x->sel.dport = fl->uli_u.ports.dport;
-		x->sel.dport_mask = ~0;
-		x->sel.sport = fl->uli_u.ports.sport;
-		x->sel.sport_mask = ~0;
-		x->sel.prefixlen_d = 128;
-		x->sel.prefixlen_s = 128;
-		x->sel.proto = fl->proto;
-		x->sel.ifindex = fl->oif;
-		x->id = tmpl->id;
-		if (ipv6_addr_any((struct in6_addr*)&x->id.daddr))
-			memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr));
-		memcpy(&x->props.saddr, &tmpl->saddr, sizeof(x->props.saddr));
-		if (ipv6_addr_any((struct in6_addr*)&x->props.saddr))
-			memcpy(&x->props.saddr, &saddr, sizeof(x->sel.saddr));
-		x->props.mode = tmpl->mode;
-		x->props.reqid = tmpl->reqid;
-		x->props.family = AF_INET6;
+		xfrm_init_tempsel(x, fl, tmpl, daddr, saddr, family);
 
 		if (km_query(x, tmpl, pol) == 0) {
 			x->km.state = XFRM_STATE_ACQ;
 			list_add_tail(&x->bydst, xfrm_state_bydst+h);
 			atomic_inc(&x->refcnt);
 			if (x->id.spi) {
-				struct in6_addr *addr = (struct in6_addr*)&x->id.daddr;
-				h = ntohl((addr->s6_addr32[2]^addr->s6_addr32[3])^x->id.spi^x->id.proto);
-				h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE;
+				h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, family);
 				list_add(&x->byspi, xfrm_state_byspi+h);
 				atomic_inc(&x->refcnt);
 			}
-			x->lft.hard_add_expires_seconds = ACQ_EXPIRES;
+			x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
 			atomic_inc(&x->refcnt);
-			mod_timer(&x->timer, ACQ_EXPIRES*HZ);
+			mod_timer(&x->timer, XFRM_ACQ_EXPIRES*HZ);
 		} else {
 			x->km.state = XFRM_STATE_DEAD;
 			xfrm_state_put(x);
@@ -436,36 +319,17 @@
 			(error ? -ESRCH : -ENOMEM);
 	return x;
 }
-#endif /* CONFIG_IPV6 || CONFIG_IPV6_MODULE */
 
 void xfrm_state_insert(struct xfrm_state *x)
 {
-	unsigned h = 0;
-
-	switch (x->props.family) {
-	case AF_INET:
-		h = ntohl(x->id.daddr.xfrm4_addr);
-		break;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	case AF_INET6:
-		h = ntohl(x->id.daddr.a6[2]^x->id.daddr.a6[3]);
-		break;
-#endif
-	default:
-		return;
-	}
-
-	h = (h ^ (h>>16)) % XFRM_DST_HSIZE;
+	unsigned h = xfrm_dst_hash(&x->id.daddr, x->props.family);
 
 	spin_lock_bh(&xfrm_state_lock);
 	list_add(&x->bydst, xfrm_state_bydst+h);
 	atomic_inc(&x->refcnt);
 
-	if (x->props.family == AF_INET)
-		h = ntohl(x->id.daddr.xfrm4_addr^x->id.spi^x->id.proto);
-	else
-		h = ntohl(x->id.daddr.a6[2]^x->id.daddr.a6[3]^x->id.spi^x->id.proto);
-	h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE;
+	h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, x->props.family);
+
 	list_add(&x->byspi, xfrm_state_byspi+h);
 	atomic_inc(&x->refcnt);
 
@@ -487,7 +351,7 @@
 	if (x->curlft.bytes >= x->lft.hard_byte_limit ||
 	    x->curlft.packets >= x->lft.hard_packet_limit) {
 		km_expired(x);
-		if (!mod_timer(&x->timer, jiffies + ACQ_EXPIRES*HZ))
+		if (!mod_timer(&x->timer, jiffies + XFRM_ACQ_EXPIRES*HZ))
 			atomic_inc(&x->refcnt);
 		return -EINVAL;
 	}
@@ -501,7 +365,7 @@
 
 int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
 {
-	int nhead = x->props.header_len + skb->dst->dev->hard_header_len
+	int nhead = x->props.header_len + LL_RESERVED_SPACE(skb->dst->dev)
 		- skb_headroom(skb);
 
 	if (nhead > 0)
@@ -512,158 +376,37 @@
 }
 
 struct xfrm_state *
-xfrm4_state_lookup(u32 daddr, u32 spi, u8 proto)
+xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto,
+		  unsigned short family)
 {
-	unsigned h = ntohl(daddr^spi^proto);
 	struct xfrm_state *x;
-
-	h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE;
+	struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
+	if (!afinfo)
+		return NULL;
 
 	spin_lock_bh(&xfrm_state_lock);
-	list_for_each_entry(x, xfrm_state_byspi+h, byspi) {
-		if (x->props.family == AF_INET &&
-		    spi == x->id.spi &&
-		    daddr == x->id.daddr.xfrm4_addr &&
-		    proto == x->id.proto) {
-			atomic_inc(&x->refcnt);
-			spin_unlock_bh(&xfrm_state_lock);
-			return x;
-		}
-	}
+	x = afinfo->state_lookup(daddr, spi, proto);
 	spin_unlock_bh(&xfrm_state_lock);
-	return NULL;
+	xfrm_state_put_afinfo(afinfo);
+	return x;
 }
 
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 struct xfrm_state *
-xfrm6_state_lookup(struct in6_addr *daddr, u32 spi, u8 proto)
+xfrm_find_acq(u8 mode, u16 reqid, u8 proto, 
+	      xfrm_address_t *daddr, xfrm_address_t *saddr, 
+	      int create, unsigned short family)
 {
-	unsigned h = ntohl(daddr->s6_addr32[2]^daddr->s6_addr32[3]^spi^proto);
 	struct xfrm_state *x;
-
-	h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE;
+	struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
+	if (!afinfo)
+		return NULL;
 
 	spin_lock_bh(&xfrm_state_lock);
-	list_for_each_entry(x, xfrm_state_byspi+h, byspi) {
-		if (x->props.family == AF_INET6 &&
-		    spi == x->id.spi &&
-		    !ipv6_addr_cmp(daddr, (struct in6_addr *)x->id.daddr.a6) &&
-		    proto == x->id.proto) {
-			atomic_inc(&x->refcnt);
-			spin_unlock_bh(&xfrm_state_lock);
-			return x;
-		}
-	}
+	x = afinfo->find_acq(mode, reqid, proto, daddr, saddr, create);
 	spin_unlock_bh(&xfrm_state_lock);
-	return NULL;
-}
-#endif
-
-struct xfrm_state *
-xfrm_find_acq(u8 mode, u16 reqid, u8 proto, u32 daddr, u32 saddr, int create)
-{
-	struct xfrm_state *x, *x0;
-	unsigned h = ntohl(daddr);
-
-	h = (h ^ (h>>16)) % XFRM_DST_HSIZE;
-	x0 = NULL;
-
-	spin_lock_bh(&xfrm_state_lock);
-	list_for_each_entry(x, xfrm_state_bydst+h, bydst) {
-		if (x->props.family == AF_INET &&
-		    daddr == x->id.daddr.xfrm4_addr &&
-		    mode == x->props.mode &&
-		    proto == x->id.proto &&
-		    saddr == x->props.saddr.xfrm4_addr &&
-		    reqid == x->props.reqid &&
-		    x->km.state == XFRM_STATE_ACQ) {
-			    if (!x0)
-				    x0 = x;
-			    if (x->id.spi)
-				    continue;
-			    x0 = x;
-			    break;
-		    }
-	}
-	if (x0) {
-		atomic_inc(&x0->refcnt);
-	} else if (create && (x0 = xfrm_state_alloc()) != NULL) {
-		x0->sel.daddr.xfrm4_addr = daddr;
-		x0->sel.daddr.xfrm4_mask = ~0;
-		x0->sel.saddr.xfrm4_addr = saddr;
-		x0->sel.saddr.xfrm4_mask = ~0;
-		x0->sel.prefixlen_d = 32;
-		x0->sel.prefixlen_s = 32;
-		x0->props.saddr.xfrm4_addr = saddr;
-		x0->km.state = XFRM_STATE_ACQ;
-		x0->id.daddr.xfrm4_addr = daddr;
-		x0->id.proto = proto;
-		x0->props.mode = mode;
-		x0->props.reqid = reqid;
-		x0->props.family = AF_INET;
-		x0->lft.hard_add_expires_seconds = ACQ_EXPIRES;
-		atomic_inc(&x0->refcnt);
-		mod_timer(&x0->timer, jiffies + ACQ_EXPIRES*HZ);
-		atomic_inc(&x0->refcnt);
-		list_add_tail(&x0->bydst, xfrm_state_bydst+h);
-		wake_up(&km_waitq);
-	}
-	spin_unlock_bh(&xfrm_state_lock);
-	return x0;
-}
-
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-struct xfrm_state *
-xfrm6_find_acq(u8 mode, u16 reqid, u8 proto, struct in6_addr *daddr, struct in6_addr *saddr, int create)
-{
-	struct xfrm_state *x, *x0;
-	unsigned h = ntohl(daddr->s6_addr32[2]^daddr->s6_addr32[3]);
-
-	h = (h ^ (h>>16)) % XFRM_DST_HSIZE;
-	x0 = NULL;
-
-	spin_lock_bh(&xfrm_state_lock);
-	list_for_each_entry(x, xfrm_state_bydst+h, bydst) {
-		if (x->props.family == AF_INET6 &&
-		    !ipv6_addr_cmp(daddr, (struct in6_addr *)x->id.daddr.a6) &&
-		    mode == x->props.mode &&
-		    proto == x->id.proto &&
-		    !ipv6_addr_cmp(saddr, (struct in6_addr *)x->props.saddr.a6) &&
-		    reqid == x->props.reqid &&
-		    x->km.state == XFRM_STATE_ACQ) {
-			    if (!x0)
-				    x0 = x;
-			    if (x->id.spi)
-				    continue;
-			    x0 = x;
-			    break;
-		    }
-	}
-	if (x0) {
-		atomic_inc(&x0->refcnt);
-	} else if (create && (x0 = xfrm_state_alloc()) != NULL) {
-		memcpy(x0->sel.daddr.a6, daddr, sizeof(struct in6_addr));
-		memcpy(x0->sel.saddr.a6, saddr, sizeof(struct in6_addr));
-		x0->sel.prefixlen_d = 128;
-		x0->sel.prefixlen_s = 128;
-		memcpy(x0->props.saddr.a6, saddr, sizeof(struct in6_addr));
-		x0->km.state = XFRM_STATE_ACQ;
-		memcpy(x0->id.daddr.a6, daddr, sizeof(struct in6_addr));
-		x0->id.proto = proto;
-		x0->props.family = AF_INET6;
-		x0->props.mode = mode;
-		x0->props.reqid = reqid;
-		x0->lft.hard_add_expires_seconds = ACQ_EXPIRES;
-		atomic_inc(&x0->refcnt);
-		mod_timer(&x0->timer, jiffies + ACQ_EXPIRES*HZ);
-		atomic_inc(&x0->refcnt);
-		list_add_tail(&x0->bydst, xfrm_state_bydst+h);
-		wake_up(&km_waitq);
-	}
-	spin_unlock_bh(&xfrm_state_lock);
-	return x0;
+	xfrm_state_put_afinfo(afinfo);
+	return x;
 }
-#endif
 
 /* Silly enough, but I'm lazy to build resolution list */
 
@@ -697,18 +440,7 @@
 		return;
 
 	if (minspi == maxspi) {
-		switch(x->props.family) {
-		case AF_INET:
-			x0 = xfrm4_state_lookup(x->id.daddr.xfrm4_addr, minspi, x->id.proto);
-			break;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-		case AF_INET6:
-			x0 = xfrm6_state_lookup((struct in6_addr*)x->id.daddr.a6, minspi, x->id.proto);
-			break;
-#endif
-		default:
-			x0 = NULL;
-		}
+		x0 = xfrm_state_lookup(&x->id.daddr, minspi, x->id.proto, x->props.family);
 		if (x0) {
 			xfrm_state_put(x0);
 			return;
@@ -720,18 +452,7 @@
 		maxspi = ntohl(maxspi);
 		for (h=0; h<maxspi-minspi+1; h++) {
 			spi = minspi + net_random()%(maxspi-minspi+1);
-			switch(x->props.family) {
-			case AF_INET:
-				x0 = xfrm4_state_lookup(x->id.daddr.xfrm4_addr, minspi, x->id.proto);
-				break;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-			case AF_INET6:
-				x0 = xfrm6_state_lookup((struct in6_addr*)x->id.daddr.a6, minspi, x->id.proto);
-				break;
-#endif
-			default:
-				x0 = NULL;
-			}
+			x0 = xfrm_state_lookup(&x->id.daddr, minspi, x->id.proto, x->props.family);
 			if (x0 == NULL)
 				break;
 			xfrm_state_put(x0);
@@ -740,19 +461,7 @@
 	}
 	if (x->id.spi) {
 		spin_lock_bh(&xfrm_state_lock);
-		switch(x->props.family) {
-		case AF_INET:
-			h = ntohl(x->id.daddr.xfrm4_addr^x->id.spi^x->id.proto);
-			break;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-		case AF_INET6:
-			h = ntohl(x->id.daddr.a6[2]^x->id.daddr.a6[3]^x->id.spi^x->id.proto);
-			break;
-#endif
-		default:
-			h = 0;	/* XXX */
-		}
-		h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE;
+		h = xfrm_spi_hash(&x->id.daddr, x->id.spi, x->id.proto, x->props.family);
 		list_add(&x->byspi, xfrm_state_byspi+h);
 		atomic_inc(&x->refcnt);
 		spin_unlock_bh(&xfrm_state_lock);
@@ -845,18 +554,7 @@
 
 	for (i=0; i<n; i++) {
 		int match;
-		switch(x[i]->props.family) {
-		case AF_INET:
-			match = xfrm4_selector_match(&x[i]->sel, fl);
-			break;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-		case AF_INET6:
-			match = xfrm6_selector_match(&x[i]->sel, fl);
-			break;
-#endif
-		default:
-			match = 0;
-		}
+		match = xfrm_selector_match(&x[i]->sel, fl, x[i]->props.family);
 		if (!match)
 			return -EINVAL;
 	}
@@ -956,6 +654,66 @@
 	list_del(&km->list);
 	write_unlock_bh(&xfrm_km_lock);
 	return 0;
+}
+
+int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo)
+{
+	int err = 0;
+	if (unlikely(afinfo == NULL))
+		return -EINVAL;
+	if (unlikely(afinfo->family >= NPROTO))
+		return -EAFNOSUPPORT;
+	write_lock(&xfrm_state_afinfo_lock);
+	if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL))
+		err = -ENOBUFS;
+	else {
+		afinfo->state_bydst = xfrm_state_bydst;
+		afinfo->state_byspi = xfrm_state_byspi;
+		xfrm_state_afinfo[afinfo->family] = afinfo;
+	}
+	write_unlock(&xfrm_state_afinfo_lock);
+	return err;
+}
+
+int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
+{
+	int err = 0;
+	if (unlikely(afinfo == NULL))
+		return -EINVAL;
+	if (unlikely(afinfo->family >= NPROTO))
+		return -EAFNOSUPPORT;
+	write_lock(&xfrm_state_afinfo_lock);
+	if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) {
+		if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo))
+			err = -EINVAL;
+		else {
+			xfrm_state_afinfo[afinfo->family] = NULL;
+			afinfo->state_byspi = NULL;
+			afinfo->state_bydst = NULL;
+		}
+	}
+	write_unlock(&xfrm_state_afinfo_lock);
+	return err;
+}
+
+struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family)
+{
+	struct xfrm_state_afinfo *afinfo;
+	if (unlikely(family >= NPROTO))
+		return NULL;
+	read_lock(&xfrm_state_afinfo_lock);
+	afinfo = xfrm_state_afinfo[family];
+	if (likely(afinfo != NULL))
+		read_lock(&afinfo->lock);
+	read_unlock(&xfrm_state_afinfo_lock);
+	return afinfo;
+}
+
+void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
+{
+	if (unlikely(afinfo == NULL))
+		return;
+	read_unlock(&afinfo->lock);
 }
 
 void __init xfrm_state_init(void)
diff -Nru a/net/ipv4/xfrm_user.c b/net/ipv4/xfrm_user.c
--- a/net/ipv4/xfrm_user.c	Wed Mar  5 15:45:36 2003
+++ b/net/ipv4/xfrm_user.c	Sun Mar 23 02:21:29 2003
@@ -2,11 +2,11 @@
  *
  * Copyright (C) 2002 David S. Miller (davem@redhat.com)
  *
- * Changes
- *
- *	Mitsuru KANDA @USAGI       : IPv6 Support 
- * 	Kazunori MIYAZAWA @USAGI   :
- * 	Kunihiro Ishiguro          :
+ * Changes:
+ *	Mitsuru KANDA @USAGI
+ * 	Kazunori MIYAZAWA @USAGI
+ * 	Kunihiro Ishiguro
+ * 		IPv6 support
  * 	
  */
 
@@ -24,9 +24,6 @@
 #include <linux/ipsec.h>
 #include <linux/init.h>
 #include <linux/security.h>
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-#include <linux/in6.h>
-#endif
 #include <net/sock.h>
 #include <net/xfrm.h>
 
@@ -46,8 +43,14 @@
 	algp = RTA_DATA(rt);
 	switch (type) {
 	case XFRMA_ALG_AUTH:
+		if (!algp->alg_key_len &&
+		    strcmp(algp->alg_name, "digest_null") != 0)
+			return -EINVAL;
+		break;
+
 	case XFRMA_ALG_CRYPT:
-		if (!algp->alg_key_len)
+		if (!algp->alg_key_len &&
+		    strcmp(algp->alg_name, "cipher_null") != 0)
 			return -EINVAL;
 		break;
 
@@ -185,19 +188,7 @@
 		goto error;
 
 	err = -ENOENT;
-	switch (x->props.family) {
-	case AF_INET:
-		x->type = xfrm_get_type(x->id.proto);
-		break;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	case AF_INET6:
-		x->type = xfrm6_get_type(x->id.proto);
-		break;
-#endif
-	default:
-		x->type = NULL;
-		break;
-	}
+	x->type = xfrm_get_type(x->id.proto, x->props.family);
 	if (x->type == NULL)
 		goto error;
 
@@ -232,21 +223,7 @@
 	if (!x)
 		return err;
 
-	switch (x->props.family) {
-	case AF_INET:
-		x1 = xfrm4_state_lookup(x->props.saddr.xfrm4_addr,
-					x->id.spi, x->id.proto);
-		break;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	case AF_INET6:
-		x1 = xfrm6_state_lookup((struct in6_addr*)x->props.saddr.a6,
-					x->id.spi, x->id.proto);
-		break;
-#endif
-	default:
-		x1 = NULL;
-		break;
-	}
+	x1 = xfrm_state_lookup(&x->props.saddr, x->id.spi, x->id.proto, x->props.family);
 	if (x1) {
 		xfrm_state_put(x);
 		xfrm_state_put(x1);
@@ -263,19 +240,7 @@
 	struct xfrm_state *x;
 	struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
 
-	switch (p->family) {
-	case AF_INET:
-		x = xfrm4_state_lookup(p->saddr.xfrm4_addr, p->spi, p->proto);
-		break;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	case AF_INET6:
-		x = xfrm6_state_lookup((struct in6_addr*)p->saddr.a6, p->spi, p->proto);
-		break;
-#endif
-	default:
-		x = NULL;
-		break;
-	}
+	x = xfrm_state_lookup(&p->saddr, p->spi, p->proto, p->family);
 	if (x == NULL)
 		return -ESRCH;
 
@@ -393,19 +358,7 @@
 	struct sk_buff *resp_skb;
 	int err;
 
-	switch (p->family) {
-	case AF_INET:
-		x = xfrm4_state_lookup(p->saddr.xfrm4_addr, p->spi, p->proto);
-		break;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	case AF_INET6:
-		x = xfrm6_state_lookup((struct in6_addr*)p->saddr.a6, p->spi, p->proto);
-		break;
-#endif
-	default:
-		x = NULL;
-		break;
-	}
+	x = xfrm_state_lookup(&p->saddr, p->spi, p->proto, p->family);
 	err = -ESRCH;
 	if (x == NULL)
 		goto out_noput;
@@ -456,23 +409,10 @@
 	err = verify_userspi_info(p);
 	if (err)
 		goto out_noput;
-	switch (p->info.family) {
-	case AF_INET:
-		x = xfrm_find_acq(p->info.mode, p->info.reqid, p->info.id.proto,
-				  p->info.sel.daddr.xfrm4_addr,
-				  p->info.sel.saddr.xfrm4_addr, 1);
-		break;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	case AF_INET6:
-		x = xfrm6_find_acq(p->info.mode, p->info.reqid, p->info.id.proto,
-				   (struct in6_addr*)p->info.sel.daddr.a6,
-				   (struct in6_addr*)p->info.sel.saddr.a6, 1);
-		break;
-#endif
-	default:
-		x = NULL;
-		break;
-	}
+	x = xfrm_find_acq(p->info.mode, p->info.reqid, p->info.id.proto,
+			  &p->info.sel.daddr,
+			  &p->info.sel.saddr, 1,
+			  p->info.family);
 	err = -ENOENT;
 	if (x == NULL)
 		goto out_noput;
@@ -1080,10 +1020,26 @@
 	struct xfrm_policy *xp;
 	int nr;
 
-	if (opt != IP_XFRM_POLICY) {
-		*dir = -EOPNOTSUPP;
+	switch (family) {
+	case AF_INET:
+		if (opt != IP_XFRM_POLICY) {
+			*dir = -EOPNOTSUPP;
+			return NULL;
+		}
+		break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		if (opt != IPV6_XFRM_POLICY) {
+			*dir = -EOPNOTSUPP;
+			return NULL;
+		}
+		break;
+#endif
+	default:
+		*dir = -EINVAL;
 		return NULL;
 	}
+
 	*dir = -EINVAL;
 
 	if (len < sizeof(*p) ||
diff -Nru a/net/ipv6/Makefile b/net/ipv6/Makefile
--- a/net/ipv6/Makefile	Wed Mar  5 15:45:36 2003
+++ b/net/ipv6/Makefile	Sun Mar 23 02:21:29 2003
@@ -4,11 +4,12 @@
 
 obj-$(CONFIG_IPV6) += ipv6.o
 
-ipv6-objs :=	af_inet6.o ip6_output.o ip6_input.o addrconf.o sit.o \
+ipv6-objs :=	af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o sit.o \
 		route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \
 		protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
 		exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
-		ip6_flowlabel.o ipv6_syms.o
+		ip6_flowlabel.o ipv6_syms.o \
+		xfrm6_policy.o xfrm6_state.o xfrm6_input.o
 
 obj-$(CONFIG_INET6_AH) += ah6.o
 obj-$(CONFIG_INET6_ESP) += esp6.o
diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
--- a/net/ipv6/addrconf.c	Mon Mar  3 01:47:43 2003
+++ b/net/ipv6/addrconf.c	Sun Mar 23 21:45:41 2003
@@ -97,6 +97,8 @@
 static void ipv6_regen_rndid(unsigned long data);
 
 static int desync_factor = MAX_DESYNC_FACTOR * HZ;
+static struct crypto_tfm *md5_tfm;
+static spinlock_t md5_tfm_lock = SPIN_LOCK_UNLOCKED;
 #endif
 
 static int ipv6_count_addresses(struct inet6_dev *idev);
@@ -172,21 +174,15 @@
 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
 
-int ipv6_addr_type(struct in6_addr *addr)
+int ipv6_addr_type(const struct in6_addr *addr)
 {
+	int type;
 	u32 st;
 
 	st = addr->s6_addr32[0];
 
-	/* Consider all addresses with the first three bits different of
-	   000 and 111 as unicasts.
-	 */
-	if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
-	    (st & htonl(0xE0000000)) != htonl(0xE0000000))
-		return IPV6_ADDR_UNICAST;
-
 	if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
-		int type = IPV6_ADDR_MULTICAST;
+		type = IPV6_ADDR_MULTICAST;
 
 		switch((st & htonl(0x00FF0000))) {
 			case __constant_htonl(0x00010000):
@@ -203,29 +199,53 @@
 		};
 		return type;
 	}
+	/* check for reserved anycast addresses */
+	
+	if ((st & htonl(0xE0000000)) &&
+	    ((addr->s6_addr32[2] == htonl(0xFDFFFFFF) &&
+	    (addr->s6_addr32[3] | htonl(0x7F)) == (u32)~0) ||
+	    (addr->s6_addr32[2] == 0 && addr->s6_addr32[3] == 0)))
+		type = IPV6_ADDR_ANYCAST;
+	else
+		type = IPV6_ADDR_UNICAST;
+
+	/* Consider all addresses with the first three bits different of
+	   000 and 111 as finished.
+	 */
+	if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
+	    (st & htonl(0xE0000000)) != htonl(0xE0000000))
+		return type;
 	
 	if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
-		return (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST);
+		return (IPV6_ADDR_LINKLOCAL | type);
 
 	if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
-		return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST);
+		return (IPV6_ADDR_SITELOCAL | type);
 
 	if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
 		if (addr->s6_addr32[2] == 0) {
-			if (addr->s6_addr32[3] == 0)
+			if (addr->in6_u.u6_addr32[3] == 0)
 				return IPV6_ADDR_ANY;
 
 			if (addr->s6_addr32[3] == htonl(0x00000001))
-				return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST);
+				return (IPV6_ADDR_LOOPBACK | type);
 
-			return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST);
+			return (IPV6_ADDR_COMPATv4 | type);
 		}
 
 		if (addr->s6_addr32[2] == htonl(0x0000ffff))
 			return IPV6_ADDR_MAPPED;
 	}
 
-	return IPV6_ADDR_RESERVED;
+	st &= htonl(0xFF000000);
+	if (st == 0)
+		return IPV6_ADDR_RESERVED;
+	st &= htonl(0xFE000000);
+	if (st == htonl(0x02000000))
+		return IPV6_ADDR_RESERVED;	/* for NSAP */
+	if (st == htonl(0x04000000))
+		return IPV6_ADDR_RESERVED;	/* for IPX */
+	return type;
 }
 
 static void addrconf_del_timer(struct inet6_ifaddr *ifp)
@@ -261,7 +281,6 @@
 	add_timer(&ifp->timer);
 }
 
-
 /* Nobody refers to this device, we may destroy it. */
 
 void in6_dev_finish_destroy(struct inet6_dev *idev)
@@ -358,24 +377,90 @@
 	return idev;
 }
 
+void ipv6_addr_prefix(struct in6_addr *prefix,
+	struct in6_addr *addr, int prefix_len)
+{
+	unsigned long mask;
+	int ncopy, nbits;
+
+	memset(prefix, 0, sizeof(*prefix));
+
+	if (prefix_len <= 0)
+		return;
+	if (prefix_len > 128)
+		prefix_len = 128;
+
+	ncopy = prefix_len / 32;
+	switch (ncopy) {
+	case 4:	prefix->s6_addr32[3] = addr->s6_addr32[3];
+	case 3:	prefix->s6_addr32[2] = addr->s6_addr32[2];
+	case 2:	prefix->s6_addr32[1] = addr->s6_addr32[1];
+	case 1:	prefix->s6_addr32[0] = addr->s6_addr32[0];
+	case 0:	break;
+	}
+	nbits = prefix_len % 32;
+	if (nbits == 0)
+		return;
+
+	mask = ~((1 << (32 - nbits)) - 1);
+	mask = htonl(mask);
+
+	prefix->s6_addr32[ncopy] = addr->s6_addr32[ncopy] & mask;
+}
+
+
+static void dev_forward_change(struct inet6_dev *idev)
+{
+	struct net_device *dev;
+	struct inet6_ifaddr *ifa;
+	struct in6_addr addr;
+
+	if (!idev)
+		return;
+	dev = idev->dev;
+	if (dev && (dev->flags & IFF_MULTICAST)) {
+		ipv6_addr_all_routers(&addr);
+	
+		if (idev->cnf.forwarding)
+			ipv6_dev_mc_inc(dev, &addr);
+		else
+			ipv6_dev_mc_dec(dev, &addr);
+	}
+	for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
+		ipv6_addr_prefix(&addr, &ifa->addr, ifa->prefix_len);
+		if (ipv6_addr_any(&addr))
+			continue;
+		if (idev->cnf.forwarding)
+			ipv6_dev_ac_inc(idev->dev, &addr);
+		else
+			ipv6_dev_ac_dec(idev->dev, &addr);
+	}
+}
+
+
 static void addrconf_forward_change(struct inet6_dev *idev)
 {
 	struct net_device *dev;
 
-	if (idev)
+	if (idev) {
+		dev_forward_change(idev);
 		return;
+	}
 
 	read_lock(&dev_base_lock);
 	for (dev=dev_base; dev; dev=dev->next) {
 		read_lock(&addrconf_lock);
 		idev = __in6_dev_get(dev);
-		if (idev)
+		if (idev) {
 			idev->cnf.forwarding = ipv6_devconf.forwarding;
+			dev_forward_change(idev);
+		}
 		read_unlock(&addrconf_lock);
 	}
 	read_unlock(&dev_base_lock);
 }
 
+
 /* Nobody refers to this ifaddr, destroy it */
 
 void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
@@ -402,7 +487,7 @@
 /* On success it returns ifp with increased reference count */
 
 static struct inet6_ifaddr *
-ipv6_add_addr(struct inet6_dev *idev, struct in6_addr *addr, int pfxlen,
+ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
 	      int scope, unsigned flags)
 {
 	struct inet6_ifaddr *ifa;
@@ -658,30 +743,20 @@
 #define IPV6_GET_SADDR_MAXSCORE(score)	(score)
 #endif
 
-int ipv6_get_saddr(struct dst_entry *dst,
-		   struct in6_addr *daddr, struct in6_addr *saddr)
+int ipv6_dev_get_saddr(struct net_device *dev,
+		   struct in6_addr *daddr, struct in6_addr *saddr, int onlink)
 {
-	int scope;
 	struct inet6_ifaddr *ifp = NULL;
 	struct inet6_ifaddr *match = NULL;
-	struct net_device *dev = NULL;
 	struct inet6_dev *idev;
-	struct rt6_info *rt;
+	int scope;
 	int err;
 	int hiscore = -1, score;
 
-	rt = (struct rt6_info *) dst;
-	if (rt)
-		dev = rt->rt6i_dev;
-
-	scope = ipv6_addr_scope(daddr);
-	if (rt && (rt->rt6i_flags & RTF_ALLONLINK)) {
-		/*
-		 *	route for the "all destinations on link" rule
-		 *	when no routers are present
-		 */
+	if (!onlink)
+		scope = ipv6_addr_scope(daddr);
+	else
 		scope = IFA_LINK;
-	}
 
 	/*
 	 *	known dev
@@ -782,6 +857,24 @@
 	return err;
 }
 
+
+int ipv6_get_saddr(struct dst_entry *dst,
+		   struct in6_addr *daddr, struct in6_addr *saddr)
+{
+	struct rt6_info *rt;
+	struct net_device *dev = NULL;
+	int onlink;
+
+	rt = (struct rt6_info *) dst;
+	if (rt)
+		dev = rt->rt6i_dev;
+
+	onlink = (rt && (rt->rt6i_flags & RTF_ALLONLINK));
+
+	return ipv6_dev_get_saddr(dev, daddr, saddr, onlink);
+}
+
+
 int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr)
 {
 	struct inet6_dev *idev;
@@ -889,7 +982,7 @@
 
 /* Join to solicited addr multicast group. */
 
-static void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr)
+void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr)
 {
 	struct in6_addr maddr;
 
@@ -900,7 +993,7 @@
 	ipv6_dev_mc_inc(dev, &maddr);
 }
 
-static void addrconf_leave_solict(struct net_device *dev, struct in6_addr *addr)
+void addrconf_leave_solict(struct net_device *dev, struct in6_addr *addr)
 {
 	struct in6_addr maddr;
 
@@ -954,7 +1047,6 @@
 	struct net_device *dev;
 	u8 eui64[8];
 	u8 digest[16];
-	struct crypto_tfm *tfm;
 	struct scatterlist sg[2];
 
 	sg[0].page = virt_to_page(idev->entropy);
@@ -976,18 +1068,16 @@
 		get_random_bytes(eui64, sizeof(eui64));
 	}
 regen:
-	tfm = crypto_alloc_tfm("md5", 0);
-	if (tfm == NULL) {
-		if (net_ratelimit())
-			printk(KERN_WARNING
-				"failed to load transform for md5\n");
+	spin_lock(&md5_tfm_lock);
+	if (unlikely(md5_tfm == NULL)) {
+		spin_unlock(&md5_tfm_lock);
 		in6_dev_put(idev);
 		return -1;
 	}
-	crypto_digest_init(tfm);
-	crypto_digest_update(tfm, sg, 2);
-	crypto_digest_final(tfm, digest);
-	crypto_free_tfm(tfm);
+	crypto_digest_init(md5_tfm);
+	crypto_digest_update(md5_tfm, sg, 2);
+	crypto_digest_final(md5_tfm, digest);
+	spin_unlock(&md5_tfm_lock);
 
 	memcpy(idev->rndid, &digest[0], 8);
 	idev->rndid[0] &= ~0x02;
@@ -1015,6 +1105,9 @@
 			goto regen;
 	}
 	
+	idev->regen_timer.expires = jiffies +
+					idev->cnf.temp_prefered_lft * HZ - 
+					idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - desync_factor;
 	if (time_before(idev->regen_timer.expires, jiffies)) {
 		idev->regen_timer.expires = 0;
 		printk(KERN_WARNING
@@ -1554,7 +1647,6 @@
 
 static void init_loopback(struct net_device *dev)
 {
-	struct in6_addr addr;
 	struct inet6_dev  *idev;
 	struct inet6_ifaddr * ifp;
 
@@ -1562,15 +1654,12 @@
 
 	ASSERT_RTNL();
 
-	memset(&addr, 0, sizeof(struct in6_addr));
-	addr.s6_addr[15] = 1;
-
 	if ((idev = ipv6_find_idev(dev)) == NULL) {
 		printk(KERN_DEBUG "init loopback: add_dev failed\n");
 		return;
 	}
 
-	ifp = ipv6_add_addr(idev, &addr, 128, IFA_HOST, IFA_F_PERMANENT);
+	ifp = ipv6_add_addr(idev, &in6addr_loopback, 128, IFA_HOST, IFA_F_PERMANENT);
 	if (ifp) {
 		spin_lock_bh(&ifp->lock);
 		ifp->flags &= ~IFA_F_TENTATIVE;
@@ -1937,6 +2026,14 @@
 		addrconf_mod_timer(ifp, AC_RS, ifp->idev->cnf.rtr_solicit_interval);
 		spin_unlock_bh(&ifp->lock);
 	}
+
+	if (ifp->idev->cnf.forwarding) {
+		struct in6_addr addr;
+
+		ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
+		if (!ipv6_addr_any(&addr))
+			ipv6_dev_ac_inc(ifp->idev->dev, &addr);
+	}
 }
 
 #ifdef CONFIG_PROC_FS
@@ -2267,6 +2364,13 @@
 		break;
 	case RTM_DELADDR:
 		addrconf_leave_solict(ifp->idev->dev, &ifp->addr);
+		if (ifp->idev->cnf.forwarding) {
+			struct in6_addr addr;
+
+			ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
+			if (!ipv6_addr_any(&addr))
+				ipv6_dev_ac_dec(ifp->idev->dev, &addr);
+		}
 		if (!ipv6_chk_addr(&ifp->addr, NULL))
 			ip6_rt_addr_del(&ifp->addr, ifp->idev->dev);
 		break;
@@ -2289,11 +2393,7 @@
 		struct inet6_dev *idev = NULL;
 
 		if (valp != &ipv6_devconf.forwarding) {
-			struct net_device *dev = dev_get_by_index(ctl->ctl_name);
-			if (dev) {
-				idev = in6_dev_get(dev);
-				dev_put(dev);
-			}
+			idev = (struct inet6_dev *)ctl->extra1;
 			if (idev == NULL)
 				return ret;
 		} else
@@ -2303,8 +2403,6 @@
 
 		if (*valp)
 			rt6_purge_dflt_routers(0);
-		if (idev)
-			in6_dev_put(idev);
 	}
 
         return ret;
@@ -2491,6 +2589,7 @@
 	for (i=0; t->addrconf_vars[i].data; i++) {
 		t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf;
 		t->addrconf_vars[i].de = NULL;
+		t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */
 	}
 	if (dev) {
 		t->addrconf_dev[0].procname = dev->name;
@@ -2550,7 +2649,16 @@
 {
 #ifdef MODULE
 	struct net_device *dev;
+#endif
+
+#ifdef CONFIG_IPV6_PRIVACY
+	md5_tfm = crypto_alloc_tfm("md5", 0);
+	if (unlikely(md5_tfm == NULL))
+		printk(KERN_WARNING
+			"failed to load transform for md5\n");
+#endif
 
+#ifdef MODULE
 	/* This takes sense only during module load. */
 	rtnl_lock();
 	for (dev = dev_base; dev; dev = dev->next) {
@@ -2634,6 +2742,13 @@
 	del_timer(&addr_chk_timer);
 
 	rtnl_unlock();
+
+#ifdef CONFIG_IPV6_PRIVACY
+	if (likely(md5_tfm != NULL)) {
+		crypto_free_tfm(md5_tfm);
+		md5_tfm = NULL;
+	}
+#endif
 
 #ifdef CONFIG_PROC_FS
 	proc_net_remove("if_inet6");
diff -Nru a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
--- a/net/ipv6/af_inet6.c	Sat Jan 18 09:11:38 2003
+++ b/net/ipv6/af_inet6.c	Sun Mar 23 21:30:34 2003
@@ -74,6 +74,7 @@
 /* IPv6 procfs goodies... */
 
 #ifdef CONFIG_PROC_FS
+extern int anycast6_get_info(char *, char **, off_t, int);
 extern int raw6_get_info(char *, char **, off_t, int);
 extern int tcp6_get_info(char *, char **, off_t, int);
 extern int udp6_get_info(char *, char **, off_t, int);
@@ -381,6 +382,9 @@
 	/* Free mc lists */
 	ipv6_sock_mc_close(sk);
 
+	/* Free ac lists */
+	ipv6_sock_ac_close(sk);
+
 	return inet_release(sock);
 }
 
@@ -785,6 +789,8 @@
 		goto proc_sockstat6_fail;
 	if (!proc_net_create("snmp6", 0, afinet6_get_snmp))
 		goto proc_snmp6_fail;
+	if (!proc_net_create("anycast6", 0, anycast6_get_info))
+		goto proc_anycast6_fail;
 #endif
 	ipv6_netdev_notif_init();
 	ipv6_packet_init();
@@ -793,6 +799,13 @@
 	addrconf_init();
 	sit_init();
 
+	/* Init v6 extention headers. */
+	ipv6_hopopts_init();
+	ipv6_rthdr_init();
+	ipv6_frag_init();
+	ipv6_nodata_init();
+	ipv6_destopt_init();
+
 	/* Init v6 transport protocols. */
 	udpv6_init();
 	tcpv6_init();
@@ -800,6 +813,8 @@
 	return 0;
 
 #ifdef CONFIG_PROC_FS
+proc_anycast6_fail:
+	proc_net_remove("anycast6");
 proc_snmp6_fail:
 	proc_net_remove("sockstat6");
 proc_sockstat6_fail:
@@ -837,6 +852,7 @@
 	proc_net_remove("udp6");
 	proc_net_remove("sockstat6");
 	proc_net_remove("snmp6");
+	proc_net_remove("anycast6");
 #endif
 	/* Cleanup code parts. */
 	sit_cleanup();
diff -Nru a/net/ipv6/ah6.c b/net/ipv6/ah6.c
--- a/net/ipv6/ah6.c	Thu Mar  6 16:16:15 2003
+++ b/net/ipv6/ah6.c	Sun Mar 23 02:21:29 2003
@@ -60,9 +60,11 @@
 	struct ah_data *ahp;
 	u16 nh_offset = 0;
 	u8 nexthdr;
-printk(KERN_DEBUG "%s\n", __FUNCTION__);
-	if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL)
-		return -EINVAL;
+
+	if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
+		err = -EINVAL;
+		goto error_nolock;
+	}
 
 	spin_lock_bh(&x->lock);
 	if ((err = xfrm_state_check_expire(x)) != 0)
@@ -134,8 +136,10 @@
 	x->curlft.bytes += skb->len;
 	x->curlft.packets++;
 	spin_unlock_bh(&x->lock);
-	if ((skb->dst = dst_pop(dst)) == NULL)
+	if ((skb->dst = dst_pop(dst)) == NULL) {
+		err = -EHOSTUNREACH;
 		goto error_nolock;
+	}
 	return NET_XMIT_BYPASS;
 error:
 	spin_unlock_bh(&x->lock);
@@ -224,7 +228,7 @@
 	    type != ICMPV6_PKT_TOOBIG)
 		return;
 
-	x = xfrm6_state_lookup(&iph->daddr, ah->spi, IPPROTO_AH);
+	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET6);
 	if (!x)
 		return;
 
@@ -332,14 +336,14 @@
 {
 	SET_MODULE_OWNER(&ah6_type);
 
-	if (xfrm6_register_type(&ah6_type) < 0) {
+	if (xfrm_register_type(&ah6_type, AF_INET6) < 0) {
 		printk(KERN_INFO "ipv6 ah init: can't add xfrm type\n");
 		return -EAGAIN;
 	}
 
 	if (inet6_add_protocol(&ah6_protocol, IPPROTO_AH) < 0) {
 		printk(KERN_INFO "ipv6 ah init: can't add protocol\n");
-		xfrm6_unregister_type(&ah6_type);
+		xfrm_unregister_type(&ah6_type, AF_INET6);
 		return -EAGAIN;
 	}
 
@@ -351,7 +355,7 @@
 	if (inet6_del_protocol(&ah6_protocol, IPPROTO_AH) < 0)
 		printk(KERN_INFO "ipv6 ah close: can't remove protocol\n");
 
-	if (xfrm6_unregister_type(&ah6_type) < 0)
+	if (xfrm_unregister_type(&ah6_type, AF_INET6) < 0)
 		printk(KERN_INFO "ipv6 ah close: can't remove xfrm type\n");
 
 }
diff -Nru a/net/ipv6/anycast.c b/net/ipv6/anycast.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv6/anycast.c	Wed Mar 19 17:25:59 2003
@@ -0,0 +1,489 @@
+/*
+ *	Anycast support for IPv6
+ *	Linux INET6 implementation 
+ *
+ *	Authors:
+ *	David L Stevens (dlstevens@us.ibm.com)
+ *
+ *	based heavily on net/ipv6/mcast.c
+ *
+ *	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/module.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/random.h>
+#include <linux/string.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/sched.h>
+#include <linux/net.h>
+#include <linux/in6.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/route.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+
+#include <net/sock.h>
+#include <net/snmp.h>
+
+#include <net/ipv6.h>
+#include <net/protocol.h>
+#include <net/if_inet6.h>
+#include <net/ndisc.h>
+#include <net/addrconf.h>
+#include <net/ip6_route.h>
+
+#include <net/checksum.h>
+
+/* Big ac list lock for all the sockets */
+static rwlock_t ipv6_sk_ac_lock = RW_LOCK_UNLOCKED;
+
+/* XXX ip6_addr_match() and ip6_onlink() really belong in net/core.c */
+
+static int
+ip6_addr_match(struct in6_addr *addr1, struct in6_addr *addr2, int prefix)
+{
+	__u32	mask;
+	int	i;
+
+	if (prefix > 128 || prefix < 0)
+		return 0;
+	if (prefix == 0)
+		return 1;
+	for (i=0; i<4; ++i) {
+		if (prefix >= 32)
+			mask = ~0;
+		else
+			mask = htonl(~0 << (32 - prefix));
+		if ((addr1->s6_addr32[i] ^ addr2->s6_addr32[i]) & mask)
+			return 0;
+		prefix -= 32;
+		if (prefix <= 0)
+			break;
+	}
+	return 1;
+}
+
+static int
+ip6_onlink(struct in6_addr *addr, struct net_device *dev)
+{
+	struct inet6_dev	*idev;
+	struct inet6_ifaddr	*ifa;
+	int	onlink;
+
+	onlink = 0;
+	read_lock(&addrconf_lock);
+	idev = __in6_dev_get(dev);
+	if (idev) {
+		read_lock_bh(&idev->lock);
+		for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
+			onlink = ip6_addr_match(addr, &ifa->addr,
+					ifa->prefix_len);
+			if (onlink)
+				break;
+		}
+		read_unlock_bh(&idev->lock);
+	}
+	read_unlock(&addrconf_lock);
+	return onlink;
+}
+
+
+/*
+ *	socket join an anycast group
+ */
+
+int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
+{
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct net_device *dev = NULL;
+	struct inet6_dev *idev;
+	struct ipv6_ac_socklist *pac;
+	int	ishost = !ipv6_devconf.forwarding;
+	int	err = 0;
+
+	if (ipv6_addr_type(addr) & IPV6_ADDR_MULTICAST)
+		return -EINVAL;
+
+	pac = sock_kmalloc(sk, sizeof(struct ipv6_ac_socklist), GFP_KERNEL);
+	if (pac == NULL)
+		return -ENOMEM;
+	pac->acl_next = NULL;
+	ipv6_addr_copy(&pac->acl_addr, addr);
+
+	if (ifindex == 0) {
+		struct rt6_info *rt;
+
+		rt = rt6_lookup(addr, NULL, 0, 0);
+		if (rt) {
+			dev = rt->rt6i_dev;
+			dev_hold(dev);
+			dst_release(&rt->u.dst);
+		} else if (ishost) {
+			sock_kfree_s(sk, pac, sizeof(*pac));
+			return -EADDRNOTAVAIL;
+		} else {
+			/* router, no matching interface: just pick one */
+
+			dev = dev_get_by_flags(IFF_UP, IFF_UP|IFF_LOOPBACK);
+		}
+	} else
+		dev = dev_get_by_index(ifindex);
+
+	if (dev == NULL) {
+		sock_kfree_s(sk, pac, sizeof(*pac));
+		return -ENODEV;
+	}
+
+	idev = in6_dev_get(dev);
+	if (!idev) {
+		sock_kfree_s(sk, pac, sizeof(*pac));
+		dev_put(dev);
+		if (ifindex)
+			return -ENODEV;
+		else
+			return -EADDRNOTAVAIL;
+	}
+	/* reset ishost, now that we have a specific device */
+	ishost = !idev->cnf.forwarding;
+	in6_dev_put(idev);
+
+	pac->acl_ifindex = dev->ifindex;
+
+	/* XXX
+	 * For hosts, allow link-local or matching prefix anycasts.
+	 * This obviates the need for propagating anycast routes while
+	 * still allowing some non-router anycast participation.
+	 *
+	 * allow anyone to join anycasts that don't require a special route
+	 * and can't be spoofs of unicast addresses (reserved anycast only)
+	 */
+	if (!ip6_onlink(addr, dev)) {
+		if (ishost)
+			err = -EADDRNOTAVAIL;
+		else if (!capable(CAP_NET_ADMIN))
+			err = -EPERM;
+		if (err) {
+			sock_kfree_s(sk, pac, sizeof(*pac));
+			dev_put(dev);
+			return err;
+		}
+	} else if (!(ipv6_addr_type(addr) & IPV6_ADDR_ANYCAST) &&
+		   !capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	err = ipv6_dev_ac_inc(dev, addr);
+	if (err) {
+		sock_kfree_s(sk, pac, sizeof(*pac));
+		dev_put(dev);
+		return err;
+	}
+
+	write_lock_bh(&ipv6_sk_ac_lock);
+	pac->acl_next = np->ipv6_ac_list;
+	np->ipv6_ac_list = pac;
+	write_unlock_bh(&ipv6_sk_ac_lock);
+
+	dev_put(dev);
+
+	return 0;
+}
+
+/*
+ *	socket leave an anycast group
+ */
+int ipv6_sock_ac_drop(struct sock *sk, int ifindex, struct in6_addr *addr)
+{
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct net_device *dev;
+	struct ipv6_ac_socklist *pac, *prev_pac;
+
+	write_lock_bh(&ipv6_sk_ac_lock);
+	prev_pac = 0;
+	for (pac = np->ipv6_ac_list; pac; pac = pac->acl_next) {
+		if ((ifindex == 0 || pac->acl_ifindex == ifindex) &&
+		     ipv6_addr_cmp(&pac->acl_addr, addr) == 0)
+			break;
+		prev_pac = pac;
+	}
+	if (!pac) {
+		write_unlock_bh(&ipv6_sk_ac_lock);
+		return -ENOENT;
+	}
+	if (prev_pac)
+		prev_pac->acl_next = pac->acl_next;
+	else
+		np->ipv6_ac_list = pac->acl_next;
+
+	write_unlock_bh(&ipv6_sk_ac_lock);
+
+	dev = dev_get_by_index(pac->acl_ifindex);
+	if (dev) {
+		ipv6_dev_ac_dec(dev, &pac->acl_addr);
+		dev_put(dev);
+	}
+	sock_kfree_s(sk, pac, sizeof(*pac));
+	return 0;
+}
+
+void ipv6_sock_ac_close(struct sock *sk)
+{
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct net_device *dev = 0;
+	struct ipv6_ac_socklist *pac;
+	int	prev_index;
+
+	write_lock_bh(&ipv6_sk_ac_lock);
+	pac = np->ipv6_ac_list;
+	np->ipv6_ac_list = 0;
+	write_unlock_bh(&ipv6_sk_ac_lock);
+
+	prev_index = 0;
+	while (pac) {
+		struct ipv6_ac_socklist *next = pac->acl_next;
+
+		if (pac->acl_ifindex != prev_index) {
+			if (dev)
+				dev_put(dev);
+			dev = dev_get_by_index(pac->acl_ifindex);
+			prev_index = pac->acl_ifindex;
+		}
+		if (dev)
+			ipv6_dev_ac_dec(dev, &pac->acl_addr);
+		sock_kfree_s(sk, pac, sizeof(*pac));
+		pac = next;
+	}
+	if (dev)
+		dev_put(dev);
+}
+
+int inet6_ac_check(struct sock *sk, struct in6_addr *addr, int ifindex)
+{
+	struct ipv6_ac_socklist *pac;
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	int	found;
+
+	found = 0;
+	read_lock(&ipv6_sk_ac_lock);
+	for (pac=np->ipv6_ac_list; pac; pac=pac->acl_next) {
+		if (ifindex && pac->acl_ifindex != ifindex)
+			continue;
+		found = ipv6_addr_cmp(&pac->acl_addr, addr) == 0;
+		if (found)
+			break;
+	}
+	read_unlock(&ipv6_sk_ac_lock);
+
+	return found;
+}
+
+static void aca_put(struct ifacaddr6 *ac)
+{
+	if (atomic_dec_and_test(&ac->aca_refcnt)) {
+		in6_dev_put(ac->aca_idev);
+		kfree(ac);
+	}
+}
+
+/*
+ *	device anycast group inc (add if not found)
+ */
+int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr)
+{
+	struct ifacaddr6 *aca;
+	struct inet6_dev *idev;
+
+	idev = in6_dev_get(dev);
+
+	if (idev == NULL)
+		return -EINVAL;
+
+	write_lock_bh(&idev->lock);
+	if (idev->dead) {
+		write_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
+		return -ENODEV;
+	}
+
+	for (aca = idev->ac_list; aca; aca = aca->aca_next) {
+		if (ipv6_addr_cmp(&aca->aca_addr, addr) == 0) {
+			aca->aca_users++;
+			write_unlock_bh(&idev->lock);
+			in6_dev_put(idev);
+			return 0;
+		}
+	}
+
+	/*
+	 *	not found: create a new one.
+	 */
+
+	aca = kmalloc(sizeof(struct ifacaddr6), GFP_ATOMIC);
+
+	if (aca == NULL) {
+		write_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
+		return -ENOMEM;
+	}
+
+	memset(aca, 0, sizeof(struct ifacaddr6));
+
+	ipv6_addr_copy(&aca->aca_addr, addr);
+	aca->aca_idev = idev;
+	aca->aca_users = 1;
+	atomic_set(&aca->aca_refcnt, 2);
+	aca->aca_lock = SPIN_LOCK_UNLOCKED;
+
+	aca->aca_next = idev->ac_list;
+	idev->ac_list = aca;
+	write_unlock_bh(&idev->lock);
+
+	ip6_rt_addr_add(&aca->aca_addr, dev);
+
+	addrconf_join_solict(dev, &aca->aca_addr);
+
+	aca_put(aca);
+	return 0;
+}
+
+/*
+ *	device anycast group decrement
+ */
+int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
+{
+	struct inet6_dev *idev;
+	struct ifacaddr6 *aca, *prev_aca;
+
+	idev = in6_dev_get(dev);
+	if (idev == NULL)
+		return -ENODEV;
+
+	write_lock_bh(&idev->lock);
+	prev_aca = 0;
+	for (aca = idev->ac_list; aca; aca = aca->aca_next) {
+		if (ipv6_addr_cmp(&aca->aca_addr, addr) == 0)
+			break;
+		prev_aca = aca;
+	}
+	if (!aca) {
+		write_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
+		return -ENOENT;
+	}
+	if (--aca->aca_users > 0) {
+		write_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
+		return 0;
+	}
+	if (prev_aca)
+		prev_aca->aca_next = aca->aca_next;
+	else
+		idev->ac_list = aca->aca_next;
+	write_unlock_bh(&idev->lock);
+	addrconf_leave_solict(dev, &aca->aca_addr);
+
+	ip6_rt_addr_del(&aca->aca_addr, dev);
+
+	aca_put(aca);
+	in6_dev_put(idev);
+	return 0;
+}
+
+/*
+ *	check if the interface has this anycast address
+ */
+static int ipv6_chk_acast_dev(struct net_device *dev, struct in6_addr *addr)
+{
+	struct inet6_dev *idev;
+	struct ifacaddr6 *aca;
+
+	idev = in6_dev_get(dev);
+	if (idev) {
+		read_lock_bh(&idev->lock);
+		for (aca = idev->ac_list; aca; aca = aca->aca_next)
+			if (ipv6_addr_cmp(&aca->aca_addr, addr) == 0)
+				break;
+		read_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
+		return aca != 0;
+	}
+	return 0;
+}
+
+/*
+ *	check if given interface (or any, if dev==0) has this anycast address
+ */
+int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr)
+{
+	if (dev)
+		return ipv6_chk_acast_dev(dev, addr);
+	read_lock(&dev_base_lock);
+	for (dev=dev_base; dev; dev=dev->next)
+		if (ipv6_chk_acast_dev(dev, addr))
+			break;
+	read_unlock(&dev_base_lock);
+	return dev != 0;
+}
+
+
+#ifdef CONFIG_PROC_FS
+int anycast6_get_info(char *buffer, char **start, off_t offset, int length)
+{
+	off_t pos=0, begin=0;
+	struct ifacaddr6 *im;
+	int len=0;
+	struct net_device *dev;
+	
+	read_lock(&dev_base_lock);
+	for (dev = dev_base; dev; dev = dev->next) {
+		struct inet6_dev *idev;
+
+		if ((idev = in6_dev_get(dev)) == NULL)
+			continue;
+
+		read_lock_bh(&idev->lock);
+		for (im = idev->ac_list; im; im = im->aca_next) {
+			int i;
+
+			len += sprintf(buffer+len,"%-4d %-15s ", dev->ifindex, dev->name);
+
+			for (i=0; i<16; i++)
+				len += sprintf(buffer+len, "%02x", im->aca_addr.s6_addr[i]);
+
+			len += sprintf(buffer+len, " %5d\n", im->aca_users);
+
+			pos=begin+len;
+			if (pos < offset) {
+				len=0;
+				begin=pos;
+			}
+			if (pos > offset+length) {
+				read_unlock_bh(&idev->lock);
+				in6_dev_put(idev);
+				goto done;
+			}
+		}
+		read_unlock_bh(&idev->lock);
+		in6_dev_put(idev);
+	}
+
+done:
+	read_unlock(&dev_base_lock);
+
+	*start=buffer+(offset-begin);
+	len-=(offset-begin);
+	if(len>length)
+		len=length;
+	if (len<0)
+		len=0;
+	return len;
+}
+
+#endif
diff -Nru a/net/ipv6/esp6.c b/net/ipv6/esp6.c
--- a/net/ipv6/esp6.c	Thu Mar  6 16:16:15 2003
+++ b/net/ipv6/esp6.c	Sun Mar 23 02:21:29 2003
@@ -118,10 +118,12 @@
 	int alen;
 	int nfrags;
 	u8 nexthdr;
-printk(KERN_DEBUG "%s\n", __FUNCTION__);
+
 	/* First, if the skb is not checksummed, complete checksum. */
-	if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL)
-		return -EINVAL;
+	if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
+		err = -EINVAL;
+		goto error_nolock;
+	}
 
 	spin_lock_bh(&x->lock);
 	if ((err = xfrm_state_check_expire(x)) != 0)
@@ -239,8 +241,10 @@
 	x->curlft.bytes += skb->len;
 	x->curlft.packets++;
 	spin_unlock_bh(&x->lock);
-	if ((skb->dst = dst_pop(dst)) == NULL)
+	if ((skb->dst = dst_pop(dst)) == NULL) {
+		err = -EHOSTUNREACH;
 		goto error_nolock;
+	}
 	return NET_XMIT_BYPASS;
 
 error:
@@ -373,7 +377,7 @@
 	    type != ICMPV6_PKT_TOOBIG)
 		return;
 
-	x = xfrm6_state_lookup(&iph->daddr, esph->spi, IPPROTO_ESP);
+	x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);
 	if (!x)
 		return;
 	printk(KERN_DEBUG "pmtu discvovery on SA ESP/%08x/"
@@ -500,13 +504,13 @@
 int __init esp6_init(void)
 {
 	SET_MODULE_OWNER(&esp6_type);
-	if (xfrm6_register_type(&esp6_type) < 0) {
+	if (xfrm_register_type(&esp6_type, AF_INET6) < 0) {
 		printk(KERN_INFO "ipv6 esp init: can't add xfrm type\n");
 		return -EAGAIN;
 	}
 	if (inet6_add_protocol(&esp6_protocol, IPPROTO_ESP) < 0) {
 		printk(KERN_INFO "ipv6 esp init: can't add protocol\n");
-		xfrm6_unregister_type(&esp6_type);
+		xfrm_unregister_type(&esp6_type, AF_INET6);
 		return -EAGAIN;
 	}
 
@@ -517,7 +521,7 @@
 {
 	if (inet6_del_protocol(&esp6_protocol, IPPROTO_ESP) < 0)
 		printk(KERN_INFO "ipv6 esp close: can't remove protocol\n");
-	if (xfrm6_unregister_type(&esp6_type) < 0)
+	if (xfrm_unregister_type(&esp6_type, AF_INET6) < 0)
 		printk(KERN_INFO "ipv6 esp close: can't remove xfrm type\n");
 }
 
diff -Nru a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
--- a/net/ipv6/exthdrs.c	Wed Feb 19 13:55:33 2003
+++ b/net/ipv6/exthdrs.c	Sun Mar 23 21:30:34 2003
@@ -18,6 +18,9 @@
 /* Changes:
  *	yoshfuji		: ensure not to overrun while parsing 
  *				  tlv options.
+ *	Mitsuru KANDA @USAGI	: Remove ipv6_parse_exthdrs().
+ *				: Register inbound extention header
+ *				: handlers as inet6_protocol{}.
  */
 
 #include <linux/errno.h>
@@ -44,20 +47,6 @@
 #include <asm/uaccess.h>
 
 /*
- *	Parsing inbound headers.
- *
- *	Parsing function "func" returns offset wrt skb->nh of the place,
- *	where next nexthdr value is stored or NULL, if parsing
- *	failed. It should also update skb->h tp point at the next header.
- */
-
-struct hdrtype_proc
-{
-	int	type;
-	int	(*func) (struct sk_buff **, int offset);
-};
-
-/*
  *	Parsing tlv encoded headers.
  *
  *	Parsing function "func" returns 1, if parsing succeed
@@ -164,49 +153,77 @@
 	{-1,			NULL}
 };
 
-static int ipv6_dest_opt(struct sk_buff **skb_ptr, int nhoff)
+static int ipv6_destopt_rcv(struct sk_buff **skbp) 
 {
-	struct sk_buff *skb=*skb_ptr;
+	struct sk_buff *skb = *skbp;
 	struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
+	u8 nexthdr = 0;
 
 	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
 	    !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
 		kfree_skb(skb);
-		return -1;
+		return 0;
 	}
 
+	nexthdr = ((struct ipv6_destopt_hdr *)skb->h.raw)->nexthdr;
+	
 	opt->dst1 = skb->h.raw - skb->nh.raw;
 
 	if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
 		skb->h.raw += ((skb->h.raw[1]+1)<<3);
-		return opt->dst1;
+		return -nexthdr;
 	}
+						
+	return 0;
+}
 
-	return -1;
+static struct inet6_protocol destopt_protocol =
+{
+	.handler 	= 	ipv6_destopt_rcv,
+};
+
+void __init ipv6_destopt_init(void)
+{
+	if (inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS) < 0) 
+		printk(KERN_ERR "ipv6_destopt_init: Could not register protocol\n");
 }
 
 /********************************
   NONE header. No data in packet.
  ********************************/
 
-static int ipv6_nodata(struct sk_buff **skb_ptr, int nhoff)
+static int ipv6_nodata_rcv(struct sk_buff **skbp)
 {
-	kfree_skb(*skb_ptr);
-	return -1;
+	struct sk_buff *skb = *skbp;
+
+	kfree_skb(skb);
+	return 0;
+}
+
+static struct inet6_protocol nodata_protocol =
+{
+	.handler	=	ipv6_nodata_rcv,
+};
+
+void __init ipv6_nodata_init(void)
+{
+	if (inet6_add_protocol(&nodata_protocol, IPPROTO_NONE) < 0)
+		printk(KERN_ERR "ipv6_nodata_init: Could not register protocol\n");
 }
 
 /********************************
   Routing header.
  ********************************/
 
-static int ipv6_routing_header(struct sk_buff **skb_ptr, int nhoff)
+static int ipv6_rthdr_rcv(struct sk_buff **skbp)
 {
-	struct sk_buff *skb = *skb_ptr;
+	struct sk_buff *skb = *skbp;
 	struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
 	struct in6_addr *addr;
 	struct in6_addr daddr;
 	int addr_type;
 	int n, i;
+	u8 nexthdr = 0;
 
 	struct ipv6_rt_hdr *hdr;
 	struct rt0_hdr *rthdr;
@@ -215,15 +232,16 @@
 	    !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
 		IP6_INC_STATS_BH(Ip6InHdrErrors);
 		kfree_skb(skb);
-		return -1;
+		return 0;
 	}
 
 	hdr = (struct ipv6_rt_hdr *) skb->h.raw;
+	nexthdr = hdr->nexthdr;
 
 	if ((ipv6_addr_type(&skb->nh.ipv6h->daddr)&IPV6_ADDR_MULTICAST) ||
 	    skb->pkt_type != PACKET_HOST) {
 		kfree_skb(skb);
-		return -1;
+		return 0;
 	}
 
 looped_back:
@@ -232,24 +250,24 @@
 		skb->h.raw += (hdr->hdrlen + 1) << 3;
 		opt->dst0 = opt->dst1;
 		opt->dst1 = 0;
-		return (&hdr->nexthdr) - skb->nh.raw;
+		return -nexthdr;
 	}
 
 	if (hdr->type != IPV6_SRCRT_TYPE_0 || (hdr->hdrlen & 0x01)) {
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, hdr->type != IPV6_SRCRT_TYPE_0 ? 2 : 1);
-		return -1;
+		return 0;
 	}
 
 	/*
 	 *	This is the routing header forwarding algorithm from
-	 *	RFC 1883, page 17.
+	 *	RFC 2460, page 16.
 	 */
 
 	n = hdr->hdrlen >> 1;
 
 	if (hdr->segments_left > n) {
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
-		return -1;
+		return 0;
 	}
 
 	/* We are about to mangle packet header. Be careful!
@@ -259,8 +277,8 @@
 		struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
 		kfree_skb(skb);
 		if (skb2 == NULL)
-			return -1;
-		*skb_ptr = skb = skb2;
+			return 0;
+		*skbp = skb = skb2;
 		opt = (struct inet6_skb_parm *)skb2->cb;
 		hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
 	}
@@ -278,7 +296,7 @@
 
 	if (addr_type&IPV6_ADDR_MULTICAST) {
 		kfree_skb(skb);
-		return -1;
+		return 0;
 	}
 
 	ipv6_addr_copy(&daddr, addr);
@@ -289,23 +307,34 @@
 	ip6_route_input(skb);
 	if (skb->dst->error) {
 		dst_input(skb);
-		return -1;
+		return 0;
 	}
 	if (skb->dst->dev->flags&IFF_LOOPBACK) {
 		if (skb->nh.ipv6h->hop_limit <= 1) {
 			icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
 				    0, skb->dev);
 			kfree_skb(skb);
-			return -1;
+			return 0;
 		}
 		skb->nh.ipv6h->hop_limit--;
 		goto looped_back;
 	}
 
 	dst_input(skb);
-	return -1;
+	return 0;
 }
 
+static struct inet6_protocol rthdr_protocol =
+{
+	.handler	=	ipv6_rthdr_rcv,
+};
+
+void __init ipv6_rthdr_init(void)
+{
+	if (inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING) < 0)
+		printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
+};
+
 /*
    This function inverts received rthdr.
    NOTE: specs allow to make it automatically only if
@@ -371,97 +400,6 @@
 	return opt;
 }
 
-/********************************
-  AUTH header.
- ********************************/
-
-/*
-   rfc1826 said, that if a host does not implement AUTH header
-   it MAY ignore it. We use this hole 8)
-
-   Actually, now we can implement OSPFv6 without kernel IPsec.
-   Authentication for poors may be done in user space with the same success.
-
-   Yes, it means, that we allow application to send/receive
-   raw authentication header. Apparently, we suppose, that it knows
-   what it does and calculates authentication data correctly.
-   Certainly, it is possible only for udp and raw sockets, but not for tcp.
-
-   AUTH header has 4byte granular length, which kills all the idea
-   behind AUTOMATIC 64bit alignment of IPv6. Now we will lose
-   cpu ticks, checking that sender did not something stupid
-   and opt->hdrlen is even. Shit!		--ANK (980730)
- */
-
-static int ipv6_auth_hdr(struct sk_buff **skb_ptr, int nhoff)
-{
-	struct sk_buff *skb=*skb_ptr;
-	struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
-	int len;
-
-	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8))
-		goto fail;
-
-	/*
-	 * RFC2402 2.2 Payload Length
-	 * The 8-bit field specifies the length of AH in 32-bit words 
-	 * (4-byte units), minus "2".
-	 * -- Noriaki Takamiya @USAGI Project
-	 */
-	len = (skb->h.raw[1]+2)<<2;
-
-	if (len&7)
-		goto fail;
-
-	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+len))
-		goto fail;
-
-	opt->auth = skb->h.raw - skb->nh.raw;
-	skb->h.raw += len;
-	return opt->auth;
-
-fail:
-	kfree_skb(skb);
-	return -1;
-}
-
-/* This list MUST NOT contain entry for NEXTHDR_HOP.
-   It is parsed immediately after packet received
-   and if it occurs somewhere in another place we must
-   generate error.
- */
-
-static struct hdrtype_proc hdrproc_lst[] = {
-	{NEXTHDR_FRAGMENT,	ipv6_reassembly},
-	{NEXTHDR_ROUTING,	ipv6_routing_header},
-	{NEXTHDR_DEST,		ipv6_dest_opt},
-	{NEXTHDR_NONE,		ipv6_nodata},
-	{NEXTHDR_AUTH,		ipv6_auth_hdr},
-   /*
-	{NEXTHDR_ESP,		ipv6_esp_hdr},
-    */
-	{-1,			NULL}
-};
-
-int ipv6_parse_exthdrs(struct sk_buff **skb_in, int nhoff)
-{
-	struct hdrtype_proc *hdrt;
-	u8 nexthdr = (*skb_in)->nh.raw[nhoff];
-
-restart:
-	for (hdrt=hdrproc_lst; hdrt->type >= 0; hdrt++) {
-		if (hdrt->type == nexthdr) {
-			if ((nhoff = hdrt->func(skb_in, nhoff)) >= 0) {
-				nexthdr = (*skb_in)->nh.raw[nhoff];
-				goto restart;
-			}
-			return -1;
-		}
-	}
-	return nhoff;
-}
-
-
 /**********************************
   Hop-by-hop options.
  **********************************/
@@ -530,6 +468,34 @@
 	if (ip6_parse_tlv(tlvprochopopt_lst, skb))
 		return sizeof(struct ipv6hdr);
 	return -1;
+}
+
+/* This is fake. We have already parsed hopopts in ipv6_rcv(). -mk */
+static int ipv6_hopopts_rcv(struct sk_buff **skbp)
+{
+	struct sk_buff *skb = *skbp;
+	u8 nexthdr = 0;
+
+	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
+	    !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
+		kfree_skb(skb);
+		return 0;
+	}
+	nexthdr = ((struct ipv6_hopopt_hdr *)skb->h.raw)->nexthdr;
+	skb->h.raw += (skb->h.raw[1]+1)<<3;
+
+       return -nexthdr;
+}
+
+static struct inet6_protocol hopopts_protocol =
+{
+	.handler	=	ipv6_hopopts_rcv,
+};
+
+void __init ipv6_hopopts_init(void)
+{
+	if (inet6_add_protocol(&hopopts_protocol, IPPROTO_HOPOPTS) < 0)
+		printk(KERN_ERR "ipv6_hopopts_init: Could not register protocol\n");
 }
 
 /*
diff -Nru a/net/ipv6/icmp.c b/net/ipv6/icmp.c
--- a/net/ipv6/icmp.c	Thu Mar  6 16:30:30 2003
+++ b/net/ipv6/icmp.c	Sun Mar 23 21:30:34 2003
@@ -74,7 +74,7 @@
 static struct socket *__icmpv6_socket[NR_CPUS];
 #define icmpv6_socket	__icmpv6_socket[smp_processor_id()]
 
-static int icmpv6_rcv(struct sk_buff *skb);
+static int icmpv6_rcv(struct sk_buff **pskb);
 
 static struct inet6_protocol icmpv6_protocol = {
 	.handler	=	icmpv6_rcv,
@@ -369,7 +369,8 @@
 
 	saddr = &skb->nh.ipv6h->daddr;
 
-	if (ipv6_addr_type(saddr) & IPV6_ADDR_MULTICAST)
+	if (ipv6_addr_type(saddr) & IPV6_ADDR_MULTICAST ||
+	    ipv6_chk_acast_addr(0, saddr)) 
 		saddr = NULL;
 
 	msg.icmph.icmp6_type = ICMPV6_ECHO_REPLY;
@@ -458,8 +459,9 @@
  *	Handle icmp messages
  */
 
-static int icmpv6_rcv(struct sk_buff *skb)
+static int icmpv6_rcv(struct sk_buff **pskb)
 {
+	struct sk_buff *skb = *pskb;
 	struct net_device *dev = skb->dev;
 	struct in6_addr *saddr, *daddr;
 	struct ipv6hdr *orig_hdr;
diff -Nru a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
--- a/net/ipv6/ip6_input.c	Wed Mar  5 15:45:36 2003
+++ b/net/ipv6/ip6_input.c	Sun Mar 23 21:30:34 2003
@@ -15,6 +15,10 @@
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  */
+/* Changes
+ *
+ * 	Mitsuru KANDA @USAGI	: Remove ipv6_parse_exthdrs().
+ */
 
 #include <linux/errno.h>
 #include <linux/types.h>
@@ -126,39 +130,11 @@
 	struct ipv6hdr *hdr = skb->nh.ipv6h;
 	struct inet6_protocol *ipprot;
 	struct sock *raw_sk;
-	int nhoff;
-	int nexthdr;
+	int nexthdr = hdr->nexthdr;
 	u8 hash;
 
 	skb->h.raw = skb->nh.raw + sizeof(struct ipv6hdr);
 
-	/*
-	 *	Parse extension headers
-	 */
-
-	nexthdr = hdr->nexthdr;
-	nhoff = offsetof(struct ipv6hdr, nexthdr);
-
-	/* Skip  hop-by-hop options, they are already parsed. */
-	if (nexthdr == NEXTHDR_HOP) {
-		nhoff = sizeof(struct ipv6hdr);
-		nexthdr = skb->h.raw[0];
-		skb->h.raw += (skb->h.raw[1]+1)<<3;
-	}
-
-	/* This check is sort of optimization.
-	   It would be stupid to detect for optional headers,
-	   which are missing with probability of 200%
-	 */
-	if (nexthdr != IPPROTO_TCP && nexthdr != IPPROTO_UDP &&
-	    nexthdr != NEXTHDR_AUTH && nexthdr != NEXTHDR_ESP) {
-		nhoff = ipv6_parse_exthdrs(&skb, nhoff);
-		if (nhoff < 0)
-			return 0;
-		nexthdr = skb->nh.raw[nhoff];
-		hdr = skb->nh.ipv6h;
-	}
-
 	if (!pskb_pull(skb, skb->h.raw - skb->data))
 		goto discard;
 
@@ -173,7 +149,7 @@
 
 	hash = nexthdr & (MAX_INET_PROTOS - 1);
 	if ((ipprot = inet6_protos[hash]) != NULL) {
-		int ret = ipprot->handler(skb);
+		int ret = ipprot->handler(&skb);
 		if (ret < 0) {
 			nexthdr = -ret;
 			goto resubmit;
@@ -182,7 +158,8 @@
 	} else {
 		if (!raw_sk) {
 			IP6_INC_STATS_BH(Ip6InUnknownProtos);
-			icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff);
+			icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR,
+					  offsetof(struct ipv6hdr, nexthdr));
 		} else {
 			IP6_INC_STATS_BH(Ip6InDelivers);
 			kfree_skb(skb);
diff -Nru a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
--- a/net/ipv6/ip6_output.c	Wed Mar  5 15:45:36 2003
+++ b/net/ipv6/ip6_output.c	Sun Mar 23 01:23:32 2003
@@ -643,7 +643,8 @@
 		if (flags&MSG_PROBE)
 			goto out;
 		/* alloc skb with mtu as we do in the IPv4 stack for IPsec */
-		skb = sock_alloc_send_skb(sk, mtu, flags & MSG_DONTWAIT, &err);
+		skb = sock_alloc_send_skb(sk, mtu + LL_RESERVED_SPACE(dev),
+					  flags & MSG_DONTWAIT, &err);
 
 		if (skb == NULL) {
 			IP6_INC_STATS(Ip6OutDiscards);
diff -Nru a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
--- a/net/ipv6/ipv6_sockglue.c	Sat Feb 22 16:15:34 2003
+++ b/net/ipv6/ipv6_sockglue.c	Thu Mar 20 21:23:30 2003
@@ -47,6 +47,7 @@
 #include <net/inet_common.h>
 #include <net/tcp.h>
 #include <net/udp.h>
+#include <net/xfrm.h>
 
 #include <asm/uaccess.h>
 
@@ -358,6 +359,24 @@
 			retv = ipv6_sock_mc_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
 		break;
 	}
+	case IPV6_JOIN_ANYCAST:
+	case IPV6_LEAVE_ANYCAST:
+	{
+		struct ipv6_mreq mreq;
+
+		if (optlen != sizeof(struct ipv6_mreq))
+			goto e_inval;
+
+		retv = -EFAULT;
+		if (copy_from_user(&mreq, optval, sizeof(struct ipv6_mreq)))
+			break;
+
+		if (optname == IPV6_JOIN_ANYCAST)
+			retv = ipv6_sock_ac_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_acaddr);
+		else
+			retv = ipv6_sock_ac_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_acaddr);
+		break;
+	}
 	case IPV6_ROUTER_ALERT:
 		retv = ip6_ra_control(sk, val, NULL);
 		break;
@@ -385,6 +404,10 @@
 		break;
 	case IPV6_FLOWLABEL_MGR:
 		retv = ipv6_flowlabel_opt(sk, optval, optlen);
+		break;
+	case IPV6_IPSEC_POLICY:
+	case IPV6_XFRM_POLICY:
+		retv = xfrm_user_policy(sk, optname, optval, optlen);
 		break;
 
 #ifdef CONFIG_NETFILTER
diff -Nru a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c
--- a/net/ipv6/ipv6_syms.c	Mon Mar  3 01:02:25 2003
+++ b/net/ipv6/ipv6_syms.c	Sun Mar 23 02:21:29 2003
@@ -5,6 +5,7 @@
 #include <net/ipv6.h>
 #include <net/addrconf.h>
 #include <net/ip6_route.h>
+#include <net/xfrm.h>
 
 EXPORT_SYMBOL(ipv6_addr_type);
 EXPORT_SYMBOL(icmpv6_send);
@@ -31,3 +32,5 @@
 EXPORT_SYMBOL(ipv6_chk_addr);
 EXPORT_SYMBOL(in6addr_any);
 EXPORT_SYMBOL(in6addr_loopback);
+EXPORT_SYMBOL(xfrm6_rcv);
+EXPORT_SYMBOL(xfrm6_clear_mutable_options);
diff -Nru a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
--- a/net/ipv6/ndisc.c	Wed Mar  5 15:45:36 2003
+++ b/net/ipv6/ndisc.c	Wed Mar 19 18:12:47 2003
@@ -413,10 +413,13 @@
 		   struct in6_addr *daddr, struct in6_addr *solicited_addr,
 	 	   int router, int solicited, int override, int inc_opt) 
 {
+	static struct in6_addr tmpaddr;
+	struct inet6_ifaddr *ifp;
 	struct flowi fl;
 	struct rt6_info *rt = NULL;
 	struct dst_entry* dst;
         struct sock *sk = ndisc_socket->sk;
+	struct in6_addr *src_addr;
         struct nd_msg *msg;
         int len;
         struct sk_buff *skb;
@@ -428,7 +431,18 @@
 	if (!rt) 
 		return;
 
-	ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, solicited_addr, daddr);
+	/* for anycast or proxy, solicited_addr != src_addr */
+	ifp = ipv6_get_ifaddr(solicited_addr, dev);
+ 	if (ifp) {
+		src_addr = solicited_addr;
+		in6_ifa_put(ifp);
+	} else {
+		if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr, 0))
+			return;
+		src_addr = &tmpaddr;
+	}
+
+	ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
 	ndisc_rt_init(rt, dev, neigh);	
 
 	dst = (struct dst_entry*)rt;
@@ -456,7 +470,7 @@
 	}
 
 	skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
-	ip6_nd_hdr(sk, skb, dev, solicited_addr, daddr, IPPROTO_ICMPV6, len);
+	ip6_nd_hdr(sk, skb, dev, src_addr, daddr, IPPROTO_ICMPV6, len);
 
 	skb->h.raw = (unsigned char*) msg = (struct nd_msg *) skb_put(skb, len);
 
@@ -470,13 +484,13 @@
         msg->icmph.icmp6_override  = !!override;
 
         /* Set the target address. */
-	ipv6_addr_copy(&msg->target, solicited_addr);
+	ipv6_addr_copy(&msg->target, src_addr);
 
 	if (inc_opt)
 		ndisc_fill_option(msg->opt, ND_OPT_TARGET_LL_ADDR, dev->dev_addr, dev->addr_len);
 
 	/* checksum */
-	msg->icmph.icmp6_cksum = csum_ipv6_magic(solicited_addr, daddr, len, 
+	msg->icmph.icmp6_cksum = csum_ipv6_magic(src_addr, daddr, len, 
 						 IPPROTO_ICMPV6,
 						 csum_partial((__u8 *) msg, 
 							      len, 0));
@@ -793,6 +807,50 @@
 			}
 		}
 		in6_ifa_put(ifp);
+	} else if (ipv6_chk_acast_addr(dev, &msg->target)) {
+		struct inet6_dev *idev = in6_dev_get(dev);
+		int addr_type = ipv6_addr_type(saddr);
+	
+		/* anycast */
+	
+		if (!idev) {
+			/* XXX: count this drop? */
+			return;
+		}
+	
+		if (addr_type == IPV6_ADDR_ANY) {
+			struct in6_addr maddr;
+	
+			ipv6_addr_all_nodes(&maddr);
+			ndisc_send_na(dev, NULL, &maddr, &msg->target,
+				      idev->cnf.forwarding, 0, 0, 1);
+			in6_dev_put(idev);
+			return;
+		}
+
+		if (addr_type & IPV6_ADDR_UNICAST) {
+			int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
+			if (inc)  
+				nd_tbl.stats.rcv_probes_mcast++;
+			else
+				nd_tbl.stats.rcv_probes_ucast++;
+	
+			/*
+			 *   update / create cache entry
+			 *   for the source adddress
+			 */
+
+			neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, skb->dev);
+
+			if (neigh || !dev->hard_header) {
+				ndisc_send_na(dev, neigh, saddr,
+					      &msg->target, 
+					      idev->cnf.forwarding, 1, 0, inc);
+				if (neigh)
+					neigh_release(neigh);
+			}
+		}
+		in6_dev_put(idev);
 	} else {
 		struct inet6_dev *in6_dev = in6_dev_get(dev);
 		int addr_type = ipv6_addr_type(saddr);
diff -Nru a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
--- a/net/ipv6/netfilter/ip6_queue.c	Sun Feb 23 22:41:51 2003
+++ b/net/ipv6/netfilter/ip6_queue.c	Thu Mar 20 00:43:40 2003
@@ -558,9 +558,7 @@
 }
 
 static struct notifier_block ipq_dev_notifier = {
-	ipq_rcv_dev_event,
-	NULL,
-	0
+	.notifier_call	= ipq_rcv_dev_event,
 };
 
 static int
@@ -580,9 +578,7 @@
 }
 
 static struct notifier_block ipq_nl_notifier = {
-	ipq_rcv_nl_event,
-	NULL,
-	0
+	.notifier_call	= ipq_rcv_nl_event,
 };
 
 static int sysctl_maxlen = IPQ_QMAX_DEFAULT;
@@ -604,7 +600,6 @@
 	{
 		.ctl_name	= NET_IPV6,
 		.procname	= "ipv6",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= ipq_table
 	},
@@ -615,7 +610,6 @@
 	{
 		.ctl_name	= CTL_NET,
 		.procname	= "net",
-		.maxlen		= 0,
 		.mode		= 0555,
 		.child		= ipq_dir_table
 	},
diff -Nru a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
--- a/net/ipv6/netfilter/ip6_tables.c	Mon Mar  3 01:15:36 2003
+++ b/net/ipv6/netfilter/ip6_tables.c	Fri Mar 21 06:06:26 2003
@@ -1178,19 +1178,25 @@
 		goto free_newinfo_counters_untrans_unlock;
 	}
 
+	/* Get a reference in advance, we're not allowed fail later */
+	if (!try_module_get(t->me)) {
+		ret = -EBUSY;
+		goto free_newinfo_counters_untrans_unlock;
+	}
+
 	oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret);
 	if (!oldinfo)
-		goto free_newinfo_counters_untrans_unlock;
+		goto put_module;
 
 	/* Update module usage count based on number of rules */
 	duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n",
 		oldinfo->number, oldinfo->initial_entries, newinfo->number);
-	if (t->me && (oldinfo->number <= oldinfo->initial_entries) &&
- 	    (newinfo->number > oldinfo->initial_entries))
-		__MOD_INC_USE_COUNT(t->me);
-	else if (t->me && (oldinfo->number > oldinfo->initial_entries) &&
-	 	 (newinfo->number <= oldinfo->initial_entries))
-		__MOD_DEC_USE_COUNT(t->me);
+	if ((oldinfo->number > oldinfo->initial_entries) || 
+	    (newinfo->number <= oldinfo->initial_entries)) 
+		module_put(t->me);
+	if ((oldinfo->number > oldinfo->initial_entries) &&
+	    (newinfo->number <= oldinfo->initial_entries))
+		module_put(t->me);
 
 	/* Get the old counters. */
 	get_counters(oldinfo, counters);
@@ -1204,6 +1210,8 @@
 	up(&ip6t_mutex);
 	return 0;
 
+ put_module:
+	module_put(t->me);
  free_newinfo_counters_untrans_unlock:
 	up(&ip6t_mutex);
  free_newinfo_counters_untrans:
@@ -1735,21 +1743,42 @@
 }
 
 /* The built-in targets: standard (NULL) and error. */
-static struct ip6t_target ip6t_standard_target
-= { { NULL, NULL }, IP6T_STANDARD_TARGET, NULL, NULL, NULL };
-static struct ip6t_target ip6t_error_target
-= { { NULL, NULL }, IP6T_ERROR_TARGET, ip6t_error, NULL, NULL };
-
-static struct nf_sockopt_ops ip6t_sockopts
-= { { NULL, NULL }, PF_INET6, IP6T_BASE_CTL, IP6T_SO_SET_MAX+1, do_ip6t_set_ctl,
-    IP6T_BASE_CTL, IP6T_SO_GET_MAX+1, do_ip6t_get_ctl, 0, NULL  };
-
-static struct ip6t_match tcp_matchstruct
-= { { NULL, NULL }, "tcp", &tcp_match, &tcp_checkentry, NULL };
-static struct ip6t_match udp_matchstruct
-= { { NULL, NULL }, "udp", &udp_match, &udp_checkentry, NULL };
-static struct ip6t_match icmp6_matchstruct
-= { { NULL, NULL }, "icmp6", &icmp6_match, &icmp6_checkentry, NULL };
+static struct ip6t_target ip6t_standard_target = {
+	.name		= IP6T_STANDARD_TARGET,
+};
+
+static struct ip6t_target ip6t_error_target = {
+	.name		= IP6T_ERROR_TARGET,
+	.target		= ip6t_error,
+};
+
+static struct nf_sockopt_ops ip6t_sockopts = {
+	.pf		= PF_INET6,
+	.set_optmin	= IP6T_BASE_CTL,
+	.set_optmax	= IP6T_SO_SET_MAX+1,
+	.set		= do_ip6t_set_ctl,
+	.get_optmin	= IP6T_BASE_CTL,
+	.get_optmax	= IP6T_SO_GET_MAX+1,
+	.get		= do_ip6t_get_ctl,
+};
+
+static struct ip6t_match tcp_matchstruct = {
+	.name		= "tcp",
+	.match		= &tcp_match,
+	.checkentry	= &tcp_checkentry,
+};
+
+static struct ip6t_match udp_matchstruct = {
+	.name		= "udp",
+	.match		= &udp_match,
+	.checkentry	= &udp_checkentry,
+};
+
+static struct ip6t_match icmp6_matchstruct = {
+	.name		= "icmp6",
+	.match		= &icmp6_match,
+	.checkentry	= &icmp6_checkentry,
+};
 
 #ifdef CONFIG_PROC_FS
 static inline int print_name(const struct ip6t_table *t,
diff -Nru a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
--- a/net/ipv6/netfilter/ip6t_ah.c	Thu Mar  6 09:11:12 2003
+++ b/net/ipv6/netfilter/ip6t_ah.c	Thu Mar 20 00:49:19 2003
@@ -26,17 +26,6 @@
        __u32   spi;
 };
 
-int ipv6_ext_hdr(u8 nexthdr)
-{
-        return ( (nexthdr == NEXTHDR_HOP)       ||
-                 (nexthdr == NEXTHDR_ROUTING)   ||
-                 (nexthdr == NEXTHDR_FRAGMENT)  ||
-                 (nexthdr == NEXTHDR_AUTH)      ||
-                 (nexthdr == NEXTHDR_ESP)       ||
-                 (nexthdr == NEXTHDR_NONE)      ||
-                 (nexthdr == NEXTHDR_DEST) );
-}
-
 /* Returns 1 if the spi is matched by the range, 0 otherwise */
 static inline int
 spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
@@ -79,7 +68,7 @@
        len = skb->len - ptr;
        temp = 0;
 
-        while (ipv6_ext_hdr(nexthdr)) {
+        while (ip6t_ext_hdr(nexthdr)) {
                struct ipv6_opt_hdr *hdr;
 
               DEBUGP("ipv6_ah header iteration \n");
@@ -200,8 +189,12 @@
        return 1;
 }
 
-static struct ip6t_match ah_match
-= { { NULL, NULL }, "ah", &match, &checkentry, NULL, THIS_MODULE };
+static struct ip6t_match ah_match = {
+	.name		= "ah",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/netfilter/ip6t_dst.c b/net/ipv6/netfilter/ip6t_dst.c
--- a/net/ipv6/netfilter/ip6t_dst.c	Thu Mar  6 09:11:12 2003
+++ b/net/ipv6/netfilter/ip6t_dst.c	Thu Mar 20 00:49:19 2003
@@ -29,17 +29,6 @@
 #define DEBUGP(format, args...)
 #endif
 
-int ipv6_ext_hdr(u8 nexthdr)
-{
-        return ( (nexthdr == NEXTHDR_HOP)       ||
-                 (nexthdr == NEXTHDR_ROUTING)   ||
-                 (nexthdr == NEXTHDR_FRAGMENT)  ||
-                 (nexthdr == NEXTHDR_AUTH)      ||
-                 (nexthdr == NEXTHDR_ESP)       ||
-                 (nexthdr == NEXTHDR_NONE)      ||
-                 (nexthdr == NEXTHDR_DEST) );
-}
-
 /*
  * (Type & 0xC0) >> 6
  * 	0	-> ignorable
@@ -84,7 +73,7 @@
        len = skb->len - ptr;
        temp = 0;
 
-        while (ipv6_ext_hdr(nexthdr)) {
+        while (ip6t_ext_hdr(nexthdr)) {
                struct ipv6_opt_hdr *hdr;
 
               DEBUGP("ipv6_opts header iteration \n");
@@ -265,12 +254,15 @@
        return 1;
 }
 
-static struct ip6t_match opts_match
+static struct ip6t_match opts_match = {
 #if HOPBYHOP
-= { { NULL, NULL }, "hbh", &match, &checkentry, NULL, THIS_MODULE };
+	.name		= "hbh",
 #else
-= { { NULL, NULL }, "dst", &match, &checkentry, NULL, THIS_MODULE };
+	.name		= "dst",
 #endif
+	.match		= &match,
+	.checkentry	= &checkentry,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/netfilter/ip6t_esp.c b/net/ipv6/netfilter/ip6t_esp.c
--- a/net/ipv6/netfilter/ip6t_esp.c	Thu Mar  6 09:11:12 2003
+++ b/net/ipv6/netfilter/ip6t_esp.c	Thu Mar 20 00:49:19 2003
@@ -23,17 +23,6 @@
 	__u32   spi;
 };
 
-int ipv6_ext_hdr(u8 nexthdr)
-{
-        return ( (nexthdr == NEXTHDR_HOP)       ||
-                 (nexthdr == NEXTHDR_ROUTING)   ||
-                 (nexthdr == NEXTHDR_FRAGMENT)  ||
-                 (nexthdr == NEXTHDR_AUTH)      ||
-                 (nexthdr == NEXTHDR_ESP)       ||
-                 (nexthdr == NEXTHDR_NONE)      ||
-                 (nexthdr == NEXTHDR_DEST) );
-}
-
 /* Returns 1 if the spi is matched by the range, 0 otherwise */
 static inline int
 spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
@@ -74,7 +63,7 @@
 	len = skb->len - ptr;
 	temp = 0;
 
-        while (ipv6_ext_hdr(nexthdr)) {
+        while (ip6t_ext_hdr(nexthdr)) {
         	struct ipv6_opt_hdr *hdr;
         	int hdrlen;
 
@@ -168,8 +157,12 @@
 	return 1;
 }
 
-static struct ip6t_match esp_match
-= { { NULL, NULL }, "esp", &match, &checkentry, NULL, THIS_MODULE };
+static struct ip6t_match esp_match = {
+	.name		= "esp",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
--- a/net/ipv6/netfilter/ip6t_eui64.c	Mon Aug 19 11:48:29 2002
+++ b/net/ipv6/netfilter/ip6t_eui64.c	Thu Mar 20 00:43:40 2003
@@ -69,8 +69,12 @@
 	return 1;
 }
 
-static struct ip6t_match eui64_match
-= { { NULL, NULL }, "eui64", &match, &ip6t_eui64_checkentry, NULL, THIS_MODULE };
+static struct ip6t_match eui64_match = {
+	.name		= "eui64",
+	.match		= &match,
+	.checkentry	= &ip6t_eui64_checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
--- a/net/ipv6/netfilter/ip6t_frag.c	Thu Mar  6 09:11:12 2003
+++ b/net/ipv6/netfilter/ip6t_frag.c	Thu Mar 20 00:49:19 2003
@@ -44,17 +44,6 @@
        __u32   id;
 };
 
-int ipv6_ext_hdr(u8 nexthdr)
-{
-        return ( (nexthdr == NEXTHDR_HOP)       ||
-                 (nexthdr == NEXTHDR_ROUTING)   ||
-                 (nexthdr == NEXTHDR_FRAGMENT)  ||
-                 (nexthdr == NEXTHDR_AUTH)      ||
-                 (nexthdr == NEXTHDR_ESP)       ||
-                 (nexthdr == NEXTHDR_NONE)      ||
-                 (nexthdr == NEXTHDR_DEST) );
-}
-
 /* Returns 1 if the id is matched by the range, 0 otherwise */
 static inline int
 id_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
@@ -93,7 +82,7 @@
        len = skb->len - ptr;
        temp = 0;
 
-        while (ipv6_ext_hdr(nexthdr)) {
+        while (ip6t_ext_hdr(nexthdr)) {
                struct ipv6_opt_hdr *hdr;
 
               DEBUGP("ipv6_frag header iteration \n");
@@ -232,8 +221,12 @@
        return 1;
 }
 
-static struct ip6t_match frag_match
-= { { NULL, NULL }, "frag", &match, &checkentry, NULL, THIS_MODULE };
+static struct ip6t_match frag_match = {
+	.name		= "frag",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
--- a/net/ipv6/netfilter/ip6t_hbh.c	Thu Mar  6 09:11:12 2003
+++ b/net/ipv6/netfilter/ip6t_hbh.c	Thu Mar 20 00:49:19 2003
@@ -29,17 +29,6 @@
 #define DEBUGP(format, args...)
 #endif
 
-int ipv6_ext_hdr(u8 nexthdr)
-{
-        return ( (nexthdr == NEXTHDR_HOP)       ||
-                 (nexthdr == NEXTHDR_ROUTING)   ||
-                 (nexthdr == NEXTHDR_FRAGMENT)  ||
-                 (nexthdr == NEXTHDR_AUTH)      ||
-                 (nexthdr == NEXTHDR_ESP)       ||
-                 (nexthdr == NEXTHDR_NONE)      ||
-                 (nexthdr == NEXTHDR_DEST) );
-}
-
 /*
  * (Type & 0xC0) >> 6
  * 	0	-> ignorable
@@ -84,7 +73,7 @@
        len = skb->len - ptr;
        temp = 0;
 
-        while (ipv6_ext_hdr(nexthdr)) {
+        while (ip6t_ext_hdr(nexthdr)) {
                struct ipv6_opt_hdr *hdr;
 
               DEBUGP("ipv6_opts header iteration \n");
@@ -265,12 +254,16 @@
        return 1;
 }
 
-static struct ip6t_match opts_match
+static struct ip6t_match opts_match = {
 #if HOPBYHOP
-= { { NULL, NULL }, "hbh", &match, &checkentry, NULL, THIS_MODULE };
+	.name		= "hbh",
 #else
-= { { NULL, NULL }, "dst", &match, &checkentry, NULL, THIS_MODULE };
+	.name		= "dst",
 #endif
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/netfilter/ip6t_hl.c b/net/ipv6/netfilter/ip6t_hl.c
--- a/net/ipv6/netfilter/ip6t_hl.c	Mon Mar  3 01:40:34 2003
+++ b/net/ipv6/netfilter/ip6t_hl.c	Thu Mar 20 00:43:40 2003
@@ -56,8 +56,12 @@
 	return 1;
 }
 
-static struct ip6t_match hl_match = { { NULL, NULL }, "hl", &match,
-		&checkentry, NULL, THIS_MODULE };
+static struct ip6t_match hl_match = {
+	.name		= "hl",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c
--- a/net/ipv6/netfilter/ip6t_ipv6header.c	Thu Mar  6 09:11:12 2003
+++ b/net/ipv6/netfilter/ip6t_ipv6header.c	Thu Mar 20 00:49:19 2003
@@ -24,17 +24,6 @@
 #define DEBUGP(format, args...)
 #endif
 
-int ipv6_ext_hdr(u8 nexthdr)
-{
-        return ( (nexthdr == NEXTHDR_HOP)       ||
-                 (nexthdr == NEXTHDR_ROUTING)   ||
-                 (nexthdr == NEXTHDR_FRAGMENT)  ||
-                 (nexthdr == NEXTHDR_AUTH)      ||
-                 (nexthdr == NEXTHDR_ESP)       ||
-                 (nexthdr == NEXTHDR_NONE)      ||
-                 (nexthdr == NEXTHDR_DEST) );
-}
-
 static int
 ipv6header_match(const struct sk_buff *skb,
 		 const struct net_device *in,
@@ -95,7 +84,7 @@
 
 	temp = 0;
 
-        while (ipv6_ext_hdr(nexthdr)) {
+        while (ip6t_ext_hdr(nexthdr)) {
         	struct ipv6_opt_hdr *hdr;
         	int hdrlen;
 
@@ -196,14 +185,12 @@
 	return;
 }
 
-static struct ip6t_match
-ip6t_ipv6header_match = {
-	{ NULL, NULL },
-	"ipv6header",
-	&ipv6header_match,
-	&ipv6header_checkentry,
-	&ipv6header_destroy,
-	THIS_MODULE
+static struct ip6t_match ip6t_ipv6header_match = {
+	.name		= "ipv6header",
+	.match		= &ipv6header_match,
+	.checkentry	= &ipv6header_checkentry,
+	.destroy	= &ipv6header_destroy,
+	.me		= THIS_MODULE,
 };
 
 static int  __init ipv6header_init(void)
diff -Nru a/net/ipv6/netfilter/ip6t_length.c b/net/ipv6/netfilter/ip6t_length.c
--- a/net/ipv6/netfilter/ip6t_length.c	Mon Aug 19 11:48:29 2002
+++ b/net/ipv6/netfilter/ip6t_length.c	Thu Mar 20 00:43:40 2003
@@ -34,8 +34,12 @@
 	return 1;
 }
 
-static struct ip6t_match length_match
-= { { NULL, NULL }, "length", &match, &checkentry, NULL, THIS_MODULE };
+static struct ip6t_match length_match = {
+	.name		= "length",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/netfilter/ip6t_limit.c b/net/ipv6/netfilter/ip6t_limit.c
--- a/net/ipv6/netfilter/ip6t_limit.c	Mon Feb  4 23:54:00 2002
+++ b/net/ipv6/netfilter/ip6t_limit.c	Thu Mar 20 00:43:40 2003
@@ -115,9 +115,12 @@
 	return 1;
 }
 
-static struct ip6t_match ip6t_limit_reg
-= { { NULL, NULL }, "limit", ip6t_limit_match, ip6t_limit_checkentry, NULL,
-    THIS_MODULE };
+static struct ip6t_match ip6t_limit_reg = {
+	.name		= "limit",
+	.match		= ip6t_limit_match,
+	.checkentry	= ip6t_limit_checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/netfilter/ip6t_mac.c b/net/ipv6/netfilter/ip6t_mac.c
--- a/net/ipv6/netfilter/ip6t_mac.c	Wed Apr 10 21:49:23 2002
+++ b/net/ipv6/netfilter/ip6t_mac.c	Thu Mar 20 00:43:40 2003
@@ -47,8 +47,12 @@
 	return 1;
 }
 
-static struct ip6t_match mac_match
-= { { NULL, NULL }, "mac", &match, &ip6t_mac_checkentry, NULL, THIS_MODULE };
+static struct ip6t_match mac_match = {
+	.name		= "mac",
+	.match		= &match,
+	.checkentry	= &ip6t_mac_checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/netfilter/ip6t_mark.c b/net/ipv6/netfilter/ip6t_mark.c
--- a/net/ipv6/netfilter/ip6t_mark.c	Mon Feb  4 23:49:27 2002
+++ b/net/ipv6/netfilter/ip6t_mark.c	Thu Mar 20 00:43:40 2003
@@ -33,8 +33,12 @@
 	return 1;
 }
 
-static struct ip6t_match mark_match
-= { { NULL, NULL }, "mark", &match, &checkentry, NULL, THIS_MODULE };
+static struct ip6t_match mark_match = {
+	.name		= "mark",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/netfilter/ip6t_multiport.c b/net/ipv6/netfilter/ip6t_multiport.c
--- a/net/ipv6/netfilter/ip6t_multiport.c	Mon Feb  4 23:54:00 2002
+++ b/net/ipv6/netfilter/ip6t_multiport.c	Thu Mar 20 00:43:40 2003
@@ -84,8 +84,12 @@
 		&& multiinfo->count <= IP6T_MULTI_PORTS;
 }
 
-static struct ip6t_match multiport_match
-= { { NULL, NULL }, "multiport", &match, &checkentry, NULL, THIS_MODULE };
+static struct ip6t_match multiport_match = {
+	.name		= "multiport",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
--- a/net/ipv6/netfilter/ip6t_owner.c	Sat Sep 14 06:17:21 2002
+++ b/net/ipv6/netfilter/ip6t_owner.c	Thu Mar 20 00:43:40 2003
@@ -142,8 +142,12 @@
 	return 1;
 }
 
-static struct ip6t_match owner_match
-= { { NULL, NULL }, "owner", &match, &checkentry, NULL, THIS_MODULE };
+static struct ip6t_match owner_match = {
+	.name		= "owner",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
--- a/net/ipv6/netfilter/ip6t_rt.c	Thu Mar  6 09:11:12 2003
+++ b/net/ipv6/netfilter/ip6t_rt.c	Thu Mar 20 00:49:19 2003
@@ -21,17 +21,6 @@
 #define DEBUGP(format, args...)
 #endif
 
-int ipv6_ext_hdr(u8 nexthdr)
-{
-        return ( (nexthdr == NEXTHDR_HOP)       ||
-                 (nexthdr == NEXTHDR_ROUTING)   ||
-                 (nexthdr == NEXTHDR_FRAGMENT)  ||
-                 (nexthdr == NEXTHDR_AUTH)      ||
-                 (nexthdr == NEXTHDR_ESP)       ||
-                 (nexthdr == NEXTHDR_NONE)      ||
-                 (nexthdr == NEXTHDR_DEST) );
-}
-
 /* Returns 1 if the id is matched by the range, 0 otherwise */
 static inline int
 segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
@@ -71,7 +60,7 @@
        len = skb->len - ptr;
        temp = 0;
 
-        while (ipv6_ext_hdr(nexthdr)) {
+        while (ip6t_ext_hdr(nexthdr)) {
                struct ipv6_opt_hdr *hdr;
 
               DEBUGP("ipv6_rt header iteration \n");
@@ -287,8 +276,12 @@
        return 1;
 }
 
-static struct ip6t_match rt_match
-= { { NULL, NULL }, "rt", &match, &checkentry, NULL, THIS_MODULE };
+static struct ip6t_match rt_match = {
+	.name		= "rt",
+	.match		= &match,
+	.checkentry	= &checkentry,
+	.me		= THIS_MODULE,
+};
 
 static int __init init(void)
 {
diff -Nru a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
--- a/net/ipv6/reassembly.c	Tue Feb 18 20:15:07 2003
+++ b/net/ipv6/reassembly.c	Sun Mar 23 21:30:34 2003
@@ -23,6 +23,7 @@
  *      Horst von Brand Add missing #include <linux/string.h>
  *	Alexey Kuznetsov	SMP races, threading, cleanup.
  *	Patrick McHardy		LRU queue of frag heads for evictor.
+ *	Mitsuru KANDA @USAGI	Register inet6_protocol{}.
  */
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -525,6 +526,7 @@
 	int    remove_fraghdr = 0;
 	int    payload_len;
 	int    nhoff;
+	u8     nexthdr = 0;
 
 	fq_kill(fq);
 
@@ -535,6 +537,8 @@
 	payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len;
 	nhoff = head->h.raw - head->nh.raw;
 
+	nexthdr = ((struct frag_hdr*)head->h.raw)->nexthdr;
+
 	if (payload_len > 65535) {
 		payload_len -= 8;
 		if (payload_len > 65535)
@@ -609,9 +613,12 @@
 	if (head->ip_summed == CHECKSUM_HW)
 		head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
 
+	if (!pskb_pull(head, head->h.raw - head->data))
+		goto out_fail;
+
 	IP6_INC_STATS_BH(Ip6ReasmOKs);
 	fq->fragments = NULL;
-	return nhoff;
+	return nexthdr;
 
 out_oversize:
 	if (net_ratelimit())
@@ -622,16 +629,18 @@
 		printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n");
 out_fail:
 	IP6_INC_STATS_BH(Ip6ReasmFails);
-	return -1;
+	return 0;
 }
 
-int ipv6_reassembly(struct sk_buff **skbp, int nhoff)
+static int ipv6_frag_rcv(struct sk_buff **skbp)
 {
 	struct sk_buff *skb = *skbp; 
 	struct net_device *dev = skb->dev;
 	struct frag_hdr *fhdr;
 	struct frag_queue *fq;
 	struct ipv6hdr *hdr;
+	int nhoff = skb->h.raw - skb->nh.raw;
+	u8 nexthdr = 0;
 
 	hdr = skb->nh.ipv6h;
 
@@ -640,15 +649,16 @@
 	/* Jumbo payload inhibits frag. header */
 	if (hdr->payload_len==0) {
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
-		return -1;
+		goto discard;
 	}
 	if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+sizeof(struct frag_hdr))) {
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
-		return -1;
+		goto discard;
 	}
 
 	hdr = skb->nh.ipv6h;
 	fhdr = (struct frag_hdr *)skb->h.raw;
+	nexthdr = fhdr->nexthdr;
 
 	if (!(fhdr->frag_off & htons(0xFFF9))) {
 		/* It is not a fragmented frame */
@@ -674,10 +684,22 @@
 
 		spin_unlock(&fq->lock);
 		fq_put(fq);
-		return ret;
+		return -ret;
 	}
 
+discard:
 	IP6_INC_STATS_BH(Ip6ReasmFails);
 	kfree_skb(skb);
-	return -1;
+	return 0;
+}
+
+static struct inet6_protocol frag_protocol =
+{
+	.handler	=	ipv6_frag_rcv,
+};
+
+void __init ipv6_frag_init(void)
+{
+	if (inet6_add_protocol(&frag_protocol, IPPROTO_FRAGMENT) < 0)
+		printk(KERN_ERR "ipv6_frag_init: Could not register protocol\n");
 }
diff -Nru a/net/ipv6/route.c b/net/ipv6/route.c
--- a/net/ipv6/route.c	Wed Mar  5 15:45:36 2003
+++ b/net/ipv6/route.c	Sun Mar 23 02:21:29 2003
@@ -1867,15 +1867,6 @@
 
 #endif
 
-int xfrm6_dst_lookup(struct xfrm_dst **dst, struct flowi *fl)
-{
-	int err = 0;
-	*dst = (struct xfrm_dst*)ip6_route_output(NULL, fl);
-	if (!*dst)
-		err = -ENETUNREACH;
-	return err;
-}
-
 void __init ip6_route_init(void)
 {
 	ip6_dst_ops.kmem_cachep = kmem_cache_create("ip6_dst_cache",
@@ -1883,11 +1874,11 @@
 						     0, SLAB_HWCACHE_ALIGN,
 						     NULL, NULL);
 	fib6_init();
-	xfrm_dst_lookup_register(xfrm6_dst_lookup, AF_INET6);
 #ifdef 	CONFIG_PROC_FS
 	proc_net_create("ipv6_route", 0, rt6_proc_info);
 	proc_net_create("rt6_stats", 0, rt6_proc_stats);
 #endif
+	xfrm6_init();
 }
 
 #ifdef MODULE
@@ -1897,7 +1888,7 @@
 	proc_net_remove("ipv6_route");
 	proc_net_remove("rt6_stats");
 #endif
-	xfrm_dst_lookup_unregister(AF_INET6);
+	xfrm6_fini();
 	rt6_ifdown(NULL);
 	fib6_gc_cleanup();
 }
diff -Nru a/net/ipv6/sit.c b/net/ipv6/sit.c
--- a/net/ipv6/sit.c	Mon Mar  3 01:47:43 2003
+++ b/net/ipv6/sit.c	Wed Mar 19 21:17:02 2003
@@ -181,7 +181,6 @@
 	nt = (struct ip_tunnel*)dev->priv;
 	nt->dev = dev;
 	dev->init = ipip6_tunnel_init;
-	dev->features |= NETIF_F_DYNALLOC;
 	memcpy(&nt->parms, parms, sizeof(*parms));
 	nt->parms.name[IFNAMSIZ-1] = '\0';
 	strcpy(dev->name, nt->parms.name);
@@ -213,6 +212,7 @@
 static void ipip6_tunnel_destructor(struct net_device *dev)
 {
 	if (dev != &ipip6_fb_tunnel_dev) {
+		kfree(dev);
 		MOD_DEC_USE_COUNT;
 	}
 }
@@ -552,7 +552,7 @@
 	/*
 	 * Okay, now see if we can stuff it in the buffer as-is.
 	 */
-	max_headroom = (((tdev->hard_header_len+15)&~15)+sizeof(struct iphdr));
+	max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr);
 
 	if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
 		struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
--- a/net/ipv6/tcp_ipv6.c	Wed Mar  5 15:45:36 2003
+++ b/net/ipv6/tcp_ipv6.c	Sun Mar 23 21:30:34 2003
@@ -967,7 +967,7 @@
 	struct ipv6_pinfo *np = inet6_sk(sk);
 
 	if (skb->ip_summed == CHECKSUM_HW) {
-		th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP,  0);
+		th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP,  0);
 		skb->csum = offsetof(struct tcphdr, check);
 	} else {
 		th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 
@@ -1591,8 +1591,9 @@
 	return 0;
 }
 
-static int tcp_v6_rcv(struct sk_buff *skb)
+static int tcp_v6_rcv(struct sk_buff **pskb)
 {
+	struct sk_buff *skb = *pskb;
 	struct tcphdr *th;	
 	struct sock *sk;
 	int ret;
@@ -1642,7 +1643,7 @@
 		goto discard_and_relse;
 
 	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
-		goto discard_it;
+		goto discard_and_relse;
 
 	skb->dev = NULL;
 
diff -Nru a/net/ipv6/udp.c b/net/ipv6/udp.c
--- a/net/ipv6/udp.c	Wed Mar  5 15:45:36 2003
+++ b/net/ipv6/udp.c	Sun Mar 23 21:30:34 2003
@@ -641,8 +641,9 @@
 	read_unlock(&udp_hash_lock);
 }
 
-static int udpv6_rcv(struct sk_buff *skb)
+static int udpv6_rcv(struct sk_buff **pskb)
 {
+	struct sk_buff *skb = *pskb;
 	struct sock *sk;
   	struct udphdr *uh;
 	struct net_device *dev = skb->dev;
diff -Nru a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv6/xfrm6_input.c	Sun Mar 23 21:30:34 2003
@@ -0,0 +1,262 @@
+/*
+ * xfrm6_input.c: based on net/ipv4/xfrm4_input.c
+ *
+ * Authors:
+ *	Mitsuru KANDA @USAGI
+ * 	Kazunori MIYAZAWA @USAGI
+ * 	Kunihiro Ishiguro
+ *	YOSHIFUJI Hideaki @USAGI
+ *		IPv6 support
+ */
+
+#include <net/ip.h>
+#include <net/ipv6.h>
+#include <net/xfrm.h>
+
+static kmem_cache_t *secpath_cachep;
+
+static int zero_out_mutable_opts(struct ipv6_opt_hdr *opthdr)
+{
+	u8 *opt = (u8 *)opthdr;
+	int len = ipv6_optlen(opthdr);
+	int off = 0;
+	int optlen = 0;
+
+	off += 2;
+	len -= 2;
+
+	while (len > 0) {
+
+		switch (opt[off]) {
+
+		case IPV6_TLV_PAD0:
+			optlen = 1;
+			break;
+		default:
+			if (len < 2) 
+				goto bad;
+			optlen = opt[off+1]+2;
+			if (len < optlen)
+				goto bad;
+			if (opt[off] & 0x20)
+				memset(&opt[off+2], 0, opt[off+1]);
+			break;
+		}
+
+		off += optlen;
+		len -= optlen;
+	}
+	if (len == 0)
+		return 1;
+
+bad:
+	return 0;
+}
+
+int xfrm6_clear_mutable_options(struct sk_buff *skb, u16 *nh_offset, int dir)
+{
+	u16 offset = sizeof(struct ipv6hdr);
+	struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+	unsigned int packet_len = skb->tail - skb->nh.raw;
+	u8 nexthdr = skb->nh.ipv6h->nexthdr;
+	u8 nextnexthdr = 0;
+
+	*nh_offset = ((unsigned char *)&skb->nh.ipv6h->nexthdr) - skb->nh.raw;
+
+	while (offset + 1 <= packet_len) {
+
+		switch (nexthdr) {
+
+		case NEXTHDR_HOP:
+			*nh_offset = offset;
+			offset += ipv6_optlen(exthdr);
+			if (!zero_out_mutable_opts(exthdr)) {
+				if (net_ratelimit())
+					printk(KERN_WARNING "overrun hopopts\n"); 
+				return 0;
+			}
+			nexthdr = exthdr->nexthdr;
+			exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+			break;
+
+		case NEXTHDR_ROUTING:
+			*nh_offset = offset;
+			offset += ipv6_optlen(exthdr);
+			((struct ipv6_rt_hdr*)exthdr)->segments_left = 0; 
+			nexthdr = exthdr->nexthdr;
+			exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+			break;
+
+		case NEXTHDR_DEST:
+			*nh_offset = offset;
+			offset += ipv6_optlen(exthdr);
+			if (!zero_out_mutable_opts(exthdr))  {
+				if (net_ratelimit())
+					printk(KERN_WARNING "overrun destopt\n"); 
+				return 0;
+			}
+			nexthdr = exthdr->nexthdr;
+			exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+			break;
+
+		case NEXTHDR_AUTH:
+			if (dir == XFRM_POLICY_OUT) {
+				memset(((struct ipv6_auth_hdr*)exthdr)->auth_data, 0, 
+				       (((struct ipv6_auth_hdr*)exthdr)->hdrlen - 1) << 2);
+			}
+			if (exthdr->nexthdr == NEXTHDR_DEST) {
+				offset += (((struct ipv6_auth_hdr*)exthdr)->hdrlen + 2) << 2;
+				exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+				nextnexthdr = exthdr->nexthdr;
+				if (!zero_out_mutable_opts(exthdr)) {
+					if (net_ratelimit())
+						printk(KERN_WARNING "overrun destopt\n");
+					return 0;
+				}
+			}
+			return nexthdr;
+		default :
+			return nexthdr;
+		}
+	}
+
+	return nexthdr;
+}
+
+int xfrm6_rcv(struct sk_buff **pskb)
+{
+	struct sk_buff *skb = *pskb;
+	int err;
+	u32 spi, seq;
+	struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
+	struct xfrm_state *x;
+	int xfrm_nr = 0;
+	int decaps = 0;
+	struct ipv6hdr *hdr = skb->nh.ipv6h;
+	unsigned char *tmp_hdr = NULL;
+	int hdr_len = 0;
+	u16 nh_offset = 0;
+	u8 nexthdr = 0;
+
+	nh_offset = ((unsigned char*)&skb->nh.ipv6h->nexthdr) - skb->nh.raw;
+	hdr_len = sizeof(struct ipv6hdr);
+
+	tmp_hdr = kmalloc(hdr_len, GFP_ATOMIC);
+	if (!tmp_hdr)
+		goto drop;
+	memcpy(tmp_hdr, skb->nh.raw, hdr_len);
+
+	nexthdr = xfrm6_clear_mutable_options(skb, &nh_offset, XFRM_POLICY_IN);
+	hdr->priority    = 0;
+	hdr->flow_lbl[0] = 0;
+	hdr->flow_lbl[1] = 0;
+	hdr->flow_lbl[2] = 0;
+	hdr->hop_limit   = 0;
+
+	if ((err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
+		goto drop;
+	
+	do {
+		struct ipv6hdr *iph = skb->nh.ipv6h;
+
+		if (xfrm_nr == XFRM_MAX_DEPTH)
+			goto drop;
+
+		x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, nexthdr, AF_INET6);
+		if (x == NULL)
+			goto drop;
+		spin_lock(&x->lock);
+		if (unlikely(x->km.state != XFRM_STATE_VALID))
+			goto drop_unlock;
+
+		if (x->props.replay_window && xfrm_replay_check(x, seq))
+			goto drop_unlock;
+
+		nexthdr = x->type->input(x, skb);
+		if (nexthdr <= 0)
+			goto drop_unlock;
+
+		if (x->props.replay_window)
+			xfrm_replay_advance(x, seq);
+
+		x->curlft.bytes += skb->len;
+		x->curlft.packets++;
+
+		spin_unlock(&x->lock);
+
+		xfrm_vec[xfrm_nr++] = x;
+
+		if (x->props.mode) { /* XXX */
+			if (iph->nexthdr != IPPROTO_IPV6)
+				goto drop;
+			skb->nh.raw = skb->data;
+			iph = skb->nh.ipv6h;
+			decaps = 1;
+			break;
+		}
+
+		if ((err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) < 0)
+			goto drop;
+	} while (!err);
+
+	memcpy(skb->nh.raw, tmp_hdr, hdr_len);
+	skb->nh.raw[nh_offset] = nexthdr;
+	skb->nh.ipv6h->payload_len = htons(hdr_len + skb->len - sizeof(struct ipv6hdr));
+
+	/* Allocate new secpath or COW existing one. */
+	if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
+		kmem_cache_t *pool = skb->sp ? skb->sp->pool : secpath_cachep;
+		struct sec_path *sp;
+		sp = kmem_cache_alloc(pool, SLAB_ATOMIC);
+		if (!sp)
+			goto drop;
+		if (skb->sp) {
+			memcpy(sp, skb->sp, sizeof(struct sec_path));
+			secpath_put(skb->sp);
+		} else {
+			sp->pool = pool;
+			sp->len = 0;
+		}
+		atomic_set(&sp->refcnt, 1);
+		skb->sp = sp;
+	}
+
+	if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
+		goto drop;
+
+	memcpy(skb->sp->xvec+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(void*));
+	skb->sp->len += xfrm_nr;
+
+	if (decaps) {
+		if (!(skb->dev->flags&IFF_LOOPBACK)) {
+			dst_release(skb->dst);
+			skb->dst = NULL;
+		}
+		netif_rx(skb);
+		return 0;
+	} else {
+		return -nexthdr;
+	}
+
+drop_unlock:
+	spin_unlock(&x->lock);
+	xfrm_state_put(x);
+drop:
+	if (tmp_hdr) kfree(tmp_hdr);
+	while (--xfrm_nr >= 0)
+		xfrm_state_put(xfrm_vec[xfrm_nr]);
+	kfree_skb(skb);
+	return 0;
+}
+
+void __init xfrm6_input_init(void)
+{
+	secpath_cachep = kmem_cache_create("secpath6_cache",
+					   sizeof(struct sec_path),
+					   0, SLAB_HWCACHE_ALIGN,
+					   NULL, NULL);
+
+	if (!secpath_cachep)
+		panic("IPv6: failed to allocate secpath6_cache\n");
+}
+
diff -Nru a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv6/xfrm6_policy.c	Sun Mar 23 02:21:03 2003
@@ -0,0 +1,273 @@
+/*
+ * xfrm6_policy.c: based on xfrm4_policy.c
+ *
+ * Authors:
+ *	Mitsuru KANDA @USAGI
+ * 	Kazunori MIYAZAWA @USAGI
+ * 	Kunihiro Ishiguro
+ * 		IPv6 support
+ * 	YOSHIFUJI Hideaki
+ * 		Split up af-specific portion
+ * 
+ */
+
+#include <linux/config.h>
+#include <net/xfrm.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+#include <net/ip6_route.h>
+
+extern struct dst_ops xfrm6_dst_ops;
+extern struct xfrm_policy_afinfo xfrm6_policy_afinfo;
+
+static struct xfrm_type_map xfrm6_type_map = { .lock = RW_LOCK_UNLOCKED };
+
+int xfrm6_dst_lookup(struct xfrm_dst **dst, struct flowi *fl)
+{
+	int err = 0;
+	*dst = (struct xfrm_dst*)ip6_route_output(NULL, fl);
+	if (!*dst)
+		err = -ENETUNREACH;
+	return err;
+}
+
+/* Check that the bundle accepts the flow and its components are
+ * still valid.
+ */
+
+static int __xfrm6_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl)
+{
+	do {
+		if (xdst->u.dst.ops != &xfrm6_dst_ops)
+			return 1;
+
+		if (!xfrm_selector_match(&xdst->u.dst.xfrm->sel, fl, AF_INET6))
+			return 0;
+		if (xdst->u.dst.xfrm->km.state != XFRM_STATE_VALID ||
+		    xdst->u.dst.path->obsolete > 0)
+			return 0;
+		xdst = (struct xfrm_dst*)xdst->u.dst.child;
+	} while (xdst);
+	return 0;
+}
+
+static struct dst_entry *
+__xfrm6_find_bundle(struct flowi *fl, struct rtable *rt, struct xfrm_policy *policy)
+{
+	struct dst_entry *dst;
+
+	/* Still not clear if we should set fl->fl6_{src,dst}... */
+	read_lock_bh(&policy->lock);
+	for (dst = policy->bundles; dst; dst = dst->next) {
+		struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
+		if (!ipv6_addr_cmp(&xdst->u.rt6.rt6i_dst.addr, fl->fl6_dst) &&
+		    !ipv6_addr_cmp(&xdst->u.rt6.rt6i_src.addr, fl->fl6_src) &&
+		    __xfrm6_bundle_ok(xdst, fl)) {
+			dst_clone(dst);
+			break;
+		}
+	}
+	read_unlock_bh(&policy->lock);
+	return dst;
+}
+
+/* Allocate chain of dst_entry's, attach known xfrm's, calculate
+ * all the metrics... Shortly, bundle a bundle.
+ */
+
+static int
+__xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
+		      struct flowi *fl, struct dst_entry **dst_p)
+{
+	struct dst_entry *dst, *dst_prev;
+	struct rt6_info *rt0 = (struct rt6_info*)(*dst_p);
+	struct rt6_info *rt  = rt0;
+	struct in6_addr *remote = fl->fl6_dst;
+	struct in6_addr *local  = fl->fl6_src;
+	int i;
+	int err = 0;
+	int header_len = 0;
+	int trailer_len = 0;
+
+	dst = dst_prev = NULL;
+
+	for (i = 0; i < nx; i++) {
+		struct dst_entry *dst1 = dst_alloc(&xfrm6_dst_ops);
+
+		if (unlikely(dst1 == NULL)) {
+			err = -ENOBUFS;
+			goto error;
+		}
+
+		dst1->xfrm = xfrm[i];
+		if (!dst)
+			dst = dst1;
+		else {
+			dst_prev->child = dst1;
+			dst1->flags |= DST_NOHASH;
+			dst_clone(dst1);
+		}
+		dst_prev = dst1;
+		if (xfrm[i]->props.mode) {
+			remote = (struct in6_addr*)&xfrm[i]->id.daddr;
+			local  = (struct in6_addr*)&xfrm[i]->props.saddr;
+		}
+		header_len += xfrm[i]->props.header_len;
+		trailer_len += xfrm[i]->props.trailer_len;
+	}
+
+	if (ipv6_addr_cmp(remote, fl->fl6_dst)) {
+		struct flowi fl_tunnel = { .nl_u = { .ip6_u =
+						     { .daddr = remote,
+						       .saddr = local }
+					           }
+				         };
+		err = xfrm_dst_lookup((struct xfrm_dst**)&rt, &fl_tunnel, AF_INET6);
+		if (err)
+			goto error;
+	} else {
+		dst_hold(&rt->u.dst);
+	}
+	dst_prev->child = &rt->u.dst;
+	for (dst_prev = dst; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
+		struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
+		x->u.rt.fl = *fl;
+
+		dst_prev->dev = rt->u.dst.dev;
+		if (rt->u.dst.dev)
+			dev_hold(rt->u.dst.dev);
+		dst_prev->obsolete	= -1;
+		dst_prev->flags	       |= DST_HOST;
+		dst_prev->lastuse	= jiffies;
+		dst_prev->header_len	= header_len;
+		dst_prev->trailer_len	= trailer_len;
+		memcpy(&dst_prev->metrics, &rt->u.dst.metrics, sizeof(dst_prev->metrics));
+		dst_prev->path		= &rt->u.dst;
+
+		/* Copy neighbout for reachability confirmation */
+		dst_prev->neighbour	= neigh_clone(rt->u.dst.neighbour);
+		dst_prev->input		= rt->u.dst.input;
+		dst_prev->output	= dst_prev->xfrm->type->output;
+		/* Sheit... I remember I did this right. Apparently,
+		 * it was magically lost, so this code needs audit */
+		x->u.rt6.rt6i_flags    = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
+		x->u.rt6.rt6i_metric   = rt0->rt6i_metric;
+		x->u.rt6.rt6i_node     = rt0->rt6i_node;
+		x->u.rt6.rt6i_hoplimit = rt0->rt6i_hoplimit;
+		x->u.rt6.rt6i_gateway  = rt0->rt6i_gateway;
+		memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway)); 
+		header_len -= x->u.dst.xfrm->props.header_len;
+		trailer_len -= x->u.dst.xfrm->props.trailer_len;
+	}
+	*dst_p = dst;
+	return 0;
+
+error:
+	if (dst)
+		dst_free(dst);
+	return err;
+}
+
+static inline void
+_decode_session6(struct sk_buff *skb, struct flowi *fl)
+{
+	u16 offset = sizeof(struct ipv6hdr);
+	struct ipv6hdr *hdr = skb->nh.ipv6h;
+	struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+	u8 nexthdr = skb->nh.ipv6h->nexthdr;
+
+	fl->fl6_dst = &hdr->daddr;
+	fl->fl6_src = &hdr->saddr;
+
+	while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) {
+		switch (nexthdr) {
+		case NEXTHDR_ROUTING:
+		case NEXTHDR_HOP:
+		case NEXTHDR_DEST:
+			offset += ipv6_optlen(exthdr);
+			nexthdr = exthdr->nexthdr;
+			exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+			break;
+
+		case IPPROTO_UDP:
+		case IPPROTO_TCP:
+		case IPPROTO_SCTP:
+			if (pskb_may_pull(skb, skb->nh.raw + offset + 4 - skb->data)) {
+				u16 *ports = (u16 *)exthdr;
+
+				fl->uli_u.ports.sport = ports[0];
+				fl->uli_u.ports.dport = ports[1];
+			}
+			return;
+
+		/* XXX Why are there these headers? */
+		case IPPROTO_AH:
+		case IPPROTO_ESP:
+		default:
+			fl->uli_u.spi = 0;
+			return;
+		};
+	}
+}
+
+static inline int xfrm6_garbage_collect(void)
+{
+	read_lock(&xfrm6_policy_afinfo.lock);
+	xfrm6_policy_afinfo.garbage_collect();
+	read_unlock(&xfrm6_policy_afinfo.lock);
+	return (atomic_read(&xfrm6_dst_ops.entries) > xfrm6_dst_ops.gc_thresh*2);
+}
+
+static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu)
+{
+	struct dst_entry *path = dst->path;
+
+	if (mtu >= 1280 && mtu < dst_pmtu(dst))
+		return;
+
+	path->ops->update_pmtu(path, mtu);
+}
+
+struct dst_ops xfrm6_dst_ops = {
+	.family =		AF_INET6,
+	.protocol =		__constant_htons(ETH_P_IPV6),
+	.gc =			xfrm6_garbage_collect,
+	.update_pmtu =		xfrm6_update_pmtu,
+	.gc_thresh =		1024,
+	.entry_size =		sizeof(struct xfrm_dst),
+};
+
+struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
+	.family =		AF_INET6,
+	.lock = 		RW_LOCK_UNLOCKED,
+	.type_map = 		&xfrm6_type_map,
+	.dst_ops =		&xfrm6_dst_ops,
+	.dst_lookup =		xfrm6_dst_lookup,
+	.find_bundle =		__xfrm6_find_bundle,
+	.bundle_create =	__xfrm6_bundle_create,
+	.decode_session =	_decode_session6,
+};
+
+void __init xfrm6_policy_init(void)
+{
+	xfrm_policy_register_afinfo(&xfrm6_policy_afinfo);
+}
+
+void __exit xfrm6_policy_fini(void)
+{
+	xfrm_policy_unregister_afinfo(&xfrm6_policy_afinfo);
+}
+
+void __init xfrm6_init(void)
+{
+	xfrm6_policy_init();
+	xfrm6_state_init();
+	xfrm6_input_init();
+}
+
+void __exit xfrm6_fini(void)
+{
+	//xfrm6_input_fini();
+	xfrm6_policy_fini();
+	xfrm6_state_fini();
+}
diff -Nru a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv6/xfrm6_state.c	Sun Mar 23 02:21:03 2003
@@ -0,0 +1,134 @@
+/*
+ * xfrm6_state.c: based on xfrm4_state.c
+ *
+ * Authors:
+ *	Mitsuru KANDA @USAGI
+ * 	Kazunori MIYAZAWA @USAGI
+ * 	Kunihiro Ishiguro
+ * 		IPv6 support
+ * 	YOSHIFUJI Hideaki @USAGI
+ * 		Split up af-specific portion
+ * 	
+ */
+
+#include <net/xfrm.h>
+#include <linux/pfkeyv2.h>
+#include <linux/ipsec.h>
+#include <net/ipv6.h>
+
+extern struct xfrm_state_afinfo xfrm6_state_afinfo;
+
+static void
+__xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl,
+		     struct xfrm_tmpl *tmpl,
+		     xfrm_address_t *daddr, xfrm_address_t *saddr)
+{
+	/* Initialize temporary selector matching only
+	 * to current session. */
+	memcpy(&x->sel.daddr, fl->fl6_dst, sizeof(struct in6_addr));
+	memcpy(&x->sel.saddr, fl->fl6_src, sizeof(struct in6_addr));
+	x->sel.dport = fl->uli_u.ports.dport;
+	x->sel.dport_mask = ~0;
+	x->sel.sport = fl->uli_u.ports.sport;
+	x->sel.sport_mask = ~0;
+	x->sel.prefixlen_d = 128;
+	x->sel.prefixlen_s = 128;
+	x->sel.proto = fl->proto;
+	x->sel.ifindex = fl->oif;
+	x->id = tmpl->id;
+	if (ipv6_addr_any((struct in6_addr*)&x->id.daddr))
+		memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr));
+	memcpy(&x->props.saddr, &tmpl->saddr, sizeof(x->props.saddr));
+	if (ipv6_addr_any((struct in6_addr*)&x->props.saddr))
+		memcpy(&x->props.saddr, saddr, sizeof(x->props.saddr));
+	x->props.mode = tmpl->mode;
+	x->props.reqid = tmpl->reqid;
+	x->props.family = AF_INET6;
+}
+
+static struct xfrm_state *
+__xfrm6_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto)
+{
+	unsigned h = __xfrm6_spi_hash(daddr, spi, proto);
+	struct xfrm_state *x;
+
+	list_for_each_entry(x, xfrm6_state_afinfo.state_byspi+h, byspi) {
+		if (x->props.family == AF_INET6 &&
+		    spi == x->id.spi &&
+		    !ipv6_addr_cmp((struct in6_addr *)daddr, (struct in6_addr *)x->id.daddr.a6) &&
+		    proto == x->id.proto) {
+			atomic_inc(&x->refcnt);
+			return x;
+		}
+	}
+	return NULL;
+}
+
+static struct xfrm_state *
+__xfrm6_find_acq(u8 mode, u16 reqid, u8 proto, 
+		 xfrm_address_t *daddr, xfrm_address_t *saddr, 
+		 int create)
+{
+	struct xfrm_state *x, *x0;
+	unsigned h = __xfrm6_dst_hash(daddr);
+
+	x0 = NULL;
+
+	list_for_each_entry(x, xfrm6_state_afinfo.state_bydst+h, bydst) {
+		if (x->props.family == AF_INET6 &&
+		    !ipv6_addr_cmp((struct in6_addr *)daddr, (struct in6_addr *)x->id.daddr.a6) &&
+		    mode == x->props.mode &&
+		    proto == x->id.proto &&
+		    !ipv6_addr_cmp((struct in6_addr *)saddr, (struct in6_addr *)x->props.saddr.a6) &&
+		    reqid == x->props.reqid &&
+		    x->km.state == XFRM_STATE_ACQ) {
+			    if (!x0)
+				    x0 = x;
+			    if (x->id.spi)
+				    continue;
+			    x0 = x;
+			    break;
+		    }
+	}
+	if (x0) {
+		atomic_inc(&x0->refcnt);
+	} else if (create && (x0 = xfrm_state_alloc()) != NULL) {
+		memcpy(x0->sel.daddr.a6, daddr, sizeof(struct in6_addr));
+		memcpy(x0->sel.saddr.a6, saddr, sizeof(struct in6_addr));
+		x0->sel.prefixlen_d = 128;
+		x0->sel.prefixlen_s = 128;
+		memcpy(x0->props.saddr.a6, saddr, sizeof(struct in6_addr));
+		x0->km.state = XFRM_STATE_ACQ;
+		memcpy(x0->id.daddr.a6, daddr, sizeof(struct in6_addr));
+		x0->id.proto = proto;
+		x0->props.family = AF_INET6;
+		x0->props.mode = mode;
+		x0->props.reqid = reqid;
+		x0->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
+		atomic_inc(&x0->refcnt);
+		mod_timer(&x0->timer, jiffies + XFRM_ACQ_EXPIRES*HZ);
+		atomic_inc(&x0->refcnt);
+		list_add_tail(&x0->bydst, xfrm6_state_afinfo.state_bydst+h);
+		wake_up(&km_waitq);
+	}
+	return x0;
+}
+
+static struct xfrm_state_afinfo xfrm6_state_afinfo = {
+	.family			= AF_INET6,
+	.lock			= RW_LOCK_UNLOCKED,
+	.init_tempsel		= __xfrm6_init_tempsel,
+	.state_lookup		= __xfrm6_state_lookup,
+	.find_acq		= __xfrm6_find_acq,
+};
+
+void __init xfrm6_state_init(void)
+{
+	xfrm_state_register_afinfo(&xfrm6_state_afinfo);
+}
+
+void __exit xfrm6_state_fini(void)
+{
+	xfrm_state_unregister_afinfo(&xfrm6_state_afinfo);
+}
+
diff -Nru a/net/irda/irda_device.c b/net/irda/irda_device.c
--- a/net/irda/irda_device.c	Mon Sep 23 16:31:57 2002
+++ b/net/irda/irda_device.c	Wed Mar 19 21:17:03 2003
@@ -372,6 +372,11 @@
 	irda_task_kick(task);
 }
 
+static void irda_device_destructor(struct net_device *dev)
+{
+	kfree(dev);
+}
+
 /*
  * Function irda_device_setup (dev)
  *
@@ -385,8 +390,7 @@
         dev->hard_header_len = 0;
         dev->addr_len        = 0;
 
-	dev->features        |= NETIF_F_DYNALLOC;
-	/* dev->destructor      = irda_device_destructor; */
+	dev->destructor      = irda_device_destructor;
 
         dev->type            = ARPHRD_IRDA;
         dev->tx_queue_len    = 8; /* Window size + 1 s-frame */
diff -Nru a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c
--- a/net/irda/irlan/irlan_eth.c	Mon Sep 23 16:34:20 2002
+++ b/net/irda/irlan/irlan_eth.c	Wed Mar 19 21:17:03 2003
@@ -62,16 +62,6 @@
 	dev->get_stats	        = irlan_eth_get_stats;
 	dev->set_multicast_list = irlan_eth_set_multicast_list;
 
-	/* NETIF_F_DYNALLOC feature was set by irlan_eth_init() and would
-	 * cause the unregister_netdev() to do asynch completion _and_
-	 * kfree self->dev afterwards. Which is really bad because the
-	 * netdevice was not allocated separately but is embedded in
-	 * our control block and therefore gets freed with *self.
-	 * The only reason why this would have been enabled is to hide
-	 * some netdev refcount issues. If unregister_netdev() blocks
-	 * forever, tell us about it... */
-	//dev->features          |= NETIF_F_DYNALLOC;
-
 	ether_setup(dev);
 	
 	/* 
diff -Nru a/net/key/af_key.c b/net/key/af_key.c
--- a/net/key/af_key.c	Thu Mar  6 11:06:45 2003
+++ b/net/key/af_key.c	Sun Mar 23 02:21:29 2003
@@ -510,10 +510,8 @@
 {
 	switch (((struct sockaddr*)(addr + 1))->sa_family) {
 	case AF_INET:
-		xaddr->xfrm4_addr = 
+		xaddr->a4 = 
 			((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr;
-		if (addr->sadb_address_prefixlen)
-			xaddr->xfrm4_mask = htonl(~0 << (32 - addr->sadb_address_prefixlen));
 		return AF_INET;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	case AF_INET6:
@@ -530,10 +528,11 @@
 
 static struct  xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs)
 {
-	struct xfrm_state *x;
 	struct sadb_sa *sa;
 	struct sadb_address *addr;
 	uint16_t proto;
+	unsigned short family;
+	xfrm_address_t *xaddr;
 
 	sa = (struct sadb_sa *) ext_hdrs[SADB_EXT_SA-1];
 	if (sa == NULL)
@@ -548,23 +547,24 @@
 	if (addr == NULL)
 		return NULL;
 
-	switch (((struct sockaddr *)(addr + 1))->sa_family) {
+	family = ((struct sockaddr *)(addr + 1))->sa_family;
+	switch (family) {
 	case AF_INET:
-		x = xfrm4_state_lookup(((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr,
-				       sa->sadb_sa_spi, proto);
+		xaddr = (xfrm_address_t *)&((struct sockaddr_in *)(addr + 1))->sin_addr;
 		break;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	case AF_INET6:
-		x = xfrm6_state_lookup(&((struct sockaddr_in6 *)(addr + 1))->sin6_addr,
-				       sa->sadb_sa_spi, proto);
+		xaddr = (xfrm_address_t *)&((struct sockaddr_in6 *)(addr + 1))->sin6_addr;
 		break;
 #endif
 	default:
-		x = NULL;
-		break;
+		xaddr = NULL;
 	}
 
-	return x;
+	if (!xaddr)
+		return NULL;
+
+	return xfrm_state_lookup(xaddr, sa->sadb_sa_spi, proto, family);
 }
 
 #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1)))
@@ -619,7 +619,7 @@
 	/* identity & sensitivity */
 
 	if ((x->props.family == AF_INET &&
-	     x->sel.saddr.xfrm4_addr != x->props.saddr.xfrm4_addr)
+	     x->sel.saddr.a4 != x->props.saddr.a4)
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	    || (x->props.family == AF_INET6 &&
 		memcmp (x->sel.saddr.a6, x->props.saddr.a6, sizeof (struct in6_addr)))
@@ -667,10 +667,17 @@
 		sa->sadb_sa_auth = a ? a->desc.sadb_alg_id : 0;
 	}
 	sa->sadb_sa_encrypt = 0;
+	BUG_ON(x->ealg && x->calg);
 	if (x->ealg) {
 		struct xfrm_algo_desc *a = xfrm_ealg_get_byname(x->ealg->alg_name);
 		sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0;
 	}
+	/* KAME compatible: sadb_sa_encrypt is overloaded with calg id */
+	if (x->calg) {
+		struct xfrm_algo_desc *a = xfrm_calg_get_byname(x->calg->alg_name);
+		sa->sadb_sa_encrypt = a ? a->desc.sadb_alg_id : 0;
+	}
+
 	sa->sadb_sa_flags = 0;
 
 	/* hard time */
@@ -724,7 +731,7 @@
 
 		sin = (struct sockaddr_in *) (addr + 1);
 		sin->sin_family = AF_INET;
-		sin->sin_addr.s_addr = x->props.saddr.xfrm4_addr;
+		sin->sin_addr.s_addr = x->props.saddr.a4;
 		sin->sin_port = 0;
 		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 	}
@@ -757,11 +764,11 @@
 	if (x->props.family == AF_INET) {
 		sin = (struct sockaddr_in *) (addr + 1);
 		sin->sin_family = AF_INET;
-		sin->sin_addr.s_addr = x->id.daddr.xfrm4_addr;
+		sin->sin_addr.s_addr = x->id.daddr.a4;
 		sin->sin_port = 0;
 		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 
-		if (x->sel.saddr.xfrm4_addr != x->props.saddr.xfrm4_addr) {
+		if (x->sel.saddr.a4 != x->props.saddr.a4) {
 			addr = (struct sadb_address*) skb_put(skb, 
 				sizeof(struct sadb_address)+sockaddr_size);
 			addr->sadb_address_len = 
@@ -775,7 +782,7 @@
 
 			sin = (struct sockaddr_in *) (addr + 1);
 			sin->sin_family = AF_INET;
-			sin->sin_addr.s_addr = x->sel.saddr.xfrm4_addr;
+			sin->sin_addr.s_addr = x->sel.saddr.a4;
 			sin->sin_port = x->sel.sport;
 			memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 		}
@@ -896,10 +903,13 @@
 	   Hence, we have to _ignore_ sadb_sa_state, which is also reasonable.
 	 */
 	if (sa->sadb_sa_auth > SADB_AALG_MAX ||
+	    (hdr->sadb_msg_satype == SADB_X_SATYPE_IPCOMP &&
+	     sa->sadb_sa_encrypt > SADB_X_CALG_MAX) ||
 	    sa->sadb_sa_encrypt > SADB_EALG_MAX)
 		return ERR_PTR(-EINVAL);
 	key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_AUTH-1];
 	if (key != NULL &&
+	    sa->sadb_sa_auth != SADB_X_AALG_NULL &&
 	    ((key->sadb_key_bits+7) / 8 == 0 ||
 	     (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
 		return ERR_PTR(-EINVAL);
@@ -952,24 +962,35 @@
 		x->props.aalgo = sa->sadb_sa_auth;
 		/* x->algo.flags = sa->sadb_sa_flags; */
 	}
-	key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_ENCRYPT-1];
 	if (sa->sadb_sa_encrypt) {
-		int keysize = 0;
-		struct xfrm_algo_desc *a = xfrm_ealg_get_byid(sa->sadb_sa_encrypt);
-		if (!a)
-			goto out;
-		if (key)
-			keysize = (key->sadb_key_bits + 7) / 8;
-		x->ealg = kmalloc(sizeof(*x->ealg) + keysize, GFP_KERNEL);
-		if (!x->ealg)
-			goto out;
-		strcpy(x->ealg->alg_name, a->name);
-		x->ealg->alg_key_len = 0;
-		if (key) {
-			x->ealg->alg_key_len = key->sadb_key_bits;
-			memcpy(x->ealg->alg_key, key+1, keysize);
+		if (hdr->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) {
+			struct xfrm_algo_desc *a = xfrm_calg_get_byid(sa->sadb_sa_encrypt);
+			if (!a)
+				goto out;
+			x->calg = kmalloc(sizeof(*x->calg), GFP_KERNEL);
+			if (!x->calg)
+				goto out;
+			strcpy(x->calg->alg_name, a->name);
+			x->props.calgo = sa->sadb_sa_encrypt;
+		} else {
+			int keysize = 0;
+			struct xfrm_algo_desc *a = xfrm_ealg_get_byid(sa->sadb_sa_encrypt);
+			if (!a)
+				goto out;
+			key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_ENCRYPT-1];
+			if (key)
+				keysize = (key->sadb_key_bits + 7) / 8;
+			x->ealg = kmalloc(sizeof(*x->ealg) + keysize, GFP_KERNEL);
+			if (!x->ealg)
+				goto out;
+			strcpy(x->ealg->alg_name, a->name);
+			x->ealg->alg_key_len = 0;
+			if (key) {
+				x->ealg->alg_key_len = key->sadb_key_bits;
+				memcpy(x->ealg->alg_key, key+1, keysize);
+			}
+			x->props.ealgo = sa->sadb_sa_encrypt;
 		}
-		x->props.ealgo = sa->sadb_sa_encrypt;
 	}
 	/* x->algo.flags = sa->sadb_sa_flags; */
 
@@ -996,20 +1017,7 @@
 		x->sel.prefixlen_s = addr->sadb_address_prefixlen;
 	}
 
-	switch (x->props.family) {
-	case AF_INET:
-		x->type = xfrm_get_type(proto);
-		break;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	case AF_INET6:
-		x->type = xfrm6_get_type(proto);
-		break;
-#endif
-	default:
-		x->type = NULL;
-		break;
-	}
-
+	x->type = xfrm_get_type(proto, x->props.family);
 	if (x->type == NULL)
 		goto out;
 	if (x->type->init_state(x, NULL))
@@ -1023,6 +1031,8 @@
 		kfree(x->aalg);
 	if (x->ealg)
 		kfree(x->ealg);
+	if (x->calg)
+		kfree(x->calg);
 	kfree(x);
 	return ERR_PTR(-ENOBUFS);
 }
@@ -1038,10 +1048,12 @@
 	struct sadb_x_sa2 *sa2;
 	struct sadb_address *saddr, *daddr;
 	struct sadb_msg *out_hdr;
-	struct xfrm_state *x;
+	struct xfrm_state *x = NULL;
 	u8 mode;
 	u16 reqid;
 	u8 proto;
+	unsigned short family;
+	xfrm_address_t *xsaddr = NULL, *xdaddr = NULL;
 
 	if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
 				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]))
@@ -1062,23 +1074,21 @@
 	saddr = ext_hdrs[SADB_EXT_ADDRESS_SRC-1];
 	daddr = ext_hdrs[SADB_EXT_ADDRESS_DST-1];
 
-	switch (((struct sockaddr *)(saddr + 1))->sa_family) {
+	family = ((struct sockaddr *)(saddr + 1))->sa_family;
+	switch (family) {
 	case AF_INET:
-		x = xfrm_find_acq(mode, reqid, proto,
-				  ((struct sockaddr_in *)(daddr + 1))->sin_addr.s_addr,
-				  ((struct sockaddr_in *)(saddr + 1))->sin_addr.s_addr, 1);
+		xdaddr = (xfrm_address_t *)&((struct sockaddr_in *)(daddr + 1))->sin_addr.s_addr;
+		xsaddr = (xfrm_address_t *)&((struct sockaddr_in *)(saddr + 1))->sin_addr.s_addr;
 		break;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	case AF_INET6:
-		x = xfrm6_find_acq(mode, reqid, proto,
-				   &((struct sockaddr_in6 *)(daddr + 1))->sin6_addr,
-				   &((struct sockaddr_in6 *)(saddr + 1))->sin6_addr, 1);
+		xdaddr = (xfrm_address_t *)&((struct sockaddr_in6 *)(daddr + 1))->sin6_addr;
+		xsaddr = (xfrm_address_t *)&((struct sockaddr_in6 *)(saddr + 1))->sin6_addr;
 		break;
 #endif
-	default:
-		x = NULL;
-		break;
 	}
+	if (xdaddr)
+		x = xfrm_find_acq(mode, reqid, proto, xdaddr, xsaddr, 1, family);
 
 	if (x == NULL)
 		return -ENOENT;
@@ -1165,23 +1175,9 @@
 	/* XXX there is race condition */
 	x1 = pfkey_xfrm_state_lookup(hdr, ext_hdrs);
 	if (!x1) {
-		switch (x->props.family) {
-		case AF_INET:
-			x1 = xfrm_find_acq(x->props.mode, x->props.reqid, x->id.proto,
-					   x->id.daddr.xfrm4_addr,
-					   x->props.saddr.xfrm4_addr, 0);
-			break;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-		case AF_INET6:
-			x1 = xfrm6_find_acq(x->props.mode, x->props.reqid, x->id.proto,
-					    (struct in6_addr*)x->id.daddr.a6,
-					    (struct in6_addr*)x->props.saddr.a6, 0);
-			break;
-#endif
-		default:
-			x1 = NULL;
-			break;
-		}
+		x1 = xfrm_find_acq(x->props.mode, x->props.reqid, x->id.proto,
+				   &x->id.daddr,
+				   &x->props.saddr, 0, x->props.family);
 		if (x1 && x1->id.spi != x->id.spi && x1->id.spi) {
 			xfrm_state_put(x1);
 			x1 = NULL;
@@ -1520,11 +1516,11 @@
 			sin = (void*)(rq+1);
 			if (sin->sin_family != AF_INET)
 				return -EINVAL;
-			t->saddr.xfrm4_addr = sin->sin_addr.s_addr;
+			t->saddr.a4 = sin->sin_addr.s_addr;
 			sin++;
 			if (sin->sin_family != AF_INET)
 				return -EINVAL;
-			t->id.daddr.xfrm4_addr = sin->sin_addr.s_addr;
+			t->id.daddr.a4 = sin->sin_addr.s_addr;
 			break;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 		case AF_INET6:
@@ -1631,7 +1627,7 @@
 	if (xp->family == AF_INET) {
 		sin = (struct sockaddr_in *) (addr + 1);
 		sin->sin_family = AF_INET;
-		sin->sin_addr.s_addr = xp->selector.saddr.xfrm4_addr;
+		sin->sin_addr.s_addr = xp->selector.saddr.a4;
 		sin->sin_port = xp->selector.sport;
 		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 	}
@@ -1662,7 +1658,7 @@
 	if (xp->family == AF_INET) {
 		sin = (struct sockaddr_in *) (addr + 1);
 		sin->sin_family = AF_INET;
-		sin->sin_addr.s_addr = xp->selector.daddr.xfrm4_addr;
+		sin->sin_addr.s_addr = xp->selector.daddr.a4;
 		sin->sin_port = xp->selector.dport;
 		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 	}
@@ -1750,12 +1746,12 @@
 			case AF_INET:
 				sin = (void*)(rq+1);
 				sin->sin_family = AF_INET;
-				sin->sin_addr.s_addr = t->saddr.xfrm4_addr;
+				sin->sin_addr.s_addr = t->saddr.a4;
 				sin->sin_port = 0;
 				memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 				sin++;
 				sin->sin_family = AF_INET;
-				sin->sin_addr.s_addr = t->id.daddr.xfrm4_addr;
+				sin->sin_addr.s_addr = t->id.daddr.a4;
 				sin->sin_port = 0;
 				memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 				break;
@@ -2339,7 +2335,7 @@
 
 		sin = (struct sockaddr_in *) (addr + 1);
 		sin->sin_family = AF_INET;
-		sin->sin_addr.s_addr = x->props.saddr.xfrm4_addr;
+		sin->sin_addr.s_addr = x->props.saddr.a4;
 		sin->sin_port = 0;
 		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 	}
@@ -2373,7 +2369,7 @@
 
 		sin = (struct sockaddr_in *) (addr + 1);
 		sin->sin_family = AF_INET;
-		sin->sin_addr.s_addr = x->id.daddr.xfrm4_addr;
+		sin->sin_addr.s_addr = x->id.daddr.a4;
 		sin->sin_port = 0;
 		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 	}
@@ -2415,8 +2411,23 @@
 	struct xfrm_policy *xp;
 	struct sadb_x_policy *pol = (struct sadb_x_policy*)data;
 
-	if (opt != IP_IPSEC_POLICY) {
-		*dir = -EOPNOTSUPP;
+	switch (family) {
+	case AF_INET:
+		if (opt != IP_IPSEC_POLICY) {
+			*dir = -EOPNOTSUPP;
+			return NULL;
+		}
+		break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		if (opt != IPV6_IPSEC_POLICY) {
+			*dir = -EOPNOTSUPP;
+			return NULL;
+		}
+		break;
+#endif
+	default:
+		*dir = -EINVAL;
 		return NULL;
 	}
 
diff -Nru a/net/netlink/netlink_dev.c b/net/netlink/netlink_dev.c
--- a/net/netlink/netlink_dev.c	Fri Dec  6 19:24:09 2002
+++ b/net/netlink/netlink_dev.c	Sat Mar 22 07:38:04 2003
@@ -198,7 +198,7 @@
 		printk(KERN_ERR "netlink: unable to get major %d\n", NETLINK_MAJOR);
 		return -EIO;
 	}
-	devfs_mk_dir (NULL, "netlink", NULL);
+	devfs_mk_dir("netlink");
 	/*  Someone tell me the official names for the uppercase ones  */
 	for (i = 0; i < sizeof(entries)/sizeof(entries[0]); i++) {
 		char name[20];
diff -Nru a/net/netsyms.c b/net/netsyms.c
--- a/net/netsyms.c	Thu Mar  6 16:16:15 2003
+++ b/net/netsyms.c	Sun Mar 23 02:21:29 2003
@@ -292,6 +292,7 @@
 EXPORT_SYMBOL(dlci_ioctl_hook);
 #endif
 
+EXPORT_SYMBOL(xfrm_user_policy);
 EXPORT_SYMBOL(km_waitq);
 EXPORT_SYMBOL(xfrm_cfg_sem);
 EXPORT_SYMBOL(xfrm_policy_alloc);
@@ -302,14 +303,20 @@
 EXPORT_SYMBOL(__xfrm_route_forward);
 EXPORT_SYMBOL(xfrm_state_alloc);
 EXPORT_SYMBOL(__xfrm_state_destroy);
-EXPORT_SYMBOL(xfrm4_state_find);
+EXPORT_SYMBOL(xfrm_state_find);
 EXPORT_SYMBOL(xfrm_state_insert);
 EXPORT_SYMBOL(xfrm_state_check_expire);
 EXPORT_SYMBOL(xfrm_state_check_space);
-EXPORT_SYMBOL(xfrm4_state_lookup);
+EXPORT_SYMBOL(xfrm_state_lookup);
+EXPORT_SYMBOL(xfrm_state_register_afinfo);
+EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
+EXPORT_SYMBOL(xfrm_state_get_afinfo);
+EXPORT_SYMBOL(xfrm_state_put_afinfo);
 EXPORT_SYMBOL(xfrm_replay_check);
 EXPORT_SYMBOL(xfrm_replay_advance);
 EXPORT_SYMBOL(xfrm_check_selectors);
+EXPORT_SYMBOL(__secpath_destroy);
+EXPORT_SYMBOL(xfrm_parse_spi);
 EXPORT_SYMBOL(xfrm4_rcv);
 EXPORT_SYMBOL(xfrm_register_type);
 EXPORT_SYMBOL(xfrm_unregister_type);
@@ -330,28 +337,24 @@
 EXPORT_SYMBOL(xfrm_policy_flush);
 EXPORT_SYMBOL(xfrm_policy_byid);
 EXPORT_SYMBOL(xfrm_policy_list);
-EXPORT_SYMBOL(xfrm_dst_lookup_register);
-EXPORT_SYMBOL(xfrm_dst_lookup_unregister);
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-EXPORT_SYMBOL(xfrm6_state_find);
-EXPORT_SYMBOL(xfrm6_rcv);
-EXPORT_SYMBOL(xfrm6_state_lookup);
-EXPORT_SYMBOL(xfrm6_find_acq);
-EXPORT_SYMBOL(xfrm6_register_type);
-EXPORT_SYMBOL(xfrm6_unregister_type);
-EXPORT_SYMBOL(xfrm6_get_type);
-EXPORT_SYMBOL(xfrm6_clear_mutable_options);
-#endif
+EXPORT_SYMBOL(xfrm_dst_lookup);
+EXPORT_SYMBOL(xfrm_policy_register_afinfo);
+EXPORT_SYMBOL(xfrm_policy_unregister_afinfo);
+EXPORT_SYMBOL(xfrm_policy_get_afinfo);
+EXPORT_SYMBOL(xfrm_policy_put_afinfo);
 
 EXPORT_SYMBOL_GPL(xfrm_probe_algs);
 EXPORT_SYMBOL_GPL(xfrm_count_auth_supported);
 EXPORT_SYMBOL_GPL(xfrm_count_enc_supported);
 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
+EXPORT_SYMBOL_GPL(xfrm_calg_get_byidx);
 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
+EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
+EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
 #if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE)
 EXPORT_SYMBOL_GPL(skb_ah_walk);
 #endif
@@ -547,6 +550,8 @@
 EXPORT_SYMBOL(unregister_netdevice);
 EXPORT_SYMBOL(netdev_state_change);
 EXPORT_SYMBOL(dev_new_index);
+EXPORT_SYMBOL(dev_get_by_flags);
+EXPORT_SYMBOL(__dev_get_by_flags);
 EXPORT_SYMBOL(dev_get_by_index);
 EXPORT_SYMBOL(__dev_get_by_index);
 EXPORT_SYMBOL(dev_get_by_name);
diff -Nru a/net/nonet.c b/net/nonet.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/nonet.c	Thu Mar 20 00:55:20 2003
@@ -0,0 +1,28 @@
+/*
+ * net/nonet.c
+ *
+ * Dummy functions to allow us to configure network support entirely
+ * out of the kernel.
+ *
+ * Distributed under the terms of the GNU GPL version 2.
+ * Copyright (c) Matthew Wilcox 2003
+ */
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+void __init sock_init(void)
+{
+	printk(KERN_INFO "Linux NoNET1.0 for Linux 2.6\n");
+}
+
+static int sock_no_open(struct inode *irrelevant, struct file *dontcare)
+{
+	return -ENXIO;
+}
+
+struct file_operations bad_sock_fops = {
+	.open = sock_no_open,
+};
diff -Nru a/net/sched/sch_atm.c b/net/sched/sch_atm.c
--- a/net/sched/sch_atm.c	Tue Feb 18 10:38:27 2003
+++ b/net/sched/sch_atm.c	Thu Mar 20 00:45:11 2003
@@ -508,7 +508,7 @@
 			ATM_SKB(skb)->vcc = flow->vcc;
 			memcpy(skb_push(skb,flow->hdr_len),flow->hdr,
 			    flow->hdr_len);
-			atomic_add(skb->truesize,&flow->vcc->tx_inuse);
+			atomic_add(skb->truesize,&flow->vcc->sk->wmem_alloc);
 			ATM_SKB(skb)->iovcnt = 0;
 			/* atm.atm_options are already set by atm_tc_enqueue */
 			(void) flow->vcc->send(flow->vcc,skb);
diff -Nru a/net/sctp/associola.c b/net/sctp/associola.c
--- a/net/sctp/associola.c	Tue Feb 18 16:28:52 2003
+++ b/net/sctp/associola.c	Thu Mar  6 09:04:50 2003
@@ -181,7 +181,7 @@
 	else
 		asoc->rwnd = sk->rcvbuf;
 
-	asoc->a_rwnd = 0;
+	asoc->a_rwnd = asoc->rwnd;
 
 	asoc->rwnd_over = 0;
 
@@ -360,9 +360,25 @@
 	}
 }
 
+/* Change the primary destination address for the peer. */
+void sctp_assoc_set_primary(struct sctp_association *asoc,
+			    struct sctp_transport *transport)
+{
+	asoc->peer.primary_path = transport;
+
+	/* Set a default msg_name for events. */
+	memcpy(&asoc->peer.primary_addr, &transport->ipaddr,
+	       sizeof(union sctp_addr));
+
+	/* If the primary path is changing, assume that the
+	 * user wants to use this new path.
+	 */
+	if (transport->active)
+		asoc->peer.active_path = transport;
+}
 
 /* Add a transport address to an association.  */
-struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *asoc,
+struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
 					   const union sctp_addr *addr,
 					   int priority)
 {
@@ -397,17 +413,16 @@
 	 * If not and the current association PMTU is higher than the new
 	 * peer's PMTU, reset the association PMTU to the new peer's PMTU.
 	 */
-	if (asoc->pmtu) {
+	if (asoc->pmtu)
 		asoc->pmtu = min_t(int, peer->pmtu, asoc->pmtu);
-	} else {
+	else
 		asoc->pmtu = peer->pmtu;
-	}
 
 	SCTP_DEBUG_PRINTK("sctp_assoc_add_peer:association %p PMTU set to "
 			  "%d\n", asoc, asoc->pmtu);
 
-	asoc->frag_point = asoc->pmtu -
-		(SCTP_IP_OVERHEAD + sizeof(sctp_data_chunk_t));
+	asoc->frag_point = asoc->pmtu;
+	asoc->frag_point -= SCTP_IP_OVERHEAD + sizeof(struct sctp_data_chunk);
 
 	/* The asoc->peer.port might not be meaningful yet, but
 	 * initialize the packet structure anyway.
@@ -460,11 +475,7 @@
 
 	/* If we do not yet have a primary path, set one.  */
 	if (NULL == asoc->peer.primary_path) {
-		asoc->peer.primary_path = peer;
-		/* Set a default msg_name for events. */
-		memcpy(&asoc->peer.primary_addr, &peer->ipaddr,
-		       sizeof(union sctp_addr));
-		asoc->peer.active_path = peer;
+		sctp_assoc_set_primary(asoc, peer);
 		asoc->peer.retran_path = peer;
 	}
 
@@ -603,7 +614,7 @@
 /* Allocate the next TSN, Transmission Sequence Number, for the given
  * association.
  */
-__u32 __sctp_association_get_next_tsn(sctp_association_t *asoc)
+__u32 sctp_association_get_next_tsn(sctp_association_t *asoc)
 {
 	/* From Section 1.6 Serial Number Arithmetic:
 	 * Transmission Sequence Numbers wrap around when they reach
@@ -618,7 +629,7 @@
 }
 
 /* Allocate 'num' TSNs by incrementing the association's TSN by num. */
-__u32 __sctp_association_get_tsn_block(sctp_association_t *asoc, int num)
+__u32 sctp_association_get_tsn_block(sctp_association_t *asoc, int num)
 {
 	__u32 retval = asoc->next_tsn;
 
@@ -942,7 +953,7 @@
 {
 	/* If this is the first time SHUTDOWN is sent, use the active path,
 	 * else use the retran path. If the last SHUTDOWN was sent over the
-	 * retran path, update the retran path and use it. 
+	 * retran path, update the retran path and use it.
 	 */
 	if (!asoc->shutdown_last_sent_to)
 		return asoc->peer.active_path;
@@ -983,6 +994,24 @@
 			  __FUNCTION__, asoc, asoc->pmtu, asoc->frag_point);
 }
 
+/* Should we send a SACK to update our peer? */
+static inline int sctp_peer_needs_update(struct sctp_association *asoc)
+{
+	switch (asoc->state) {
+	case SCTP_STATE_ESTABLISHED:
+	case SCTP_STATE_SHUTDOWN_PENDING:
+	case SCTP_STATE_SHUTDOWN_RECEIVED:
+		if ((asoc->rwnd > asoc->a_rwnd) && 
+		    ((asoc->rwnd - asoc->a_rwnd) >=
+		     min_t(__u32, (asoc->base.sk->rcvbuf >> 1), asoc->pmtu))) 
+			return 1;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
 /* Increase asoc's rwnd by len and send any window update SACK if needed. */
 void sctp_assoc_rwnd_increase(sctp_association_t *asoc, int len)
 {
@@ -1009,10 +1038,8 @@
 	 * The algorithm used is similar to the one described in
 	 * Section 4.2.3.3 of RFC 1122.
 	 */
-	if ((asoc->state == SCTP_STATE_ESTABLISHED) &&
-	    (asoc->rwnd > asoc->a_rwnd) &&
-	    ((asoc->rwnd - asoc->a_rwnd) >=
-		     min_t(__u32, (asoc->base.sk->rcvbuf >> 1), asoc->pmtu))) {
+	if (sctp_peer_needs_update(asoc)) {
+		asoc->a_rwnd = asoc->rwnd;
 		SCTP_DEBUG_PRINTK("%s: Sending window update SACK- asoc: %p "
 				  "rwnd: %u a_rwnd: %u\n", __FUNCTION__,
 				  asoc, asoc->rwnd, asoc->a_rwnd);
@@ -1020,9 +1047,6 @@
 		if (!sack)
 			return;
 
-		/* Update the last advertised rwnd value. */
-		asoc->a_rwnd = asoc->rwnd;
-
 		asoc->peer.sack_needed = 0;
 
 		sctp_outq_tail(&asoc->outqueue, sack);
@@ -1046,7 +1070,8 @@
 		asoc->rwnd = 0;
 	}
 	SCTP_DEBUG_PRINTK("%s: asoc %p rwnd decreased by %d to (%u, %u)\n",
-			  __FUNCTION__, asoc, len, asoc->rwnd, asoc->rwnd_over);
+			  __FUNCTION__, asoc, len, asoc->rwnd, 
+			  asoc->rwnd_over);
 }
 
 /* Build the bind address list for the association based on info from the
diff -Nru a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
--- a/net/sctp/bind_addr.c	Thu Nov 21 12:43:21 2002
+++ b/net/sctp/bind_addr.c	Mon Feb 24 13:55:49 2003
@@ -302,7 +302,7 @@
 static int sctp_copy_one_addr(sctp_bind_addr_t *dest, union sctp_addr *addr,
 			      sctp_scope_t scope, int priority, int flags)
 {
-	sctp_protocol_t *proto = sctp_get_protocol();
+	struct sctp_protocol *proto = sctp_get_protocol();
 	int error = 0;
 
 	if (sctp_is_any(addr)) {
diff -Nru a/net/sctp/endpointola.c b/net/sctp/endpointola.c
--- a/net/sctp/endpointola.c	Wed Feb 12 13:28:00 2003
+++ b/net/sctp/endpointola.c	Mon Mar  3 15:13:51 2003
@@ -65,7 +65,7 @@
 /* Create a sctp_endpoint_t with all that boring stuff initialized.
  * Returns NULL if there isn't enough memory.
  */
-sctp_endpoint_t *sctp_endpoint_new(sctp_protocol_t *proto,
+sctp_endpoint_t *sctp_endpoint_new(struct sctp_protocol *proto,
 				   struct sock *sk, int priority)
 {
 	sctp_endpoint_t *ep;
@@ -89,7 +89,8 @@
 /*
  * Initialize the base fields of the endpoint structure.
  */
-sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *ep, sctp_protocol_t *proto,
+sctp_endpoint_t *sctp_endpoint_init(sctp_endpoint_t *ep, 
+				    struct sctp_protocol *proto,
 				    struct sock *sk, int priority)
 {
 	struct sctp_opt *sp = sctp_sk(sk);
@@ -193,6 +194,8 @@
 void sctp_endpoint_destroy(sctp_endpoint_t *ep)
 {
 	SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return);
+
+	ep->base.sk->state = SCTP_SS_CLOSED;
 
 	/* Unlink this endpoint, so we can't find it again! */
 	sctp_unhash_endpoint(ep);
diff -Nru a/net/sctp/input.c b/net/sctp/input.c
--- a/net/sctp/input.c	Wed Feb 12 13:28:00 2003
+++ b/net/sctp/input.c	Sun Mar 23 02:21:29 2003
@@ -110,6 +110,7 @@
 	struct sctphdr *sh;
 	union sctp_addr src;
 	union sctp_addr dest;
+	int family;
 	struct sctp_af *af;
 	int ret = 0;
 
@@ -129,7 +130,8 @@
 
 	skb_pull(skb, sizeof(struct sctphdr));	
 
-	af = sctp_get_af_specific(ipver2af(skb->nh.iph->version));
+	family = ipver2af(skb->nh.iph->version);
+	af = sctp_get_af_specific(family);
 	if (unlikely(!af)) 
 		goto bad_packet;
 
@@ -173,7 +175,7 @@
 	rcvr = asoc ? &asoc->base : &ep->base;
 	sk = rcvr->sk;
 
-	if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb))
+	if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family))
 		goto discard_release;
 
 	ret = sk_filter(sk, skb, 1);
diff -Nru a/net/sctp/ipv6.c b/net/sctp/ipv6.c
--- a/net/sctp/ipv6.c	Mon Mar  3 00:57:24 2003
+++ b/net/sctp/ipv6.c	Sun Mar 23 22:38:04 2003
@@ -432,6 +432,62 @@
 	return retval;
 }
 
+/* Create and initialize a new sk for the socket to be returned by accept(). */ 
+struct sock *sctp_v6_create_accept_sk(struct sock *sk,
+				      struct sctp_association *asoc)
+{
+	struct inet_opt *inet = inet_sk(sk);
+	struct sock *newsk;
+	struct inet_opt *newinet;
+	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+	struct sctp6_sock *newsctp6sk;
+
+	newsk = sk_alloc(PF_INET6, GFP_KERNEL, sizeof(struct sctp6_sock),
+			 sk->slab);
+	if (!newsk)
+		goto out;
+
+	sock_init_data(NULL, newsk);
+
+	newsk->type = SOCK_STREAM;
+
+	newsk->prot = sk->prot;
+	newsk->no_check = sk->no_check;
+	newsk->reuse = sk->reuse;
+
+	newsk->destruct = inet_sock_destruct;
+	newsk->zapped = 0;
+	newsk->family = PF_INET6;
+	newsk->protocol = IPPROTO_SCTP;
+	newsk->backlog_rcv = sk->prot->backlog_rcv;
+
+	newsctp6sk = (struct sctp6_sock *)newsk;
+	newsctp6sk->pinet6 = &newsctp6sk->inet6;
+
+	newinet = inet_sk(newsk);
+	newnp = inet6_sk(newsk);
+
+	memcpy(newnp, np, sizeof(struct ipv6_pinfo));
+
+	ipv6_addr_copy(&newnp->daddr, &asoc->peer.primary_addr.v6.sin6_addr); 
+
+	newinet->sport = inet->sport;
+	newinet->dport = asoc->peer.port;
+	
+#ifdef INET_REFCNT_DEBUG
+	atomic_inc(&inet6_sock_nr);
+	atomic_inc(&inet_sock_nr);
+#endif
+
+	if (0 != newsk->prot->init(newsk)) {
+		inet_sock_release(newsk);
+		newsk = NULL;
+	}
+
+out:
+	return newsk;
+}
+
 /* Initialize a PF_INET6 socket msg_name. */
 static void sctp_inet6_msgname(char *msgname, int *addr_len)
 {
@@ -564,6 +620,20 @@
 	return af->available(addr);
 }
 
+/* Fill in Supported Address Type information for INIT and INIT-ACK
+ * chunks.   Note: In the future, we may want to look at sock options
+ * to determine whether a PF_INET6 socket really wants to have IPV4
+ * addresses.  
+ * Returns number of addresses supported.
+ */
+static int sctp_inet6_supported_addrs(const struct sctp_opt *opt,
+				      __u16 *types) 
+{
+	types[0] = SCTP_PARAM_IPV4_ADDRESS;
+	types[1] = SCTP_PARAM_IPV6_ADDRESS;
+	return 2;
+}
+
 static struct proto_ops inet6_seqpacket_ops = {
 	.family     = PF_INET6,
 	.release    = inet6_release,
@@ -583,7 +653,7 @@
 	.mmap       = sock_no_mmap,
 };
 
-static struct inet_protosw sctpv6_protosw = {
+static struct inet_protosw sctpv6_seqpacket_protosw = {
 	.type          = SOCK_SEQPACKET,
 	.protocol      = IPPROTO_SCTP,
 	.prot 	       = &sctp_prot,
@@ -592,9 +662,23 @@
 	.no_check      = 0,
 	.flags         = SCTP_PROTOSW_FLAG
 };
+static struct inet_protosw sctpv6_stream_protosw = {
+	.type          = SOCK_STREAM,
+	.protocol      = IPPROTO_SCTP,
+	.prot 	       = &sctp_prot,
+	.ops           = &inet6_seqpacket_ops,
+	.capability    = -1,
+	.no_check      = 0,
+	.flags         = SCTP_PROTOSW_FLAG
+};
+
+static int sctp6_rcv(struct sk_buff **pskb)
+{
+	return sctp_rcv(*pskb);
+}
 
 static struct inet6_protocol sctpv6_protocol = {
-	.handler      = sctp_rcv,
+	.handler      = sctp6_rcv,
 	.err_handler  = sctp_v6_err,
 };
 
@@ -626,6 +710,8 @@
 	.af_supported  = sctp_inet6_af_supported,
 	.cmp_addr      = sctp_inet6_cmp_addr,
 	.bind_verify   = sctp_inet6_bind_verify,
+	.supported_addrs = sctp_inet6_supported_addrs,
+	.create_accept_sk = sctp_v6_create_accept_sk,
 	.af            = &sctp_ipv6_specific,
 };
 
@@ -636,8 +722,9 @@
 	if (inet6_add_protocol(&sctpv6_protocol, IPPROTO_SCTP) < 0)
 		return -EAGAIN;
 
-	/* Add SCTPv6 to inetsw6 linked list. */
-	inet6_register_protosw(&sctpv6_protosw);
+	/* Add SCTPv6(UDP and TCP style) to inetsw6 linked list. */
+	inet6_register_protosw(&sctpv6_seqpacket_protosw);
+	inet6_register_protosw(&sctpv6_stream_protosw);
 
 	/* Register the SCTP specfic PF_INET6 functions. */
 	sctp_register_pf(&sctp_pf_inet6_specific, PF_INET6);
@@ -656,6 +743,7 @@
 {
 	list_del(&sctp_ipv6_specific.list);
 	inet6_del_protocol(&sctpv6_protocol, IPPROTO_SCTP);
-	inet6_unregister_protosw(&sctpv6_protosw);
+	inet6_unregister_protosw(&sctpv6_seqpacket_protosw);
+	inet6_unregister_protosw(&sctpv6_stream_protosw);
 	unregister_inet6addr_notifier(&sctp_inetaddr_notifier);
 }
diff -Nru a/net/sctp/output.c b/net/sctp/output.c
--- a/net/sctp/output.c	Mon Feb 17 16:31:26 2003
+++ b/net/sctp/output.c	Thu Mar  6 09:04:50 2003
@@ -62,17 +62,16 @@
 #include <net/sctp/sm.h>
 
 /* Forward declarations for private helpers. */
-static void sctp_packet_reset(sctp_packet_t *packet);
-static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet,
-					   sctp_chunk_t *chunk);
+static void sctp_packet_reset(struct sctp_packet *packet);
+static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
+					   struct sctp_chunk *chunk);
 
 /* Config a packet.
  * This appears to be a followup set of initializations.)
  */
-sctp_packet_t *sctp_packet_config(sctp_packet_t *packet,
-				  __u32 vtag,
-				  int ecn_capable,
-				  sctp_packet_phandler_t *prepend_handler)
+struct sctp_packet *sctp_packet_config(struct sctp_packet *packet,
+				       __u32 vtag, int ecn_capable,
+				       sctp_packet_phandler_t *prepend_handler)
 {
 	int packet_empty = (packet->size == SCTP_IP_OVERHEAD);
 
@@ -89,10 +88,9 @@
 }
 
 /* Initialize the packet structure. */
-sctp_packet_t *sctp_packet_init(sctp_packet_t *packet,
-				struct sctp_transport *transport,
-				__u16 sport,
-				__u16 dport)
+struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
+				     struct sctp_transport *transport,
+				     __u16 sport, __u16 dport)
 {
 	packet->transport = transport;
 	packet->source_port = sport;
@@ -109,14 +107,12 @@
 }
 
 /* Free a packet.  */
-void sctp_packet_free(sctp_packet_t *packet)
+void sctp_packet_free(struct sctp_packet *packet)
 {
-	sctp_chunk_t *chunk;
+	struct sctp_chunk *chunk;
 
-        while (NULL != 
-	       (chunk = (sctp_chunk_t *)skb_dequeue(&packet->chunks))) {
+        while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks)))
 		sctp_free_chunk(chunk);
-	}
 
 	if (packet->malloced)
 		kfree(packet);
@@ -129,8 +125,8 @@
  * as it can fit in the packet, but any more data that does not fit in this
  * packet can be sent only after receiving the COOKIE_ACK.
  */
-sctp_xmit_t sctp_packet_transmit_chunk(sctp_packet_t *packet,
-				       sctp_chunk_t *chunk)
+sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *packet,
+				       struct sctp_chunk *chunk)
 {
 	sctp_xmit_t retval;
 	int error = 0;
@@ -152,6 +148,7 @@
 	case SCTP_XMIT_MUST_FRAG:
 	case SCTP_XMIT_RWND_FULL:
 	case SCTP_XMIT_OK:
+	case SCTP_XMIT_NAGLE_DELAY:
 		break;
 	};
 
@@ -161,7 +158,8 @@
 /* Append a chunk to the offered packet reporting back any inability to do
  * so.
  */
-sctp_xmit_t sctp_packet_append_chunk(sctp_packet_t *packet, sctp_chunk_t *chunk)
+sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
+				     struct sctp_chunk *chunk)
 {
 	sctp_xmit_t retval = SCTP_XMIT_OK;
 	__u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length));
@@ -182,7 +180,7 @@
 		/* Both control chunks and data chunks with TSNs are
 		 * non-fragmentable.
 		 */
-		int fragmentable = sctp_chunk_is_data(chunk) && 
+		int fragmentable = sctp_chunk_is_data(chunk) &&
 			(!chunk->has_tsn);
 		if (packet_empty) {
 			if (fragmentable) {
@@ -223,7 +221,7 @@
 	}
 
 	/* It is OK to send this chunk.  */
-	skb_queue_tail(&packet->chunks, (struct sk_buff *)chunk);
+	__skb_queue_tail(&packet->chunks, (struct sk_buff *)chunk);
 	packet->size += chunk_len;
 finish:
 	return retval;
@@ -234,18 +232,18 @@
  *
  * The return value is a normal kernel error return value.
  */
-int sctp_packet_transmit(sctp_packet_t *packet)
+int sctp_packet_transmit(struct sctp_packet *packet)
 {
 	struct sctp_transport *transport = packet->transport;
-	sctp_association_t *asoc = transport->asoc;
+	struct sctp_association *asoc = transport->asoc;
 	struct sctphdr *sh;
 	__u32 crc32;
 	struct sk_buff *nskb;
-	sctp_chunk_t *chunk;
+	struct sctp_chunk *chunk;
 	struct sock *sk;
 	int err = 0;
 	int padding;		/* How much padding do we need?  */
-	__u8 packet_has_data = 0;
+	__u8 has_data = 0;
 	struct dst_entry *dst;
 
 	/* Do NOT generate a chunkless packet... */
@@ -253,7 +251,7 @@
 		return err;
 
 	/* Set up convenience variables... */
-	chunk = (sctp_chunk_t *) (packet->chunks.next);
+	chunk = (struct sctp_chunk *) (packet->chunks.next);
 	sk = chunk->skb->sk;
 
 	/* Allocate the new skb.  */
@@ -291,8 +289,7 @@
 	 * [This whole comment explains WORD_ROUND() below.]
 	 */
 	SCTP_DEBUG_PRINTK("***sctp_transmit_packet***\n");
-	while (NULL != (chunk = (sctp_chunk_t *)
-			skb_dequeue(&packet->chunks))) {
+	while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks))) {
 		chunk->num_times_sent++;
 		chunk->sent_at = jiffies;
 		if (sctp_chunk_is_data(chunk)) {
@@ -309,7 +306,7 @@
 				chunk->rtt_in_progress = 1;
 				transport->rto_pending = 1;
 			}
-			packet_has_data = 1;
+			has_data = 1;
 		}
 		memcpy(skb_put(nskb, chunk->skb->len),
 		       chunk->skb->data, chunk->skb->len);
@@ -399,7 +396,7 @@
 		asoc->peer.last_sent_to = transport;
 	}
 
-	if (packet_has_data) {
+	if (has_data) {
 		struct timer_list *timer;
 		unsigned long timeout;
 
@@ -456,9 +453,9 @@
 /*
  * This private function resets the packet to a fresh state.
  */
-static void sctp_packet_reset(sctp_packet_t *packet)
+static void sctp_packet_reset(struct sctp_packet *packet)
 {
-	sctp_chunk_t *chunk = NULL;
+	struct sctp_chunk *chunk = NULL;
 
 	packet->size = SCTP_IP_OVERHEAD;
 
@@ -473,13 +470,16 @@
 }
 
 /* This private function handles the specifics of appending DATA chunks.  */
-static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet, 
-					   sctp_chunk_t *chunk)
+static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
+					   struct sctp_chunk *chunk)
 {
 	sctp_xmit_t retval = SCTP_XMIT_OK;
 	size_t datasize, rwnd, inflight;
 	struct sctp_transport *transport = packet->transport;
 	__u32 max_burst_bytes;
+	struct sctp_association *asoc = transport->asoc;
+	struct sctp_opt *sp = sctp_sk(asoc->base.sk);
+	struct sctp_outq *q = &asoc->outqueue;
 
 	/* RFC 2960 6.1  Transmission of DATA Chunks
 	 *
@@ -494,8 +494,8 @@
 	 * receiver to the data sender.
 	 */
 
-	rwnd = transport->asoc->peer.rwnd;
-	inflight = transport->asoc->outqueue.outstanding_bytes;
+	rwnd = asoc->peer.rwnd;
+	inflight = asoc->outqueue.outstanding_bytes;
 
 	datasize = sctp_data_size(chunk);
 
@@ -517,7 +517,7 @@
 	 * 	if ((flightsize + Max.Burst * MTU) < cwnd)
 	 *		cwnd = flightsize + Max.Burst * MTU
 	 */
-	max_burst_bytes = transport->asoc->max_burst * transport->asoc->pmtu;
+	max_burst_bytes = asoc->max_burst * asoc->pmtu;
 	if ((transport->flight_size + max_burst_bytes) < transport->cwnd) {
 		transport->cwnd = transport->flight_size + max_burst_bytes;
 		SCTP_DEBUG_PRINTK("%s: cwnd limited by max_burst: "
@@ -543,27 +543,44 @@
 	 *    When a Fast Retransmit is being performed the sender SHOULD
 	 *    ignore the value of cwnd and SHOULD NOT delay retransmission.
 	 */
-	if (!chunk->fast_retransmit) {
+	if (!chunk->fast_retransmit)
 		if (transport->flight_size >= transport->cwnd) {
 			retval = SCTP_XMIT_RWND_FULL;
 			goto finish;
 		}
+
+	/* Nagle's algorithm to solve small-packet problem:
+	 * Inhibit the sending of new chunks when new outgoing data arrives
+	 * if any previously transmitted data on the connection remains
+	 * unacknowledged.
+	 */
+	if (!sp->nodelay && SCTP_IP_OVERHEAD == packet->size && 
+	    q->outstanding_bytes && SCTP_STATE_ESTABLISHED == asoc->state) {
+		unsigned len = datasize + q->out_qlen;
+
+		/* Check whether this chunk and all the rest of pending
+		 * data will fit or delay in hopes of bundling a full
+		 * sized packet.
+		 */
+		if (len < asoc->pmtu - SCTP_IP_OVERHEAD) {
+			retval = SCTP_XMIT_NAGLE_DELAY;
+			goto finish;
+		}
 	}
 
 	/* Keep track of how many bytes are in flight over this transport. */
 	transport->flight_size += datasize;
 
 	/* Keep track of how many bytes are in flight to the receiver. */
-	transport->asoc->outqueue.outstanding_bytes += datasize;
+	asoc->outqueue.outstanding_bytes += datasize;
 
 	/* Update our view of the receiver's rwnd. */
-	if (datasize < rwnd) {
+	if (datasize < rwnd)
 		rwnd -= datasize;
-	} else {
+	else
 		rwnd = 0;
-	}
 
-	transport->asoc->peer.rwnd = rwnd;
+	asoc->peer.rwnd = rwnd;
 
 finish:
 	return retval;
diff -Nru a/net/sctp/outqueue.c b/net/sctp/outqueue.c
--- a/net/sctp/outqueue.c	Mon Mar  3 00:57:24 2003
+++ b/net/sctp/outqueue.c	Thu Mar  6 13:36:45 2003
@@ -1,7 +1,7 @@
 /* SCTP kernel reference Implementation
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001-2003 Intel Corp.
  * Copyright (c) 2001-2003 International Business Machines Corp.
  *
  * This file is part of the SCTP kernel reference Implementation
@@ -62,6 +62,43 @@
 				   sctp_sackhdr_t *sack,
 				   __u32 highest_new_tsn);
 
+/* Add data to the front of the queue. */
+static inline void sctp_outq_head_data(struct sctp_outq *q,
+					struct sctp_chunk *ch)
+{
+	__skb_queue_head(&q->out, (struct sk_buff *)ch);
+	q->out_qlen += ch->skb->len;
+	return;
+}
+
+/* Take data from the front of the queue. */
+static inline struct sctp_chunk *sctp_outq_dequeue_data(struct sctp_outq *q)
+{
+	struct sctp_chunk *ch;
+	ch = (struct sctp_chunk *)__skb_dequeue(&q->out);
+	if (ch)
+		q->out_qlen -= ch->skb->len;
+	return ch;
+}
+/* Add data chunk to the end of the queue. */
+static inline void sctp_outq_tail_data(struct sctp_outq *q,
+				       struct sctp_chunk *ch)
+{
+	__skb_queue_tail(&q->out, (struct sk_buff *)ch);
+	q->out_qlen += ch->skb->len;
+	return;
+}
+
+/* Insert a chunk behind chunk 'pos'. */
+static inline void sctp_outq_insert_data(struct sctp_outq *q,
+					 struct sctp_chunk *ch,
+					 struct sctp_chunk *pos)
+{
+	__skb_insert((struct sk_buff *)ch, (struct sk_buff *)pos->prev, 
+		     (struct sk_buff *)pos, pos->list);
+	q->out_qlen += ch->skb->len;
+}
+
 /* Generate a new outqueue.  */
 struct sctp_outq *sctp_outq_new(sctp_association_t *asoc)
 {
@@ -97,6 +134,7 @@
 	q->empty = 1;
 
 	q->malloced = 0;
+	q->out_qlen = 0;
 }
 
 /* Free the outqueue structure and any related pending chunks.
@@ -125,7 +163,7 @@
 		sctp_free_chunk(chunk);
 	}
 
-	/* Throw away any chunks in the retransmit queue. */ 
+	/* Throw away any chunks in the retransmit queue. */
 	list_for_each_safe(lchunk, temp, &q->retransmit) {
 		list_del(lchunk);
 		chunk = list_entry(lchunk, sctp_chunk_t, transmitted_list);
@@ -133,7 +171,7 @@
 	}
 
 	/* Throw away any leftover data chunks. */
-	while ((chunk = (sctp_chunk_t *) skb_dequeue(&q->out)))
+	while ((chunk = sctp_outq_dequeue_data(q)))
 		sctp_free_chunk(chunk);
 
 	/* Throw away any leftover control chunks. */
@@ -192,7 +230,7 @@
 			  sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type))
 			  : "Illegal Chunk");
 
-			skb_queue_tail(&q->out, (struct sk_buff *) chunk);
+			sctp_outq_tail_data(q, chunk);
 			if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
 				SCTP_INC_STATS(SctpOutUnorderChunks);
 			else
@@ -201,7 +239,7 @@
 			break;
 		};
 	} else {
-		skb_queue_tail(&q->control, (struct sk_buff *) chunk);
+		__skb_queue_tail(&q->control, (struct sk_buff *) chunk);
 		SCTP_INC_STATS(SctpOutCtrlChunks);
 	}
 
@@ -241,7 +279,7 @@
 }
 
 /* Mark all the eligible packets on a transport for retransmission.  */
-void sctp_retransmit_mark(struct sctp_outq *q, 
+void sctp_retransmit_mark(struct sctp_outq *q,
 			  struct sctp_transport *transport,
 			  __u8 fast_retransmit)
 {
@@ -351,7 +389,7 @@
  *
  * The return value is a normal kernel error return value.
  */
-static int sctp_outq_flush_rtx(struct sctp_outq *q, sctp_packet_t *pkt,
+static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
 			       int rtx_timeout, int *start_timer)
 {
 	struct list_head *lqueue;
@@ -385,17 +423,6 @@
 
 	while (lchunk) {
 		chunk = list_entry(lchunk, sctp_chunk_t, transmitted_list);
-#if 0
-		/* If a chunk has been tried for more than SCTP_DEF_MAX_SEND
-		 * times, discard it, and check the empty flag of the outqueue.
-		 *
-		 * --xguo
-		 */
-		if (chunk->snd_count > SCTP_DEF_MAX_SEND) {
-			sctp_free_chunk(chunk);
-			continue;
-		}
-#endif
 
 		/* Make sure that Gap Acked TSNs are not retransmitted.  A
 		 * simple approach is just to move such TSNs out of the
@@ -461,8 +488,8 @@
  * queue.  'pos' points to the next chunk in the output queue after the
  * chunk that is currently in the process of fragmentation.
  */
-void sctp_xmit_frag(struct sctp_outq *q, struct sk_buff *pos,
-		    sctp_packet_t *packet, sctp_chunk_t *frag, __u32 tsn)
+void sctp_xmit_frag(struct sctp_outq *q, struct sctp_chunk *pos,
+		struct sctp_packet *packet, struct sctp_chunk *frag, __u32 tsn)
 {
 	struct sctp_transport *transport = packet->transport;
 	struct sk_buff_head *queue = &q->out;
@@ -480,11 +507,10 @@
 		SCTP_DEBUG_PRINTK("sctp_xmit_frag: q not empty. "
 				  "adding 0x%x to outqueue\n",
 				  ntohl(frag->subh.data_hdr->tsn));
-		if (pos) {
-			skb_insert(pos, (struct sk_buff *) frag);
-		} else {
-			skb_queue_tail(queue, (struct sk_buff *) frag);
-		}
+		if (pos)		
+			sctp_outq_insert_data(q, frag, pos);
+		else
+			sctp_outq_tail_data(q, frag);
 		return;
 	}
 
@@ -496,11 +522,10 @@
 		SCTP_DEBUG_PRINTK("sctp_xmit_frag: rwnd full. "
 				  "adding 0x%x to outqueue\n",
 				  ntohl(frag->subh.data_hdr->tsn));
-		if (pos) {
-			skb_insert(pos, (struct sk_buff *) frag);
-		} else {
-			skb_queue_tail(queue, (struct sk_buff *) frag);
-		}
+		if (pos)
+			sctp_outq_insert_data(q, frag, pos);
+		else
+			sctp_outq_tail_data(q, frag);
 		break;
 
 	case SCTP_XMIT_OK:
@@ -512,11 +537,10 @@
 			SCTP_DEBUG_PRINTK("sctp_xmit_frag: force output "
 					  "failed. adding 0x%x to outqueue\n",
 					  ntohl(frag->subh.data_hdr->tsn));
-			if (pos) {
-				skb_insert(pos, (struct sk_buff *) frag);
-			} else {
-				skb_queue_tail(queue, (struct sk_buff *) frag);
-			}
+			if (pos)
+				sctp_outq_insert_data(q, frag, pos);
+			else
+				sctp_outq_tail_data(q, frag);
 		} else {
 			SCTP_DEBUG_PRINTK("sctp_xmit_frag: force output "
 					  "success. 0x%x sent\n",
@@ -537,14 +561,14 @@
  * The argument 'frag' point to the first fragment and it holds the list
  * of all the other fragments in the 'frag_list' field.
  */
-void sctp_xmit_fragmented_chunks(struct sctp_outq *q, sctp_packet_t *packet,
+void sctp_xmit_fragmented_chunks(struct sctp_outq *q, struct sctp_packet *pkt,
 				 sctp_chunk_t *frag)
 {
 	sctp_association_t *asoc = frag->asoc;
 	struct list_head *lfrag, *frag_list;
 	__u32 tsn;
 	int nfrags = 1;
-	struct sk_buff *pos;
+	struct sctp_chunk *pos;
 
 	/* Count the number of fragments. */
 	frag_list = &frag->frag_list;
@@ -553,17 +577,17 @@
 	}
 
 	/* Get a TSN block of nfrags TSNs. */
-	tsn = __sctp_association_get_tsn_block(asoc, nfrags);
+	tsn = sctp_association_get_tsn_block(asoc, nfrags);
 
-	pos = skb_peek(&q->out);
+	pos = (struct sctp_chunk *)skb_peek(&q->out);
 	/* Transmit the first fragment. */
-	sctp_xmit_frag(q, pos, packet, frag, tsn++);
+	sctp_xmit_frag(q, pos, pkt, frag, tsn++);
 
 	/* Transmit the rest of fragments. */
 	frag_list = &frag->frag_list;
 	list_for_each(lfrag, frag_list) {
 		frag = list_entry(lfrag, sctp_chunk_t, frag_list);
-		sctp_xmit_frag(q, pos, packet, frag, tsn++);
+		sctp_xmit_frag(q, pos, pkt, frag, tsn++);
 	}
 }
 
@@ -595,7 +619,7 @@
  	old_flags = chunk->chunk_hdr->flags;
 	if (old_flags & SCTP_DATA_FIRST_FRAG)
 		flags = SCTP_DATA_FIRST_FRAG;
-	else 
+	else
 		flags = SCTP_DATA_MIDDLE_FRAG;
 
 	/* Make the first fragment. */
@@ -672,15 +696,14 @@
  *
  * Description: Send everything in q which we legally can, subject to
  * congestion limitations.
- *
- * Note: This function can be called from multiple contexts so appropriate
+ * * Note: This function can be called from multiple contexts so appropriate
  * locking concerns must be made.  Today we use the sock lock to protect
  * this function.
  */
 int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
 {
-	sctp_packet_t *packet;
-	sctp_packet_t singleton;
+	struct sctp_packet *packet;
+	struct sctp_packet singleton;
 	sctp_association_t *asoc = q->asoc;
 	int ecn_capable = asoc->peer.ecn_capable;
 	__u16 sport = asoc->base.bind_addr.port;
@@ -719,7 +742,7 @@
 	}
 
 	queue = &q->control;
-	while (NULL != (chunk = (sctp_chunk_t *)skb_dequeue(queue))) {
+	while ((chunk = (sctp_chunk_t *)skb_dequeue(queue))) {
 		/* Pick the right transport to use. */
 		new_transport = chunk->transport;
 
@@ -852,7 +875,8 @@
 		/* Finally, transmit new packets.  */
 		start_timer = 0;
 		queue = &q->out;
-		while (NULL != (chunk = (sctp_chunk_t *) skb_dequeue(queue))) {
+
+		while (NULL != (chunk = sctp_outq_dequeue_data(q))) {
 			/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
 			 * stream identifier.
 			 */
@@ -925,6 +949,7 @@
 			switch (status) {
 			case SCTP_XMIT_PMTU_FULL:
 			case SCTP_XMIT_RWND_FULL:
+			case SCTP_XMIT_NAGLE_DELAY:
 				/* We could not append this chunk, so put
 				 * the chunk back on the output queue.
 				 */
@@ -932,7 +957,7 @@
 					"not transmit TSN: 0x%x, status: %d\n",
 					ntohl(chunk->subh.data_hdr->tsn),
 					status);
-				skb_queue_head(queue, (struct sk_buff *)chunk);
+				sctp_outq_head_data(q, chunk);
 				goto sctp_flush_out;
 				break;
 
@@ -994,6 +1019,7 @@
 	}
 
 sctp_flush_out:
+
 	/* Before returning, examine all the transports touched in
 	 * this call.  Right now, we bluntly force clear all the
 	 * transports.  Things might change after we implement Nagle.
@@ -1003,7 +1029,7 @@
 	 */
 	while ((ltransport = sctp_list_dequeue(&transport_list)) != NULL ) {
 		struct sctp_transport *t = list_entry(ltransport,
-						      struct sctp_transport, 
+						      struct sctp_transport,
 						      send_ready);
 		if (t != transport)
 			transport = t;
@@ -1125,7 +1151,7 @@
 	 * This is a MASSIVE candidate for optimization.
 	 */
 	list_for_each(pos, transport_list) {
-		transport  = list_entry(pos, struct sctp_transport, 
+		transport  = list_entry(pos, struct sctp_transport,
 					transports);
 		sctp_check_transmitted(q, &transport->transmitted,
 				       transport, sack, highest_new_tsn);
@@ -1163,11 +1189,10 @@
 	sack_a_rwnd = ntohl(sack->a_rwnd);
 	outstanding = q->outstanding_bytes;
 
-	if (outstanding < sack_a_rwnd) {
+	if (outstanding < sack_a_rwnd)
 		sack_a_rwnd -= outstanding;
-	} else {
+	else
 		sack_a_rwnd = 0;
-	}
 
 	asoc->peer.rwnd = sack_a_rwnd;
 
@@ -1179,7 +1204,7 @@
 		goto finish;
 
 	list_for_each(pos, transport_list) {
-		transport  = list_entry(pos, struct sctp_transport, 
+		transport  = list_entry(pos, struct sctp_transport,
 					transports);
 		q->empty = q->empty && list_empty(&transport->transmitted);
 		if (!q->empty)
diff -Nru a/net/sctp/protocol.c b/net/sctp/protocol.c
--- a/net/sctp/protocol.c	Mon Feb 17 16:31:26 2003
+++ b/net/sctp/protocol.c	Tue Mar  4 08:32:52 2003
@@ -58,7 +58,7 @@
 #include <net/inet_common.h>
 
 /* Global data structures. */
-sctp_protocol_t sctp_proto;
+struct sctp_protocol sctp_proto;
 struct proc_dir_entry	*proc_net_sctp;
 DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics);
 
@@ -152,7 +152,7 @@
 /* Extract our IP addresses from the system and stash them in the
  * protocol structure.
  */
-static void __sctp_get_local_addr_list(sctp_protocol_t *proto)
+static void __sctp_get_local_addr_list(struct sctp_protocol *proto)
 {
 	struct net_device *dev;
 	struct list_head *pos;
@@ -168,7 +168,7 @@
 	read_unlock(&dev_base_lock);
 }
 
-static void sctp_get_local_addr_list(sctp_protocol_t *proto)
+static void sctp_get_local_addr_list(struct sctp_protocol *proto)
 {
 	long flags __attribute__ ((unused));
 
@@ -178,7 +178,7 @@
 }
 
 /* Free the existing local addresses.  */
-static void __sctp_free_local_addr_list(sctp_protocol_t *proto)
+static void __sctp_free_local_addr_list(struct sctp_protocol *proto)
 {
 	struct sockaddr_storage_list *addr;
 	struct list_head *pos, *temp;
@@ -191,7 +191,7 @@
 }
 
 /* Free the existing local addresses.  */
-static void sctp_free_local_addr_list(sctp_protocol_t *proto)
+static void sctp_free_local_addr_list(struct sctp_protocol *proto)
 {
 	long flags __attribute__ ((unused));
 
@@ -201,8 +201,9 @@
 }
 
 /* Copy the local addresses which are valid for 'scope' into 'bp'.  */
-int sctp_copy_local_addr_list(sctp_protocol_t *proto, sctp_bind_addr_t *bp,
-			      sctp_scope_t scope, int priority, int copy_flags)
+int sctp_copy_local_addr_list(struct sctp_protocol *proto,
+			      struct sctp_bind_addr *bp, sctp_scope_t scope,
+			      int priority, int copy_flags)
 {
 	struct sockaddr_storage_list *addr;
 	int error = 0;
@@ -331,7 +332,7 @@
 static int sctp_v4_available(const union sctp_addr *addr)
 {
 	int ret = inet_addr_type(addr->v4.sin_addr.s_addr);
-	
+
 	/* FIXME: ip_nonlocal_bind sysctl support. */
 
 	if (addr->v4.sin_addr.s_addr != INADDR_ANY && ret != RTN_LOCAL)
@@ -380,7 +381,7 @@
 
 /* Returns a valid dst cache entry for the given source and destination ip
  * addresses. If an association is passed, trys to get a dst entry with a
- * source adddress that matches an address in the bind address list. 
+ * source adddress that matches an address in the bind address list.
  */
 struct dst_entry *sctp_v4_get_dst(sctp_association_t *asoc,
 				  union sctp_addr *daddr,
@@ -479,6 +480,61 @@
 
 }
 
+/* Create and initialize a new sk for the socket returned by accept(). */ 
+struct sock *sctp_v4_create_accept_sk(struct sock *sk,
+				      struct sctp_association *asoc)
+{
+	struct sock *newsk;
+	struct inet_opt *inet = inet_sk(sk);
+	struct inet_opt *newinet;
+
+	newsk = sk_alloc(PF_INET, GFP_KERNEL, sizeof(struct sctp_sock),
+			 sk->slab);
+	if (!newsk)
+		goto out;
+
+	sock_init_data(NULL, newsk);
+
+	newsk->type = SOCK_STREAM;
+
+	newsk->prot = sk->prot;
+	newsk->no_check = sk->no_check;
+	newsk->reuse = sk->reuse;
+
+	newsk->destruct = inet_sock_destruct;
+	newsk->zapped = 0;
+	newsk->family = PF_INET;
+	newsk->protocol = IPPROTO_SCTP;
+	newsk->backlog_rcv = sk->prot->backlog_rcv;
+	
+	newinet = inet_sk(newsk);
+	newinet->sport = inet->sport;
+	newinet->saddr = inet->saddr;
+	newinet->rcv_saddr = inet->saddr;
+	newinet->dport = asoc->peer.port;
+	newinet->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr;
+	newinet->pmtudisc = inet->pmtudisc;
+      	newinet->id = 0;
+	
+	newinet->ttl = sysctl_ip_default_ttl;
+	newinet->mc_loop = 1;
+	newinet->mc_ttl = 1;
+	newinet->mc_index = 0;
+	newinet->mc_list = NULL;
+
+#ifdef INET_REFCNT_DEBUG
+	atomic_inc(&inet_sock_nr);
+#endif
+
+	if (0 != newsk->prot->init(newsk)) {
+		inet_sock_release(newsk);
+		newsk = NULL;
+	}
+
+out:
+	return newsk;
+}
+
 /* Event handler for inet address addition/deletion events.
  * Basically, whenever there is an event, we re-build our local address list.
  */
@@ -501,10 +557,13 @@
  */
 int sctp_ctl_sock_init(void)
 {
-	int err = 0;
-	int family = PF_INET;
+	int err;
+	sa_family_t family;
 
-	SCTP_V6(family = PF_INET6;)
+	if (sctp_get_pf_specific(PF_INET6))
+		family = PF_INET6;
+	else 
+		family = PF_INET;
 
 	err = sock_create(family, SOCK_SEQPACKET, IPPROTO_SCTP,
 			  &sctp_ctl_socket);
@@ -630,6 +689,16 @@
 	return sctp_v4_available(addr);
 }
 
+/* Fill in Supported Address Type information for INIT and INIT-ACK
+ * chunks.  Returns number of addresses supported.
+ */
+static int sctp_inet_supported_addrs(const struct sctp_opt *opt, 
+				     __u16 *types)
+{
+	types[0] = SCTP_PARAM_IPV4_ADDRESS;
+	return 1;
+}
+
 /* Wrapper routine that calls the ip transmit routine. */
 static inline int sctp_v4_xmit(struct sk_buff *skb,
 			       struct sctp_transport *transport, int ipfragok)
@@ -652,6 +721,8 @@
 	.af_supported  = sctp_inet_af_supported,
 	.cmp_addr      = sctp_inet_cmp_addr,
 	.bind_verify   = sctp_inet_bind_verify,
+	.supported_addrs = sctp_inet_supported_addrs,
+	.create_accept_sk = sctp_v4_create_accept_sk,
 	.af            = &sctp_ipv4_specific,
 };
 
@@ -682,7 +753,7 @@
 };
 
 /* Registration with AF_INET family.  */
-struct inet_protosw sctp_protosw = {
+static struct inet_protosw sctp_seqpacket_protosw = {
 	.type       = SOCK_SEQPACKET,
 	.protocol   = IPPROTO_SCTP,
 	.prot       = &sctp_prot,
@@ -691,6 +762,15 @@
 	.no_check   = 0,
 	.flags      = SCTP_PROTOSW_FLAG
 };
+static struct inet_protosw sctp_stream_protosw = {
+	.type       = SOCK_STREAM,
+	.protocol   = IPPROTO_SCTP,
+	.prot       = &sctp_prot,
+	.ops        = &inet_seqpacket_ops,
+	.capability = -1,
+	.no_check   = 0,
+	.flags      = SCTP_PROTOSW_FLAG
+};
 
 /* Register with IP layer.  */
 static struct inet_protocol sctp_protocol = {
@@ -756,7 +836,7 @@
 static int __init init_sctp_mibs(void)
 {
 	int i;
-	
+
 	sctp_statistics[0] = kmalloc_percpu(sizeof (struct sctp_mib),
 					    GFP_KERNEL);
 	if (!sctp_statistics[0])
@@ -778,7 +858,7 @@
 		}
 	}
 	return 0;
-	
+
 }
 
 static void cleanup_sctp_mibs(void)
@@ -797,14 +877,15 @@
 	if (inet_add_protocol(&sctp_protocol, IPPROTO_SCTP) < 0)
 		return -EAGAIN;
 
-	/* Add SCTP to inetsw linked list.  */
-	inet_register_protosw(&sctp_protosw);
+	/* Add SCTP(TCP and UDP style) to inetsw linked list.  */
+	inet_register_protosw(&sctp_seqpacket_protosw);
+	inet_register_protosw(&sctp_stream_protosw);
 
 	/* Allocate and initialise sctp mibs.  */
 	status = init_sctp_mibs();
-	if (status) 
+	if (status)
 		goto err_init_mibs;
-		
+
 	/* Initialize proc fs directory.  */
 	sctp_proc_init();
 
@@ -831,7 +912,7 @@
 	/* Valid.Cookie.Life        - 60  seconds */
 	sctp_proto.valid_cookie_life	= 60 * HZ;
 
-	/* Whether Cookie Preservative is enabled(1) or not(0) */ 
+	/* Whether Cookie Preservative is enabled(1) or not(0) */
 	sctp_proto.cookie_preserve_enable = 1;
 
 	/* Max.Burst		    - 4 */
@@ -920,7 +1001,7 @@
 	INIT_LIST_HEAD(&sctp_proto.local_addr_list);
 	sctp_proto.local_addr_lock = SPIN_LOCK_UNLOCKED;
 
-	/* Register notifier for inet address additions/deletions. */ 
+	/* Register notifier for inet address additions/deletions. */
 	register_inetaddr_notifier(&sctp_inetaddr_notifier);
 
 	sctp_get_local_addr_list(&sctp_proto);
@@ -942,9 +1023,10 @@
 	sctp_dbg_objcnt_exit();
 	sctp_proc_exit();
 	cleanup_sctp_mibs();
-err_init_mibs:	
+err_init_mibs:
 	inet_del_protocol(&sctp_protocol, IPPROTO_SCTP);
-	inet_unregister_protosw(&sctp_protosw);
+	inet_unregister_protosw(&sctp_seqpacket_protosw);
+	inet_unregister_protosw(&sctp_stream_protosw);
 	return status;
 }
 
@@ -977,7 +1059,8 @@
 	cleanup_sctp_mibs();
 
 	inet_del_protocol(&sctp_protocol, IPPROTO_SCTP);
-	inet_unregister_protosw(&sctp_protosw);
+	inet_unregister_protosw(&sctp_seqpacket_protosw);
+	inet_unregister_protosw(&sctp_stream_protosw);
 }
 
 module_init(sctp_init);
diff -Nru a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
--- a/net/sctp/sm_make_chunk.c	Thu Feb 13 10:24:15 2003
+++ b/net/sctp/sm_make_chunk.c	Thu Mar  6 09:04:50 2003
@@ -68,29 +68,6 @@
 
 /* RFC 2960 3.3.2 Initiation (INIT) (1)
  *
- * Note 4: This parameter, when present, specifies all the
- * address types the sending endpoint can support. The absence
- * of this parameter indicates that the sending endpoint can
- * support any address type.
- */
-static const sctp_supported_addrs_param_t sat_param = {
-	{
-		SCTP_PARAM_SUPPORTED_ADDRESS_TYPES,
-		__constant_htons(SCTP_SAT_LEN),
-	}
-};
-
-/* gcc 3.2 doesn't allow initialization of zero-length arrays. So the above
- * structure is split and the address types array is initialized using a
- * fixed length array.
- */
-static const __u16 sat_addr_types[2] = {
-	SCTP_PARAM_IPV4_ADDRESS,
-	SCTP_V6(SCTP_PARAM_IPV6_ADDRESS,)
-};
-
-/* RFC 2960 3.3.2 Initiation (INIT) (1)
- *
  * Note 2: The ECN capable field is reserved for future use of
  * Explicit Congestion Notification.
  */
@@ -174,7 +151,10 @@
 	union sctp_params addrs;
 	size_t chunksize;
 	sctp_chunk_t *retval = NULL;
-	int addrs_len = 0;
+	int num_types, addrs_len = 0;
+	struct sctp_opt *sp;
+	sctp_supported_addrs_param_t sat;
+	__u16 types[2];
 
 	/* RFC 2960 3.3.2 Initiation (INIT) (1)
 	 *
@@ -195,7 +175,11 @@
 	init.num_inbound_streams   = htons(asoc->c.sinit_max_instreams);
 	init.initial_tsn	   = htonl(asoc->c.initial_tsn);
 
-	chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN;
+	/* How many address types are needed? */
+	sp = sctp_sk(asoc->base.sk);
+	num_types = sp->pf->supported_addrs(sp, types);
+
+	chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types);
 	chunksize += sizeof(ecap_param);
 	chunksize += vparam_len;
 
@@ -220,8 +204,18 @@
 	retval->param_hdr.v =
 		sctp_addto_chunk(retval, addrs_len, addrs.v);
 
-	sctp_addto_chunk(retval, sizeof(sctp_paramhdr_t), &sat_param);
-	sctp_addto_chunk(retval, sizeof(sat_addr_types), sat_addr_types);
+	/* RFC 2960 3.3.2 Initiation (INIT) (1)
+	 *
+	 * Note 4: This parameter, when present, specifies all the
+	 * address types the sending endpoint can support. The absence
+	 * of this parameter indicates that the sending endpoint can
+	 * support any address type.
+	 */
+	sat.param_hdr.type = SCTP_PARAM_SUPPORTED_ADDRESS_TYPES;
+	sat.param_hdr.length = htons(SCTP_SAT_LEN(num_types));
+	sctp_addto_chunk(retval, sizeof(sat), &sat);
+	sctp_addto_chunk(retval, num_types * sizeof(__u16), &types);
+
 	sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param);
 nodata:
 	if (addrs.v)
@@ -604,7 +598,7 @@
 
 	/* Initialize the SACK header.  */
 	sack.cum_tsn_ack	    = htonl(ctsn);
-	sack.a_rwnd 		    = htonl(asoc->rwnd);
+	sack.a_rwnd 		    = htonl(asoc->a_rwnd);
 	sack.num_gap_ack_blocks     = htons(num_gabs);
 	sack.num_dup_tsns           = htons(num_dup_tsns);
 
@@ -1159,7 +1153,7 @@
 	first_len = max;
 
 	/* Encourage Cookie-ECHO bundling. */
-	if (asoc->state < SCTP_STATE_ESTABLISHED) {
+	if (asoc->state < SCTP_STATE_COOKIE_ECHOED) {
 		whole = msg_len / (max - SCTP_ARBITRARY_COOKIE_ECHO_LEN);
 
 		/* Account for the DATA to be bundled with the COOKIE-ECHO. */
@@ -1282,7 +1276,7 @@
 		 * assign a TSN.
 		 */
 		chunk->subh.data_hdr->tsn =
-			htonl(__sctp_association_get_next_tsn(chunk->asoc));
+			htonl(sctp_association_get_next_tsn(chunk->asoc));
 		chunk->has_tsn = 1;
 	}
 }
diff -Nru a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
--- a/net/sctp/sm_sideeffect.c	Tue Feb 18 16:21:43 2003
+++ b/net/sctp/sm_sideeffect.c	Fri Mar  7 02:28:09 2003
@@ -105,8 +105,8 @@
 #define DEBUG_POST_SFX \
 	SCTP_DEBUG_PRINTK("sctp_do_sm post sfx: error %d, asoc %p[%s]\n", \
 			  error, asoc, \
-			  sctp_state_tbl[sctp_id2assoc(ep->base.sk, \
-			  sctp_assoc2id(asoc))?asoc->state:SCTP_STATE_CLOSED])
+			  sctp_state_tbl[(asoc && sctp_id2assoc(ep->base.sk, \
+			  sctp_assoc2id(asoc)))?asoc->state:SCTP_STATE_CLOSED])
 
 /*
  * This is the master state machine processing function.
@@ -256,7 +256,7 @@
 	sctp_cmd_t *cmd;
 	sctp_chunk_t *new_obj;
 	sctp_chunk_t *chunk = NULL;
-	sctp_packet_t *packet;
+	struct sctp_packet *packet;
 	struct list_head *pos;
 	struct timer_list *timer;
 	unsigned long timeout;
@@ -716,13 +716,12 @@
 		asoc->peer.sack_needed = 1;
 		goto out;
 	} else {
+		if (asoc->a_rwnd > asoc->rwnd)
+			asoc->a_rwnd = asoc->rwnd;
 		sack = sctp_make_sack(asoc);
 		if (!sack)
 			goto nomem;
 
-		/* Update the last advertised rwnd value. */
-		asoc->a_rwnd = asoc->rwnd;
-
 		asoc->peer.sack_needed = 0;
 
 		error = sctp_outq_tail(&asoc->outqueue, sack);
@@ -1223,13 +1222,35 @@
 static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds, sctp_association_t *asoc,
 			       sctp_state_t state)
 {
+
+	struct sock *sk = asoc->base.sk;
+	struct sctp_opt *sp = sctp_sk(sk);
+
 	asoc->state = state;
 	asoc->state_timestamp = jiffies;
 
-	/* Wake up any process waiting for the association to
-	 * get established.
+	if ((SCTP_STATE_ESTABLISHED == asoc->state) ||
+	    (SCTP_STATE_CLOSED == asoc->state)) { 
+		/* Wake up any processes waiting in the asoc's wait queue in
+		 * sctp_wait_for_connect() or sctp_wait_for_sndbuf(). 
+	 	 */
+		if (waitqueue_active(&asoc->wait))
+			wake_up_interruptible(&asoc->wait);
+
+		/* Wake up any processes waiting in the sk's sleep queue of
+		 * a TCP-style or UDP-style peeled-off socket in
+		 * sctp_wait_for_accept() or sctp_wait_for_packet().
+		 * For a UDP-style socket, the waiters are woken up by the
+		 * notifications.
+		 */
+		if (SCTP_SOCKET_UDP != sp->type)
+			sk->state_change(sk);
+	}
+
+	/* Change the sk->state of a TCP-style socket that has sucessfully
+	 * completed a connect() call.
 	 */
 	if ((SCTP_STATE_ESTABLISHED == asoc->state) &&
-	    (waitqueue_active(&asoc->wait)))
-		wake_up_interruptible(&asoc->wait);
+	    (SCTP_SOCKET_TCP == sp->type) && (SCTP_SS_CLOSED == sk->state))
+	    sk->state = SCTP_SS_ESTABLISHED;
 }
diff -Nru a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
--- a/net/sctp/sm_statefuns.c	Mon Mar  3 00:57:24 2003
+++ b/net/sctp/sm_statefuns.c	Thu Mar  6 13:36:45 2003
@@ -189,7 +189,7 @@
 	sctp_chunk_t *repl;
 	sctp_association_t *new_asoc;
 	sctp_chunk_t *err_chunk;
-	sctp_packet_t *packet;
+	struct sctp_packet *packet;
 	sctp_unrecognized_param_t *unk_param;
 	int len;
 
@@ -354,10 +354,9 @@
 	sctp_init_chunk_t *initchunk;
 	__u32 init_tag;
 	sctp_chunk_t *err_chunk;
-	sctp_packet_t *packet;
+	struct sctp_packet *packet;
 	sctp_disposition_t ret;
 
-
 	/* 6.10 Bundling
 	 * An endpoint MUST NOT bundle INIT, INIT ACK or
 	 * SHUTDOWN COMPLETE with any other chunks.
@@ -912,14 +911,14 @@
 				      sctp_cmd_seq_t *commands)
 {
 	int len;
-	sctp_packet_t *pkt;
+	struct sctp_packet *pkt;
 	sctp_addr_param_t *addrparm;
 	sctp_errhdr_t *errhdr;
 	sctp_endpoint_t *ep;
 	char buffer[sizeof(sctp_errhdr_t) + sizeof(sctp_addr_param_t)];
 
-	/* Build the error on the stack.   We are way to malloc
-	 * malloc crazy throughout the code today.
+	/* Build the error on the stack.   We are way to malloc crazy
+	 * throughout the code today.
 	 */
 	errhdr = (sctp_errhdr_t *)buffer;
 	addrparm = (sctp_addr_param_t *)errhdr->variable;
@@ -1105,11 +1104,10 @@
 	sctp_chunk_t *repl;
 	sctp_association_t *new_asoc;
 	sctp_chunk_t *err_chunk;
-	sctp_packet_t *packet;
+	struct sctp_packet *packet;
 	sctp_unrecognized_param_t *unk_param;
 	int len;
 
-
 	/* 6.10 Bundling
 	 * An endpoint MUST NOT bundle INIT, INIT ACK or
 	 * SHUTDOWN COMPLETE with any other chunks.
@@ -2351,7 +2349,7 @@
 		 * room.   Note: Playing nice with a confused sender.  A
 		 * malicious sender can still eat up all our buffer
 		 * space and in the future we may want to detect and
-		 * do more drastic reneging. 
+		 * do more drastic reneging.
 		 */
 		if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) &&
 		    (sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) {
@@ -2751,7 +2749,7 @@
 					void *arg,
 					sctp_cmd_seq_t *commands)
 {
-	sctp_packet_t *packet = NULL;
+	struct sctp_packet *packet = NULL;
 	sctp_chunk_t *chunk = arg;
 	sctp_chunk_t *abort;
 
@@ -2953,7 +2951,7 @@
 				      void *arg,
 				      sctp_cmd_seq_t *commands)
 {
-	sctp_packet_t *packet = NULL;
+	struct sctp_packet *packet = NULL;
 	sctp_chunk_t *chunk = arg;
 	sctp_chunk_t *shut;
 
@@ -4377,13 +4375,13 @@
 /* Create an ABORT packet to be sent as a response, with the specified
  * error causes.
  */
-sctp_packet_t *sctp_abort_pkt_new(const sctp_endpoint_t *ep,
+struct sctp_packet *sctp_abort_pkt_new(const sctp_endpoint_t *ep,
 				  const sctp_association_t *asoc,
 				  sctp_chunk_t *chunk,
 				  const void *payload,
 				  size_t paylen)
 {
-	sctp_packet_t *packet;
+	struct sctp_packet *packet;
 	sctp_chunk_t *abort;
 
 	packet = sctp_ootb_pkt_new(asoc, chunk);
@@ -4413,10 +4411,10 @@
 }
 
 /* Allocate a packet for responding in the OOTB conditions.  */
-sctp_packet_t *sctp_ootb_pkt_new(const sctp_association_t *asoc,
+struct sctp_packet *sctp_ootb_pkt_new(const sctp_association_t *asoc,
 				 const sctp_chunk_t *chunk)
 {
-	sctp_packet_t *packet;
+	struct sctp_packet *packet;
 	struct sctp_transport *transport;
 	__u16 sport;
 	__u16 dport;
@@ -4449,7 +4447,7 @@
 		goto nomem;
 
 	/* Allocate a new packet for sending the response. */
-	packet = t_new(sctp_packet_t, GFP_ATOMIC);
+	packet = t_new(struct sctp_packet, GFP_ATOMIC);
 	if (!packet)
 		goto nomem_packet;
 
@@ -4471,7 +4469,7 @@
 }
 
 /* Free the packet allocated earlier for responding in the OOTB condition.  */
-void sctp_ootb_pkt_free(sctp_packet_t *packet)
+void sctp_ootb_pkt_free(struct sctp_packet *packet)
 {
 	sctp_transport_free(packet->transport);
 	sctp_packet_free(packet);
@@ -4484,7 +4482,7 @@
 				sctp_cmd_seq_t *commands,
 				sctp_chunk_t *err_chunk)
 {
-	sctp_packet_t *packet;
+	struct sctp_packet *packet;
 
 	if (err_chunk) {
 		packet = sctp_ootb_pkt_new(asoc, chunk);
diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c	Tue Feb 18 16:25:57 2003
+++ b/net/sctp/socket.c	Thu Mar  6 09:46:23 2003
@@ -88,12 +88,46 @@
 				int msg_len);
 static int sctp_wait_for_packet(struct sock * sk, int *err, long *timeo_p);
 static int sctp_wait_for_connect(struct sctp_association *, long *timeo_p);
+static int sctp_wait_for_accept(struct sock *sk, long timeo);
 static inline int sctp_verify_addr(struct sock *, union sctp_addr *, int);
 static int sctp_bindx_add(struct sock *, struct sockaddr_storage *, int);
 static int sctp_bindx_rem(struct sock *, struct sockaddr_storage *, int);
 static int sctp_do_bind(struct sock *, union sctp_addr *, int);
 static int sctp_autobind(struct sock *sk);
+static void sctp_sock_migrate(struct sock *, struct sock *,
+			      struct sctp_association *, sctp_socket_type_t);
 
+/* Look up the association by its id.  If this is not a UDP-style
+ * socket, the ID field is always ignored.
+ */
+sctp_association_t *sctp_id2assoc(struct sock *sk, sctp_assoc_t id)
+{
+	sctp_association_t *asoc = NULL;
+
+	/* If this is not a UDP-style socket, assoc id should be 
+	 * ignored.
+	 */
+	if (SCTP_SOCKET_UDP != sctp_sk(sk)->type) {
+		if (!list_empty(&sctp_sk(sk)->ep->asocs))
+			asoc = list_entry(sctp_sk(sk)->ep->asocs.next,
+					  sctp_association_t, asocs);
+		return asoc;
+	}
+
+	/* First, verify that this is a kernel address. */
+	if (sctp_is_valid_kaddr((unsigned long) id)) {
+		sctp_association_t *temp = (sctp_association_t *) id;
+
+		/* Verify that this _is_ an sctp_association_t
+		 * data structure and if so, that the socket matches.
+		 */
+		if ((SCTP_ASSOC_EYECATCHER == temp->eyecatcher) &&
+		    (temp->base.sk == sk))
+			asoc = temp;
+	}
+
+	return asoc;
+}
 
 /* API 3.1.2 bind() - UDP Style Syntax
  * The syntax of bind() is,
@@ -818,19 +852,7 @@
 			}
 		}
 	} else {
-		/* For a peeled-off socket, ignore any associd specified by
-		 * the user with SNDRCVINFO.
-		 */
-		if (SCTP_SOCKET_UDP_HIGH_BANDWIDTH == sp->type) {
-			if (list_empty(&ep->asocs)) {
-				err = -EINVAL;
-				goto out_unlock;
-			}
-			asoc = list_entry(ep->asocs.next, sctp_association_t,
-					  asocs);
-		} else if (associd) {
-			asoc = sctp_id2assoc(sk, associd);
-		}
+		asoc = sctp_id2assoc(sk, associd);
 		if (!asoc) {
 			err = -EINVAL;
 			goto out_unlock;
@@ -1007,7 +1029,7 @@
 		sctp_set_owner_w(chunk);
 
 		/* This flag, in the UDP model, requests the SCTP stack to
-		 * override the primary destination address with the 
+		 * override the primary destination address with the
 		 * address found with the sendto/sendmsg call.
 		 */
 		if (sinfo_flags & MSG_ADDR_OVER) {
@@ -1126,17 +1148,19 @@
 	int err = 0;
 	int skb_len;
 
-	SCTP_DEBUG_PRINTK("sctp_recvmsg("
-			  "%s: %p, %s: %p, %s: %d, %s: %d, %s: "
-			  "0x%x, %s: %p)\n",
-			  "sk", sk,
-			  "msghdr", msg,
-			  "len", len,
-			  "knoblauch", noblock,
-			  "flags", flags,
-			  "addr_len", addr_len);
+	SCTP_DEBUG_PRINTK("sctp_recvmsg(%s: %p, %s: %p, %s: %d, %s: %d, %s: "
+			  "0x%x, %s: %p)\n", "sk", sk, "msghdr", msg,
+			  "len", len, "knoblauch", noblock,
+			  "flags", flags, "addr_len", addr_len);
 
 	sctp_lock_sock(sk);
+
+	if ((SCTP_SOCKET_TCP == sp->type) &&
+	    (SCTP_SS_ESTABLISHED != sk->state)) {
+		err = -ENOTCONN;
+		goto out;
+	}
+	
 	skb = sctp_skb_recv_datagram(sk, flags, noblock, &err);
 	if (!skb)
 		goto out;
@@ -1207,7 +1231,7 @@
 	return err;
 }
 
-static inline int sctp_setsockopt_disable_fragments(struct sock *sk,
+static int sctp_setsockopt_disable_fragments(struct sock *sk,
 						    char *optval, int optlen)
 {
 	int val;
@@ -1223,8 +1247,8 @@
 	return 0;
 }
 
-static inline int sctp_setsockopt_set_events(struct sock *sk, char *optval,
-					     int optlen)
+static int sctp_setsockopt_events(struct sock *sk, char *optval,
+					int optlen)
 {
 	if (optlen != sizeof(struct sctp_event_subscribe))
 		return -EINVAL;
@@ -1233,7 +1257,7 @@
 	return 0;
 }
 
-static inline int sctp_setsockopt_autoclose(struct sock *sk, char *optval,
+static int sctp_setsockopt_autoclose(struct sock *sk, char *optval,
 					    int optlen)
 {
 	struct sctp_opt *sp = sctp_sk(sk);
@@ -1250,9 +1274,8 @@
 	return 0;
 }
 
-static inline int sctp_setsockopt_set_peer_addr_params(struct sock *sk,
-						       char *optval,
-						       int optlen)
+static int sctp_setsockopt_peer_addr_params(struct sock *sk,
+						   char *optval, int optlen)
 {
 	struct sctp_paddrparams params;
 	sctp_association_t *asoc;
@@ -1290,8 +1313,7 @@
 		error = sctp_primitive_REQUESTHEARTBEAT (asoc, trans);
 		if (error)
 			return error;
-	}
-	else {
+	} else {
 	/* The value of the heartbeat interval, in milliseconds. A value of 0,
 	 * when modifying the parameter, specifies that the heartbeat on this
 	 * address should be disabled.
@@ -1311,7 +1333,7 @@
 	return 0;
 }
 
-static inline int sctp_setsockopt_initmsg(struct sock *sk, char *optval,
+static int sctp_setsockopt_initmsg(struct sock *sk, char *optval,
 					  int optlen)
 {
 	if (optlen != sizeof(struct sctp_initmsg))
@@ -1336,7 +1358,7 @@
  *   sinfo_timetolive.  The user must provide the sinfo_assoc_id field in
  *   to this call if the caller is using the UDP model.
  */
-static inline int sctp_setsockopt_set_default_send_param(struct sock *sk,
+static int sctp_setsockopt_default_send_param(struct sock *sk,
 						char *optval, int optlen)
 {
 	struct sctp_sndrcvinfo info;
@@ -1359,6 +1381,66 @@
 	return 0;
 }
 
+/* 7.1.10 Set Peer Primary Address (SCTP_SET_PEER_PRIMARY_ADDR)
+ *
+ * Requests that the local SCTP stack use the enclosed peer address as
+ * the association primary.  The enclosed address must be one of the
+ * association peer's addresses.
+ */
+static int sctp_setsockopt_peer_prim(struct sock *sk, char *optval, int optlen)
+{
+	struct sctp_setpeerprim prim;
+	struct sctp_association *asoc;
+	union sctp_addr *addr;
+	struct sctp_transport *trans;
+
+	if (optlen != sizeof(struct sctp_setpeerprim))
+		return -EINVAL;
+
+	if (copy_from_user(&prim, optval, sizeof(struct sctp_setpeerprim)))
+		return -EFAULT;
+
+	asoc = sctp_id2assoc(sk, prim.sspp_assoc_id);
+	if (!asoc)
+		return -EINVAL;
+
+	/* Find the requested address. */
+	addr = (union sctp_addr *) &(prim.sspp_addr);
+
+	trans = sctp_assoc_lookup_paddr(asoc, addr);
+	if (!trans)
+		return -ENOENT;
+
+	sctp_assoc_set_primary(asoc, trans);
+
+	return 0;
+}
+
+/*
+ *
+ * 7.1.5 SCTP_NODELAY
+ *
+ * Turn on/off any Nagle-like algorithm.  This means that packets are
+ * generally sent as soon as possible and no unnecessary delays are
+ * introduced, at the cost of more packets in the network.  Expects an
+ *  integer boolean flag.
+ */
+static int sctp_setsockopt_nodelay(struct sock *sk, char *optval,
+					int optlen)
+{
+	__u8 val;
+
+	if (optlen < sizeof(__u8))
+		return -EINVAL;
+
+	if (get_user(val, (__u8 *)optval))
+		return -EFAULT;
+
+	sctp_sk(sk)->nodelay = (val == 0) ? 0 : 1;
+
+	return 0;
+}
+
 /* API 6.2 setsockopt(), getsockopt()
  *
  * Applications use setsockopt() and getsockopt() to set or retrieve
@@ -1434,7 +1516,7 @@
 		break;
 
 	case SCTP_SET_EVENTS:
-		retval = sctp_setsockopt_set_events(sk, optval, optlen);
+		retval = sctp_setsockopt_events(sk, optval, optlen);
 		break;
 
 	case SCTP_AUTOCLOSE:
@@ -1442,8 +1524,7 @@
 		break;
 
 	case SCTP_SET_PEER_ADDR_PARAMS:
-		retval = sctp_setsockopt_set_peer_addr_params(sk, optval,
-							      optlen);
+		retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen);
 		break;
 
 	case SCTP_INITMSG:
@@ -1451,8 +1532,16 @@
 		break;
 
 	case SCTP_SET_DEFAULT_SEND_PARAM:
-		retval = sctp_setsockopt_set_default_send_param(sk,
-							optval, optlen);
+		retval = sctp_setsockopt_default_send_param(sk, optval,
+							    optlen);
+		break;
+
+	case SCTP_SET_PEER_PRIMARY_ADDR:
+		retval = sctp_setsockopt_peer_prim(sk, optval, optlen);
+		break;
+
+	case SCTP_NODELAY:
+		retval = sctp_setsockopt_nodelay(sk, optval, optlen);
 		break;
 
 	default:
@@ -1503,8 +1592,14 @@
 	sp = sctp_sk(sk);
 	ep = sp->ep;
 
-	/* connect() cannot be done on a peeled-off socket. */
-	if (SCTP_SOCKET_UDP_HIGH_BANDWIDTH == sp->type) {
+	/* connect() cannot be done on a socket that is already in ESTABLISHED
+	 * state - UDP-style peeled off socket or a TCP-style socket that
+	 * is already connected. 
+	 * It cannot be done even on a TCP-style listening socket.
+	 */
+	if ((SCTP_SS_ESTABLISHED == sk->state) ||
+	    ((SCTP_SOCKET_TCP == sp->type) &&
+	     (SCTP_SS_LISTENING == sk->state))) {
 		err = -EISCONN;
 		goto out_unlock;
 	}
@@ -1513,6 +1608,8 @@
 	if (err)
 		goto out_unlock;
 
+	if (addr_len > sizeof(to))
+		addr_len = sizeof(to);
 	memcpy(&to, uaddr, addr_len);
 	to.v4.sin_port = ntohs(to.v4.sin_port);
 
@@ -1585,13 +1682,63 @@
 	return -EOPNOTSUPP; /* STUB */
 }
 
-/* FIXME: Write comments. */
+/* 4.1.4 accept() - TCP Style Syntax
+ *
+ * Applications use accept() call to remove an established SCTP
+ * association from the accept queue of the endpoint.  A new socket
+ * descriptor will be returned from accept() to represent the newly
+ * formed association.
+ */
 SCTP_STATIC struct sock *sctp_accept(struct sock *sk, int flags, int *err)
 {
-	int error = -EOPNOTSUPP;
+	struct sctp_opt *sp;
+	struct sctp_endpoint *ep;
+	struct sock *newsk = NULL;
+	struct sctp_association *assoc;
+	long timeo;
+	int error = 0;
+ 
+	sctp_lock_sock(sk);
 
-	*err = error;
-	return NULL;
+	sp = sctp_sk(sk);
+	ep = sp->ep;
+
+	if (SCTP_SOCKET_TCP != sp->type) {
+		error = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (SCTP_SS_LISTENING != sk->state) {
+		error = -EINVAL;
+		goto out;
+	}
+
+	timeo = sock_rcvtimeo(sk, sk->socket->file->f_flags & O_NONBLOCK);
+
+	error = sctp_wait_for_accept(sk, timeo);
+	if (error)
+		goto out;
+
+	/* We treat the list of associations on the endpoint as the accept 
+	 * queue and pick the first association on the list. 
+	 */
+	assoc = list_entry(ep->asocs.next, struct sctp_association, asocs);
+
+	newsk = sp->pf->create_accept_sk(sk, assoc); 
+	if (!newsk) {
+		error = -ENOMEM;
+		goto out;
+	}
+
+	/* Populate the fields of the newsk from the oldsk and migrate the
+	 * assoc to the newsk.
+	 */ 
+	sctp_sock_migrate(sk, newsk, assoc, SCTP_SOCKET_TCP);
+
+out:
+	sctp_release_sock(sk);
+ 	*err = error;
+	return newsk;
 }
 
 /* FIXME: Write Comments. */
@@ -1607,7 +1754,7 @@
 SCTP_STATIC int sctp_init_sock(struct sock *sk)
 {
 	sctp_endpoint_t *ep;
-	sctp_protocol_t *proto;
+	struct sctp_protocol *proto;
 	struct sctp_opt *sp;
 
 	SCTP_DEBUG_PRINTK("sctp_init_sock(sk: %p)\n", sk);
@@ -1617,7 +1764,16 @@
 	sp = sctp_sk(sk);
 
 	/* Initialize the SCTP per socket area.  */
-	sp->type = SCTP_SOCKET_UDP;
+	switch (sk->type) {
+	case SOCK_SEQPACKET:
+		sp->type = SCTP_SOCKET_UDP;
+		break;
+	case SOCK_STREAM:
+		sp->type = SCTP_SOCKET_TCP;
+		break;
+	default:
+		return -ESOCKTNOSUPPORT;
+	}
 
 	/* FIXME:  The next draft (04) of the SCTP Sockets Extensions
 	 * should include a socket option for manipulating these
@@ -1665,7 +1821,7 @@
 	sp->disable_fragments = 0;
 
 	/* Turn on/off any Nagle-like algorithm.  */
-	sp->nodelay           = 0;
+	sp->nodelay           = 1;
 
 	/* Auto-close idle associations after the configured
 	 * number of seconds.  A value of 0 disables this
@@ -1714,11 +1870,17 @@
 	/* STUB */
 }
 
+/* 7.2.1 Association Status (SCTP_STATUS)
+
+ * Applications can retrieve current status information about an
+ * association, including association state, peer receiver window size,
+ * number of unacked data chunks, and number of data chunks pending
+ * receipt.  This information is read-only.
+ */
 static int sctp_getsockopt_sctp_status(struct sock *sk, int len, char *optval,
 				       int *optlen)
 {
 	struct sctp_status status;
-	sctp_endpoint_t *ep;
 	sctp_association_t *assoc = NULL;
 	struct sctp_transport *transport;
 	sctp_assoc_t associd;
@@ -1735,20 +1897,10 @@
 	}
 
 	associd = status.sstat_assoc_id;
-	if ((SCTP_SOCKET_UDP_HIGH_BANDWIDTH != sctp_sk(sk)->type) && associd) {
-		assoc = sctp_id2assoc(sk, associd);
-		if (!assoc) {
-			retval = -EINVAL;
-			goto out;
-		}
-	} else {
-		ep = sctp_sk(sk)->ep;
-		if (list_empty(&ep->asocs)) {
-			retval = -EINVAL;
-			goto out;
-		}
-
-		assoc = list_entry(ep->asocs.next, sctp_association_t, asocs);
+	assoc = sctp_id2assoc(sk, associd);
+	if (!assoc) {
+		retval = -EINVAL;
+		goto out;
 	}
 
 	transport = assoc->peer.primary_path;
@@ -1788,7 +1940,7 @@
 	return (retval);
 }
 
-static inline int sctp_getsockopt_disable_fragments(struct sock *sk, int len,
+static int sctp_getsockopt_disable_fragments(struct sock *sk, int len,
 						    char *optval, int *optlen)
 {
 	int val;
@@ -1805,7 +1957,7 @@
 	return 0;
 }
 
-static inline int sctp_getsockopt_set_events(struct sock *sk, int len, char *optval, int *optlen)
+static int sctp_getsockopt_set_events(struct sock *sk, int len, char *optval, int *optlen)
 {
 	if (len != sizeof(struct sctp_event_subscribe))
 		return -EINVAL;
@@ -1814,7 +1966,7 @@
 	return 0;
 }
 
-static inline int sctp_getsockopt_autoclose(struct sock *sk, int len, char *optval, int *optlen)
+static int sctp_getsockopt_autoclose(struct sock *sk, int len, char *optval, int *optlen)
 {
 	/* Applicable to UDP-style socket only */
 	if (SCTP_SOCKET_TCP == sctp_sk(sk)->type)
@@ -1832,11 +1984,6 @@
 	struct sock *oldsk = assoc->base.sk;
 	struct sock *newsk;
 	struct socket *tmpsock;
-	sctp_endpoint_t *newep;
-	struct sctp_opt *oldsp = sctp_sk(oldsk);
-	struct sctp_opt *newsp;
-	struct sk_buff *skb, *tmp;
-	struct sctp_ulpevent *event;
 	int err = 0;
 
 	/* An association cannot be branched off from an already peeled-off
@@ -1846,88 +1993,24 @@
 		return -EOPNOTSUPP;
 
 	/* Create a new socket.  */
-	err = sock_create(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP, &tmpsock);
+	err = sock_create(oldsk->family, SOCK_SEQPACKET, IPPROTO_SCTP,
+			  &tmpsock);
 	if (err < 0)
 		return err;
 
 	newsk = tmpsock->sk;
-	newsp = sctp_sk(newsk);
-	newep = newsp->ep;
-
-	/* Migrate socket buffer sizes and all the socket level options to the
-	 * new socket.
-	 */
-	newsk->sndbuf = oldsk->sndbuf;
-	newsk->rcvbuf = oldsk->rcvbuf;
-	*newsp = *oldsp;
-
-	/* Restore the ep value that was overwritten with the above structure
-	 * copy.
-	 */
-	newsp->ep = newep;
-
-	/* Move any messages in the old socket's receive queue that are for the
-	 * peeled off association to the new socket's receive queue.
-	 */
-	sctp_skb_for_each(skb, &oldsk->receive_queue, tmp) {
-		event = sctp_skb2event(skb);
-		if (event->asoc == assoc) {
-			__skb_unlink(skb, skb->list);
-			__skb_queue_tail(&newsk->receive_queue, skb);
-		}
-	}
 
-	/* Clean up an messages pending delivery due to partial
-	 * delivery.   Three cases:
-	 * 1) No partial deliver;  no work.
-	 * 2) Peeling off partial delivery; keep pd_lobby in new pd_lobby.
-	 * 3) Peeling off non-partial delivery; move pd_lobby to recieve_queue.
-	 */
-	skb_queue_head_init(&newsp->pd_lobby);
-	sctp_sk(newsk)->pd_mode = assoc->ulpq.pd_mode;;
-
-	if (sctp_sk(oldsk)->pd_mode) {
-		struct sk_buff_head *queue;
-
-		/* Decide which queue to move pd_lobby skbs to. */
-		if (assoc->ulpq.pd_mode) {
-			queue = &newsp->pd_lobby;
-		} else
-			queue = &newsk->receive_queue;
-
-		/* Walk through the pd_lobby, looking for skbs that
-		 * need moved to the new socket.
-		 */
-		sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
-			event = sctp_skb2event(skb);
-			if (event->asoc == assoc) {
-				__skb_unlink(skb, skb->list);
-				__skb_queue_tail(queue, skb);
-			}
-		}
-
-		/* Clear up any skbs waiting for the partial
-		 * delivery to finish.
-		 */
-		if (assoc->ulpq.pd_mode)
-			sctp_clear_pd(oldsk);
-
-	}
-
-	/* Set the type of socket to indicate that it is peeled off from the
-	 * original socket.
-	 */
-	newsp->type = SCTP_SOCKET_UDP_HIGH_BANDWIDTH;
-
-	/* Migrate the association to the new socket.  */
-	sctp_assoc_migrate(assoc, newsk);
+	/* Populate the fields of the newsk from the oldsk and migrate the
+	 * assoc to the newsk.
+	 */ 
+	sctp_sock_migrate(oldsk, newsk, assoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
 
 	*newsock = tmpsock;
 
 	return err;
 }
 
-static inline int sctp_getsockopt_peeloff(struct sock *sk, int len, char *optval, int *optlen)
+static int sctp_getsockopt_peeloff(struct sock *sk, int len, char *optval, int *optlen)
 {
 	sctp_peeloff_arg_t peeloff;
 	struct socket *newsock;
@@ -1970,8 +2053,8 @@
 	return retval;
 }
 
-static inline int sctp_getsockopt_get_peer_addr_params(struct sock *sk,
-					int len, char *optval, int *optlen)
+static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, 
+						char *optval, int *optlen)
 {
 	struct sctp_paddrparams params;
 	sctp_association_t *asoc;
@@ -2014,7 +2097,7 @@
 	return 0;
 }
 
-static inline int sctp_getsockopt_initmsg(struct sock *sk, int len, char *optval, int *optlen)
+static int sctp_getsockopt_initmsg(struct sock *sk, int len, char *optval, int *optlen)
 {
 	if (len != sizeof(struct sctp_initmsg))
 		return -EINVAL;
@@ -2023,8 +2106,8 @@
 	return 0;
 }
 
-static inline int sctp_getsockopt_get_peer_addrs_num(struct sock *sk, int len,
-				char *optval, int *optlen)
+static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len, 
+					char *optval, int *optlen)
 {
 	sctp_assoc_t id;
 	sctp_association_t *asoc;
@@ -2053,7 +2136,7 @@
 	return 0;
 }
 
-static inline int sctp_getsockopt_get_peer_addrs(struct sock *sk, int len,
+static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
 				char *optval, int *optlen)
 {
 	sctp_association_t *asoc;
@@ -2093,8 +2176,8 @@
 	return 0;
 }
 
-static inline int sctp_getsockopt_get_local_addrs_num(struct sock *sk, int len,
-				char *optval, int *optlen)
+static int sctp_getsockopt_local_addrs_num(struct sock *sk, int len,
+						char *optval, int *optlen)
 {
 	sctp_assoc_t id;
 	sctp_bind_addr_t *bp;
@@ -2132,8 +2215,8 @@
 	return 0;
 }
 
-static inline int sctp_getsockopt_get_local_addrs(struct sock *sk, int len,
-				char *optval, int *optlen)
+static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
+					char *optval, int *optlen)
 {
 	sctp_bind_addr_t *bp;
 	sctp_association_t *asoc;
@@ -2183,6 +2266,40 @@
 	return 0;
 }
 
+/* 7.1.10 Set Peer Primary Address (SCTP_SET_PEER_PRIMARY_ADDR)
+ *
+ * Requests that the local SCTP stack use the enclosed peer address as
+ * the association primary.  The enclosed address must be one of the
+ * association peer's addresses.
+ */
+static int sctp_getsockopt_peer_prim(struct sock *sk, int len,
+				char *optval, int *optlen)
+{
+	struct sctp_setpeerprim prim;
+	struct sctp_association *asoc;
+
+	if (len != sizeof(struct sctp_setpeerprim))
+		return -EINVAL;
+
+	if (copy_from_user(&prim, optval, sizeof(struct sctp_setpeerprim)))
+		return -EFAULT;
+
+	asoc = sctp_id2assoc(sk, prim.sspp_assoc_id);
+	if (!asoc)
+		return -EINVAL;
+
+	if (!asoc->peer.primary_path)
+		return -ENOTCONN;
+
+	memcpy(&prim.sspp_addr, &asoc->peer.primary_path->ipaddr,
+	       sizeof(union sctp_addr));
+
+	if (copy_to_user(optval, &prim, sizeof(struct sctp_setpeerprim)))
+		return -EFAULT;
+
+	return 0;
+}
+
 /*
  *
  * 7.1.15 Set default send parameters (SET_DEFAULT_SEND_PARAM)
@@ -2200,7 +2317,7 @@
  *
  *   For getsockopt, it get the default sctp_sndrcvinfo structure.
  */
-static inline int sctp_getsockopt_set_default_send_param(struct sock *sk,
+static int sctp_getsockopt_default_send_param(struct sock *sk,
 					int len, char *optval, int *optlen)
 {
 	struct sctp_sndrcvinfo info;
@@ -2227,6 +2344,33 @@
 	return 0;
 }
 
+/*
+ *
+ * 7.1.5 SCTP_NODELAY
+ *
+ * Turn on/off any Nagle-like algorithm.  This means that packets are
+ * generally sent as soon as possible and no unnecessary delays are
+ * introduced, at the cost of more packets in the network.  Expects an
+ * integer boolean flag.
+ */
+
+static int sctp_getsockopt_nodelay(struct sock *sk, int len, 
+					char *optval, int *optlen)
+{
+	__u8 val;
+
+	if (len < sizeof(__u8))
+		return -EINVAL;
+
+	len = sizeof(__u8);
+	val = (sctp_sk(sk)->nodelay == 1);
+	if (put_user(len, optlen))
+		return -EFAULT;
+	if (copy_to_user(optval, &val, len))
+		return -EFAULT;
+	return 0;
+}
+
 SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
 				char *optval, int *optlen)
 {
@@ -2257,58 +2401,52 @@
 	case SCTP_STATUS:
 		retval = sctp_getsockopt_sctp_status(sk, len, optval, optlen);
 		break;
-
 	case SCTP_DISABLE_FRAGMENTS:
 		retval = sctp_getsockopt_disable_fragments(sk, len, optval,
 							   optlen);
 		break;
-
 	case SCTP_SET_EVENTS:
 		retval = sctp_getsockopt_set_events(sk, len, optval, optlen);
 		break;
-
 	case SCTP_AUTOCLOSE:
 		retval = sctp_getsockopt_autoclose(sk, len, optval, optlen);
 		break;
-
 	case SCTP_SOCKOPT_PEELOFF:
 		retval = sctp_getsockopt_peeloff(sk, len, optval, optlen);
 		break;
-
 	case SCTP_GET_PEER_ADDR_PARAMS:
-		retval = sctp_getsockopt_get_peer_addr_params(sk, len, optval,
-							      optlen);
+		retval = sctp_getsockopt_peer_addr_params(sk, len, optval,
+							  optlen);
 		break;
-
 	case SCTP_INITMSG:
 		retval = sctp_getsockopt_initmsg(sk, len, optval, optlen);
 		break;
-
 	case SCTP_GET_PEER_ADDRS_NUM:
-		retval = sctp_getsockopt_get_peer_addrs_num(sk, len, optval,
-							      optlen);
+		retval = sctp_getsockopt_peer_addrs_num(sk, len, optval, 
+							optlen);
 		break;
-
 	case SCTP_GET_LOCAL_ADDRS_NUM:
-		retval = sctp_getsockopt_get_local_addrs_num(sk, len, optval,
-							      optlen);
+		retval = sctp_getsockopt_local_addrs_num(sk, len, optval,
+							 optlen);
 		break;
-
 	case SCTP_GET_PEER_ADDRS:
-		retval = sctp_getsockopt_get_peer_addrs(sk, len, optval,
-							      optlen);
+		retval = sctp_getsockopt_peer_addrs(sk, len, optval,
+						    optlen);
 		break;
-
 	case SCTP_GET_LOCAL_ADDRS:
-		retval = sctp_getsockopt_get_local_addrs(sk, len, optval,
-							      optlen);
+		retval = sctp_getsockopt_local_addrs(sk, len, optval,
+						     optlen);
 		break;
-
 	case SCTP_SET_DEFAULT_SEND_PARAM:
-		retval = sctp_getsockopt_set_default_send_param(sk, len,
-							optval, optlen);
+		retval = sctp_getsockopt_default_send_param(sk, len,
+							    optval, optlen);
+		break;
+	case SCTP_SET_PEER_PRIMARY_ADDR:
+		retval = sctp_getsockopt_peer_prim(sk, len, optval, optlen);
+		break;
+	case SCTP_NODELAY:
+		retval = sctp_getsockopt_nodelay(sk, len, optval, optlen);
 		break;
-
 	default:
 		retval = -ENOPROTOOPT;
 		break;
@@ -2331,7 +2469,7 @@
 /* Check if port is acceptable.  Possibly find first available port.
  *
  * The port hash table (contained in the 'global' SCTP protocol storage
- * returned by sctp_protocol_t * sctp_get_protocol()). The hash
+ * returned by struct sctp_protocol *sctp_get_protocol()). The hash
  * table is an array of 4096 lists (sctp_bind_hashbucket_t). Each
  * list (the list number is the port number hashed out, so as you
  * would expect from a hash function, all the ports in a given list have
@@ -2346,7 +2484,7 @@
 {
 	sctp_bind_hashbucket_t *head; /* hash list */
 	sctp_bind_bucket_t *pp; /* hash list port iterator */
-	sctp_protocol_t *sctp = sctp_get_protocol();
+	struct sctp_protocol *sctp = sctp_get_protocol();
 	unsigned short snum;
 	int ret;
 
@@ -2543,6 +2681,9 @@
 	if (SCTP_SOCKET_UDP != sp->type)
 		return -EINVAL;
 
+	if (sk->state == SCTP_SS_LISTENING)
+		return 0;
+
 	/*
 	 * If a bind() or sctp_bindx() is not called prior to a listen()
 	 * call that allows new associations to be accepted, the system
@@ -2563,6 +2704,40 @@
 }
 
 /*
+ * 4.1.3 listen() - TCP Style Syntax
+ *
+ *   Applications uses listen() to ready the SCTP endpoint for accepting 
+ *   inbound associations.
+ */
+SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog)
+{
+	struct sctp_opt *sp = sctp_sk(sk);
+	sctp_endpoint_t *ep = sp->ep;
+
+	if (sk->state == SCTP_SS_LISTENING)
+		return 0;
+
+	/*
+	 * If a bind() or sctp_bindx() is not called prior to a listen()
+	 * call that allows new associations to be accepted, the system
+	 * picks an ephemeral port and will choose an address set equivalent
+	 * to binding with a wildcard address.
+	 *
+	 * This is not currently spelled out in the SCTP sockets
+	 * extensions draft, but follows the practice as seen in TCP
+	 * sockets.
+	 */
+	if (!ep->base.bind_addr.port) {
+		if (sctp_autobind(sk))
+			return -EAGAIN;
+	}
+	sk->state = SCTP_SS_LISTENING;
+	sk->max_ack_backlog = backlog;
+	sctp_hash_endpoint(ep);
+	return 0;
+}
+
+/*
  *  Move a socket to LISTENING state.
  */
 int sctp_inet_listen(struct socket *sock, int backlog)
@@ -2579,10 +2754,9 @@
 	case SOCK_SEQPACKET:
 		err = sctp_seqpacket_listen(sk, backlog);
 		break;
-
 	case SOCK_STREAM:
-		/* FIXME for TCP-style sockets. */
-		err = -EOPNOTSUPP;
+		err = sctp_stream_listen(sk, backlog);
+		break;
 
 	default:
 		goto out;
@@ -2684,7 +2858,7 @@
 /* FIXME: Commments! */
 static __inline__ void __sctp_put_port(struct sock *sk)
 {
-	sctp_protocol_t *sctp_proto = sctp_get_protocol();
+	struct sctp_protocol *sctp_proto = sctp_get_protocol();
 	sctp_bind_hashbucket_t *head =
 		&sctp_proto->port_hashtable[sctp_phashfn(inet_sk(sk)->num)];
 	sctp_bind_bucket_t *pp;
@@ -2967,7 +3141,8 @@
 }
 
 /* Verify that this is a valid address. */
-static int sctp_verify_addr(struct sock *sk, union sctp_addr *addr, int len)
+static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr, 
+				   int len)
 {
 	struct sctp_af *af;
 
@@ -3213,7 +3388,7 @@
 	return err;
 
 do_error:
-	err = -ECONNABORTED;
+	err = -ECONNREFUSED;
 	goto out;
 
 do_interrupted:
@@ -3225,6 +3400,131 @@
 	goto out;
 }
 
+static int sctp_wait_for_accept(struct sock *sk, long timeo)
+{
+	struct sctp_endpoint *ep;
+	int err = 0;
+	DECLARE_WAITQUEUE(wait, current);
+
+	ep = sctp_sk(sk)->ep;
+
+	add_wait_queue_exclusive(sk->sleep, &wait);
+
+	for (;;) {
+		__set_current_state(TASK_INTERRUPTIBLE);
+		if (list_empty(&ep->asocs)) {
+			sctp_release_sock(sk);
+			timeo = schedule_timeout(timeo);
+			sctp_lock_sock(sk);
+		}
+
+		err = -EINVAL;
+		if (sk->state != SCTP_SS_LISTENING)
+			break;
+
+		err = 0;
+		if (!list_empty(&ep->asocs))
+			break;
+
+		err = sock_intr_errno(timeo);
+		if (signal_pending(current))
+			break;
+
+		err = -EAGAIN;
+		if (!timeo)
+			break;
+	}
+
+	remove_wait_queue(sk->sleep, &wait);
+	__set_current_state(TASK_RUNNING);
+
+	return err;
+}
+
+/* Populate the fields of the newsk from the oldsk and migrate the assoc 
+ * and its messages to the newsk.
+ */ 
+void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
+		  struct sctp_association *assoc, sctp_socket_type_t type)
+{
+	struct sctp_opt *oldsp = sctp_sk(oldsk);
+	struct sctp_opt *newsp = sctp_sk(newsk);
+	sctp_endpoint_t *newep = newsp->ep;
+	struct sk_buff *skb, *tmp;
+	struct sctp_ulpevent *event;
+
+	/* Migrate socket buffer sizes and all the socket level options to the
+	 * new socket.
+	 */
+	newsk->sndbuf = oldsk->sndbuf;
+	newsk->rcvbuf = oldsk->rcvbuf;
+	*newsp = *oldsp;
+
+	/* Restore the ep value that was overwritten with the above structure
+	 * copy.
+	 */
+	newsp->ep = newep;
+
+	/* Move any messages in the old socket's receive queue that are for the
+	 * peeled off association to the new socket's receive queue.
+	 */
+	sctp_skb_for_each(skb, &oldsk->receive_queue, tmp) {
+		event = sctp_skb2event(skb);
+		if (event->asoc == assoc) {
+			__skb_unlink(skb, skb->list);
+			__skb_queue_tail(&newsk->receive_queue, skb);
+		}
+	}
+
+	/* Clean up any messages pending delivery due to partial
+	 * delivery.   Three cases:
+	 * 1) No partial deliver;  no work.
+	 * 2) Peeling off partial delivery; keep pd_lobby in new pd_lobby.
+	 * 3) Peeling off non-partial delivery; move pd_lobby to recieve_queue.
+	 */
+	skb_queue_head_init(&newsp->pd_lobby);
+	sctp_sk(newsk)->pd_mode = assoc->ulpq.pd_mode;;
+
+	if (sctp_sk(oldsk)->pd_mode) {
+		struct sk_buff_head *queue;
+
+		/* Decide which queue to move pd_lobby skbs to. */
+		if (assoc->ulpq.pd_mode) {
+			queue = &newsp->pd_lobby;
+		} else
+			queue = &newsk->receive_queue;
+
+		/* Walk through the pd_lobby, looking for skbs that
+		 * need moved to the new socket.
+		 */
+		sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
+			event = sctp_skb2event(skb);
+			if (event->asoc == assoc) {
+				__skb_unlink(skb, skb->list);
+				__skb_queue_tail(queue, skb);
+			}
+		}
+
+		/* Clear up any skbs waiting for the partial
+		 * delivery to finish.
+		 */
+		if (assoc->ulpq.pd_mode)
+			sctp_clear_pd(oldsk);
+
+	}
+
+	/* Set the type of socket to indicate that it is peeled off from the
+	 * original UDP-style socket or created with the accept() call on a
+	 * TCP-style socket..
+	 */
+	newsp->type = type;
+
+	/* Migrate the association to the new socket. */
+	sctp_assoc_migrate(assoc, newsk);
+
+	newsk->state = SCTP_SS_ESTABLISHED;
+}
+ 
 /* This proto struct describes the ULP interface for SCTP.  */
 struct proto sctp_prot = {
 	.name        =	"SCTP",
diff -Nru a/net/sctp/sysctl.c b/net/sctp/sysctl.c
--- a/net/sctp/sysctl.c	Fri Feb 14 23:26:35 2003
+++ b/net/sctp/sysctl.c	Mon Feb 24 13:55:49 2003
@@ -42,7 +42,7 @@
 #include <net/sctp/structs.h>
 #include <linux/sysctl.h>
 
-extern sctp_protocol_t sctp_proto;
+extern struct sctp_protocol sctp_proto;
 
 static ctl_table sctp_table[] = {
 	{
diff -Nru a/net/sctp/transport.c b/net/sctp/transport.c
--- a/net/sctp/transport.c	Wed Feb  5 15:23:48 2003
+++ b/net/sctp/transport.c	Mon Feb 24 13:55:49 2003
@@ -83,7 +83,7 @@
 					   const union sctp_addr *addr,
 					   int priority)
 {
-	sctp_protocol_t *proto = sctp_get_protocol();
+	struct sctp_protocol *proto = sctp_get_protocol();
 
 	/* Copy in the address.  */
 	peer->ipaddr = *addr;
@@ -262,7 +262,7 @@
 /* Update transport's RTO based on the newly calculated RTT. */
 void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
 {
-	sctp_protocol_t *proto = sctp_get_protocol();
+	struct sctp_protocol *proto = sctp_get_protocol();
 
 	/* Check for valid transport.  */
 	SCTP_ASSERT(tp, "NULL transport", return);
diff -Nru a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c
--- a/net/sctp/tsnmap.c	Tue Feb 18 16:21:44 2003
+++ b/net/sctp/tsnmap.c	Mon Mar  3 04:52:39 2003
@@ -250,7 +250,7 @@
 	/* The Gap Ack Block happens to end at the end of the
 	 * overflow map.
 	 */
-	if (started & !ended) {
+	if (started && !ended) {
 		ended++;
 		_end = map->len + map->len - 1;
 	}
@@ -395,7 +395,7 @@
 		return;
 	if (!TSN_lt(tsn, map->base_tsn + map->len + map->len))
 		return;
-	
+
 	/* Assert: TSN is in range.  */
 	gap = tsn - map->base_tsn;
 
diff -Nru a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
--- a/net/sctp/ulpqueue.c	Mon Mar  3 04:56:53 2003
+++ b/net/sctp/ulpqueue.c	Thu Mar 20 00:11:44 2003
@@ -220,7 +220,7 @@
 	if (sctp_event2skb(event)->list)
 		sctp_skb_list_tail(sctp_event2skb(event)->list, queue);
 	else
-		skb_queue_tail(queue, sctp_event2skb(event));
+		__skb_queue_tail(queue, sctp_event2skb(event));
 
 	/* Did we just complete partial delivery and need to get
 	 * rolling again?  Move pending data to the receive
@@ -230,7 +230,7 @@
 		sctp_ulpq_clear_pd(ulpq);
 
 	if (queue == &sk->receive_queue)
-		wake_up_interruptible(sk->sleep);
+		sk->data_ready(sk, 0);
 	return 1;
 
 out_free:
@@ -247,14 +247,14 @@
 static inline void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq,
 					 struct sctp_ulpevent *event)
 {
-	struct sk_buff *pos, *tmp;
+	struct sk_buff *pos;
 	struct sctp_ulpevent *cevent;
 	__u32 tsn, ctsn;
 
 	tsn = event->sndrcvinfo.sinfo_tsn;
 
 	/* Find the right place in this list. We store them by TSN.  */
-	sctp_skb_for_each(pos, &ulpq->reasm, tmp) {
+	skb_queue_walk(&ulpq->reasm, pos) {
 		cevent = sctp_skb2event(pos);
 		ctsn = cevent->sndrcvinfo.sinfo_tsn;
 
@@ -334,7 +334,7 @@
  */
 static inline struct sctp_ulpevent *sctp_ulpq_retrieve_reassembled(struct sctp_ulpq *ulpq)
 {
-	struct sk_buff *pos, *tmp;
+	struct sk_buff *pos;
 	struct sctp_ulpevent *cevent;
 	struct sk_buff *first_frag = NULL;
 	__u32 ctsn, next_tsn;
@@ -355,7 +355,7 @@
 	 * fragment in order. If not, first_frag is reset to NULL and we
 	 * start the next pass when we find another first fragment.
 	 */
-	sctp_skb_for_each(pos, &ulpq->reasm, tmp) {
+	skb_queue_walk(&ulpq->reasm, pos) {
 		cevent = sctp_skb2event(pos);
 		ctsn = cevent->sndrcvinfo.sinfo_tsn;
 
@@ -374,29 +374,26 @@
 
 		case SCTP_DATA_LAST_FRAG:
 			if (first_frag && (ctsn == next_tsn))
-				retval = sctp_make_reassembled_event(
-						first_frag, pos);
+				goto found;
 			else
 				first_frag = NULL;
 			break;
 		};
 
-		/* We have the reassembled event. There is no need to look
-		 * further.
-		 */
-		if (retval) {
-			retval->msg_flags |= MSG_EOR;
-			break;
-		}
 	}
-
+done:
 	return retval;
+found:
+	retval = sctp_make_reassembled_event(first_frag, pos);
+	if (retval)
+		retval->msg_flags |= MSG_EOR;
+	goto done;
 }
 
 /* Retrieve the next set of fragments of a partial message. */
 static inline struct sctp_ulpevent *sctp_ulpq_retrieve_partial(struct sctp_ulpq *ulpq)
 {
-	struct sk_buff *pos, *tmp, *last_frag, *first_frag;
+	struct sk_buff *pos, *last_frag, *first_frag;
 	struct sctp_ulpevent *cevent;
 	__u32 ctsn, next_tsn;
 	int is_last;
@@ -415,7 +412,7 @@
 	next_tsn = 0;
 	is_last = 0;
 
-	sctp_skb_for_each(pos, &ulpq->reasm, tmp) {
+	skb_queue_walk(&ulpq->reasm, pos) {
 		cevent = sctp_skb2event(pos);
 		ctsn = cevent->sndrcvinfo.sinfo_tsn;
 
@@ -448,7 +445,7 @@
 	 */
 done:
 	retval = sctp_make_reassembled_event(first_frag, last_frag);
-	if (is_last)
+	if (retval && is_last)
 		retval->msg_flags |= MSG_EOR;
 
 	return retval;
@@ -490,7 +487,7 @@
 /* Retrieve the first part (sequential fragments) for partial delivery.  */
 static inline struct sctp_ulpevent *sctp_ulpq_retrieve_first(struct sctp_ulpq *ulpq)
 {
-	struct sk_buff *pos, *tmp, *last_frag, *first_frag;
+	struct sk_buff *pos, *last_frag, *first_frag;
 	struct sctp_ulpevent *cevent;
 	__u32 ctsn, next_tsn;
 	struct sctp_ulpevent *retval;
@@ -507,7 +504,7 @@
 	retval = NULL;
 	next_tsn = 0;
 
-	sctp_skb_for_each(pos, &ulpq->reasm, tmp) {
+	skb_queue_walk(&ulpq->reasm, pos) {
 		cevent = sctp_skb2event(pos);
 		ctsn = cevent->sndrcvinfo.sinfo_tsn;
 
@@ -590,7 +587,7 @@
 static inline void sctp_ulpq_store_ordered(struct sctp_ulpq *ulpq,
 					   struct sctp_ulpevent *event)
 {
-	struct sk_buff *pos, *tmp;
+	struct sk_buff *pos;
 	struct sctp_ulpevent *cevent;
 	__u16 sid, csid;
 	__u16 ssn, cssn;
@@ -601,7 +598,7 @@
 	/* Find the right place in this list.  We store them by
 	 * stream ID and then by SSN.
 	 */
-	sctp_skb_for_each(pos, &ulpq->lobby, tmp) {
+	skb_queue_walk(&ulpq->lobby, pos) {
 		cevent = (struct sctp_ulpevent *) pos->cb;
 		csid = cevent->sndrcvinfo.sinfo_stream;
 		cssn = cevent->sndrcvinfo.sinfo_ssn;
@@ -786,9 +783,9 @@
 					      SCTP_PARTIAL_DELIVERY_ABORTED,
 					      priority);
 	if (ev)
-		skb_queue_tail(&sk->receive_queue, sctp_event2skb(ev));
+		__skb_queue_tail(&sk->receive_queue, sctp_event2skb(ev));
 
 	/* If there is data waiting, send it up the socket now. */
 	if (sctp_ulpq_clear_pd(ulpq) || ev)
-		wake_up_interruptible(sk->sleep);
+		sk->data_ready(sk, 0);
 }
diff -Nru a/net/socket.c b/net/socket.c
--- a/net/socket.c	Thu Mar  6 11:06:45 2003
+++ b/net/socket.c	Sun Mar 23 22:06:53 2003
@@ -89,7 +89,7 @@
 #endif	/* CONFIG_NET_RADIO */
 
 #include <asm/uaccess.h>
-#include <net/compat_socket.h>
+#include <net/compat.h>
 
 #include <net/sock.h>
 #include <linux/netfilter.h>
@@ -1558,7 +1558,7 @@
 	
 	err = -EFAULT;
 	if (MSG_CMSG_COMPAT & flags) {
-		if (msghdr_from_user_compat_to_kern(&msg_sys, msg_compat))
+		if (get_compat_msghdr(&msg_sys, msg_compat))
 			return -EFAULT;
 	} else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr)))
 		return -EFAULT;
@@ -1652,7 +1652,7 @@
 	int *uaddr_len;
 	
 	if (MSG_CMSG_COMPAT & flags) {
-		if (msghdr_from_user_compat_to_kern(&msg_sys, msg_compat))
+		if (get_compat_msghdr(&msg_sys, msg_compat))
 			return -EFAULT;
 	} else
 		if (copy_from_user(&msg_sys,msg,sizeof(struct msghdr)))
@@ -1708,15 +1708,9 @@
 	err = __put_user(msg_sys.msg_flags, COMPAT_FLAGS(msg));
 	if (err)
 		goto out_freeiov;
-	if (MSG_CMSG_COMPAT & flags) {
-		unsigned long ucmsg_ptr;
-		compat_size_t uclen;
-		if((unsigned long) msg_sys.msg_control != cmsg_ptr)
-			cmsg_compat_recvmsg_fixup(&msg_sys, cmsg_ptr);
-		ucmsg_ptr = ((unsigned long)msg_sys.msg_control);
-		uclen = (compat_size_t) (ucmsg_ptr - cmsg_ptr);
-		err = __put_user(uclen, &msg_compat->msg_controllen);
-	} else
+	if (MSG_CMSG_COMPAT & flags)
+		err = put_compat_msg_controllen(&msg_sys, msg_compat, cmsg_ptr);
+	else
 		err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr, 
 				 &msg->msg_controllen);
 	if (err)
diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c
--- a/net/unix/af_unix.c	Thu Mar  6 11:06:45 2003
+++ b/net/unix/af_unix.c	Tue Mar 11 23:12:12 2003
@@ -859,10 +859,9 @@
 {
 	struct unix_sock *u = unix_sk(other);
 	int sched;
-	DECLARE_WAITQUEUE(wait, current);
+	DEFINE_WAIT(wait);
 
-	__set_current_state(TASK_INTERRUPTIBLE);
-	add_wait_queue_exclusive(&u->peer_wait, &wait);
+	prepare_to_wait_exclusive(&u->peer_wait, &wait, TASK_INTERRUPTIBLE);
 
 	sched = (!test_bit(SOCK_DEAD, &other->flags) &&
 		 !(other->shutdown&RCV_SHUTDOWN) &&
@@ -873,8 +872,7 @@
 	if (sched)
 		timeo = schedule_timeout(timeo);
 
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&u->peer_wait, &wait);
+	finish_wait(&u->peer_wait, &wait);
 	return timeo;
 }
 
@@ -1542,14 +1540,12 @@
  
 static long unix_stream_data_wait(unix_socket * sk, long timeo)
 {
-	DECLARE_WAITQUEUE(wait, current);
+	DEFINE_WAIT(wait);
 
 	unix_state_rlock(sk);
 
-	add_wait_queue(sk->sleep, &wait);
-
 	for (;;) {
-		set_current_state(TASK_INTERRUPTIBLE);
+		prepare_to_wait(sk->sleep, &wait, TASK_INTERRUPTIBLE);
 
 		if (skb_queue_len(&sk->receive_queue) ||
 		    sk->err ||
@@ -1565,8 +1561,7 @@
 		clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
 	}
 
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(sk->sleep, &wait);
+	finish_wait(sk->sleep, &wait);
 	unix_state_runlock(sk);
 	return timeo;
 }
diff -Nru a/scripts/Makefile b/scripts/Makefile
--- a/scripts/Makefile	Mon Mar 10 13:03:33 2003
+++ b/scripts/Makefile	Tue Mar 18 10:19:44 2003
@@ -9,7 +9,7 @@
 # conmakehash:	 Create arrays for initializing the kernel console tables
 
 host-progs	:= fixdep split-include conmakehash docproc kallsyms modpost \
-		   mk_elfconfig
+		   mk_elfconfig pnmtologo
 always		:= $(host-progs) empty.o
 
 modpost-objs	:= modpost.o file2alias.o
diff -Nru a/scripts/pnmtologo.c b/scripts/pnmtologo.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/scripts/pnmtologo.c	Mon Feb 24 13:47:01 2003
@@ -0,0 +1,507 @@
+
+/*
+ *  Convert a logo in ASCII PNM format to C source suitable for inclusion in
+ *  the Linux kernel
+ *
+ *  (C) Copyright 2001-2003 by Geert Uytterhoeven <geert@linux-m68k.org>
+ *
+ *  --------------------------------------------------------------------------
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of the Linux
+ *  distribution for more details.
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static const char *programname;
+static const char *filename;
+static const char *logoname = "linux_logo";
+static const char *outputname;
+static FILE *out;
+
+
+#define LINUX_LOGO_MONO		1	/* monochrome black/white */
+#define LINUX_LOGO_VGA16	2	/* 16 colors VGA text palette */
+#define LINUX_LOGO_CLUT224	3	/* 224 colors */
+#define LINUX_LOGO_GRAY256	4	/* 256 levels grayscale */
+
+static const char *logo_types[LINUX_LOGO_GRAY256+1] = {
+    [LINUX_LOGO_MONO] = "LINUX_LOGO_MONO",
+    [LINUX_LOGO_VGA16] = "LINUX_LOGO_VGA16",
+    [LINUX_LOGO_CLUT224] = "LINUX_LOGO_CLUT224",
+    [LINUX_LOGO_GRAY256] = "LINUX_LOGO_GRAY256"
+};
+
+#define MAX_LINUX_LOGO_COLORS	224
+
+struct color {
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+};
+
+static const struct color clut_vga16[16] = {
+    { 0x00, 0x00, 0x00 },
+    { 0x00, 0x00, 0xaa },
+    { 0x00, 0xaa, 0x00 },
+    { 0x00, 0xaa, 0xaa },
+    { 0xaa, 0x00, 0x00 },
+    { 0xaa, 0x00, 0xaa },
+    { 0xaa, 0x55, 0x00 },
+    { 0xaa, 0xaa, 0xaa },
+    { 0x55, 0x55, 0x55 },
+    { 0x55, 0x55, 0xff },
+    { 0x55, 0xff, 0x55 },
+    { 0x55, 0xff, 0xff },
+    { 0xff, 0x55, 0x55 },
+    { 0xff, 0x55, 0xff },
+    { 0xff, 0xff, 0x55 },
+    { 0xff, 0xff, 0xff },
+};
+
+
+static int logo_type = LINUX_LOGO_CLUT224;
+static unsigned int logo_width;
+static unsigned int logo_height;
+static struct color **logo_data;
+static struct color logo_clut[MAX_LINUX_LOGO_COLORS];
+static unsigned int logo_clutsize = 0;
+
+static void die(const char *fmt, ...)
+    __attribute__ ((noreturn)) __attribute ((format (printf, 1, 2)));
+static void usage(void) __attribute ((noreturn));
+
+
+static unsigned int get_number(FILE *fp)
+{
+    int c, val;
+
+    /* Skip leading whitespace */
+    do {
+	c = fgetc(fp);
+	if (c == EOF)
+	    die("%s: end of file\n", filename);
+	if (c == '#') {
+	    /* Ignore comments 'till end of line */
+	    do {
+		c = fgetc(fp);
+		if (c == EOF)
+		    die("%s: end of file\n", filename);
+	    } while (c != '\n');
+	}
+    } while (isspace(c));
+
+    /* Parse decimal number */
+    val = 0;
+    while (isdigit(c)) {
+	val = 10*val+c-'0';
+	c = fgetc(fp);
+	if (c == EOF)
+	    die("%s: end of file\n", filename);
+    }
+    return val;
+}
+
+static unsigned int get_number255(FILE *fp, unsigned int maxval)
+{
+    unsigned int val = get_number(fp);
+    return (255*val+maxval/2)/maxval;
+}
+
+static void read_image(void)
+{
+    FILE *fp;
+    int i, j, magic;
+    unsigned int maxval;
+
+    /* open image file */
+    fp = fopen(filename, "r");
+    if (!fp)
+	die("Cannot open file %s: %s\n", filename, strerror(errno));
+
+    /* check file type and read file header */
+    magic = fgetc(fp);
+    if (magic != 'P')
+	die("%s is not a PNM file\n", filename);
+    magic = fgetc(fp);
+    switch (magic) {
+	case '1':
+	case '2':
+	case '3':
+	    /* Plain PBM/PGM/PPM */
+	    break;
+
+	case '4':
+	case '5':
+	case '6':
+	    /* Binary PBM/PGM/PPM */
+	    die("%s: Binary PNM is not supported\n"
+		"Use pnmnoraw(1) to convert it to ASCII PNM\n", filename);
+
+	default:
+	    die("%s is not a PNM file\n", filename);
+    }
+    logo_width = get_number(fp);
+    logo_height = get_number(fp);
+
+    /* allocate image data */
+    logo_data = (struct color **)malloc(logo_height*sizeof(struct color *));
+    if (!logo_data)
+	die("%s\n", strerror(errno));
+    for (i = 0; i < logo_height; i++) {
+	logo_data[i] = malloc(logo_width*sizeof(struct color));
+	if (!logo_data[i])
+	    die("%s\n", strerror(errno));
+    }
+
+    /* read image data */
+    switch (magic) {
+	case '1':
+	    /* Plain PBM */
+	    for (i = 0; i < logo_height; i++)
+		for (j = 0; j < logo_width; j++)
+		    logo_data[i][j].red = logo_data[i][j].green =
+			logo_data[i][j].blue = 255*(1-get_number(fp));
+	    break;
+
+	case '2':
+	    /* Plain PGM */
+	    maxval = get_number(fp);
+	    for (i = 0; i < logo_height; i++)
+		for (j = 0; j < logo_width; j++)
+		    logo_data[i][j].red = logo_data[i][j].green =
+			logo_data[i][j].blue = get_number255(fp, maxval);
+	    break;
+
+	case '3':
+	    /* Plain PPM */
+	    maxval = get_number(fp);
+	    for (i = 0; i < logo_height; i++)
+		for (j = 0; j < logo_width; j++) {
+		    logo_data[i][j].red = get_number255(fp, maxval);
+		    logo_data[i][j].green = get_number255(fp, maxval);
+		    logo_data[i][j].blue = get_number255(fp, maxval);
+		}
+	    break;
+    }
+
+    /* close file */
+    fclose(fp);
+}
+
+static inline int is_black(struct color c)
+{
+    return c.red == 0 && c.green == 0 && c.blue == 0;
+}
+
+static inline int is_white(struct color c)
+{
+    return c.red == 255 && c.green == 255 && c.blue == 255;
+}
+
+static inline int is_gray(struct color c)
+{
+    return c.red == c.green && c.red == c.blue;
+}
+
+static inline int is_equal(struct color c1, struct color c2)
+{
+    return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue;
+}
+
+static void write_header(void)
+{
+    /* open logo file */
+    if (outputname) {
+	out = fopen(outputname, "w");
+	if (!out)
+	    die("Cannot create file %s: %s\n", outputname, strerror(errno));
+    } else {
+	out = stdout;
+    }
+
+    fputs("/*\n", out);
+    fputs(" *  DO NOT EDIT THIS FILE!\n", out);
+    fputs(" *\n", out);
+    fprintf(out, " *  It was automatically generated from %s\n", filename);
+    fputs(" *\n", out);
+    fprintf(out, " *  Linux logo %s\n", logoname);
+    fputs(" */\n\n", out);
+    fputs("#include <linux/linux_logo.h>\n\n", out);
+    fprintf(out, "static const unsigned char %s_data[] __initdata = {\n",
+	    logoname);
+}
+
+static void write_footer(void)
+{
+    fputs("\n};\n\n", out);
+    fprintf(out, "const struct linux_logo %s __initdata = {\n", logoname);
+    fprintf(out, "    .type\t= %s,\n", logo_types[logo_type]);
+    fprintf(out, "    .width\t= %d,\n", logo_width);
+    fprintf(out, "    .height\t= %d,\n", logo_height);
+    if (logo_type == LINUX_LOGO_CLUT224) {
+	fprintf(out, "    .clutsize\t= %d,\n", logo_clutsize);
+	fprintf(out, "    .clut\t= %s_clut,\n", logoname);
+    }
+    fprintf(out, "    .data\t= %s_data\n", logoname);
+    fputs("};\n\n", out);
+
+    /* close logo file */
+    if (outputname)
+	fclose(out);
+}
+
+static int write_hex_cnt = 0;
+
+static void write_hex(unsigned char byte)
+{
+    if (write_hex_cnt % 12)
+	fprintf(out, ", 0x%02x", byte);
+    else if (write_hex_cnt)
+	fprintf(out, ",\n\t0x%02x", byte);
+    else
+	fprintf(out, "\t0x%02x", byte);
+    write_hex_cnt++;
+}
+
+static void write_logo_mono(void)
+{
+    int i, j;
+    unsigned char val, bit;
+
+    /* validate image */
+    for (i = 0; i < logo_height; i++)
+	for (j = 0; j < logo_width; j++)
+	    if (!is_black(logo_data[i][j]) && !is_white(logo_data[i][j]))
+		die("Image must be monochrome\n");
+
+    /* write file header */
+    write_header();
+
+    /* write logo data */
+    for (i = 0; i < logo_height; i++) {
+	for (j = 0; j < logo_width;) {
+	    for (val = 0, bit = 0x80; bit && j < logo_width; j++, bit >>= 1)
+		if (logo_data[i][j].red)
+		    val |= bit;
+	    write_hex(val);
+	}
+    }
+
+    /* write logo structure and file footer */
+    write_footer();
+}
+
+static void write_logo_vga16(void)
+{
+    int i, j, k;
+    unsigned char val;
+
+    /* validate image */
+    for (i = 0; i < logo_height; i++)
+	for (j = 0; j < logo_width; j++) {
+	    for (k = 0; k < 16; k++)
+		if (is_equal(logo_data[i][j], clut_vga16[k]))
+		    break;
+	    if (k == 16)
+		die("Image must use the 16 console colors only\n"
+		    "Use ppmquant(1) -map clut_vga16.ppm to reduce the number "
+		    "of colors\n");
+	}
+
+    /* write file header */
+    write_header();
+
+    /* write logo data */
+    for (i = 0; i < logo_height; i++)
+	for (j = 0; j < logo_width; j++) {
+	    for (k = 0; k < 16; k++)
+		if (is_equal(logo_data[i][j], clut_vga16[k]))
+		    break;
+	    val = k<<4;
+	    if (++j < logo_width) {
+		for (k = 0; k < 16; k++)
+		    if (is_equal(logo_data[i][j], clut_vga16[k]))
+			break;
+		val |= k;
+	    }
+	    write_hex(val);
+	}
+
+    /* write logo structure and file footer */
+    write_footer();
+}
+
+static void write_logo_clut224(void)
+{
+    int i, j, k;
+
+    /* validate image */
+    for (i = 0; i < logo_height; i++)
+	for (j = 0; j < logo_width; j++) {
+	    for (k = 0; k < logo_clutsize; k++)
+		if (is_equal(logo_data[i][j], logo_clut[k]))
+		    break;
+	    if (k == logo_clutsize) {
+		if (logo_clutsize == MAX_LINUX_LOGO_COLORS)
+		    die("Image has more than %d colors\n"
+			"Use ppmquant(1) to reduce the number of colors\n",
+			MAX_LINUX_LOGO_COLORS);
+		logo_clut[logo_clutsize++] = logo_data[i][j];
+	    }
+	}
+
+    /* write file header */
+    write_header();
+
+    /* write logo data */
+    for (i = 0; i < logo_height; i++)
+	for (j = 0; j < logo_width; j++) {
+	    for (k = 0; k < logo_clutsize; k++)
+		if (is_equal(logo_data[i][j], logo_clut[k]))
+		    break;
+	    write_hex(k+32);
+	}
+    fputs("\n};\n\n", out);
+
+    /* write logo clut */
+    fprintf(out, "static const unsigned char %s_clut[] __initdata = {\n",
+	    logoname);
+    write_hex_cnt = 0;
+    for (i = 0; i < logo_clutsize; i++) {
+	write_hex(logo_clut[i].red);
+	write_hex(logo_clut[i].green);
+	write_hex(logo_clut[i].blue);
+    }
+
+    /* write logo structure and file footer */
+    write_footer();
+}
+
+static void write_logo_gray256(void)
+{
+    int i, j;
+
+    /* validate image */
+    for (i = 0; i < logo_height; i++)
+	for (j = 0; j < logo_width; j++)
+	    if (!is_gray(logo_data[i][j]))
+		die("Image must be grayscale\n");
+
+    /* write file header */
+    write_header();
+
+    /* write logo data */
+    for (i = 0; i < logo_height; i++)
+	for (j = 0; j < logo_width; j++)
+	    write_hex(logo_data[i][j].red);
+
+    /* write logo structure and file footer */
+    write_footer();
+}
+
+static void die(const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
+
+    exit(1);
+}
+
+static void usage(void)
+{
+    die("\n"
+	"Usage: %s [options] <filename>\n"
+	"\n"
+	"Valid options:\n"
+	"    -h          : display this usage information\n"
+	"    -n <name>   : specify logo name (default: linux_logo)\n"
+	"    -o <output> : output to file <output> instead of stdout\n"
+	"    -t <type>   : specify logo type, one of\n"
+	"                      mono    : monochrome black/white\n"
+	"                      vga16   : 16 colors VGA text palette\n"
+	"                      clut224 : 224 colors (default)\n"
+	"                      gray256 : 256 levels grayscale\n"
+	"\n", programname);
+}
+
+int main(int argc, char *argv[])
+{
+    int opt;
+
+    programname = argv[0];
+
+    opterr = 0;
+    while (1) {
+	opt = getopt(argc, argv, "hn:o:t:");
+	if (opt == -1)
+	    break;
+
+	switch (opt) {
+	    case 'h':
+		usage();
+		break;
+
+	    case 'n':
+		logoname = optarg;
+		break;
+
+	    case 'o':
+		outputname = optarg;
+		break;
+
+	    case 't':
+		if (!strcmp(optarg, "mono"))
+		    logo_type = LINUX_LOGO_MONO;
+		else if (!strcmp(optarg, "vga16"))
+		    logo_type = LINUX_LOGO_VGA16;
+		else if (!strcmp(optarg, "clut224"))
+		    logo_type = LINUX_LOGO_CLUT224;
+		else if (!strcmp(optarg, "gray256"))
+		    logo_type = LINUX_LOGO_GRAY256;
+		else
+		    usage();
+		break;
+
+	    default:
+		usage();
+		break;
+	}
+    }
+    if (optind != argc-1)
+	usage();
+
+    filename = argv[optind];
+
+    read_image();
+    switch (logo_type) {
+	case LINUX_LOGO_MONO:
+	    write_logo_mono();
+	    break;
+
+	case LINUX_LOGO_VGA16:
+	    write_logo_vga16();
+	    break;
+
+	case LINUX_LOGO_CLUT224:
+	    write_logo_clut224();
+	    break;
+
+	case LINUX_LOGO_GRAY256:
+	    write_logo_gray256();
+	    break;
+    }
+    exit(0);
+}
+
diff -Nru a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c
--- a/sound/arm/sa11xx-uda1341.c	Sun Feb 16 05:47:40 2003
+++ b/sound/arm/sa11xx-uda1341.c	Tue Feb 25 05:46:05 2003
@@ -13,9 +13,48 @@
  * 2002-03-29   Tomas Kasparek  basic capture is working (native ALSA)
  * 2002-03-29   Tomas Kasparek  capture is working (OSS emulation)
  * 2002-04-04   Tomas Kasparek  better rates handling (allow non-standard rates)
+ * 2003-02-14   Brian Avery     fixed full duplex mode, other updates
+ * 2003-02-20   Tomas Kasparek  merged updates by Brian (except HAL)
  */
 
-/* $Id: sa11xx-uda1341.c,v 1.7 2003/02/13 19:19:18 perex Exp $ */
+/* $Id: sa11xx-uda1341.c,v 1.8 2003/02/25 12:48:15 perex Exp $ */
+
+/***************************************************************************************************
+*
+* To understand what Alsa Drivers should be doing look at "Writing an Alsa Driver" by Takashi Iwai
+* available in the Alsa doc section on the website		
+* 
+* A few notes to make things clearer. The UDA1341 is hooked up to Serial port 4 on the SA1100.
+* We are using  SSP mode to talk to the UDA1341. The UDA1341 bit & wordselect clocks are generated
+* by this UART. Unfortunately, the clock only runs if the transmit buffer has something in it.
+* So, if we are just recording, we feed the transmit DMA stream a bunch of 0x0000 so that the
+* transmit buffer is full and the clock keeps going. The zeroes come from FLUSH_BASE_PHYS which
+* is a mem loc that always decodes to 0's w/ no off chip access.
+*
+* Some alsa terminology:
+*	frame => num_channels * sample_size  e.g stereo 16 bit is 2 * 16 = 32 bytes
+*	period => the least number of bytes that will generate an interrupt e.g. we have a 1024 byte
+*             buffer and 4 periods in the runtime structure this means we'll get an int every 256
+*             bytes or 4 times per buffer.
+*             A number of the sizes are in frames rather than bytes, use frames_to_bytes and
+*             bytes_to_frames to convert.  The easiest way to tell the units is to look at the
+*             type i.e. runtime-> buffer_size is in frames and its type is snd_pcm_uframes_t
+*             
+*	Notes about the pointer fxn:
+*	The pointer fxn needs to return the offset into the dma buffer in frames.
+*	Interrupts must be blocked before calling the dma_get_pos fxn to avoid race with interrupts.
+*
+*	Notes about pause/resume
+*	Implementing this would be complicated so it's skipped.  The problem case is:
+*	A full duplex connection is going, then play is paused. At this point you need to start xmitting
+*	0's to keep the record active which means you cant just freeze the dma and resume it later you'd
+*	need to	save off the dma info, and restore it properly on a resume.  Yeach!
+*
+*	Notes about transfer methods:
+*	The async write calls fail.  I probably need to implement something else to support them?
+* 
+***************************************************************************************************/
+
 
 #include <sound/driver.h>
 #include <linux/module.h>
@@ -53,8 +92,6 @@
 
 #define chip_t sa11xx_uda1341_t
 
-#define SHIFT_16_STEREO         2
-
 typedef enum stream_id_t{
 	PLAYBACK=0,
 	CAPTURE,
@@ -62,32 +99,29 @@
 }stream_id_t;
 
 typedef struct audio_stream {
-	char *id;		/* identification string */
+	char *id;				/* identification string */
+	int  stream_id;			/* numeric identification */	
 	dma_device_t dma_dev;	/* device identifier for DMA */
 	dma_regs_t *dma_regs;	/* points to our DMA registers */
 
-	int active:1;		/* we are using this stream for transfer now */
+	int active:1;			/* we are using this stream for transfer now */
 
 	int sent_periods;       /* # of sent periods from actual DMA buffer */
 	int sent_total;         /* # of sent periods total (just for info & debug) */
 
 	int sync;               /* are we recoding - flag used to do DMA trans. for sync */
+	spinlock_t dma_lock;	/* for locking in DMA operations (see dma-sa1100.c in the kernel) */
         
 	snd_pcm_substream_t *stream;
 }audio_stream_t;
 
-/* I do not want to have substream = NULL when syncing - ALSA does not like it */
-#define SYNC_SUBSTREAM ((void *) -1)
-
 typedef struct snd_card_sa11xx_uda1341 {
 	struct pm_dev *pm_dev;        
 	snd_card_t *card;
 	struct l3_client *uda1341;
 
 	long samplerate;
-
 	audio_stream_t *s[MAX_STREAMS];
-	snd_info_entry_t *proc_entry;
 }sa11xx_uda1341_t;
 
 static struct snd_card_sa11xx_uda1341 *sa11xx_uda1341 = NULL;
@@ -217,7 +251,9 @@
 		break;
 	}
 
+	/* FMT setting should be moved away when other FMTs are added (FIXME) */
 	l3_command(sa11xx_uda1341->uda1341, CMD_FORMAT, (void *)LSB16);
+	
 	l3_command(sa11xx_uda1341->uda1341, CMD_FS, (void *)clk);        
 	Ser4SSCR0 = (Ser4SSCR0 & ~0xff00) + clk_div + SSCR0_SSE;
 	DEBUG(KERN_DEBUG "set_samplerate done (new rate: %ld)\n", rate);
@@ -237,11 +273,13 @@
 	/* Setup DMA stuff */
 	if (sa11xx_uda1341->s[PLAYBACK]) {
 		sa11xx_uda1341->s[PLAYBACK]->id = "UDA1341 out";
+		sa11xx_uda1341->s[PLAYBACK]->stream_id = PLAYBACK;
 		sa11xx_uda1341->s[PLAYBACK]->dma_dev = DMA_Ser4SSPWr;
 	}
 
 	if (sa11xx_uda1341->s[CAPTURE]) {
 		sa11xx_uda1341->s[CAPTURE]->id = "UDA1341 in";
+		sa11xx_uda1341->s[CAPTURE]->stream_id = CAPTURE;
 		sa11xx_uda1341->s[CAPTURE]->dma_dev = DMA_Ser4SSPRd;
 	}
 
@@ -255,22 +293,24 @@
 	Ser4SSCR0 = SSCR0_DataSize(16) + SSCR0_TI + SSCR0_SerClkDiv(8);
 	Ser4SSCR1 = SSCR1_SClkIactL + SSCR1_SClk1P + SSCR1_ExtClk;
 	Ser4SSCR0 |= SSCR0_SSE;
+	local_irq_restore(flags);
 
 	/* Enable the audio power */
 	clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_CODEC_NRESET);
 	set_sa11xx_uda1341_egpio(IPAQ_EGPIO_AUDIO_ON);
 	set_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
-	local_irq_restore(flags);
         
 	/* Initialize the UDA1341 internal state */
 	l3_open(sa11xx_uda1341->uda1341);
-
-	/* external clock configuration */
-	sa11xx_uda1341_set_samplerate(sa11xx_uda1341, 44100); /* default sample rate */                
+	
+	/* external clock configuration (after l3_open - regs must be
+	 * initialized */
+	sa11xx_uda1341_set_samplerate(sa11xx_uda1341, AUDIO_RATE_DEFAULT);
 
 	/* Wait for the UDA1341 to wake up */
 	set_sa11xx_uda1341_egpio(IPAQ_EGPIO_CODEC_NRESET);
 	mdelay(1);
+	
 
 	/* make the left and right channels unswapped (flip the WS latch ) */
 	Ser4SSDR = 0;
@@ -280,11 +320,16 @@
 
 static void sa11xx_uda1341_audio_shutdown(sa11xx_uda1341_t *sa11xx_uda1341)
 {
+	/* mute on */
+	set_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
+	
 	/* disable the audio power and all signals leading to the audio chip */
 	l3_close(sa11xx_uda1341->uda1341);
 	Ser4SSCR0 = 0;
 	clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_CODEC_NRESET);
+	/* power off */
 	clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_AUDIO_ON);
+	/* mute off */
 	clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
 }
 
@@ -292,26 +337,29 @@
 
 /* {{{ DMA staff */
 
-#define SYNC_ADDR		(dma_addr_t)FLUSH_BASE_PHYS
-#define SYNC_SIZE		4096 // was 2048
-
-#define DMA_REQUEST(s, cb)	sa1100_request_dma((s)->dma_dev, (s)->id, cb, s, \
-                                                   &((s)->dma_regs))
-#define DMA_FREE(s)		{sa1100_free_dma((s)->dma_regs); (s)->dma_regs = 0;}
-#define DMA_START(s, d, l)	sa1100_start_dma((s)->dma_regs, d, l)
-#define DMA_STOP(s)		sa1100_stop_dma((s)->dma_regs)
-#define DMA_CLEAR(s)		sa1100_clear_dma((s)->dma_regs)
-#define DMA_RESET(s)		sa1100_reset_dma((s)->dma_regs)
-#define DMA_POS(s)              sa1100_get_dma_pos((s)->dma_regs)
+/*
+ * these are the address and sizes used to fill the xmit buffer
+ * so we can get a clock in record only mode
+ */
+#define FORCE_CLOCK_ADDR		(dma_addr_t)FLUSH_BASE_PHYS
+#define FORCE_CLOCK_SIZE		4096 // was 2048
 
 static void audio_dma_request(audio_stream_t *s, void (*callback)(void *))
 {
-	DMA_REQUEST(s, callback);
+	int ret;
+
+	DEBUG_NAME(KERN_DEBUG "audio_dma_request");
+
+	DEBUG("\t request id <%s>\n", s->id);
+	DEBUG("\t  request dma_dev = 0x%x \n", s->dma_dev);
+	ret = sa1100_request_dma((s)->dma_dev, (s)->id, callback, s, &((s)->dma_regs));
+	DEBUG("\t  request ret = %d\n", ret);
 }
 
 static void audio_dma_free(audio_stream_t *s)
 {
-	DMA_FREE(s);
+	sa1100_free_dma((s)->dma_regs);
+	(s)->dma_regs = 0;
 }
 
 static u_int audio_get_dma_pos(audio_stream_t *s)
@@ -319,12 +367,17 @@
 	snd_pcm_substream_t * substream = s->stream;
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	unsigned int offset;
-        
+	unsigned long flags;
+	
 	DEBUG_NAME(KERN_DEBUG "get_dma_pos");
         
-	offset = DMA_POS(s) - substream->runtime->dma_addr;
+	// this must be called w/ interrupts locked out see dma-sa1100.c in the kernel
+	spin_lock_irqsave(&s->dma_lock, flags);
+	offset = sa1100_get_dma_pos((s)->dma_regs) - runtime->dma_addr;
+	spin_unlock_irqrestore(&s->dma_lock, flags);
+	
 	DEBUG(" %d ->", offset);
-	offset >>= SHIFT_16_STEREO;                
+	offset = bytes_to_frames(runtime,offset);
 	DEBUG(" %d [fr]\n", offset);
         
 	if (offset >= runtime->buffer_size){
@@ -339,27 +392,33 @@
 	return offset;
 }
 
-
+/*
+ * this stops the dma and clears the dma ptrs
+ */
 static void audio_stop_dma(audio_stream_t *s)
 {
 	long flags;
 
 	DEBUG_NAME(KERN_DEBUG "stop_dma\n");
         
-	if (!s->stream)
+	/*
+	 * zero filling streams (sync=1) don;t have alsa streams attached 
+	 * but the 0 fill dma xfer still needs to be stopped
+	 */
+	if (!(s->stream || s->sync))
 		return;
 
-	local_irq_save(flags);
+	spin_lock_irqsave(&(s->dma_lock), flags);	
 	s->active = 0;
 	s->sent_periods = 0;
-	s->sent_total = 0;        
+	s->sent_total = 0;
+	s->sync = 0;
 
-	DMA_STOP(s);
-	DMA_CLEAR(s);
-	local_irq_restore(flags);
+	/* this stops the dma channel and clears the buffer ptrs */
+	sa1100_clear_dma((s)->dma_regs);	
+	spin_unlock_irqrestore(&(s->dma_lock), flags);
 }
 
-
 static void audio_reset(audio_stream_t *s)
 {
 	DEBUG_NAME(KERN_DEBUG "dma_reset\n");
@@ -375,40 +434,58 @@
 {
 	snd_pcm_substream_t * substream = s->stream;
 	snd_pcm_runtime_t *runtime;
-	int ret,i;
+	int ret;
                 
 	DEBUG_NAME(KERN_DEBUG "process_dma\n");
 
-	if(!s->active){
-		DEBUG("!!!want to process DMA when stopped!!!\n");
-		return;
-	}
-
 	/* we are requested to process synchronization DMA transfer */
-	if (s->sync) {
+	if(!s->active && s->sync){
+		snd_assert(s->stream_id == PLAYBACK,return);		
+		/* fill the xmit dma buffers and return */
 		while (1) {
-			DEBUG(KERN_DEBUG "sent sync period (dma_size[B]: %d)\n", SYNC_SIZE);
-			ret = DMA_START(s, SYNC_ADDR, SYNC_SIZE);
+			DEBUG(KERN_DEBUG "sent zero dma period (dma_size[B]: %d)\n", FORCE_CLOCK_SIZE);
+			ret = sa1100_start_dma((s)->dma_regs, FORCE_CLOCK_ADDR, FORCE_CLOCK_SIZE);			
 			if (ret)
 				return;   
 		}
 	}
 
-	/* must be set here - for sync there is no runtime struct */
+	/* must be set here - only valid for running streams, not for forced_clock dma fills  */
 	runtime = substream->runtime;
-        
-	while(1) {       
-		unsigned int  dma_size = runtime->period_size << SHIFT_16_STEREO;
-		unsigned int offset = dma_size * s->sent_periods;
                 
+	DEBUG("audio_process_dma hw_ptr_base = 0x%x w_ptr_interrupt = 0x%x "
+		  "period_size = %d  periods  = %d buffer_size = %d sync=0x%x  dma_area = 0x%x\n",
+	       runtime->hw_ptr_base,
+	       runtime->hw_ptr_interrupt,
+	       runtime->period_size,
+	       runtime->periods,
+	       runtime->buffer_size,
+	       runtime->sync,
+	       runtime->dma_area);
+
+	DEBUG("audio_process_dma sent_total = %d  sent_period = %d\n",
+	       s->sent_total,
+	       s->sent_periods);
+	
+	while(s->active) {       
+		unsigned int  dma_size;		
+		unsigned int offset ;
+   
+		dma_size = frames_to_bytes(runtime,runtime->period_size) ;
+		offset = dma_size * s->sent_periods;
 		if (dma_size > MAX_DMA_SIZE){
 			/* this should not happen! */
-			DEBUG(KERN_DEBUG "-----> cut dma_size: %d -> ", dma_size);
+			printk(KERN_ERR "---> cut dma_size: %d -> ", dma_size);
 			dma_size = CUT_DMA_SIZE;
-			DEBUG("%d <-----\n", dma_size);
+			printk("%d <---\n", dma_size);
 		}
 
-		ret = DMA_START(s, runtime->dma_addr + offset, dma_size);
+		/*
+		 * the first time this while loop will run 3 times, i.e. it'll fill the 2 dma
+		 * buffers then get a -EBUSY, every other time it'll refill the completed buffer
+		 * and then get the -EBUSY so it'll just run twice
+		 */
+		ret = sa1100_start_dma((s)->dma_regs, runtime->dma_addr + offset, dma_size);
 		if (ret)
 			return;
 
@@ -429,7 +506,6 @@
 	}
 }
 
-
 static void audio_dma_callback(void *data)
 {
 	audio_stream_t *s = data;
@@ -438,24 +514,26 @@
         
 	DEBUG_NAME(KERN_DEBUG "dma_callback\n");
 
-	/* when syncing we do not have any real stream from ALSA! */
-	if (!s->sync) {
-		snd_pcm_period_elapsed(s->stream);
-		DEBUG(KERN_DEBUG "----> period done <----\n");
+	DEBUG(KERN_DEBUG "----> period done <----\n");
+
 #ifdef DEBUG_MODE
-		printk(KERN_DEBUG "  dma_area:");
-		buf = (char *)s->stream->runtime->dma_addr +
-			((s->sent_periods - 1 ) *
-			 (s->stream->runtime->period_size << SHIFT_16_STEREO));
-		for (i=0; i < 32; i++) {
-			printk(" %02x", *(char *)(buf + i));
-		}
-		printk("\n");
-#endif                      
+	printk(KERN_DEBUG "  dma_area:");
+	buf = (char *)s->stream->runtime->dma_addr + ((s->sent_periods - 1 ) *
+ 		  frames_to_bytes( s->stream->runtime, s->stream->runtime->period_size));	
+	for (i=0; i < 32; i++) {
+		printk(" %02x", *(char *)(buf + i));
 	}
+	printk("\n");
+#endif                      
         
-	if (s->active)
-		audio_process_dma(s);
+   /* 
+	* If we are getting a callback for an active stream then we inform
+	* the PCM middle layer we've finished a period
+	*/
+ 	if (s->active)
+		snd_pcm_period_elapsed(s->stream);
+
+	audio_process_dma(s);
 }
 
 /* }}} */
@@ -491,18 +569,21 @@
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		/* want to capture and have no playback - run DMA syncing */
+		/* now we need to make sure a record only stream has a clock */
 		if (stream_id == CAPTURE && !chip->s[PLAYBACK]->active) {
-			/* we need synchronization DMA transfer (zeros) */
-			DEBUG(KERN_DEBUG "starting synchronization DMA transfer\n");
+			/* we need to force fill the xmit DMA  with zeros */
+			DEBUG(KERN_DEBUG "starting zero fill  DMA transfer\n");
 			chip->s[PLAYBACK]->sync = 1;
-			chip->s[PLAYBACK]->active = 1;
-			chip->s[PLAYBACK]->stream = SYNC_SUBSTREAM; /* not really used! */
 			audio_process_dma(chip->s[PLAYBACK]);
 		}
-		/* want to playback and have capture - stop syncing */
-		if(stream_id == PLAYBACK && chip->s[PLAYBACK]->sync) {
-			chip->s[PLAYBACK]->sync = 0;
+		/* this case is when you were recording then you turn on a
+		 * playback stream so we
+		 * stop (also clears it) the dma first, clear the sync flag
+		 * and then we let it get turned on
+		 */		
+		else if (stream_id == PLAYBACK && chip->s[PLAYBACK]->sync) {
+ 			chip->s[PLAYBACK]->sync = 0;
+			audio_stop_dma(chip->s[PLAYBACK]);
 		}
 
 		/* requested stream startup */
@@ -512,27 +593,30 @@
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		/* want to stop capture and use syncing - stop DMA syncing */
-		if (stream_id == CAPTURE && chip->s[PLAYBACK]->sync) {
-			/* we do not need synchronization DMA transfer now */
-			DEBUG(KERN_DEBUG "stopping synchronization DMA transfer\n");
-			chip->s[PLAYBACK]->sync = 0;
-			chip->s[PLAYBACK]->active = 0;
-			audio_stop_dma(chip->s[PLAYBACK]);
-		}
-		/* want to stop playback and have capture - run DMA syncing */
-		if(stream_id == PLAYBACK && chip->s[CAPTURE]->active) {
-			/* we need synchronization DMA transfer (zeros) */
-			DEBUG(KERN_DEBUG "starting synchronization DMA transfer\n");
-			chip->s[PLAYBACK]->sync = 1;
-			chip->s[PLAYBACK]->active = 1;
-			chip->s[PLAYBACK]->stream = SYNC_SUBSTREAM; /* not really used! */
-			audio_process_dma(chip->s[PLAYBACK]);
-		}
-
 		/* requested stream shutdown */
 		chip->s[stream_id]->active = 0;
 		audio_stop_dma(chip->s[stream_id]);
+		
+		/*
+		 * now we need to make sure a record only stream has a clock
+		 * so if we're stopping a playback with an active capture
+		 * we need to turn the 0 fill dma on for the xmit side
+		 */
+		if (stream_id == PLAYBACK && chip->s[CAPTURE]->active) {
+			/* we need to force fill the xmit DMA  with zeros */
+			DEBUG(KERN_DEBUG "starting zero fill  DMA transfer\n");
+			chip->s[PLAYBACK]->sync = 1;
+			chip->s[PLAYBACK]->active = 0;
+			audio_process_dma(chip->s[PLAYBACK]);
+		}
+		/*
+		 * we killed a capture only stream, so we should also kill
+		 * the zero fill transmit
+		 */
+		else if (stream_id == CAPTURE  && chip->s[PLAYBACK]->sync) {
+			audio_stop_dma(chip->s[PLAYBACK]);
+		}
+		
 		break;
 	default:
 		return -EINVAL;
@@ -601,7 +685,11 @@
 	chip->s[PLAYBACK]->sent_periods = 0;
 	chip->s[PLAYBACK]->sent_total = 0;
         
-	audio_reset(chip->s[PLAYBACK]);
+	/* no reset here since we may be zero filling the DMA
+	 * if we are, the dma stream will get reset in the pcm_trigger
+	 * i.e. when it actually starts to play
+	 */
+	/* audio_reset(chip->s[PLAYBACK]); */
  
 	runtime->hw = snd_sa11xx_uda1341_playback;
 	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
@@ -652,10 +740,13 @@
 
 static snd_pcm_uframes_t snd_card_sa11xx_uda1341_playback_pointer(snd_pcm_substream_t * substream)
 {
+	snd_pcm_uframes_t pos;
 	sa11xx_uda1341_t *chip = snd_pcm_substream_chip(substream);
 
 	DEBUG_NAME(KERN_DEBUG "playback_pointer\n");        
-	return audio_get_dma_pos(chip->s[PLAYBACK]);
+	
+	pos = audio_get_dma_pos(chip->s[PLAYBACK]);
+	return pos;
 }
 
 /* }}} */
@@ -674,7 +765,7 @@
 	chip->s[CAPTURE]->sent_periods = 0;
 	chip->s[CAPTURE]->sent_total = 0;
         
-	audio_reset(chip->s[PLAYBACK]);        
+	audio_reset(chip->s[CAPTURE]);        
 
 	runtime->hw = snd_sa11xx_uda1341_capture;
 	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
@@ -725,10 +816,12 @@
 
 static snd_pcm_uframes_t snd_card_sa11xx_uda1341_capture_pointer(snd_pcm_substream_t * substream)
 {
+	snd_pcm_uframes_t pos;
 	sa11xx_uda1341_t *chip = snd_pcm_substream_chip(substream);
 
 	DEBUG_NAME(KERN_DEBUG "record_pointer\n");        
-	return audio_get_dma_pos(chip->s[CAPTURE]);
+	pos = audio_get_dma_pos(chip->s[CAPTURE]);
+	return pos;
 }
 
 /* }}} */
@@ -784,6 +877,13 @@
 			       substreams, substreams, &pcm)) < 0)
 		return err;
 
+	/*
+	 * this sets up our initial buffers and sets the dma_type to isa.
+	 * isa works but I'm not sure why (or if) it's the right choice
+	 * this may be too large, trying it for now
+	 */
+	snd_pcm_lib_preallocate_isa_pages_for_all(pcm, 64*1024, 64*1024);
+
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_sa11xx_uda1341_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_sa11xx_uda1341_capture_ops);
 	pcm->private_data = sa11xx_uda1341;
@@ -815,6 +915,10 @@
 	int stopstate;
 
 	DEBUG_NAME(KERN_DEBUG "pm_callback\n");
+
+	/* pause resume is broken  see note */
+	printk("Pause/Resume support currently broken... \n");	
+        return -1;
 
 	is = sa11xx_uda1341->s[PLAYBACK];
 	os = sa11xx_uda1341->s[CAPTURE];
diff -Nru a/sound/core/Makefile b/sound/core/Makefile
--- a/sound/core/Makefile	Mon Feb  3 14:19:39 2003
+++ b/sound/core/Makefile	Sun Mar 23 08:35:33 2003
@@ -14,8 +14,10 @@
 
 snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
 		pcm_memory.o
+
+snd-page-alloc-objs := memalloc.o
 ifeq ($(CONFIG_PCI),y)
-snd-pcm-objs += pcm_sgbuf.o
+snd-page-alloc-objs += sgbuf.o memory_wrapper.o
 endif
 
 snd-rawmidi-objs  := rawmidi.o
@@ -31,72 +33,73 @@
 obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o
 
 obj-$(CONFIG_SND_MIXER_OSS) += oss/
-obj-$(CONFIG_SND_PCM_OSS) += snd-pcm.o snd-timer.o oss/
+obj-$(CONFIG_SND_PCM_OSS) += snd-pcm.o snd-timer.o snd-page-alloc.o oss/
 obj-$(CONFIG_SND_SEQUENCER) += snd-timer.o seq/
 obj-$(CONFIG_SND_BIT32_EMUL) += ioctl32/
 
 # Toplevel Module Dependency
-obj-$(CONFIG_SND_DUMMY) += snd-pcm.o snd-timer.o snd.o
+obj-$(CONFIG_SND_DUMMY) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
 obj-$(CONFIG_SND_VIRMIDI) += snd-rawmidi.o snd.o snd-timer.o
 obj-$(CONFIG_SND_SERIAL_U16550) += snd-rawmidi.o snd.o snd-timer.o
 obj-$(CONFIG_SND_MTPAV) += snd-rawmidi.o snd.o snd-timer.o
 obj-$(CONFIG_SND_MPU401) += snd-rawmidi.o snd.o snd-timer.o
-obj-$(CONFIG_SND_ALS100) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_AZT2320) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_CMI8330) += snd-pcm.o snd-timer.o snd.o
-obj-$(CONFIG_SND_DT019X) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_ES18XX) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_OPL3SA2) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_SGALAXY) += snd-pcm.o snd-timer.o snd.o
-obj-$(CONFIG_SND_AD1816A) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_AD1848) += snd-pcm.o snd-timer.o snd.o
-obj-$(CONFIG_SND_CS4231) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_CS4232) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_CS4236) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_ES1688) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_GUSCLASSIC) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_GUSMAX) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_GUSEXTREME) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_INTERWAVE) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_INTERWAVE_STB) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_OPTI93X) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_SB8) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_SB16) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_SBAWE) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_ES968) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_WAVEFRONT) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_ALS4000) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_CMIPCI) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_CS4281) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_ENS1370) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_ENS1371) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_ES1938) += snd-pcm.o snd-timer.o snd.o snd-hwdep.o snd-rawmidi.o
-obj-$(CONFIG_SND_ES1968) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_FM801) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_ICE1712) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_INTEL8X0) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_MAESTRO3) += snd-pcm.o snd-timer.o snd.o
-obj-$(CONFIG_SND_RME32) += snd-pcm.o snd-timer.o snd.o
-obj-$(CONFIG_SND_RME96) += snd-pcm.o snd-timer.o snd.o
-obj-$(CONFIG_SND_SONICVIBES) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_VIA82XX) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_ALI5451) += snd.o snd-rawmidi.o snd-timer.o snd-pcm.o
-obj-$(CONFIG_SND_CS46XX) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_EMU10K1) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_KORG1212) += snd-pcm.o snd-timer.o snd.o
-obj-$(CONFIG_SND_NM256) += snd-pcm.o snd-timer.o snd.o
-obj-$(CONFIG_SND_RME9652) += snd-pcm.o snd-timer.o snd.o
-obj-$(CONFIG_SND_HDSP) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_TRIDENT) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_YMFPCI) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_POWERMAC) += snd-pcm.o snd-timer.o snd.o
-obj-$(CONFIG_SND_SA11XX_UDA1341) += snd-pcm.o snd-timer.o snd.o
+obj-$(CONFIG_SND_ALS100) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_AZT2320) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_CMI8330) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
+obj-$(CONFIG_SND_DT019X) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_ES18XX) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_OPL3SA2) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_SGALAXY) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
+obj-$(CONFIG_SND_AD1816A) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_AD1848) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
+obj-$(CONFIG_SND_CS4231) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_CS4232) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_CS4236) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_ES1688) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_GUSCLASSIC) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_GUSMAX) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_GUSEXTREME) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_INTERWAVE) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_INTERWAVE_STB) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_OPTI93X) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_SB8) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_SB16) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_SBAWE) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_ES968) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_WAVEFRONT) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_ALS4000) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_CMIPCI) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_CS4281) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_ENS1370) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_ENS1371) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_ES1938) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-hwdep.o snd-rawmidi.o
+obj-$(CONFIG_SND_ES1968) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_FM801) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_ICE1712) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_INTEL8X0) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_MAESTRO3) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
+obj-$(CONFIG_SND_RME32) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
+obj-$(CONFIG_SND_RME96) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
+obj-$(CONFIG_SND_SONICVIBES) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_VIA82XX) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_ALI5451) += snd.o snd-rawmidi.o snd-timer.o snd-page-alloc.o snd-pcm.o
+obj-$(CONFIG_SND_CS46XX) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_EMU10K1) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_KORG1212) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
+obj-$(CONFIG_SND_NM256) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
+obj-$(CONFIG_SND_RME9652) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
+obj-$(CONFIG_SND_HDSP) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_TRIDENT) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_YMFPCI) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
+obj-$(CONFIG_SND_POWERMAC) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
+obj-$(CONFIG_SND_SA11XX_UDA1341) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
+obj-$(CONFIG_SND_PC98_CS4232) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
 ifeq ($(CONFIG_SND_SB16_CSP),y)
   obj-$(CONFIG_SND_SB16) += snd-hwdep.o
   obj-$(CONFIG_SND_SBAWE) += snd-hwdep.o
 endif
-obj-$(CONFIG_SND_USB_AUDIO) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_USB_AUDIO) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
 
 obj-m := $(sort $(obj-m))
diff -Nru a/sound/core/control.c b/sound/core/control.c
--- a/sound/core/control.c	Mon Jan 27 11:00:12 2003
+++ b/sound/core/control.c	Thu Mar 20 08:41:11 2003
@@ -714,14 +714,14 @@
 			return -EFAULT;
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		err = -ENOPROTOOPT;
 #ifdef CONFIG_PM
 		if (card->set_power_state) {
 		    snd_power_lock(card);
 		    err = card->set_power_state(card, err);
 		    snd_power_unlock(card);
-		}
+		} else
 #endif
+			err = -ENOPROTOOPT;
 		return err;
 	case SNDRV_CTL_IOCTL_POWER_STATE:
 #ifdef CONFIG_PM
diff -Nru a/sound/core/hwdep.c b/sound/core/hwdep.c
--- a/sound/core/hwdep.c	Sun Feb 16 05:47:41 2003
+++ b/sound/core/hwdep.c	Tue Feb 25 05:46:05 2003
@@ -107,7 +107,12 @@
 #endif
 	init_waitqueue_entry(&wait, current);
 	add_wait_queue(&hw->open_wait, &wait);
+	down(&hw->open_mutex);
 	while (1) {
+		if (hw->exclusive && hw->used > 0) {
+			err = -EBUSY;
+			break;
+		}
 		err = hw->ops.open(hw, file);
 		if (err >= 0)
 			break;
@@ -127,20 +132,26 @@
 	}
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&hw->open_wait, &wait);
-	if (err >= 0)
+	if (err >= 0) {
 		file->private_data = hw;
+		hw->used++;
+	}
+	up(&hw->open_mutex);
 	return err;
 }
 
 static int snd_hwdep_release(struct inode *inode, struct file * file)
 {
-	int err;
+	int err = -ENXIO;
 	snd_hwdep_t *hw = snd_magic_cast(snd_hwdep_t, file->private_data, return -ENXIO);
+	down(&hw->open_mutex);
 	if (hw->ops.release) {
 		err = hw->ops.release(hw, file);
 		wake_up(&hw->open_wait);
-		return err;
 	}
+	if (hw->used > 0)
+		hw->used--;
+	up(&hw->open_mutex);
 	return -ENXIO;	
 }
 
@@ -166,14 +177,58 @@
 	return 0;
 }
 
+static int snd_hwdep_dsp_status(snd_hwdep_t *hw, snd_hwdep_dsp_status_t *_info)
+{
+	snd_hwdep_dsp_status_t info;
+	int err;
+	
+	if (! hw->ops.dsp_status)
+		return -ENXIO;
+	memset(&info, 0, sizeof(info));
+	info.dsp_loaded = hw->dsp_loaded;
+	if ((err = hw->ops.dsp_status(hw, &info)) < 0)
+		return err;
+	if (copy_to_user(_info, &info, sizeof(info)))
+		return -EFAULT;
+	return 0;
+}
+
+static int snd_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *_info)
+{
+	snd_hwdep_dsp_image_t info;
+	int err;
+	
+	if (! hw->ops.dsp_load || ! hw->ops.dsp_status)
+		return -ENXIO;
+	memset(&info, 0, sizeof(info));
+	if (copy_from_user(&info, _info, sizeof(info)))
+		return -EFAULT;
+	/* check whether the dsp was already loaded */
+	if (hw->dsp_loaded & (1 << info.index))
+		return -EBUSY;
+	if (verify_area(VERIFY_READ, info.image, info.length))
+		return -EFAULT;
+	err = hw->ops.dsp_load(hw, &info);
+	if (err < 0)
+		return err;
+	hw->dsp_loaded |= (1 << info.index);
+	return 0;
+}
+
 static int snd_hwdep_ioctl(struct inode *inode, struct file * file,
 			   unsigned int cmd, unsigned long arg)
 {
 	snd_hwdep_t *hw = snd_magic_cast(snd_hwdep_t, file->private_data, return -ENXIO);
-	if (cmd == SNDRV_HWDEP_IOCTL_PVERSION)
+	switch (cmd) {
+	case SNDRV_HWDEP_IOCTL_PVERSION:
 		return put_user(SNDRV_HWDEP_VERSION, (int *)arg);
-	if (cmd == SNDRV_HWDEP_IOCTL_INFO)
+	case SNDRV_HWDEP_IOCTL_INFO:
 		return snd_hwdep_info(hw, (snd_hwdep_info_t *)arg);
+	case SNDRV_HWDEP_IOCTL_DSP_STATUS:
+		return snd_hwdep_dsp_status(hw, (snd_hwdep_dsp_status_t *)arg);
+	case SNDRV_HWDEP_IOCTL_DSP_LOAD:
+		return snd_hwdep_dsp_load(hw, (snd_hwdep_dsp_image_t *)arg);
+	}
 	if (hw->ops.ioctl)
 		return hw->ops.ioctl(hw, file, cmd, arg);
 	return -ENOTTY;
@@ -298,6 +353,7 @@
 		return err;
 	}
 	init_waitqueue_head(&hwdep->open_wait);
+	init_MUTEX(&hwdep->open_mutex);
 	*rhwdep = hwdep;
 	return 0;
 }
diff -Nru a/sound/core/info.c b/sound/core/info.c
--- a/sound/core/info.c	Sat Feb  8 12:10:45 2003
+++ b/sound/core/info.c	Thu Mar 20 08:41:11 2003
@@ -220,7 +220,7 @@
 		buf = data->rbuffer;
 		if (buf == NULL)
 			return -EIO;
-		if (file->f_pos >= buf->size)
+		if (file->f_pos >= (long)buf->size)
 			return 0;
 		size = buf->size < count ? buf->size : count;
 		size1 = buf->size - file->f_pos;
@@ -260,7 +260,7 @@
 			return -EIO;
 		if (file->f_pos < 0)
 			return -EINVAL;
-		if (file->f_pos >= buf->len)
+		if (file->f_pos >= (long)buf->len)
 			return -ENOMEM;
 		size = buf->len < count ? buf->len : count;
 		size1 = buf->len - file->f_pos;
@@ -268,7 +268,7 @@
 			size = size1;
 		if (copy_from_user(buf->buffer + file->f_pos, buffer, size))
 			return -EFAULT;
-		if (buf->size < file->f_pos + size)
+		if ((long)buf->size < file->f_pos + size)
 			buf->size = file->f_pos + size;
 		file->f_pos += size;
 		break;
diff -Nru a/sound/core/init.c b/sound/core/init.c
--- a/sound/core/init.c	Sat Feb  8 12:10:45 2003
+++ b/sound/core/init.c	Thu Mar 20 08:41:11 2003
@@ -495,6 +495,22 @@
 
 #endif
 
+#ifdef MODULE
+static snd_info_entry_t *snd_card_module_info_entry;
+static void snd_card_module_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+{
+	int idx;
+	snd_card_t *card;
+
+	for (idx = 0; idx < SNDRV_CARDS; idx++) {
+		read_lock(&snd_card_rwlock);
+		if ((card = snd_cards[idx]) != NULL)
+			snd_iprintf(buffer, "%i %s\n", idx, card->module->name);
+		read_unlock(&snd_card_rwlock);
+	}
+}
+#endif
+
 int __init snd_card_info_init(void)
 {
 	snd_info_entry_t *entry;
@@ -509,6 +525,20 @@
 		return -ENOMEM;
 	}
 	snd_card_info_entry = entry;
+
+#ifdef MODULE
+	entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL);
+	if (entry) {
+		entry->content = SNDRV_INFO_CONTENT_TEXT;
+		entry->c.text.read_size = PAGE_SIZE;
+		entry->c.text.read = snd_card_module_info_read;
+		if (snd_info_register(entry) < 0)
+			snd_info_free_entry(entry);
+		else
+			snd_card_module_info_entry = entry;
+	}
+#endif
+
 	return 0;
 }
 
@@ -516,6 +546,10 @@
 {
 	if (snd_card_info_entry)
 		snd_info_unregister(snd_card_info_entry);
+#ifdef MODULE
+	if (snd_card_module_info_entry)
+		snd_info_unregister(snd_card_module_info_entry);
+#endif
 	return 0;
 }
 
diff -Nru a/sound/core/ioctl32/hwdep32.c b/sound/core/ioctl32/hwdep32.c
--- a/sound/core/ioctl32/hwdep32.c	Tue Oct  1 10:08:34 2002
+++ b/sound/core/ioctl32/hwdep32.c	Thu Mar 20 08:41:11 2003
@@ -20,13 +20,54 @@
 
 #include <sound/driver.h>
 #include <linux/time.h>
+#include <linux/fs.h>
 #include <sound/core.h>
-#include <sound/timer.h>
+#include <sound/hwdep.h>
 #include <asm/uaccess.h>
 #include "ioctl32.h"
 
+struct sndrv_hwdep_dsp_image32 {
+	u32 index;
+	unsigned char name[64];
+	u32 image;	/* pointer */
+	u32 length;
+	u32 driver_data;
+} /* don't set packed attribute here */;
+
+static int _snd_ioctl32_hwdep_dsp_image(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
+{
+	struct sndrv_hwdep_dsp_image data;
+	struct sndrv_hwdep_dsp_image data32;
+	mm_segment_t oldseg;
+	int err;
+
+	if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
+		return -EFAULT;
+	memset(&data, 0, sizeof(data));
+	data.index = data32.index;
+	memcpy(data.name, data32.name, sizeof(data.name));
+	data.image = A(data32.image);
+	data.length = data32.length;
+	data.driver_data = data32.driver_data;
+	oldseg = get_fs();
+	set_fs(KERNEL_DS);
+	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);
+	set_fs(oldseg);
+	return err;
+}
+
+DEFINE_ALSA_IOCTL_ENTRY(hwdep_dsp_image, hwdep_dsp_image, SNDRV_HWDEP_IOCTL_DSP_LOAD);
+
+#define AP(x) snd_ioctl32_##x
+
+enum {
+	SNDRV_HWDEP_IOCTL_DSP_LOAD32   = _IOW('H', 0x03, struct sndrv_hwdep_dsp_image32)
+};
+
 struct ioctl32_mapper hwdep_mappers[] = {
-	{ SNDRV_HWDEP_IOCTL_PVERSION, NULL },
-	{ SNDRV_HWDEP_IOCTL_INFO, NULL },
+	MAP_COMPAT(SNDRV_HWDEP_IOCTL_PVERSION),
+	MAP_COMPAT(SNDRV_HWDEP_IOCTL_INFO),
+	MAP_COMPAT(SNDRV_HWDEP_IOCTL_DSP_STATUS),
+	{ SNDRV_HWDEP_IOCTL_DSP_LOAD32, AP(hwdep_dsp_image) },
 	{ 0 },
 };
diff -Nru a/sound/core/ioctl32/pcm32.c b/sound/core/ioctl32/pcm32.c
--- a/sound/core/ioctl32/pcm32.c	Sat Feb  8 12:10:45 2003
+++ b/sound/core/ioctl32/pcm32.c	Sun Mar 23 00:11:45 2003
@@ -21,6 +21,7 @@
 #include <sound/driver.h>
 #include <linux/time.h>
 #include <linux/slab.h>
+#include <linux/compat.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include "ioctl32.h"
@@ -136,15 +137,10 @@
 	COPY(step);\
 }
 
-struct timeval32 {
-	s32 tv_sec;
-	s32 tv_usec;
-} __attribute__((packed));
-
 struct sndrv_pcm_status32 {
 	s32 state;
-	struct timeval32 trigger_tstamp;
-	struct timeval32 tstamp;
+	struct compat_timespec trigger_tstamp;
+	struct compat_timespec tstamp;
 	u32 appl_ptr;
 	u32 hw_ptr;
 	s32 delay;
@@ -159,9 +155,9 @@
 {\
 	COPY(state);\
 	COPY(trigger_tstamp.tv_sec);\
-	COPY(trigger_tstamp.tv_usec);\
+	COPY(trigger_tstamp.tv_nsec);\
 	COPY(tstamp.tv_sec);\
-	COPY(tstamp.tv_usec);\
+	COPY(tstamp.tv_nsec);\
 	COPY(appl_ptr);\
 	COPY(hw_ptr);\
 	COPY(delay);\
diff -Nru a/sound/core/ioctl32/rawmidi32.c b/sound/core/ioctl32/rawmidi32.c
--- a/sound/core/ioctl32/rawmidi32.c	Sat Feb  8 12:10:45 2003
+++ b/sound/core/ioctl32/rawmidi32.c	Sun Mar 23 00:13:13 2003
@@ -21,6 +21,7 @@
 #include <sound/driver.h>
 #include <linux/time.h>
 #include <linux/fs.h>
+#include <linux/compat.h>
 #include <sound/core.h>
 #include <sound/rawmidi.h>
 #include <asm/uaccess.h>
@@ -42,14 +43,9 @@
 	COPY(no_active_sensing);\
 }
 
-struct timeval32 {
-	s32 tv_sec;
-	s32 tv_usec;
-} __attribute__((packed));
-
 struct sndrv_rawmidi_status32 {
 	s32 stream;
-	struct timeval32 tstamp;
+	struct compat_timespec tstamp;
 	u32 avail;
 	u32 xruns;
 	unsigned char reserved[16];
@@ -59,7 +55,7 @@
 {\
 	COPY(stream);\
 	COPY(tstamp.tv_sec);\
-	COPY(tstamp.tv_usec);\
+	COPY(tstamp.tv_nsec);\
 	COPY(avail);\
 	COPY(xruns);\
 }
diff -Nru a/sound/core/ioctl32/timer32.c b/sound/core/ioctl32/timer32.c
--- a/sound/core/ioctl32/timer32.c	Sat Feb  8 12:10:45 2003
+++ b/sound/core/ioctl32/timer32.c	Sun Mar 23 00:30:26 2003
@@ -21,6 +21,7 @@
 #include <sound/driver.h>
 #include <linux/time.h>
 #include <linux/fs.h>
+#include <linux/compat.h>
 #include <sound/core.h>
 #include <sound/timer.h>
 #include <asm/uaccess.h>
@@ -31,7 +32,7 @@
 	s32 card;
 	unsigned char id[64];
 	unsigned char name[80];
-	u32 ticks;
+	u32 reserved0;
 	u32 resolution;
 	unsigned char reserved[64];
 };
@@ -42,17 +43,11 @@
 	COPY(card);\
 	memcpy(dst->id, src->id, sizeof(src->id));\
 	memcpy(dst->name, src->name, sizeof(src->name));\
-	COPY(ticks);\
 	COPY(resolution);\
 }
 
-struct timeval32 {
-	s32 tv_sec;
-	s32 tv_usec;
-};
-
 struct sndrv_timer_status32 {
-	struct timeval32 tstamp;
+	struct compat_timespec tstamp;
 	u32 resolution;
 	u32 lost;
 	u32 overrun;
@@ -63,7 +58,7 @@
 #define CVT_sndrv_timer_status()\
 {\
 	COPY(tstamp.tv_sec);\
-	COPY(tstamp.tv_usec);\
+	COPY(tstamp.tv_nsec);\
 	COPY(resolution);\
 	COPY(lost);\
 	COPY(overrun);\
diff -Nru a/sound/core/isadma.c b/sound/core/isadma.c
--- a/sound/core/isadma.c	Sun Feb 16 05:47:41 2003
+++ b/sound/core/isadma.c	Thu Mar 20 08:41:11 2003
@@ -96,5 +96,8 @@
 	if (result > size)
 		snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size);
 #endif
-	return result >= size ? 0 : size - result;
+	if (result >= size || result == 0)
+		return 0;
+	else
+		return size - result;
 }
diff -Nru a/sound/core/memalloc.c b/sound/core/memalloc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/sound/core/memalloc.c	Sat Mar 22 23:54:41 2003
@@ -0,0 +1,785 @@
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ *                   Takashi Iwai <tiwai@suse.de>
+ * 
+ *  Generic memory allocators
+ *
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/semaphore.h>
+#include <sound/memalloc.h>
+
+
+MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@suse.cz>");
+MODULE_DESCRIPTION("Memory allocator for ALSA system.");
+MODULE_LICENSE("GPL");
+
+
+/*
+ */
+
+static DECLARE_MUTEX(list_mutex);
+static LIST_HEAD(mem_list_head);
+
+/* buffer preservation list */
+struct snd_mem_list {
+	struct snd_dma_device dev;
+	struct snd_dma_buffer buffer;
+	int used;
+	struct list_head list;
+};
+
+
+#ifdef CONFIG_SND_DEBUG
+#define __ASTRING__(x) #x
+#define snd_assert(expr, args...) do {\
+	if (!(expr)) {\
+		printk(KERN_ERR "snd-malloc: BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
+		args;\
+	}\
+} while (0)
+#else
+#define snd_assert(expr, args...) /**/
+#endif
+
+/* redefine pci_alloc_consistent for some architectures */
+#ifdef HACK_PCI_ALLOC_CONSISTENT
+#undef pci_alloc_consistent
+#define pci_alloc_consistent snd_pci_hack_alloc_consistent
+#endif
+
+
+/*
+ * compare the two devices
+ * returns non-zero if matched.
+ */
+static int compare_device(const struct snd_dma_device *a, const struct snd_dma_device *b)
+{
+	if (a->type != b->type)
+		return 0;
+	if (a->id != b->id)
+		return 0;
+	switch (a->type) {
+	case SNDRV_DMA_TYPE_CONTINUOUS:
+#ifdef CONFIG_ISA
+	case SNDRV_DMA_TYPE_ISA:
+#endif
+		return a->dev.flags == b->dev.flags;
+#ifdef CONFIG_PCI
+	case SNDRV_DMA_TYPE_PCI:
+		return a->dev.pci == b->dev.pci;
+#endif
+#ifdef CONFIG_SBUS
+	case SNDRV_DMA_TYPE_SBUS:
+		return a->dev.sbus == b->dev.sbus;
+#endif
+	}
+	return 0;
+}
+
+/**
+ * snd_dma_alloc_pages - allocate the buffer area according to the given type
+ * @dev: the buffer device info
+ * @size: the buffer size to allocate
+ * @dmab: buffer allocation record to store the allocated data
+ *
+ * Calls the memory-allocator function for the corresponding
+ * buffer type.
+ * 
+ * Returns zero if the buffer with the given size is allocated successfuly,
+ * other a negative value at error.
+ */
+int snd_dma_alloc_pages(const struct snd_dma_device *dev, size_t size,
+			struct snd_dma_buffer *dmab)
+{
+	snd_assert(dev != NULL, return -ENXIO);
+	snd_assert(size > 0, return -ENXIO);
+	snd_assert(dmab != NULL, return -ENXIO);
+
+	dmab->bytes = 0;
+	switch (dev->type) {
+	case SNDRV_DMA_TYPE_CONTINUOUS:
+		dmab->area = snd_malloc_pages(size, dev->dev.flags);
+		dmab->addr = 0;
+		break;
+#ifdef CONFIG_ISA
+	case SNDRV_DMA_TYPE_ISA:
+		dmab->area = snd_malloc_isa_pages(size, &dmab->addr);
+		break;
+#endif
+#ifdef CONFIG_PCI
+	case SNDRV_DMA_TYPE_PCI:
+		dmab->area = snd_malloc_pci_pages(dev->dev.pci, size, &dmab->addr);
+		break;
+	case SNDRV_DMA_TYPE_PCI_SG:
+		snd_malloc_sgbuf_pages(dev->dev.pci, size, dmab);
+		break;
+#endif
+#ifdef CONFIG_SBUS
+	case SNDRV_DMA_TYPE_SBUS:
+		dmab->area = snd_malloc_sbus_pages(dev->dev.sbus, size, &dmab->addr);
+		break;
+#endif
+	default:
+		printk(KERN_ERR "snd-malloc: invalid device type %d\n", dev->type);
+		dmab->area = NULL;
+		dmab->addr = 0;
+		return -ENXIO;
+	}
+	if (dmab->area)
+		dmab->bytes = size;
+	return 0;
+}
+
+
+/**
+ * snd_dma_free_pages - release the allocated buffer
+ * @dev: the buffer device info
+ * @dmbab: the buffer allocation record to release
+ *
+ * Releases the allocated buffer via snd_dma_alloc_pages().
+ */
+void snd_dma_free_pages(const struct snd_dma_device *dev, struct snd_dma_buffer *dmab)
+{
+	switch (dev->type) {
+	case SNDRV_DMA_TYPE_CONTINUOUS:
+		snd_free_pages(dmab->area, dmab->bytes);
+		break;
+#ifdef CONFIG_ISA
+	case SNDRV_DMA_TYPE_ISA:
+		snd_free_isa_pages(dmab->bytes, dmab->area, dmab->addr);
+		break;
+#endif
+#ifdef CONFIG_PCI
+	case SNDRV_DMA_TYPE_PCI:
+		snd_free_pci_pages(dev->dev.pci, dmab->bytes, dmab->area, dmab->addr);
+		break;
+	case SNDRV_DMA_TYPE_PCI_SG:
+		snd_free_sgbuf_pages(dmab);
+		break;
+#endif
+#ifdef CONFIG_SBUS
+	case SNDRV_DMA_TYPE_SBUS:
+		snd_free_sbus_pages(dev->dev.sbus, dmab->bytes, dmab->area, dmab->addr);
+		break;
+#endif
+	default:
+		printk(KERN_ERR "snd-malloc: invalid device type %d\n", dev->type);
+	}
+}
+
+
+/*
+ * search for the device
+ */
+static struct snd_mem_list *mem_list_find(const struct snd_dma_device *dev)
+{
+	struct list_head *p;
+	struct snd_mem_list *mem;
+
+	list_for_each(p, &mem_list_head) {
+		mem = list_entry(p, struct snd_mem_list, list);
+		if (compare_device(&mem->dev, dev))
+			return mem;
+	}
+	return NULL;
+}
+
+/**
+ * snd_dma_get_reserved - get the reserved buffer for the given device
+ * @dev: the buffer device info
+ * @dmab: the buffer allocation record to store
+ *
+ * Looks for the reserved-buffer list and re-uses if the same buffer
+ * is found in the list.  When the buffer is found, it's marked as used.
+ * For unmarking the buffer, call snd_dma_free_reserved().
+ *
+ * Returns the size of buffer if the buffer is found, or zero if not found.
+ */
+size_t snd_dma_get_reserved(const struct snd_dma_device *dev, struct snd_dma_buffer *dmab)
+{
+	struct snd_mem_list *mem;
+
+	snd_assert(dev && dmab, return 0);
+
+	down(&list_mutex);
+	mem = mem_list_find(dev);
+	if (mem) {
+		mem->used = 1;
+		*dmab = mem->buffer;
+		up(&list_mutex);
+		return dmab->bytes;
+	}
+	up(&list_mutex);
+	return 0;
+}
+
+/**
+ * snd_dma_free_reserved - unmark the reserved buffer
+ * @dev: the buffer device info
+ *
+ * Looks for the matching reserved buffer and erases the mark on it
+ * if found.
+ *
+ * Returns zero.
+ */
+int snd_dma_free_reserved(const struct snd_dma_device *dev)
+{
+	struct snd_mem_list *mem;
+
+	snd_assert(dev, return -EINVAL);
+	down(&list_mutex);
+	mem = mem_list_find(dev);
+	if (mem)
+		mem->used = 0;
+	up(&list_mutex);
+	return 0;
+}
+
+/**
+ * snd_dma_set_reserved - reserve the buffer
+ * @dev: the buffer device info
+ * @dmab: the buffer to reserve
+ *
+ * Reserves the given buffer as a reserved buffer.
+ * When an old reserved buffer already exists, the old one is released
+ * and replaced with the new one.
+ *
+ * When NULL buffer pointer or zero buffer size is given, the existing
+ * release buffer is released and the entry is removed.
+ * 
+ * Returns zero if successful, or a negative code at error.
+ */
+int snd_dma_set_reserved(const struct snd_dma_device *dev, struct snd_dma_buffer *dmab)
+{
+	struct snd_mem_list *mem;
+
+	snd_assert(dev, return -EINVAL);
+	down(&list_mutex);
+	mem = mem_list_find(dev);
+	if (mem) {
+		snd_dma_free_pages(dev, &mem->buffer);
+		if (! dmab || ! dmab->bytes) {
+			/* remove the entry */
+			list_del(&mem->list);
+			kfree(mem);
+			up(&list_mutex);
+			return 0;
+		}
+	} else {
+		if (! dmab || ! dmab->bytes) {
+			up(&list_mutex);
+			return 0;
+		}
+		mem = kmalloc(sizeof(*mem), GFP_KERNEL);
+		mem->dev = *dev;
+		list_add(&mem->list, &mem_list_head);
+	}
+	/* store the entry */
+	mem->used = 1;
+	mem->buffer = *dmab;
+	up(&list_mutex);
+	return 0;
+}
+
+/*
+ * purge all reserved buffers
+ */
+static void free_all_reserved_pages(void)
+{
+	struct list_head *p;
+	struct snd_mem_list *mem;
+
+	down(&list_mutex);
+	while (! list_empty(&mem_list_head)) {
+		p = mem_list_head.next;
+		mem = list_entry(p, struct snd_mem_list, list);
+		list_del(p);
+		snd_dma_free_pages(&mem->dev, &mem->buffer);
+		kfree(mem);
+	}
+	up(&list_mutex);
+}
+
+
+/*
+ *
+ *  Generic memory allocators
+ *
+ */
+
+static long snd_allocated_pages; /* holding the number of allocated pages */
+
+static void mark_pages(void *res, int order)
+{
+	struct page *page = virt_to_page(res);
+	struct page *last_page = page + (1 << order);
+	while (page < last_page)
+		SetPageReserved(page++);
+	snd_allocated_pages += 1 << order;
+}
+
+static void unmark_pages(void *res, int order)
+{
+	struct page *page = virt_to_page(res);
+	struct page *last_page = page + (1 << order);
+	while (page < last_page)
+		ClearPageReserved(page++);
+	snd_allocated_pages -= 1 << order;
+}
+
+/**
+ * snd_malloc_pages - allocate pages with the given size
+ * @size: the size to allocate in bytes
+ * @gfp_flags: the allocation conditions, GFP_XXX
+ *
+ * Allocates the physically contiguous pages with the given size.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
+void *snd_malloc_pages(size_t size, unsigned int gfp_flags)
+{
+	int pg;
+	void *res;
+
+	snd_assert(size > 0, return NULL);
+	snd_assert(gfp_flags != 0, return NULL);
+	for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
+	if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) {
+		mark_pages(res, pg);
+	}
+	return res;
+}
+
+/**
+ * snd_malloc_pages_fallback - allocate pages with the given size with fallback
+ * @size: the requested size to allocate in bytes
+ * @gfp_flags: the allocation conditions, GFP_XXX
+ * @res_size: the pointer to store the size of buffer actually allocated
+ *
+ * Allocates the physically contiguous pages with the given request
+ * size.  When no space is left, this function reduces the size and
+ * tries to allocate again.  The size actually allocated is stored in
+ * res_size argument.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
+void *snd_malloc_pages_fallback(size_t size, unsigned int gfp_flags, size_t *res_size)
+{
+	void *res;
+
+	snd_assert(size > 0, return NULL);
+	snd_assert(res_size != NULL, return NULL);
+	do {
+		if ((res = snd_malloc_pages(size, gfp_flags)) != NULL) {
+			*res_size = size;
+			return res;
+		}
+		size >>= 1;
+	} while (size >= PAGE_SIZE);
+	return NULL;
+}
+
+/**
+ * snd_free_pages - release the pages
+ * @ptr: the buffer pointer to release
+ * @size: the allocated buffer size
+ *
+ * Releases the buffer allocated via snd_malloc_pages().
+ */
+void snd_free_pages(void *ptr, size_t size)
+{
+	int pg;
+
+	if (ptr == NULL)
+		return;
+	for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
+	unmark_pages(ptr, pg);
+	free_pages((unsigned long) ptr, pg);
+}
+
+#if defined(CONFIG_ISA) && ! defined(CONFIG_PCI)
+
+/**
+ * snd_malloc_isa_pages - allocate pages for ISA bus with the given size
+ * @size: the size to allocate in bytes
+ * @dma_addr: the pointer to store the physical address of the buffer
+ *
+ * Allocates the physically contiguous pages with the given size for
+ * ISA bus.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
+void *snd_malloc_isa_pages(size_t size, dma_addr_t *dma_addr)
+{
+	void *dma_area;
+	dma_area = snd_malloc_pages(size, GFP_ATOMIC|GFP_DMA);
+	*dma_addr = dma_area ? isa_virt_to_bus(dma_area) : 0UL;
+	return dma_area;
+}
+
+/**
+ * snd_malloc_isa_pages_fallback - allocate pages with the given size with fallback for ISA bus
+ * @size: the requested size to allocate in bytes
+ * @dma_addr: the pointer to store the physical address of the buffer
+ * @res_size: the pointer to store the size of buffer actually allocated
+ *
+ * Allocates the physically contiguous pages with the given request
+ * size for PCI bus.  When no space is left, this function reduces the size and
+ * tries to allocate again.  The size actually allocated is stored in
+ * res_size argument.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
+void *snd_malloc_isa_pages_fallback(size_t size,
+				    dma_addr_t *dma_addr,
+				    size_t *res_size)
+{
+	void *dma_area;
+	dma_area = snd_malloc_pages_fallback(size, GFP_ATOMIC|GFP_DMA, res_size);
+	*dma_addr = dma_area ? isa_virt_to_bus(dma_area) : 0UL;
+	return dma_area;
+}
+
+#endif /* CONFIG_ISA && !CONFIG_PCI */
+
+#ifdef CONFIG_PCI
+
+/**
+ * snd_malloc_pci_pages - allocate pages for PCI bus with the given size
+ * @pci: the pci device pointer
+ * @size: the size to allocate in bytes
+ * @dma_addr: the pointer to store the physical address of the buffer
+ *
+ * Allocates the physically contiguous pages with the given size for
+ * PCI bus.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
+void *snd_malloc_pci_pages(struct pci_dev *pci,
+			   size_t size,
+			   dma_addr_t *dma_addr)
+{
+	int pg;
+	void *res;
+
+	snd_assert(size > 0, return NULL);
+	snd_assert(dma_addr != NULL, return NULL);
+	for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
+	res = pci_alloc_consistent(pci, PAGE_SIZE * (1 << pg), dma_addr);
+	if (res != NULL) {
+		mark_pages(res, pg);
+	}
+	return res;
+}
+
+/**
+ * snd_malloc_pci_pages_fallback - allocate pages with the given size with fallback for PCI bus
+ * @pci: pci device pointer
+ * @size: the requested size to allocate in bytes
+ * @dma_addr: the pointer to store the physical address of the buffer
+ * @res_size: the pointer to store the size of buffer actually allocated
+ *
+ * Allocates the physically contiguous pages with the given request
+ * size for PCI bus.  When no space is left, this function reduces the size and
+ * tries to allocate again.  The size actually allocated is stored in
+ * res_size argument.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
+void *snd_malloc_pci_pages_fallback(struct pci_dev *pci,
+				    size_t size,
+				    dma_addr_t *dma_addr,
+				    size_t *res_size)
+{
+	void *res;
+
+	snd_assert(res_size != NULL, return NULL);
+	do {
+		if ((res = snd_malloc_pci_pages(pci, size, dma_addr)) != NULL) {
+			*res_size = size;
+			return res;
+		}
+		size >>= 1;
+	} while (size >= PAGE_SIZE);
+	return NULL;
+}
+
+/**
+ * snd_free_pci_pages - release the pages
+ * @pci: pci device pointer
+ * @size: the allocated buffer size
+ * @ptr: the buffer pointer to release
+ * @dma_addr: the physical address of the buffer
+ *
+ * Releases the buffer allocated via snd_malloc_pci_pages().
+ */
+void snd_free_pci_pages(struct pci_dev *pci,
+			size_t size,
+			void *ptr,
+			dma_addr_t dma_addr)
+{
+	int pg;
+
+	if (ptr == NULL)
+		return;
+	for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
+	unmark_pages(ptr, pg);
+	pci_free_consistent(pci, PAGE_SIZE * (1 << pg), ptr, dma_addr);
+}
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) && defined(__i386__)
+/*
+ * on ix86, we allocate a page with GFP_KERNEL to assure the
+ * allocation.  the code is almost same with kernel/i386/pci-dma.c but
+ * it allocates only a single page and checks the validity of the
+ * page address with the given pci dma mask.
+ */
+
+/**
+ * snd_malloc_pci_page - allocate a page in the valid pci dma mask
+ * @pci: pci device pointer
+ * @addrp: the pointer to store the physical address of the buffer
+ *
+ * Allocates a single page for the given PCI device and returns
+ * the virtual address and stores the physical address on addrp.
+ * 
+ * This function cannot be called from interrupt handlers or
+ * within spinlocks.
+ */
+void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *addrp)
+{
+	void *ptr;
+	dma_addr_t addr;
+	unsigned long rmask;
+
+	rmask = ~(unsigned long)(pci ? pci->dma_mask : 0x00ffffff);
+	ptr = (void *)__get_free_page(GFP_KERNEL);
+	if (ptr) {
+		addr = virt_to_phys(ptr);
+		if (((unsigned long)addr + PAGE_SIZE - 1) & rmask) {
+			/* try to reallocate with the GFP_DMA */
+			free_page((unsigned long)ptr);
+			/* use GFP_ATOMIC for the DMA zone to avoid stall */
+			ptr = (void *)__get_free_page(GFP_ATOMIC | GFP_DMA);
+			if (ptr) /* ok, the address must be within lower 16MB... */
+				addr = virt_to_phys(ptr);
+			else
+				addr = 0;
+		}
+	} else
+		addr = 0;
+	if (ptr) {
+		memset(ptr, 0, PAGE_SIZE);
+		mark_pages(ptr, 0);
+	}
+	*addrp = addr;
+	return ptr;
+}
+#else
+
+/* on other architectures, call snd_malloc_pci_pages() helper function
+ * which uses pci_alloc_consistent().
+ */
+void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *addrp)
+{
+	return snd_malloc_pci_pages(pci, PAGE_SIZE, addrp);
+}
+
+#endif
+
+#if 0 /* for kernel-doc */
+/**
+ * snd_free_pci_page - release a page
+ * @pci: pci device pointer
+ * @ptr: the buffer pointer to release
+ * @dma_addr: the physical address of the buffer
+ *
+ * Releases the buffer allocated via snd_malloc_pci_page().
+ */
+void snd_free_pci_page(struct pci_dev *pci, void *ptr, dma_addr_t dma_addr);
+#endif /* for kernel-doc */
+
+#endif /* CONFIG_PCI */
+
+#ifdef CONFIG_SBUS
+
+/**
+ * snd_malloc_sbus_pages - allocate pages for SBUS with the given size
+ * @sdev: sbus device pointer
+ * @size: the size to allocate in bytes
+ * @dma_addr: the pointer to store the physical address of the buffer
+ *
+ * Allocates the physically contiguous pages with the given size for
+ * SBUS.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
+void *snd_malloc_sbus_pages(struct sbus_dev *sdev,
+			    size_t size,
+			    dma_addr_t *dma_addr)
+{
+	int pg;
+	void *res;
+
+	snd_assert(size > 0, return NULL);
+	snd_assert(dma_addr != NULL, return NULL);
+	for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
+	res = sbus_alloc_consistent(sdev, PAGE_SIZE * (1 << pg), dma_addr);
+	if (res != NULL) {
+		mark_pages(res, pg);
+	}
+	return res;
+}
+
+/**
+ * snd_malloc_pci_pages_fallback - allocate pages with the given size with fallback for SBUS
+ * @sdev: sbus device pointer
+ * @size: the requested size to allocate in bytes
+ * @dma_addr: the pointer to store the physical address of the buffer
+ * @res_size: the pointer to store the size of buffer actually allocated
+ *
+ * Allocates the physically contiguous pages with the given request
+ * size for SBUS.  When no space is left, this function reduces the size and
+ * tries to allocate again.  The size actually allocated is stored in
+ * res_size argument.
+ *
+ * Returns the pointer of the buffer, or NULL if no enoguh memory.
+ */
+void *snd_malloc_sbus_pages_fallback(struct sbus_dev *sdev,
+				     size_t size,
+				     dma_addr_t *dma_addr,
+				     size_t *res_size)
+{
+	void *res;
+
+	snd_assert(res_size != NULL, return NULL);
+	do {
+		if ((res = snd_malloc_sbus_pages(sdev, size, dma_addr)) != NULL) {
+			*res_size = size;
+			return res;
+		}
+		size >>= 1;
+	} while (size >= PAGE_SIZE);
+	return NULL;
+}
+
+/**
+ * snd_free_sbus_pages - release the pages
+ * @sdev: sbus device pointer
+ * @size: the allocated buffer size
+ * @ptr: the buffer pointer to release
+ * @dma_addr: the physical address of the buffer
+ *
+ * Releases the buffer allocated via snd_malloc_pci_pages().
+ */
+void snd_free_sbus_pages(struct sbus_dev *sdev,
+			 size_t size,
+			 void *ptr,
+			 dma_addr_t dma_addr)
+{
+	int pg;
+
+	if (ptr == NULL)
+		return;
+	for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
+	unmark_pages(ptr, pg);
+	sbus_free_consistent(sdev, PAGE_SIZE * (1 << pg), ptr, dma_addr);
+}
+
+#endif /* CONFIG_SBUS */
+
+
+#ifdef CONFIG_PROC_FS
+/*
+ * proc file interface
+ */
+static int snd_mem_proc_read(char *page, char **start, off_t off,
+			     int count, int *eof, void *data)
+{
+	int len = 0;
+	long pages = snd_allocated_pages >> (PAGE_SHIFT-12);
+
+	len += sprintf(page + len, "pages  : %li bytes (%li pages per %likB)\n",
+		       pages * PAGE_SIZE, pages, PAGE_SIZE / 1024);
+	return len;
+}
+#endif /* CONFIG_PROC_FS */
+
+/*
+ * module entry
+ */
+
+static int __init snd_mem_init(void)
+{
+	create_proc_read_entry("driver/snd-page-alloc", 0, 0, snd_mem_proc_read, NULL);
+	return 0;
+}
+
+static void __exit snd_mem_exit(void)
+{
+	remove_proc_entry("driver/snd-page-alloc", NULL);
+	free_all_reserved_pages();
+	if (snd_allocated_pages > 0)
+		printk(KERN_ERR "snd-malloc: Memory leak?  pages not freed = %li\n", snd_allocated_pages);
+}
+
+
+module_init(snd_mem_init)
+module_exit(snd_mem_exit)
+
+
+/*
+ * exports
+ */
+EXPORT_SYMBOL(snd_dma_alloc_pages);
+EXPORT_SYMBOL(snd_dma_free_pages);
+EXPORT_SYMBOL(snd_dma_get_reserved);
+EXPORT_SYMBOL(snd_dma_free_reserved);
+EXPORT_SYMBOL(snd_dma_set_reserved);
+
+EXPORT_SYMBOL(snd_malloc_pages);
+EXPORT_SYMBOL(snd_malloc_pages_fallback);
+EXPORT_SYMBOL(snd_free_pages);
+#if defined(CONFIG_ISA) && ! defined(CONFIG_PCI)
+EXPORT_SYMBOL(snd_malloc_isa_pages);
+EXPORT_SYMBOL(snd_malloc_isa_pages_fallback);
+#endif
+#ifdef CONFIG_PCI
+EXPORT_SYMBOL(snd_malloc_pci_pages);
+EXPORT_SYMBOL(snd_malloc_pci_pages_fallback);
+EXPORT_SYMBOL(snd_malloc_pci_page);
+EXPORT_SYMBOL(snd_free_pci_pages);
+EXPORT_SYMBOL(snd_malloc_sgbuf_pages);
+EXPORT_SYMBOL(snd_free_sgbuf_pages);
+#ifdef HACK_PCI_ALLOC_CONSISTENT
+EXPORT_SYMBOL(snd_pci_hack_alloc_consistent);
+#endif 
+#endif
+#ifdef CONFIG_SBUS
+EXPORT_SYMBOL(snd_malloc_sbus_pages);
+EXPORT_SYMBOL(snd_malloc_sbus_pages_fallback);
+EXPORT_SYMBOL(snd_free_sbus_pages);
+#endif
diff -Nru a/sound/core/memory.c b/sound/core/memory.c
--- a/sound/core/memory.c	Mon Jan 27 09:30:51 2003
+++ b/sound/core/memory.c	Thu Mar 20 08:41:12 2003
@@ -1,6 +1,7 @@
 /*
  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
- *  Memory allocation routines.
+ * 
+ *  Memory allocation helpers.
  *
  *
  *   This program is free software; you can redistribute it and/or modify
@@ -28,9 +29,6 @@
 #include <linux/pci.h>
 #include <sound/core.h>
 #include <sound/info.h>
-#ifdef CONFIG_SBUS
-#include <asm/sbus.h>
-#endif
 
 /*
  *  memory allocation helpers and debug routines
@@ -48,7 +46,6 @@
 
 #define snd_alloc_track_entry(obj) (struct snd_alloc_track *)((char*)obj - (unsigned long)((struct snd_alloc_track *)0)->data)
 
-static long snd_alloc_pages;
 static long snd_alloc_kmalloc;
 static long snd_alloc_vmalloc;
 static LIST_HEAD(snd_alloc_kmalloc_list);
@@ -61,7 +58,6 @@
 
 void snd_memory_init(void)
 {
-	snd_alloc_pages = 0;
 	snd_alloc_kmalloc = 0;
 	snd_alloc_vmalloc = 0;
 }
@@ -70,8 +66,7 @@
 {
 	struct list_head *head;
 	struct snd_alloc_track *t;
-	if (snd_alloc_pages > 0)
-		snd_printk(KERN_ERR "Not freed snd_alloc_pages = %li\n", snd_alloc_pages);
+
 	if (snd_alloc_kmalloc > 0)
 		snd_printk(KERN_ERR "Not freed snd_alloc_kmalloc = %li\n", snd_alloc_kmalloc);
 	if (snd_alloc_vmalloc > 0)
@@ -226,8 +221,6 @@
 
 static void snd_memory_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
 {
-	long pages = snd_alloc_pages >> (PAGE_SHIFT-12);
-	snd_iprintf(buffer, "pages  : %li bytes (%li pages per %likB)\n", pages * PAGE_SIZE, pages, PAGE_SIZE / 1024);
 	snd_iprintf(buffer, "kmalloc: %li bytes\n", snd_alloc_kmalloc);
 	snd_iprintf(buffer, "vmalloc: %li bytes\n", snd_alloc_vmalloc);
 }
@@ -263,335 +256,6 @@
 
 #endif /* CONFIG_SND_DEBUG_MEMORY */
 
-
-/**
- * snd_malloc_pages - allocate pages with the given size
- * @size: the size to allocate in bytes
- * @dma_flags: the allocation conditions, GFP_XXX
- *
- * Allocates the physically contiguous pages with the given size.
- *
- * Returns the pointer of the buffer, or NULL if no enoguh memory.
- */
-void *snd_malloc_pages(unsigned long size, unsigned int dma_flags)
-{
-	int pg;
-	void *res;
-
-	snd_assert(size > 0, return NULL);
-	snd_assert(dma_flags != 0, return NULL);
-	for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-	if ((res = (void *) __get_free_pages(dma_flags, pg)) != NULL) {
-		struct page *page = virt_to_page(res);
-		struct page *last_page = page + (1 << pg);
-		while (page < last_page)
-			SetPageReserved(page++);
-#ifdef CONFIG_SND_DEBUG_MEMORY
-		snd_alloc_pages += 1 << pg;
-#endif
-	}
-	return res;
-}
-
-/**
- * snd_malloc_pages_fallback - allocate pages with the given size with fallback
- * @size: the requested size to allocate in bytes
- * @dma_flags: the allocation conditions, GFP_XXX
- * @res_size: the pointer to store the size of buffer actually allocated
- *
- * Allocates the physically contiguous pages with the given request
- * size.  When no space is left, this function reduces the size and
- * tries to allocate again.  The size actually allocated is stored in
- * res_size argument.
- *
- * Returns the pointer of the buffer, or NULL if no enoguh memory.
- */
-void *snd_malloc_pages_fallback(unsigned long size, unsigned int dma_flags, unsigned long *res_size)
-{
-	void *res;
-
-	snd_assert(size > 0, return NULL);
-	snd_assert(res_size != NULL, return NULL);
-	do {
-		if ((res = snd_malloc_pages(size, dma_flags)) != NULL) {
-			*res_size = size;
-			return res;
-		}
-		size >>= 1;
-	} while (size >= PAGE_SIZE);
-	return NULL;
-}
-
-/**
- * snd_free_pages - release the pages
- * @ptr: the buffer pointer to release
- * @size: the allocated buffer size
- *
- * Releases the buffer allocated via snd_malloc_pages().
- */
-void snd_free_pages(void *ptr, unsigned long size)
-{
-	int pg;
-	struct page *page, *last_page;
-
-	if (ptr == NULL)
-		return;
-	for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-	page = virt_to_page(ptr);
-	last_page = page + (1 << pg);
-	while (page < last_page)
-		ClearPageReserved(page++);
-	free_pages((unsigned long) ptr, pg);
-#ifdef CONFIG_SND_DEBUG_MEMORY
-	snd_alloc_pages -= 1 << pg;
-#endif
-}
-
-#if defined(CONFIG_ISA) && ! defined(CONFIG_PCI)
-
-/**
- * snd_malloc_isa_pages - allocate pages for ISA bus with the given size
- * @size: the size to allocate in bytes
- * @dma_addr: the pointer to store the physical address of the buffer
- *
- * Allocates the physically contiguous pages with the given size for
- * ISA bus.
- *
- * Returns the pointer of the buffer, or NULL if no enoguh memory.
- */
-void *snd_malloc_isa_pages(unsigned long size, dma_addr_t *dma_addr)
-{
-	void *dma_area;
-	dma_area = snd_malloc_pages(size, GFP_ATOMIC|GFP_DMA);
-	*dma_addr = dma_area ? isa_virt_to_bus(dma_area) : 0UL;
-	return dma_area;
-}
-
-/**
- * snd_malloc_isa_pages_fallback - allocate pages with the given size with fallback for ISA bus
- * @size: the requested size to allocate in bytes
- * @dma_addr: the pointer to store the physical address of the buffer
- * @res_size: the pointer to store the size of buffer actually allocated
- *
- * Allocates the physically contiguous pages with the given request
- * size for PCI bus.  When no space is left, this function reduces the size and
- * tries to allocate again.  The size actually allocated is stored in
- * res_size argument.
- *
- * Returns the pointer of the buffer, or NULL if no enoguh memory.
- */
-void *snd_malloc_isa_pages_fallback(unsigned long size,
-				    dma_addr_t *dma_addr,
-				    unsigned long *res_size)
-{
-	void *dma_area;
-	dma_area = snd_malloc_pages_fallback(size, GFP_ATOMIC|GFP_DMA, res_size);
-	*dma_addr = dma_area ? isa_virt_to_bus(dma_area) : 0UL;
-	return dma_area;
-}
-
-#endif /* CONFIG_ISA && !CONFIG_PCI */
-
-#ifdef CONFIG_PCI
-
-/**
- * snd_malloc_pci_pages - allocate pages for PCI bus with the given size
- * @pci: the pci device pointer
- * @size: the size to allocate in bytes
- * @dma_addr: the pointer to store the physical address of the buffer
- *
- * Allocates the physically contiguous pages with the given size for
- * PCI bus.
- *
- * Returns the pointer of the buffer, or NULL if no enoguh memory.
- */
-void *snd_malloc_pci_pages(struct pci_dev *pci,
-			   unsigned long size,
-			   dma_addr_t *dma_addr)
-{
-	int pg;
-	void *res;
-
-	snd_assert(size > 0, return NULL);
-	snd_assert(dma_addr != NULL, return NULL);
-	for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-	res = pci_alloc_consistent(pci, PAGE_SIZE * (1 << pg), dma_addr);
-	if (res != NULL) {
-		struct page *page = virt_to_page(res);
-		struct page *last_page = page + (1 << pg);
-		while (page < last_page)
-			SetPageReserved(page++);
-#ifdef CONFIG_SND_DEBUG_MEMORY
-		snd_alloc_pages += 1 << pg;
-#endif
-	}
-	return res;
-}
-
-/**
- * snd_malloc_pci_pages_fallback - allocate pages with the given size with fallback for PCI bus
- * @pci: pci device pointer
- * @size: the requested size to allocate in bytes
- * @dma_addr: the pointer to store the physical address of the buffer
- * @res_size: the pointer to store the size of buffer actually allocated
- *
- * Allocates the physically contiguous pages with the given request
- * size for PCI bus.  When no space is left, this function reduces the size and
- * tries to allocate again.  The size actually allocated is stored in
- * res_size argument.
- *
- * Returns the pointer of the buffer, or NULL if no enoguh memory.
- */
-void *snd_malloc_pci_pages_fallback(struct pci_dev *pci,
-				    unsigned long size,
-				    dma_addr_t *dma_addr,
-				    unsigned long *res_size)
-{
-	void *res;
-
-	snd_assert(res_size != NULL, return NULL);
-	do {
-		if ((res = snd_malloc_pci_pages(pci, size, dma_addr)) != NULL) {
-			*res_size = size;
-			return res;
-		}
-		size >>= 1;
-	} while (size >= PAGE_SIZE);
-	return NULL;
-}
-
-/**
- * snd_free_pci_pages - release the pages
- * @pci: pci device pointer
- * @size: the allocated buffer size
- * @ptr: the buffer pointer to release
- * @dma_addr: the physical address of the buffer
- *
- * Releases the buffer allocated via snd_malloc_pci_pages().
- */
-void snd_free_pci_pages(struct pci_dev *pci,
-			unsigned long size,
-			void *ptr,
-			dma_addr_t dma_addr)
-{
-	int pg;
-	struct page *page, *last_page;
-
-	if (ptr == NULL)
-		return;
-	for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-	page = virt_to_page(ptr);
-	last_page = page + (1 << pg);
-	while (page < last_page)
-		ClearPageReserved(page++);
-	pci_free_consistent(pci, PAGE_SIZE * (1 << pg), ptr, dma_addr);
-#ifdef CONFIG_SND_DEBUG_MEMORY
-	snd_alloc_pages -= 1 << pg;
-#endif
-}
-
-#endif /* CONFIG_PCI */
-
-#ifdef CONFIG_SBUS
-
-/**
- * snd_malloc_sbus_pages - allocate pages for SBUS with the given size
- * @sdev: sbus device pointer
- * @size: the size to allocate in bytes
- * @dma_addr: the pointer to store the physical address of the buffer
- *
- * Allocates the physically contiguous pages with the given size for
- * SBUS.
- *
- * Returns the pointer of the buffer, or NULL if no enoguh memory.
- */
-void *snd_malloc_sbus_pages(struct sbus_dev *sdev,
-			    unsigned long size,
-			    dma_addr_t *dma_addr)
-{
-	int pg;
-	void *res;
-
-	snd_assert(size > 0, return NULL);
-	snd_assert(dma_addr != NULL, return NULL);
-	for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-	res = sbus_alloc_consistent(sdev, PAGE_SIZE * (1 << pg), dma_addr);
-	if (res != NULL) {
-		struct page *page = virt_to_page(res);
-		struct page *last_page = page + (1 << pg);
-		while (page < last_page)
-			SetPageReserved(page++);
-#ifdef CONFIG_SND_DEBUG_MEMORY
-		snd_alloc_pages += 1 << pg;
-#endif
-	}
-	return res;
-}
-
-/**
- * snd_malloc_pci_pages_fallback - allocate pages with the given size with fallback for SBUS
- * @sdev: sbus device pointer
- * @size: the requested size to allocate in bytes
- * @dma_addr: the pointer to store the physical address of the buffer
- * @res_size: the pointer to store the size of buffer actually allocated
- *
- * Allocates the physically contiguous pages with the given request
- * size for SBUS.  When no space is left, this function reduces the size and
- * tries to allocate again.  The size actually allocated is stored in
- * res_size argument.
- *
- * Returns the pointer of the buffer, or NULL if no enoguh memory.
- */
-void *snd_malloc_sbus_pages_fallback(struct sbus_dev *sdev,
-				     unsigned long size,
-				     dma_addr_t *dma_addr,
-				     unsigned long *res_size)
-{
-	void *res;
-
-	snd_assert(res_size != NULL, return NULL);
-	do {
-		if ((res = snd_malloc_sbus_pages(sdev, size, dma_addr)) != NULL) {
-			*res_size = size;
-			return res;
-		}
-		size >>= 1;
-	} while (size >= PAGE_SIZE);
-	return NULL;
-}
-
-/**
- * snd_free_sbus_pages - release the pages
- * @sdev: sbus device pointer
- * @size: the allocated buffer size
- * @ptr: the buffer pointer to release
- * @dma_addr: the physical address of the buffer
- *
- * Releases the buffer allocated via snd_malloc_pci_pages().
- */
-void snd_free_sbus_pages(struct sbus_dev *sdev,
-			 unsigned long size,
-			 void *ptr,
-			 dma_addr_t dma_addr)
-{
-	int pg;
-	struct page *page, *last_page;
-
-	if (ptr == NULL)
-		return;
-	for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-	page = virt_to_page(ptr);
-	last_page = page + (1 << pg);
-	while (page < last_page)
-		ClearPageReserved(page++);
-	sbus_free_consistent(sdev, PAGE_SIZE * (1 << pg), ptr, dma_addr);
-#ifdef CONFIG_SND_DEBUG_MEMORY
-	snd_alloc_pages -= 1 << pg;
-#endif
-}
-
-#endif /* CONFIG_SBUS */
-
 /**
  * snd_kcalloc - memory allocation and zero-clear
  * @size: the size to allocate in bytes
@@ -695,81 +359,3 @@
 	return 0;
 #endif
 }
-
-
-#ifdef CONFIG_PCI
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) && defined(__i386__)
-/*
- * on ix86, we allocate a page with GFP_KERNEL to assure the
- * allocation.  the code is almost same with kernel/i386/pci-dma.c but
- * it allocates only a single page and checks the validity of the
- * page address with the given pci dma mask.
- */
-
-/**
- * snd_malloc_pci_page - allocate a page in the valid pci dma mask
- * @pci: pci device pointer
- * @addrp: the pointer to store the physical address of the buffer
- *
- * Allocates a single page for the given PCI device and returns
- * the virtual address and stores the physical address on addrp.
- * 
- * This function cannot be called from interrupt handlers or
- * within spinlocks.
- */
-void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *addrp)
-{
-	void *ptr;
-	dma_addr_t addr;
-	unsigned long rmask;
-
-	rmask = ~(unsigned long)(pci ? pci->dma_mask : 0x00ffffff);
-	ptr = (void *)__get_free_page(GFP_KERNEL);
-	if (ptr) {
-		addr = virt_to_phys(ptr);
-		if (((unsigned long)addr + PAGE_SIZE - 1) & rmask) {
-			/* try to reallocate with the GFP_DMA */
-			free_page((unsigned long)ptr);
-			ptr = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
-			if (ptr) /* ok, the address must be within lower 16MB... */
-				addr = virt_to_phys(ptr);
-			else
-				addr = 0;
-		}
-	} else
-		addr = 0;
-	if (ptr) {
-		struct page *page = virt_to_page(ptr);
-		memset(ptr, 0, PAGE_SIZE);
-		SetPageReserved(page);
-#ifdef CONFIG_SND_DEBUG_MEMORY
-		snd_alloc_pages++;
-#endif
-	}
-	*addrp = addr;
-	return ptr;
-}
-#else
-/* on other architectures, call snd_malloc_pci_pages() helper function
- * which uses pci_alloc_consistent().
- */
-void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *addrp)
-{
-	return snd_malloc_pci_pages(pci, PAGE_SIZE, addrp);
-}
-#endif /* 2.4 && i386 */
-
-#if 0 /* for kernel-doc */
-/**
- * snd_free_pci_page - release a page
- * @pci: pci device pointer
- * @ptr: the buffer pointer to release
- * @dma_addr: the physical address of the buffer
- *
- * Releases the buffer allocated via snd_malloc_pci_page().
- */
-void snd_free_pci_page(struct pci_dev *pci, void *ptr, dma_addr_t dma_addr);
-#endif /* for kernel-doc */
-
-#endif /* CONFIG_PCI */
diff -Nru a/sound/core/memory_wrapper.c b/sound/core/memory_wrapper.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/sound/core/memory_wrapper.c	Thu Mar 20 08:41:17 2003
@@ -0,0 +1,70 @@
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ *                   Takashi Iwai <tiwai@suse.de>
+ * 
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <sound/memalloc.h>
+
+
+#ifdef HACK_PCI_ALLOC_CONSISTENT
+/*
+ * A dirty hack... when the kernel code is fixed this should be removed.
+ *
+ * since pci_alloc_consistent always tries GFP_DMA when the requested
+ * pci memory region is below 32bit, it happens quite often that even
+ * 2 order of pages cannot be allocated.
+ *
+ * so in the following, we allocate at first without dma_mask, so that
+ * allocation will be done without GFP_DMA.  if the area doesn't match
+ * with the requested region, then realloate with the original dma_mask
+ * again.
+ */
+
+void *snd_pci_hack_alloc_consistent(struct pci_dev *hwdev, size_t size,
+				    dma_addr_t *dma_handle)
+{
+	void *ret;
+	u64 dma_mask;
+	unsigned long rmask;
+
+	if (hwdev == NULL)
+		return pci_alloc_consistent(hwdev, size, dma_handle);
+	dma_mask = hwdev->dma_mask;
+	rmask = ~((unsigned long)dma_mask);
+	hwdev->dma_mask = 0xffffffff; /* do without masking */
+	ret = pci_alloc_consistent(hwdev, size, dma_handle);
+	hwdev->dma_mask = dma_mask; /* restore */
+	if (ret) {
+		/* obtained address is out of range? */
+		if (((unsigned long)*dma_handle + size - 1) & rmask) {
+			/* reallocate with the proper mask */
+			pci_free_consistent(hwdev, size, ret, *dma_handle);
+			ret = pci_alloc_consistent(hwdev, size, dma_handle);
+		}
+	} else {
+		/* wish to success now with the proper mask... */
+		if (dma_mask != 0xffffffff)
+			ret = pci_alloc_consistent(hwdev, size, dma_handle);
+	}
+	return ret;
+}
+
+#endif /* HACK_PCI_ALLOC_CONSISTENT */
diff -Nru a/sound/core/misc.c b/sound/core/misc.c
--- a/sound/core/misc.c	Tue Oct  1 10:06:00 2002
+++ b/sound/core/misc.c	Tue Feb 25 05:46:05 2003
@@ -77,27 +77,6 @@
 	va_end(args);
 	tmpbuf[sizeof(tmpbuf)-1] = '\0';
 	printk(tmpbuf);
-}
-#endif
 
-#if defined(CONFIG_SND_DEBUG) && !defined(CONFIG_SND_VERBOSE_PRINTK)
-void snd_printd(const char *format, ...)
-{
-	va_list args;
-	char tmpbuf[512];
-	
-	if (format[0] == '<' && format[1] >= '0' && format[1] <= '9' && format[2] == '>') {
-		char tmp[] = "<0>";
-		tmp[1] = format[1];
-		printk("%sALSA: ", tmp);
-		format += 3;
-	} else {
-		printk(KERN_DEBUG "ALSA: ");
-	}
-	va_start(args, format);
-	vsnprintf(tmpbuf, sizeof(tmpbuf)-1, format, args);
-	va_end(args);
-	tmpbuf[sizeof(tmpbuf)-1] = '\0';
-	printk(tmpbuf);
 }
 #endif
diff -Nru a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
--- a/sound/core/oss/pcm_oss.c	Sun Feb 16 05:47:41 2003
+++ b/sound/core/oss/pcm_oss.c	Thu Mar 20 08:41:12 2003
@@ -294,8 +294,8 @@
 static int snd_pcm_oss_change_params(snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_hw_params_t params, sparams;
-	snd_pcm_sw_params_t sw_params;
+	snd_pcm_hw_params_t *params, *sparams;
+	snd_pcm_sw_params_t *sw_params;
 	ssize_t oss_buffer_size, oss_period_size;
 	size_t oss_frame_size;
 	int err;
@@ -304,6 +304,15 @@
 	snd_mask_t sformat_mask;
 	snd_mask_t mask;
 
+	sw_params = kmalloc(sizeof(*sw_params), GFP_KERNEL);
+	params = kmalloc(sizeof(*params), GFP_KERNEL);
+	sparams = kmalloc(sizeof(*sparams), GFP_KERNEL);
+	if (!sw_params || !params || !sparams) {
+		snd_printd("No memory\n");
+		err = -ENOMEM;
+		goto failure;
+	}
+
 	if (atomic_read(&runtime->mmap_count)) {
 		direct = 1;
 	} else {
@@ -311,9 +320,9 @@
 		direct = (setup != NULL && setup->direct);
 	}
 
-	_snd_pcm_hw_params_any(&sparams);
-	_snd_pcm_hw_param_setinteger(&sparams, SNDRV_PCM_HW_PARAM_PERIODS);
-	_snd_pcm_hw_param_min(&sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0);
+	_snd_pcm_hw_params_any(sparams);
+	_snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS);
+	_snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0);
 	snd_mask_none(&mask);
 	if (atomic_read(&runtime->mmap_count))
 		snd_mask_set(&mask, SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
@@ -322,17 +331,18 @@
 		if (!direct)
 			snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_NONINTERLEAVED);
 	}
-	err = snd_pcm_hw_param_mask(substream, &sparams, SNDRV_PCM_HW_PARAM_ACCESS, &mask);
+	err = snd_pcm_hw_param_mask(substream, sparams, SNDRV_PCM_HW_PARAM_ACCESS, &mask);
 	if (err < 0) {
 		snd_printd("No usable accesses\n");
-		return -EINVAL;
+		err = -EINVAL;
+		goto failure;
 	}
-	choose_rate(substream, &sparams, runtime->oss.rate);
-	snd_pcm_hw_param_near(substream, &sparams, SNDRV_PCM_HW_PARAM_CHANNELS, runtime->oss.channels, 0);
+	choose_rate(substream, sparams, runtime->oss.rate);
+	snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_CHANNELS, runtime->oss.channels, 0);
 
 	format = snd_pcm_oss_format_from(runtime->oss.format);
 
-	sformat_mask = *hw_param_mask(&sparams, SNDRV_PCM_HW_PARAM_FORMAT);
+	sformat_mask = *hw_param_mask(sparams, SNDRV_PCM_HW_PARAM_FORMAT);
 	if (direct)
 		sformat = format;
 	else
@@ -346,52 +356,53 @@
 		}
 		if (sformat > SNDRV_PCM_FORMAT_LAST) {
 			snd_printd("Cannot find a format!!!\n");
-			return -EINVAL;
+			err = -EINVAL;
+			goto failure;
 		}
 	}
-	err = _snd_pcm_hw_param_set(&sparams, SNDRV_PCM_HW_PARAM_FORMAT, sformat, 0);
-	snd_assert(err >= 0, return err);
+	err = _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_FORMAT, sformat, 0);
+	snd_assert(err >= 0, goto failure);
 
 	if (direct) {
-		params = sparams;
+		memcpy(params, sparams, sizeof(*params));
 	} else {
-		_snd_pcm_hw_params_any(&params);
-		_snd_pcm_hw_param_set(&params, SNDRV_PCM_HW_PARAM_ACCESS,
+		_snd_pcm_hw_params_any(params);
+		_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_ACCESS,
 				      SNDRV_PCM_ACCESS_RW_INTERLEAVED, 0);
-		_snd_pcm_hw_param_set(&params, SNDRV_PCM_HW_PARAM_FORMAT,
+		_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_FORMAT,
 				      snd_pcm_oss_format_from(runtime->oss.format), 0);
-		_snd_pcm_hw_param_set(&params, SNDRV_PCM_HW_PARAM_CHANNELS,
+		_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_CHANNELS,
 				      runtime->oss.channels, 0);
-		_snd_pcm_hw_param_set(&params, SNDRV_PCM_HW_PARAM_RATE,
+		_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_RATE,
 				      runtime->oss.rate, 0);
 		pdprintf("client: access = %i, format = %i, channels = %i, rate = %i\n",
-			 params_access(&params), params_format(&params),
-			 params_channels(&params), params_rate(&params));
+			 params_access(params), params_format(params),
+			 params_channels(params), params_rate(params));
 	}
 	pdprintf("slave: access = %i, format = %i, channels = %i, rate = %i\n",
-		 params_access(&sparams), params_format(&sparams),
-		 params_channels(&sparams), params_rate(&sparams));
+		 params_access(sparams), params_format(sparams),
+		 params_channels(sparams), params_rate(sparams));
 
-	oss_frame_size = snd_pcm_format_physical_width(params_format(&params)) *
-			 params_channels(&params) / 8;
+	oss_frame_size = snd_pcm_format_physical_width(params_format(params)) *
+			 params_channels(params) / 8;
 
 	snd_pcm_oss_plugin_clear(substream);
 	if (!direct) {
 		/* add necessary plugins */
 		snd_pcm_oss_plugin_clear(substream);
 		if ((err = snd_pcm_plug_format_plugins(substream,
-						       &params, 
-						       &sparams)) < 0) {
+						       params, 
+						       sparams)) < 0) {
 			snd_printd("snd_pcm_plug_format_plugins failed: %i\n", err);
 			snd_pcm_oss_plugin_clear(substream);
-			return err;
+			goto failure;
 		}
 		if (runtime->oss.plugin_first) {
 			snd_pcm_plugin_t *plugin;
-			if ((err = snd_pcm_plugin_build_io(substream, &sparams, &plugin)) < 0) {
+			if ((err = snd_pcm_plugin_build_io(substream, sparams, &plugin)) < 0) {
 				snd_printd("snd_pcm_plugin_build_io failed: %i\n", err);
 				snd_pcm_oss_plugin_clear(substream);
-				return err;
+				goto failure;
 			}
 			if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 				err = snd_pcm_plugin_append(plugin);
@@ -400,66 +411,66 @@
 			}
 			if (err < 0) {
 				snd_pcm_oss_plugin_clear(substream);
-				return err;
+				goto failure;
 			}
 		}
 	}
 
-	err = snd_pcm_oss_period_size(substream, &params, &sparams);
+	err = snd_pcm_oss_period_size(substream, params, sparams);
 	if (err < 0)
-		return err;
+		goto failure;
 
 	n = snd_pcm_plug_slave_size(substream, runtime->oss.period_bytes / oss_frame_size);
-	err = snd_pcm_hw_param_near(substream, &sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, 0);
-	snd_assert(err >= 0, return err);
+	err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, 0);
+	snd_assert(err >= 0, goto failure);
 
-	err = snd_pcm_hw_param_near(substream, &sparams, SNDRV_PCM_HW_PARAM_PERIODS,
+	err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIODS,
 				     runtime->oss.periods, 0);
-	snd_assert(err >= 0, return err);
+	snd_assert(err >= 0, goto failure);
 
 	snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, 0);
 
-	if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, &sparams)) < 0) {
+	if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, sparams)) < 0) {
 		snd_printd("HW_PARAMS failed: %i\n", err);
-		return err;
+		goto failure;
 	}
 
-	memset(&sw_params, 0, sizeof(sw_params));
+	memset(sw_params, 0, sizeof(*sw_params));
 	if (runtime->oss.trigger) {
-		sw_params.start_threshold = 1;
+		sw_params->start_threshold = 1;
 	} else {
-		sw_params.start_threshold = runtime->boundary;
+		sw_params->start_threshold = runtime->boundary;
 	}
 	if (atomic_read(&runtime->mmap_count))
-		sw_params.stop_threshold = runtime->boundary;
+		sw_params->stop_threshold = runtime->boundary;
 	else
-		sw_params.stop_threshold = runtime->buffer_size;
-	sw_params.tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
-	sw_params.period_step = 1;
-	sw_params.sleep_min = 0;
-	sw_params.avail_min = runtime->period_size;
-	sw_params.xfer_align = 1;
-	sw_params.silence_threshold = 0;
-	sw_params.silence_size = 0;
+		sw_params->stop_threshold = runtime->buffer_size;
+	sw_params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
+	sw_params->period_step = 1;
+	sw_params->sleep_min = 0;
+	sw_params->avail_min = runtime->period_size;
+	sw_params->xfer_align = 1;
+	sw_params->silence_threshold = 0;
+	sw_params->silence_size = 0;
 
-	if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_SW_PARAMS, &sw_params)) < 0) {
+	if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_SW_PARAMS, sw_params)) < 0) {
 		snd_printd("SW_PARAMS failed: %i\n", err);
-		return err;
+		goto failure;
 	}
 	runtime->control->avail_min = runtime->period_size;
 
-	runtime->oss.periods = params_periods(&sparams);
-	oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(&sparams));
-	snd_assert(oss_period_size >= 0, return -EINVAL);
+	runtime->oss.periods = params_periods(sparams);
+	oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams));
+	snd_assert(oss_period_size >= 0, err = -EINVAL; goto failure);
 	if (runtime->oss.plugin_first) {
 		err = snd_pcm_plug_alloc(substream, oss_period_size);
 		if (err < 0)
-			return err;
+			goto failure;
 	}
 	oss_period_size *= oss_frame_size;
 
 	oss_buffer_size = oss_period_size * runtime->oss.periods;
-	snd_assert(oss_buffer_size >= 0, return -EINVAL);
+	snd_assert(oss_buffer_size >= 0, err = -EINVAL; goto failure);
 
 	runtime->oss.period_bytes = oss_period_size;
 	runtime->oss.buffer_bytes = oss_buffer_size;
@@ -468,12 +479,12 @@
 		 runtime->oss.period_bytes,
 		 runtime->oss.buffer_bytes);
 	pdprintf("slave: period_size = %i, buffer_size = %i\n",
-		 params_period_size(&sparams),
-		 params_buffer_size(&sparams));
+		 params_period_size(sparams),
+		 params_buffer_size(sparams));
 
-	runtime->oss.format = snd_pcm_oss_format_to(params_format(&params));
-	runtime->oss.channels = params_channels(&params);
-	runtime->oss.rate = params_rate(&params);
+	runtime->oss.format = snd_pcm_oss_format_to(params_format(params));
+	runtime->oss.channels = params_channels(params);
+	runtime->oss.rate = params_rate(params);
 
 	runtime->oss.params = 0;
 	runtime->oss.prepare = 1;
@@ -483,7 +494,16 @@
 	runtime->oss.buffer_used = 0;
 	if (runtime->dma_area)
 		snd_pcm_format_set_silence(runtime->format, runtime->dma_area, bytes_to_samples(runtime, runtime->dma_bytes));
-	return 0;
+
+	err = 0;
+failure:
+	if (sw_params)
+		kfree(sw_params);
+	if (params)
+		kfree(params);
+	if (sparams)
+		kfree(sparams);
+	return err;
 }
 
 static int snd_pcm_oss_get_active_substream(snd_pcm_oss_file_t *pcm_oss_file, snd_pcm_substream_t **r_substream)
@@ -1460,9 +1480,12 @@
 		if (snd_pcm_running(substream))
 			snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
 		spin_unlock_irq(&runtime->lock);
-		if (substream->ops->hw_free != NULL)
-			substream->ops->hw_free(substream);
-		substream->ops->close(substream);
+		if (substream->open_flag) {
+			if (substream->ops->hw_free != NULL)
+				substream->ops->hw_free(substream);
+			substream->ops->close(substream);
+			substream->open_flag = 0;
+		}
 		substream->ffile = NULL;
 		snd_pcm_oss_release_substream(substream);
 		snd_pcm_release_substream(substream);
@@ -1526,6 +1549,7 @@
 			snd_pcm_oss_release_file(pcm_oss_file);
 			return err;
 		}
+		psubstream->open_flag = 1;
 		err = snd_pcm_hw_constraints_complete(psubstream);
 		if (err < 0) {
 			snd_printd("snd_pcm_hw_constraint_complete failed\n");
@@ -1547,6 +1571,7 @@
 			snd_pcm_oss_release_file(pcm_oss_file);
 			return err;
 		}
+		csubstream->open_flag = 1;
 		err = snd_pcm_hw_constraints_complete(csubstream);
 		if (err < 0) {
 			snd_printd("snd_pcm_hw_constraint_complete failed\n");
diff -Nru a/sound/core/pcm.c b/sound/core/pcm.c
--- a/sound/core/pcm.c	Sat Feb  8 12:10:46 2003
+++ b/sound/core/pcm.c	Thu Mar 20 08:41:12 2003
@@ -386,10 +386,10 @@
 		return;
 	}
 	snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));
-	snd_iprintf(buffer, "trigger_time: %ld.%06ld\n",
-		status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_usec);
-	snd_iprintf(buffer, "tstamp      : %ld.%06ld\n",
-		status.tstamp.tv_sec, status.tstamp.tv_usec);
+	snd_iprintf(buffer, "trigger_time: %ld.%09ld\n",
+		status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec);
+	snd_iprintf(buffer, "tstamp      : %ld.%09ld\n",
+		status.tstamp.tv_sec, status.tstamp.tv_nsec);
 	snd_iprintf(buffer, "delay       : %ld\n", status.delay);
 	snd_iprintf(buffer, "avail       : %ld\n", status.avail);
 	snd_iprintf(buffer, "avail_max   : %ld\n", status.avail_max);
@@ -595,8 +595,6 @@
 			snd_magic_kfree(substream);
 			return err;
 		}
-		substream->dma_type = SNDRV_PCM_DMA_TYPE_UNKNOWN;
-		substream->dma_private = NULL;
 		spin_lock_init(&substream->timer_lock);
 		prev = substream;
 	}
diff -Nru a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
--- a/sound/core/pcm_lib.c	Sun Feb 16 05:47:41 2003
+++ b/sound/core/pcm_lib.c	Thu Mar 20 08:41:12 2003
@@ -137,7 +137,7 @@
 	old_hw_ptr = runtime->status->hw_ptr;
 	pos = substream->ops->pointer(substream);
 	if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
-		snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp);
+		snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp, runtime->tstamp_timespec);
 #ifdef CONFIG_SND_DEBUG
 	if (pos >= runtime->buffer_size) {
 		snd_printk(KERN_ERR  "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size);
@@ -198,7 +198,7 @@
 	old_hw_ptr = runtime->status->hw_ptr;
 	pos = substream->ops->pointer(substream);
 	if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
-		snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp);
+		snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp, runtime->tstamp_timespec);
 #ifdef CONFIG_SND_DEBUG
 	if (pos >= runtime->buffer_size) {
 		snd_printk(KERN_ERR "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size);
@@ -2186,6 +2186,8 @@
 		} else {
 			runtime->control->appl_ptr = appl_ptr;
 		}
+		if (substream->ops->ack)
+			substream->ops->ack(substream);
 
 		offset += frames;
 		size -= frames;
@@ -2478,6 +2480,8 @@
 		} else {
 			runtime->control->appl_ptr = appl_ptr;
 		}
+		if (substream->ops->ack)
+			substream->ops->ack(substream);
 
 		offset += frames;
 		size -= frames;
@@ -2654,6 +2658,9 @@
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL(snd_pcm_lib_preallocate_pci_pages);
 EXPORT_SYMBOL(snd_pcm_lib_preallocate_pci_pages_for_all);
+EXPORT_SYMBOL(snd_pcm_lib_preallocate_sg_pages);
+EXPORT_SYMBOL(snd_pcm_lib_preallocate_sg_pages_for_all);
+EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
 #endif
 #ifdef CONFIG_SBUS
 EXPORT_SYMBOL(snd_pcm_lib_preallocate_sbus_pages);
diff -Nru a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
--- a/sound/core/pcm_memory.c	Sun Feb 16 05:47:41 2003
+++ b/sound/core/pcm_memory.c	Thu Mar 20 08:41:12 2003
@@ -26,9 +26,6 @@
 #include <sound/pcm.h>
 #include <sound/info.h>
 #include <sound/initval.h>
-#ifdef CONFIG_PCI
-#include <sound/pcm_sgbuf.h>
-#endif
 
 static int preallocate_dma = 1;
 MODULE_PARM(preallocate_dma, "i");
@@ -44,59 +41,33 @@
 
 
 /*
- * allocate pages on the specified bus
- */
-static int alloc_pcm_pages(snd_pcm_substream_t *substream, size_t size,
-			   struct snd_pcm_dma_buffer *dmab)
-{
-	switch (substream->dma_type) {
-	case SNDRV_PCM_DMA_TYPE_CONTINUOUS:
-		dmab->area = snd_malloc_pages(size, (unsigned int)((unsigned long)substream->dma_private & 0xffffffff));
-		dmab->addr = 0UL;		/* not valid */
-		break;
-#ifdef CONFIG_ISA
-	case SNDRV_PCM_DMA_TYPE_ISA:
-		dmab->area = snd_malloc_isa_pages(size, &dmab->addr);
-		break;
-#endif
-#ifdef CONFIG_PCI
-	case SNDRV_PCM_DMA_TYPE_PCI:
-		dmab->area = snd_malloc_pci_pages((struct pci_dev *)substream->dma_private, size, &dmab->addr);
-		break;
-	case SNDRV_PCM_DMA_TYPE_PCI_SG:
-		snd_pcm_sgbuf_alloc_pages((struct pci_dev *)substream->dma_private, size, dmab);
-		break;
-#endif
-#ifdef CONFIG_SBUS
-	case SNDRV_PCM_DMA_TYPE_SBUS:
-		dmab->area = snd_malloc_sbus_pages((struct sbus_dev *)substream->dma_private, size, &dmab->addr);
-		break;
-#endif
-	default:
-		dmab->area = NULL;
-		dmab->addr = 0;
-		return -ENXIO;
-	}
-	return 0;
-}
-
-/*
  * try to allocate as the large pages as possible.
  * stores the resultant memory size in *res_size.
  *
  * the minimum size is snd_minimum_buffer.  it should be power of 2.
  */
-static int alloc_pcm_pages_fallback(snd_pcm_substream_t *substream,
-				    size_t size,
-				    struct snd_pcm_dma_buffer *dmab)
+static int preallocate_pcm_pages(snd_pcm_substream_t *substream, size_t size)
 {
+	struct snd_dma_buffer *dmab = &substream->dma_buffer;
 	int err;
+
 	snd_assert(size > 0, return -EINVAL);
+
+	/* already reserved? */
+	if (snd_dma_get_reserved(&substream->dma_device, dmab) > 0) {
+		if (dmab->bytes >= size)
+			return 0; /* yes */
+		/* no, reset the reserved block */
+		snd_dma_free_reserved(&substream->dma_device);
+		dmab->bytes = 0;
+	}
+
 	do {
-		if ((err = alloc_pcm_pages(substream, size, dmab)) < 0)
+		if ((err = snd_dma_alloc_pages(&substream->dma_device, size, dmab)) < 0)
 			return err;
 		if (dmab->area) {
-			dmab->bytes = size;
+			/* remember this one */
+			snd_dma_set_reserved(&substream->dma_device, dmab);
 			return 0;
 		}
 		size >>= 1;
@@ -106,46 +77,13 @@
 }
 
 /*
- * release the pages on the specified bus
- */
-static void free_pcm_pages(snd_pcm_substream_t *substream,
-			   struct snd_pcm_dma_buffer *dmab)
-{
-	switch (substream->dma_type) {
-	case SNDRV_PCM_DMA_TYPE_CONTINUOUS:
-		snd_free_pages(dmab->area, dmab->bytes);
-		break;
-#ifdef CONFIG_ISA
-	case SNDRV_PCM_DMA_TYPE_ISA:
-		snd_free_isa_pages(dmab->bytes, dmab->area, dmab->addr);
-		break;
-#endif
-#ifdef CONFIG_PCI
-	case SNDRV_PCM_DMA_TYPE_PCI:
-		snd_free_pci_pages((struct pci_dev *)substream->dma_private,
-				   dmab->bytes, dmab->area, dmab->addr);
-		break;
-	case SNDRV_PCM_DMA_TYPE_PCI_SG:
-		snd_pcm_sgbuf_free_pages(dmab);
-		break;
-#endif
-#ifdef CONFIG_SBUS
-	case SNDRV_PCM_DMA_TYPE_SBUS:
-		snd_free_sbus_pages((struct sbus_dev *)substream->dma_private,
-				    dmab->bytes, dmab->area, dmab->addr);
-		break;
-#endif
-	}
-}
-
-/*
  * release the preallocated buffer if not yet done.
  */
 static void snd_pcm_lib_preallocate_dma_free(snd_pcm_substream_t *substream)
 {
 	if (substream->dma_buffer.area == NULL)
 		return;
-	free_pcm_pages(substream, &substream->dma_buffer);
+	snd_dma_free_reserved(&substream->dma_device);
 	substream->dma_buffer.area = NULL;
 }
 
@@ -164,7 +102,7 @@
 		snd_info_unregister(substream->proc_prealloc_entry);
 		substream->proc_prealloc_entry = NULL;
 	}
-	substream->dma_type = SNDRV_PCM_DMA_TYPE_UNKNOWN;
+	substream->dma_device.type = SNDRV_DMA_TYPE_UNKNOWN;
 	return 0;
 }
 
@@ -210,7 +148,7 @@
 	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)entry->private_data;
 	char line[64], str[64];
 	size_t size;
-	struct snd_pcm_dma_buffer new_dmab;
+	struct snd_dma_buffer new_dmab;
 
 	if (substream->runtime) {
 		buffer->error = -EBUSY;
@@ -228,7 +166,7 @@
 		memset(&new_dmab, 0, sizeof(new_dmab));
 		if (size > 0) {
 
-			if (alloc_pcm_pages(substream, size, &new_dmab) < 0 ||
+			if (snd_dma_alloc_pages(&substream->dma_device, size, &new_dmab) < 0 ||
 			    new_dmab.area == NULL) {
 				buffer->error = -ENOMEM;
 				return;
@@ -237,7 +175,7 @@
 		} else {
 			substream->buffer_bytes_max = UINT_MAX;
 		}
-		snd_pcm_lib_preallocate_dma_free(substream);
+		snd_dma_set_reserved(&substream->dma_device, &new_dmab);
 		substream->dma_buffer = new_dmab;
 	} else {
 		buffer->error = -EINVAL;
@@ -254,7 +192,7 @@
 
 	memset(&substream->dma_buffer, 0, sizeof(substream->dma_buffer));
 	if (size > 0 && preallocate_dma && substream->number < maximum_substreams)
-		alloc_pcm_pages_fallback(substream, size, &substream->dma_buffer);
+		preallocate_pcm_pages(substream, size);
 
 	if (substream->dma_buffer.bytes > 0)
 		substream->buffer_bytes_max = substream->dma_buffer.bytes;
@@ -274,6 +212,16 @@
 	return 0;
 }
 
+
+/*
+ * set up the unique pcm id
+ */
+static inline void setup_pcm_id(snd_pcm_substream_t *subs)
+{
+	subs->dma_device.id = subs->pcm->device << 16 |
+		subs->stream << 8 | subs->number;
+}
+
 /**
  * snd_pcm_lib_preallocate_pages - pre-allocation for the continuous memory type
  * @substream: the pcm substream instance
@@ -289,8 +237,9 @@
 				      size_t size, size_t max,
 				      unsigned int flags)
 {
-	substream->dma_type = SNDRV_PCM_DMA_TYPE_CONTINUOUS;
-	substream->dma_private = (void *)(unsigned long)flags;
+	substream->dma_device.type = SNDRV_DMA_TYPE_CONTINUOUS;
+	substream->dma_device.dev.flags = flags;
+	setup_pcm_id(substream);
 	return snd_pcm_lib_preallocate_pages1(substream, size, max);
 }
 
@@ -334,8 +283,9 @@
 int snd_pcm_lib_preallocate_isa_pages(snd_pcm_substream_t *substream,
 				      size_t size, size_t max)
 {
-	substream->dma_type = SNDRV_PCM_DMA_TYPE_ISA;
-	substream->dma_private = NULL;
+	substream->dma_device.type = SNDRV_DMA_TYPE_ISA;
+	substream->dma_device.dev.flags = 0; /* FIXME: any good identifier? */
+	setup_pcm_id(substream);
 	return snd_pcm_lib_preallocate_pages1(substream, size, max);
 }
 
@@ -379,9 +329,9 @@
 int snd_pcm_lib_malloc_pages(snd_pcm_substream_t *substream, size_t size)
 {
 	snd_pcm_runtime_t *runtime;
-	struct snd_pcm_dma_buffer dmab;
+	struct snd_dma_buffer dmab;
 
-	snd_assert(substream->dma_type != SNDRV_PCM_DMA_TYPE_UNKNOWN, return -EINVAL);
+	snd_assert(substream->dma_device.type != SNDRV_DMA_TYPE_UNKNOWN, return -EINVAL);
 	snd_assert(substream != NULL, return -EINVAL);
 	runtime = substream->runtime;
 	snd_assert(runtime != NULL, return -EINVAL);	
@@ -398,7 +348,7 @@
 		dmab = substream->dma_buffer;
 	} else {
 		memset(&dmab, 0, sizeof(dmab));
-		alloc_pcm_pages(substream, size, &dmab);
+		snd_dma_alloc_pages(&substream->dma_device, size, &dmab);
 	}
 	if (! dmab.area)
 		return -ENOMEM;
@@ -427,13 +377,13 @@
 	if (runtime->dma_area == NULL)
 		return 0;
 	if (runtime->dma_area != substream->dma_buffer.area) {
-		struct snd_pcm_dma_buffer dmab;
+		struct snd_dma_buffer dmab;
 		memset(&dmab, 0, sizeof(dmab));
 		dmab.area = runtime->dma_area;
 		dmab.addr = runtime->dma_addr;
 		dmab.bytes = runtime->dma_bytes;
 		dmab.private_data = runtime->dma_private;
-		free_pcm_pages(substream, &dmab);
+		snd_dma_free_pages(&substream->dma_device, &dmab);
 	}
 	runtime->dma_area = NULL;
 	runtime->dma_addr = 0UL;
@@ -459,8 +409,9 @@
 				      snd_pcm_substream_t *substream,
 				      size_t size, size_t max)
 {
-	substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI;
-	substream->dma_private = pci;
+	substream->dma_device.type = SNDRV_DMA_TYPE_PCI;
+	substream->dma_device.dev.pci = pci;
+	setup_pcm_id(substream);
 	return snd_pcm_lib_preallocate_pages1(substream, size, max);
 }
 
@@ -510,8 +461,9 @@
 				       snd_pcm_substream_t *substream,
 				       size_t size, size_t max)
 {
-	substream->dma_type = SNDRV_PCM_DMA_TYPE_SBUS;
-	substream->dma_private = sdev;
+	substream->dma_device.type = SNDRV_DMA_TYPE_SBUS;
+	substream->dma_device.dev.sbus = sdev;
+	setup_pcm_id(substream);
 	return snd_pcm_lib_preallocate_pages1(substream, size, max);
 }
 
@@ -563,8 +515,9 @@
 				     snd_pcm_substream_t *substream,
 				     size_t size, size_t max)
 {
-	substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI_SG;
-	substream->dma_private = pci;
+	substream->dma_device.type = SNDRV_DMA_TYPE_PCI_SG;
+	substream->dma_device.dev.pci = pci;
+	setup_pcm_id(substream);
 	return snd_pcm_lib_preallocate_pages1(substream, size, max);
 }
 
@@ -594,6 +547,24 @@
 			if ((err = snd_pcm_lib_preallocate_sg_pages(pci, substream, size, max)) < 0)
 				return err;
 	return 0;
+}
+
+/**
+ * snd_pcm_sgbuf_ops_page - get the page struct at the given offset
+ * @substream: the pcm substream instance
+ * @offset: the buffer offset
+ *
+ * Returns the page struct at the given buffer offset.
+ * Used as the page callback of PCM ops.
+ */
+struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset)
+{
+	struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
+
+	unsigned int idx = offset >> PAGE_SHIFT;
+	if (idx >= (unsigned int)sgbuf->pages)
+		return NULL;
+	return sgbuf->page_table[idx];
 }
 
 #endif /* CONFIG_PCI */
diff -Nru a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
--- a/sound/core/pcm_misc.c	Mon Jan 27 09:30:51 2003
+++ b/sound/core/pcm_misc.c	Tue Feb 25 05:46:05 2003
@@ -527,7 +527,7 @@
  *
  * Sets the silence data on the buffer for the given samples.
  *
- * Returns zero if sucessful, or a negative error code on failure.
+ * Returns zero if successful, or a negative error code on failure.
  */
 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples)
 {
diff -Nru a/sound/core/pcm_native.c b/sound/core/pcm_native.c
--- a/sound/core/pcm_native.c	Sun Feb 16 05:47:41 2003
+++ b/sound/core/pcm_native.c	Thu Mar 20 08:41:12 2003
@@ -30,6 +30,7 @@
 #include <sound/info.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
+#include <sound/timer.h>
 #include <sound/minors.h>
 
 /*
@@ -514,9 +515,9 @@
 		if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
 			status->tstamp = runtime->status->tstamp;
 		else
-			snd_timestamp_now(&status->tstamp);
+			snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec);
 	} else
-		snd_timestamp_now(&status->tstamp);
+		snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec);
 	status->appl_ptr = runtime->control->appl_ptr;
 	status->hw_ptr = runtime->status->hw_ptr;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -585,15 +586,15 @@
 	return 0;
 }
 
-static void snd_pcm_trigger_time(snd_pcm_substream_t *substream)
+static void snd_pcm_trigger_tstamp(snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	if (runtime->trigger_master == NULL)
 		return;
 	if (runtime->trigger_master == substream) {
-		snd_timestamp_now(&runtime->trigger_tstamp);
+		snd_timestamp_now(&runtime->trigger_tstamp, runtime->tstamp_timespec);
 	} else {
-		snd_pcm_trigger_time(runtime->trigger_master);
+		snd_pcm_trigger_tstamp(runtime->trigger_master);
 		runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp;
 	}
 	runtime->trigger_master = NULL;
@@ -668,13 +669,15 @@
 static inline void snd_pcm_post_start(snd_pcm_substream_t *substream, int state)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_trigger_time(substream);
+	snd_pcm_trigger_tstamp(substream);
 	runtime->status->state = SNDRV_PCM_STATE_RUNNING;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
 	    runtime->silence_size > 0)
 		snd_pcm_playback_silence(substream, ULONG_MAX);
 	if (runtime->sleep_min)
 		snd_pcm_tick_prepare(substream);
+	if (substream->timer)
+		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTART, &runtime->trigger_tstamp);
 }
 
 /**
@@ -703,7 +706,9 @@
 static inline void snd_pcm_post_stop(snd_pcm_substream_t *substream, int state)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_trigger_time(substream);
+	snd_pcm_trigger_tstamp(substream);
+	if (substream->timer)
+		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP, &runtime->trigger_tstamp);
 	runtime->status->state = state;
 	snd_pcm_tick_set(substream, 0);
 	wake_up(&runtime->sleep);
@@ -741,15 +746,19 @@
 static inline void snd_pcm_post_pause(snd_pcm_substream_t *substream, int push)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_trigger_time(substream);
+	snd_pcm_trigger_tstamp(substream);
 	if (push) {
 		runtime->status->state = SNDRV_PCM_STATE_PAUSED;
+		if (substream->timer)
+			snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MPAUSE, &runtime->trigger_tstamp);
 		snd_pcm_tick_set(substream, 0);
 		wake_up(&runtime->sleep);
 	} else {
 		runtime->status->state = SNDRV_PCM_STATE_RUNNING;
 		if (runtime->sleep_min)
 			snd_pcm_tick_prepare(substream);
+		if (substream->timer)
+			snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MCONTINUE, &runtime->trigger_tstamp);
 	}
 }
 
@@ -782,7 +791,9 @@
 static inline void snd_pcm_post_suspend(snd_pcm_substream_t *substream, int state)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_trigger_time(substream);
+	snd_pcm_trigger_tstamp(substream);
+	if (substream->timer)
+		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MPAUSE, &runtime->trigger_tstamp);
 	runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
 	snd_pcm_tick_set(substream, 0);
 	wake_up(&runtime->sleep);
@@ -847,7 +858,9 @@
 static inline void snd_pcm_post_resume(snd_pcm_substream_t *substream, int state)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_trigger_time(substream);
+	snd_pcm_trigger_tstamp(substream);
+	if (substream->timer)
+		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MCONTINUE, &runtime->trigger_tstamp);
 	runtime->status->state = runtime->status->suspended_state;
 	if (runtime->sleep_min)
 		snd_pcm_tick_prepare(substream);
@@ -1733,9 +1746,12 @@
 	runtime = substream->runtime;
 	str = substream->pstr;
 	snd_pcm_unlink(substream);
-	if (substream->ops->hw_free != NULL)
-		substream->ops->hw_free(substream);
-	substream->ops->close(substream);
+	if (substream->open_flag) {
+		if (substream->ops->hw_free != NULL)
+			substream->ops->hw_free(substream);
+		substream->ops->close(substream);
+		substream->open_flag = 0;
+	}
 	substream->ffile = NULL;
 	snd_pcm_remove_file(str, pcm_file);
 	snd_pcm_release_substream(substream);
@@ -1784,6 +1800,7 @@
 		snd_pcm_release_file(pcm_file);
 		return err;
 	}
+	substream->open_flag = 1;
 
 	err = snd_pcm_hw_constraints_complete(substream);
 	if (err < 0) {
@@ -1982,6 +1999,106 @@
 	return ret;
 }
 
+snd_pcm_sframes_t snd_pcm_playback_forward(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	snd_pcm_sframes_t appl_ptr;
+	snd_pcm_sframes_t ret;
+	snd_pcm_sframes_t avail;
+
+	if (frames == 0)
+		return 0;
+
+	spin_lock_irq(&runtime->lock);
+	switch (runtime->status->state) {
+	case SNDRV_PCM_STATE_PREPARED:
+	case SNDRV_PCM_STATE_PAUSED:
+		break;
+	case SNDRV_PCM_STATE_DRAINING:
+	case SNDRV_PCM_STATE_RUNNING:
+		if (snd_pcm_update_hw_ptr(substream) >= 0)
+			break;
+		/* Fall through */
+	case SNDRV_PCM_STATE_XRUN:
+		ret = -EPIPE;
+		goto __end;
+	default:
+		ret = -EBADFD;
+		goto __end;
+	}
+
+	avail = snd_pcm_playback_avail(runtime);
+	if (avail <= 0) {
+		ret = 0;
+		goto __end;
+	}
+	if (frames > (snd_pcm_uframes_t)avail)
+		frames = avail;
+	else
+		frames -= frames % runtime->xfer_align;
+	appl_ptr = runtime->control->appl_ptr + frames;
+	if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
+		appl_ptr -= runtime->boundary;
+	runtime->control->appl_ptr = appl_ptr;
+	if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
+	    runtime->sleep_min)
+		snd_pcm_tick_prepare(substream);
+	ret = frames;
+ __end:
+	spin_unlock_irq(&runtime->lock);
+	return ret;
+}
+
+snd_pcm_sframes_t snd_pcm_capture_forward(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	snd_pcm_sframes_t appl_ptr;
+	snd_pcm_sframes_t ret;
+	snd_pcm_sframes_t avail;
+
+	if (frames == 0)
+		return 0;
+
+	spin_lock_irq(&runtime->lock);
+	switch (runtime->status->state) {
+	case SNDRV_PCM_STATE_PREPARED:
+	case SNDRV_PCM_STATE_DRAINING:
+	case SNDRV_PCM_STATE_PAUSED:
+		break;
+	case SNDRV_PCM_STATE_RUNNING:
+		if (snd_pcm_update_hw_ptr(substream) >= 0)
+			break;
+		/* Fall through */
+	case SNDRV_PCM_STATE_XRUN:
+		ret = -EPIPE;
+		goto __end;
+	default:
+		ret = -EBADFD;
+		goto __end;
+	}
+
+	avail = snd_pcm_capture_avail(runtime);
+	if (avail <= 0) {
+		ret = 0;
+		goto __end;
+	}
+	if (frames > (snd_pcm_uframes_t)avail)
+		frames = avail;
+	else
+		frames -= frames % runtime->xfer_align;
+	appl_ptr = runtime->control->appl_ptr + frames;
+	if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
+		appl_ptr -= runtime->boundary;
+	runtime->control->appl_ptr = appl_ptr;
+	if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
+	    runtime->sleep_min)
+		snd_pcm_tick_prepare(substream);
+	ret = frames;
+ __end:
+	spin_unlock_irq(&runtime->lock);
+	return ret;
+}
+
 static int snd_pcm_hwsync(snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -2065,6 +2182,14 @@
 		return put_user(SNDRV_PCM_VERSION, (int *)arg) ? -EFAULT : 0;
 	case SNDRV_PCM_IOCTL_INFO:
 		return snd_pcm_info_user(substream, (snd_pcm_info_t *) arg);
+	case SNDRV_PCM_IOCTL_TSTAMP:
+	{
+		int xarg;
+		if (get_user(xarg, (int *) arg))
+			return -EFAULT;
+		substream->runtime->tstamp_timespec = xarg ? 1 : 0;
+		return 0;
+	}
 	case SNDRV_PCM_IOCTL_HW_REFINE:
 		return snd_pcm_hw_refine_user(substream, (snd_pcm_hw_params_t *) arg);
 	case SNDRV_PCM_IOCTL_HW_PARAMS:
@@ -2169,6 +2294,18 @@
 		__put_user(result, _frames);
 		return result < 0 ? result : 0;
 	}
+	case SNDRV_PCM_IOCTL_FORWARD:
+	{
+		snd_pcm_uframes_t frames, *_frames = arg;
+		snd_pcm_sframes_t result;
+		if (get_user(frames, _frames))
+			return -EFAULT;
+		if (put_user(0, _frames))
+			return -EFAULT;
+		result = snd_pcm_playback_forward(substream, frames);
+		__put_user(result, _frames);
+		return result < 0 ? result : 0;
+	}
 	case SNDRV_PCM_IOCTL_PAUSE:
 	{
 		int res;
@@ -2241,6 +2378,18 @@
 		if (put_user(0, _frames))
 			return -EFAULT;
 		result = snd_pcm_capture_rewind(substream, frames);
+		__put_user(result, _frames);
+		return result < 0 ? result : 0;
+	}
+	case SNDRV_PCM_IOCTL_FORWARD:
+	{
+		snd_pcm_uframes_t frames, *_frames = arg;
+		snd_pcm_sframes_t result;
+		if (get_user(frames, _frames))
+			return -EFAULT;
+		if (put_user(0, _frames))
+			return -EFAULT;
+		result = snd_pcm_capture_forward(substream, frames);
 		__put_user(result, _frames);
 		return result < 0 ? result : 0;
 	}
diff -Nru a/sound/core/pcm_sgbuf.c b/sound/core/pcm_sgbuf.c
--- a/sound/core/pcm_sgbuf.c	Sun Feb 16 05:47:41 2003
+++ b/sound/core/pcm_sgbuf.c	Thu Mar 20 08:41:12 2003
@@ -1,149 +0,0 @@
-/*
- * Scatter-Gather PCM access
- *
- *  Copyright (c) by Takashi Iwai <tiwai@suse.de>
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
- */
-
-#include <sound/driver.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_sgbuf.h>
-
-
-/* table entries are align to 32 */
-#define SGBUF_TBL_ALIGN		32
-#define sgbuf_align_table(tbl)	((((tbl) + SGBUF_TBL_ALIGN - 1) / SGBUF_TBL_ALIGN) * SGBUF_TBL_ALIGN)
-
-
-/**
- * snd_pcm_sgbuf_alloc_pages - allocate the pages for the SG buffer
- * @pci: the pci device pointer
- * @size: the requested buffer size in bytes
- * @dmab: the dma-buffer record to store
- *
- * Initializes the SG-buffer table and allocates the buffer pages
- * for the given size.
- * The pages are mapped to the virtually continuous memory.
- *
- * This function is usually called from snd_pcm_lib_malloc_pages().
- *
- * Returns the mapped virtual address of the buffer if allocation was
- * successful, or NULL at error.
- */
-void *snd_pcm_sgbuf_alloc_pages(struct pci_dev *pci, size_t size, struct snd_pcm_dma_buffer *dmab)
-{
-	struct snd_sg_buf *sgbuf;
-	unsigned int i, pages;
-
-	dmab->area = NULL;
-	dmab->addr = 0;
-	dmab->private_data = sgbuf = snd_magic_kcalloc(snd_pcm_sgbuf_t, 0, GFP_KERNEL);
-	if (! sgbuf)
-		return NULL;
-	sgbuf->pci = pci;
-	pages = snd_pcm_sgbuf_pages(size);
-	sgbuf->tblsize = sgbuf_align_table(pages);
-	sgbuf->table = snd_kcalloc(sizeof(*sgbuf->table) * sgbuf->tblsize, GFP_KERNEL);
-	if (! sgbuf->table)
-		goto _failed;
-	sgbuf->page_table = snd_kcalloc(sizeof(*sgbuf->page_table) * sgbuf->tblsize, GFP_KERNEL);
-	if (! sgbuf->page_table)
-		goto _failed;
-
-	/* allocate each page */
-	for (i = 0; i < pages; i++) {
-		void *ptr;
-		dma_addr_t addr;
-		ptr = snd_malloc_pci_page(sgbuf->pci, &addr);
-		if (! ptr)
-			goto _failed;
-		sgbuf->table[i].buf = ptr;
-		sgbuf->table[i].addr = addr;
-		sgbuf->page_table[i] = virt_to_page(ptr);
-		sgbuf->pages++;
-	}
-
-	sgbuf->size = size;
-	dmab->area = vmap(sgbuf->page_table, sgbuf->pages);
-	if (! dmab->area)
-		goto _failed;
-	return dmab->area;
-
- _failed:
-	snd_pcm_sgbuf_free_pages(dmab); /* free the table */
-	return NULL;
-}
-
-/**
- * snd_pcm_sgbuf_free_pages - free the sg buffer
- * @dmab: dma buffer record
- *
- * Releases the pages and the SG-buffer table.
- *
- * This function is called usually from snd_pcm_lib_free_pages().
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_pcm_sgbuf_free_pages(struct snd_pcm_dma_buffer *dmab)
-{
-	struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, dmab->private_data, return -EINVAL);
-	int i;
-
-	for (i = 0; i < sgbuf->pages; i++)
-		snd_free_pci_page(sgbuf->pci, sgbuf->table[i].buf, sgbuf->table[i].addr);
-	if (dmab->area)
-		vunmap(dmab->area);
-	dmab->area = NULL;
-
-	if (sgbuf->table)
-		kfree(sgbuf->table);
-	if (sgbuf->page_table)
-		kfree(sgbuf->page_table);
-	snd_magic_kfree(sgbuf);
-	dmab->private_data = NULL;
-	
-	return 0;
-}
-
-/**
- * snd_pcm_sgbuf_ops_page - get the page struct at the given offset
- * @substream: the pcm substream instance
- * @offset: the buffer offset
- *
- * Returns the page struct at the given buffer offset.
- * Used as the page callback of PCM ops.
- */
-struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset)
-{
-	struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, _snd_pcm_substream_sgbuf(substream), return NULL);
-
-	unsigned int idx = offset >> PAGE_SHIFT;
-	if (idx >= (unsigned int)sgbuf->pages)
-		return NULL;
-	return sgbuf->page_table[idx];
-}
-
-
-/*
- *  Exported symbols
- */
-EXPORT_SYMBOL(snd_pcm_lib_preallocate_sg_pages);
-EXPORT_SYMBOL(snd_pcm_lib_preallocate_sg_pages_for_all);
-EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
diff -Nru a/sound/core/rawmidi.c b/sound/core/rawmidi.c
--- a/sound/core/rawmidi.c	Sat Feb  8 12:10:46 2003
+++ b/sound/core/rawmidi.c	Thu Mar 20 08:41:12 2003
@@ -79,7 +79,8 @@
 static inline int snd_rawmidi_ready_append(snd_rawmidi_substream_t * substream, size_t count)
 {
 	snd_rawmidi_runtime_t *runtime = substream->runtime;
-	return runtime->avail >= runtime->avail_min && runtime->avail >= count;
+	return runtime->avail >= runtime->avail_min &&
+	       (!substream->append || runtime->avail >= count);
 }
 
 static int snd_rawmidi_init(snd_rawmidi_substream_t *substream)
diff -Nru a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
--- a/sound/core/seq/oss/seq_oss_init.c	Mon Jan 27 08:38:21 2003
+++ b/sound/core/seq/oss/seq_oss_init.c	Thu Mar 20 08:41:12 2003
@@ -51,7 +51,7 @@
 static int create_port(seq_oss_devinfo_t *dp);
 static int delete_port(seq_oss_devinfo_t *dp);
 static int alloc_seq_queue(seq_oss_devinfo_t *dp);
-static int delete_seq_queue(seq_oss_devinfo_t *dp);
+static int delete_seq_queue(int queue);
 static void free_devinfo(void *private);
 
 #define call_ctl(type,rec) snd_seq_kernel_client_ctl(system_client, type, rec)
@@ -186,6 +186,7 @@
 		snd_printk(KERN_ERR "can't malloc device info\n");
 		return -ENOMEM;
 	}
+	debug_printk(("oss_open: dp = %p\n", dp));
 
 	for (i = 0; i < SNDRV_SEQ_OSS_MAX_CLIENTS; i++) {
 		if (client_table[i] == NULL)
@@ -193,6 +194,7 @@
 	}
 	if (i >= SNDRV_SEQ_OSS_MAX_CLIENTS) {
 		snd_printk(KERN_ERR "too many applications\n");
+		kfree(dp);
 		return -ENOMEM;
 	}
 
@@ -209,22 +211,21 @@
 
 	if (dp->synth_opened == 0 && dp->max_mididev == 0) {
 		snd_printk(KERN_ERR "no device found\n");
-		kfree(dp);
-		return -ENODEV;
+		rc = -ENODEV;
+		goto _error;
 	}
 
 	/* create port */
+	debug_printk(("create new port\n"));
 	if ((rc = create_port(dp)) < 0) {
 		snd_printk(KERN_ERR "can't create port\n");
-		free_devinfo(dp);
-		return rc;
+		goto _error;
 	}
 
 	/* allocate queue */
-	if ((rc = alloc_seq_queue(dp)) < 0) {
-		delete_port(dp);
-		return rc;
-	}
+	debug_printk(("allocate queue\n"));
+	if ((rc = alloc_seq_queue(dp)) < 0)
+		goto _error;
 
 	/* set address */
 	dp->addr.client = dp->cseq;
@@ -238,31 +239,32 @@
 	dp->file_mode = translate_mode(file);
 
 	/* initialize read queue */
+	debug_printk(("initialize read queue\n"));
 	if (is_read_mode(dp->file_mode)) {
 		if ((dp->readq = snd_seq_oss_readq_new(dp, maxqlen)) == NULL) {
-			delete_seq_queue(dp);
-			delete_port(dp);
-			return -ENOMEM;
+			rc = -ENOMEM;
+			goto _error;
 		}
 	}
 
 	/* initialize write queue */
+	debug_printk(("initialize write queue\n"));
 	if (is_write_mode(dp->file_mode)) {
 		dp->writeq = snd_seq_oss_writeq_new(dp, maxqlen);
 		if (dp->writeq == NULL) {
-			delete_seq_queue(dp);
-			delete_port(dp);
-			return -ENOMEM;
+			rc = -ENOMEM;
+			goto _error;
 		}
 	}
 
 	/* initialize timer */
+	debug_printk(("initialize timer\n"));
 	if ((dp->timer = snd_seq_oss_timer_new(dp)) == NULL) {
 		snd_printk(KERN_ERR "can't alloc timer\n");
-		delete_seq_queue(dp);
-		delete_port(dp);
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto _error;
 	}
+	debug_printk(("timer initialized\n"));
 
 	/* set private data pointer */
 	file->private_data = dp;
@@ -277,8 +279,16 @@
 	num_clients++;
 
 	debug_printk(("open done\n"));
-
 	return 0;
+
+ _error:
+	snd_seq_oss_synth_cleanup(dp);
+	snd_seq_oss_midi_cleanup(dp);
+	i = dp->queue;
+	delete_port(dp);
+	delete_seq_queue(i);
+
+	return rc;
 }
 
 /*
@@ -344,6 +354,7 @@
 	if (dp->port < 0)
 		return 0;
 
+	debug_printk(("delete_port %i\n", dp->port));
 	memset(&port_info, 0, sizeof(port_info));
 	port_info.addr.client = dp->cseq;
 	port_info.addr.port = dp->port;
@@ -375,15 +386,19 @@
  * release queue
  */
 static int
-delete_seq_queue(seq_oss_devinfo_t *dp)
+delete_seq_queue(int queue)
 {
 	snd_seq_queue_info_t qinfo;
+	int rc;
 
-	if (dp->queue < 0)
+	if (queue < 0)
 		return 0;
 	memset(&qinfo, 0, sizeof(qinfo));
-	qinfo.queue = dp->queue;
-	return call_ctl(SNDRV_SEQ_IOCTL_DELETE_QUEUE, &qinfo);
+	qinfo.queue = queue;
+	rc = call_ctl(SNDRV_SEQ_IOCTL_DELETE_QUEUE, &qinfo);
+	if (rc < 0)
+		printk(KERN_ERR "seq-oss: unable to delete queue %d (%d)\n", queue, rc);
+	return rc;
 }
 
 
@@ -414,6 +429,8 @@
 void
 snd_seq_oss_release(seq_oss_devinfo_t *dp)
 {
+	int queue;
+
 	client_table[dp->index] = NULL;
 	num_clients--;
 
@@ -426,10 +443,10 @@
 
 	/* clear slot */
 	debug_printk(("releasing resource..\n"));
+	queue = dp->queue;
 	if (dp->port >= 0)
 		delete_port(dp);
-	if (dp->queue >= 0)
-		delete_seq_queue(dp);
+	delete_seq_queue(queue);
 
 	debug_printk(("release done\n"));
 }
diff -Nru a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
--- a/sound/core/seq/oss/seq_oss_midi.c	Mon Jan 27 08:38:21 2003
+++ b/sound/core/seq/oss/seq_oss_midi.c	Thu Mar 20 08:41:12 2003
@@ -206,9 +206,9 @@
 	}
 	if (i >= max_midi_devs) {
 		if (max_midi_devs >= SNDRV_SEQ_OSS_MAX_MIDI_DEVS) {
+			spin_unlock_irqrestore(&register_lock, flags);
 			snd_midi_event_free(mdev->coder);
 			kfree(mdev);
-			spin_unlock_irqrestore(&register_lock, flags);
 			return -ENOMEM;
 		}
 		max_midi_devs++;
@@ -372,6 +372,8 @@
 		subs.sender.client = mdev->client;
 		subs.sender.port = mdev->port;
 		subs.dest = dp->addr;
+		subs.flags = SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
+		subs.queue = dp->queue;		/* queue for timestamps */
 		if (snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs) >= 0)
 			mdev->opened |= PERM_READ;
 	}
@@ -462,8 +464,7 @@
 		return;
 	}
 
-	if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC &&
-	    (mdev->opened & PERM_WRITE)) {
+	if (mdev->opened & PERM_WRITE) {
 		snd_seq_event_t ev;
 		int c;
 
@@ -473,16 +474,22 @@
 		ev.dest.port = mdev->port;
 		ev.queue = dp->queue;
 		ev.source.port = dp->port;
+		if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) {
+			ev.type = SNDRV_SEQ_EVENT_SENSING;
+			snd_seq_oss_dispatch(dp, &ev, 0, 0); /* active sensing */
+		}
 		for (c = 0; c < 16; c++) {
 			ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
 			ev.data.control.channel = c;
 			ev.data.control.param = 123;
 			snd_seq_oss_dispatch(dp, &ev, 0, 0); /* all notes off */
-			ev.data.control.param = 121;
-			snd_seq_oss_dispatch(dp, &ev, 0, 0); /* reset all controllers */
-			ev.type = SNDRV_SEQ_EVENT_PITCHBEND;
-			ev.data.control.value = 0;
-			snd_seq_oss_dispatch(dp, &ev, 0, 0); /* bender off */
+			if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) {
+				ev.data.control.param = 121;
+				snd_seq_oss_dispatch(dp, &ev, 0, 0); /* reset all controllers */
+				ev.type = SNDRV_SEQ_EVENT_PITCHBEND;
+				ev.data.control.value = 0;
+				snd_seq_oss_dispatch(dp, &ev, 0, 0); /* bender off */
+			}
 		}
 	}
 	snd_seq_oss_midi_close(dp, dev);
@@ -597,10 +604,12 @@
 static int
 send_midi_event(seq_oss_devinfo_t *dp, snd_seq_event_t *ev, seq_oss_midi_t *mdev)
 {
-	char msg[32]; /* enough except for sysex? */
+	char msg[32];
 	int len;
 	
-	snd_seq_oss_readq_put_timestamp(dp->readq, snd_seq_oss_timer_cur_tick(dp->timer), dp->seq_mode);
+	snd_seq_oss_readq_put_timestamp(dp->readq, ev->time.tick, dp->seq_mode);
+	if (!dp->timer->running)
+		len = snd_seq_oss_timer_start(dp->timer);
 	if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
 		if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
 			snd_seq_oss_readq_puts(dp->readq, mdev->seq_device,
diff -Nru a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
--- a/sound/core/seq/oss/seq_oss_synth.c	Mon Dec 30 09:13:26 2002
+++ b/sound/core/seq/oss/seq_oss_synth.c	Thu Mar 20 08:41:12 2003
@@ -302,29 +302,36 @@
 	seq_oss_synth_t *rec;
 	seq_oss_synthinfo_t *info;
 
+	snd_assert(dp->max_synthdev <= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS, return);
 	for (i = 0; i < dp->max_synthdev; i++) {
 		info = &dp->synths[i];
 		if (! info->opened)
 			continue;
 		if (info->is_midi) {
-			snd_seq_oss_midi_close(dp, info->midi_mapped);
-			midi_synth_dev.opened--;
+			if (midi_synth_dev.opened > 0) {
+				snd_seq_oss_midi_close(dp, info->midi_mapped);
+				midi_synth_dev.opened--;
+			}
 		} else {
 			rec = get_sdev(i);
 			if (rec == NULL)
 				continue;
-			if (rec->opened) {
+			if (rec->opened > 0) {
 				debug_printk(("synth %d closed\n", i));
 				rec->oper.close(&info->arg);
 				module_put(rec->oper.owner);
-				rec->opened--;
+				rec->opened = 0;
 			}
 			snd_use_lock_free(&rec->use_lock);
 		}
-		if (info->sysex)
+		if (info->sysex) {
 			kfree(info->sysex);
-		if (info->ch)
+			info->sysex = NULL;
+		}
+		if (info->ch) {
 			kfree(info->ch);
+			info->ch = NULL;
+		}
 	}
 	dp->synth_opened = 0;
 	dp->max_synthdev = 0;
@@ -401,15 +408,21 @@
 		info->sysex->len = 0; /* reset sysex */
 	reset_channels(info);
 	if (info->is_midi) {
+		if (midi_synth_dev.opened <= 0)
+			return;
 		snd_seq_oss_midi_reset(dp, info->midi_mapped);
 		if (snd_seq_oss_midi_open(dp, info->midi_mapped,
 					  dp->file_mode) < 0) {
 			midi_synth_dev.opened--;
 			info->opened = 0;
-			if (info->sysex)
+			if (info->sysex) {
 				kfree(info->sysex);
-			if (info->ch)
+				info->sysex = NULL;
+			}
+			if (info->ch) {
 				kfree(info->ch);
+				info->ch = NULL;
+			}
 		}
 		return;
 	}
diff -Nru a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
--- a/sound/core/seq/seq_midi.c	Sat Feb  8 12:10:47 2003
+++ b/sound/core/seq/seq_midi.c	Thu Mar 20 08:41:12 2003
@@ -272,6 +272,21 @@
 		snd_midi_event_free(msynth->parser);
 }
 
+/* set our client name */
+static int set_client_name(seq_midisynth_client_t *client, snd_card_t *card,
+			   snd_rawmidi_info_t *rmidi)
+{
+	snd_seq_client_info_t cinfo;
+	const char *name;
+
+	memset(&cinfo, 0, sizeof(cinfo));
+	cinfo.client = client->seq_client;
+	cinfo.type = KERNEL_CLIENT;
+	name = rmidi->name[0] ? (const char *)rmidi->name : "External MIDI";
+	snprintf(cinfo.name, sizeof(cinfo.name), "Rawmidi %d - %s", card->number, name);
+	return snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
+}
+
 /* register new midi synth port */
 int
 snd_seq_midisynth_register_port(snd_seq_device_t *dev)
@@ -284,7 +299,6 @@
 	unsigned int p, ports;
 	snd_seq_client_callback_t callbacks;
 	snd_seq_port_callback_t pcallbacks;
-	snd_seq_client_info_t inf;
 	snd_card_t *card = dev->card;
 	int device = dev->device;
 	unsigned int input_count = 0, output_count = 0;
@@ -325,13 +339,9 @@
 			up(&register_mutex);
 			return -ENOMEM;
 		}
-		/* set our client name */
-		memset(&inf,0,sizeof(snd_seq_client_info_t));
-		inf.client = client->seq_client;
-		inf.type = KERNEL_CLIENT;
-		sprintf(inf.name, "External MIDI %i", card->number);
-		snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &inf);
-	}
+		set_client_name(client, card, &info);
+	} else if (device == 0)
+		set_client_name(client, card, &info); /* use the first device's name */
 
 	msynth = snd_kcalloc(sizeof(seq_midisynth_t) * ports, GFP_KERNEL);
 	if (msynth == NULL)
@@ -358,10 +368,18 @@
 		if (snd_rawmidi_info_select(card, &info) >= 0)
 			strcpy(port.name, info.subname);
 		if (! port.name[0]) {
-			if (ports > 1)
-				sprintf(port.name, "MIDI %d-%d-%d", card->number, device, p);
-			else
-				sprintf(port.name, "MIDI %d-%d", card->number, device);
+			if (info.name[0]) {
+				if (ports > 1)
+					snprintf(port.name, sizeof(port.name), "%s-%d", info.name, p);
+				else
+					snprintf(port.name, sizeof(port.name), "%s", info.name);
+			} else {
+				/* last resort */
+				if (ports > 1)
+					sprintf(port.name, "MIDI %d-%d-%d", card->number, device, p);
+				else
+					sprintf(port.name, "MIDI %d-%d", card->number, device);
+			}
 		}
 		if ((info.flags & SNDRV_RAWMIDI_INFO_OUTPUT) && p < output_count)
 			port.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
diff -Nru a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
--- a/sound/core/seq/seq_ports.c	Sat Feb  8 12:10:48 2003
+++ b/sound/core/seq/seq_ports.c	Thu Mar 20 08:41:12 2003
@@ -351,6 +351,7 @@
 
 	/* information about supported channels/voices */
 	port->midi_channels = info->midi_channels;
+	port->midi_voices = info->midi_voices;
 	port->synth_voices = info->synth_voices;
 
 	return 0;
@@ -372,6 +373,7 @@
 
 	/* information about supported channels/voices */
 	info->midi_channels = port->midi_channels;
+	info->midi_voices = port->midi_voices;
 	info->synth_voices = port->synth_voices;
 
 	/* get subscriber counts */
@@ -611,7 +613,7 @@
 int snd_seq_event_port_attach(int client,
 			      snd_seq_port_callback_t *pcbp,
 			      int cap, int type, int midi_channels,
-			      char *portname)
+			      int midi_voices, char *portname)
 {
 	snd_seq_port_info_t portinfo;
 	int  ret;
@@ -628,6 +630,7 @@
 	portinfo.type = type;
 	portinfo.kernel = pcbp;
 	portinfo.midi_channels = midi_channels;
+	portinfo.midi_voices = midi_voices;
 
 	/* Create it */
 	ret = snd_seq_kernel_client_ctl(client,
diff -Nru a/sound/core/seq/seq_ports.h b/sound/core/seq/seq_ports.h
--- a/sound/core/seq/seq_ports.h	Wed Feb 13 11:32:02 2002
+++ b/sound/core/seq/seq_ports.h	Thu Mar 20 08:41:12 2003
@@ -81,6 +81,7 @@
 
 	/* supported channels */
 	int midi_channels;
+	int midi_voices;
 	int synth_voices;
 		
 } client_port_t;
diff -Nru a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
--- a/sound/core/seq/seq_timer.c	Mon Feb 24 12:31:18 2003
+++ b/sound/core/seq/seq_timer.c	Thu Mar 20 08:41:12 2003
@@ -262,34 +262,33 @@
 	snd_timer_instance_t *t;
 	seq_timer_t *tmr;
 	char str[32];
+	int err;
 
 	tmr = q->timer;
 	snd_assert(tmr != NULL, return -EINVAL);
 	if (tmr->timeri)
 		return -EBUSY;
 	sprintf(str, "sequencer queue %i", q->queue);
-	if (tmr->type == SNDRV_SEQ_TIMER_ALSA) {	/* standard ALSA timer */
-		if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
-			tmr->alsa_id.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER;
-		t = snd_timer_open(str, &tmr->alsa_id, q->queue);
-		if (t == NULL && tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE) {
-			if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_GLOBAL ||
-			    tmr->alsa_id.device != SNDRV_TIMER_GLOBAL_SYSTEM) {
-				snd_timer_id_t tid;
-				memset(&tid, 0, sizeof(tid));
-				tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
-				tid.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER;
-				tid.card = -1;
-				tid.device = SNDRV_TIMER_GLOBAL_SYSTEM;
-				t = snd_timer_open(str, &tid, q->queue);
-			}
-			if (t == NULL) {
-				snd_printk(KERN_ERR "fatal error: cannot create timer\n");
-				return -ENODEV;
-			}
-		}
-	} else {
+	if (tmr->type != SNDRV_SEQ_TIMER_ALSA)	/* standard ALSA timer */
 		return -EINVAL;
+	if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
+		tmr->alsa_id.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER;
+	err = snd_timer_open(&t, str, &tmr->alsa_id, q->queue);
+	if (err < 0 && tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE) {
+		if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_GLOBAL ||
+		    tmr->alsa_id.device != SNDRV_TIMER_GLOBAL_SYSTEM) {
+			snd_timer_id_t tid;
+			memset(&tid, 0, sizeof(tid));
+			tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
+			tid.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER;
+			tid.card = -1;
+			tid.device = SNDRV_TIMER_GLOBAL_SYSTEM;
+			err = snd_timer_open(&t, str, &tid, q->queue);
+		}
+		if (err < 0) {
+			snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err);
+			return err;
+		}
 	}
 	t->callback = snd_seq_timer_interrupt;
 	t->callback_data = q;
@@ -319,7 +318,7 @@
 	if (!tmr->running)
 		return 0;
 	tmr->running = 0;
-	snd_timer_stop(tmr->timeri);
+	snd_timer_pause(tmr->timeri);
 	return 0;
 }
 
diff -Nru a/sound/core/sgbuf.c b/sound/core/sgbuf.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/sound/core/sgbuf.c	Thu Mar 20 08:41:18 2003
@@ -0,0 +1,131 @@
+/*
+ * Scatter-Gather buffer
+ *
+ *  Copyright (c) by Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <sound/memalloc.h>
+
+
+/* table entries are align to 32 */
+#define SGBUF_TBL_ALIGN		32
+#define sgbuf_align_table(tbl)	((((tbl) + SGBUF_TBL_ALIGN - 1) / SGBUF_TBL_ALIGN) * SGBUF_TBL_ALIGN)
+
+
+/**
+ * snd_malloc_sgbuf_pages - allocate the pages for the PCI SG buffer
+ * @pci: the pci device pointer
+ * @size: the requested buffer size in bytes
+ * @dmab: the buffer record to store
+ *
+ * Initializes the SG-buffer table and allocates the buffer pages
+ * for the given size.
+ * The pages are mapped to the virtually continuous memory.
+ *
+ * This function is usually called from the middle-level functions such as
+ * snd_pcm_lib_malloc_pages().
+ *
+ * Returns the mapped virtual address of the buffer if allocation was
+ * successful, or NULL at error.
+ */
+void *snd_malloc_sgbuf_pages(struct pci_dev *pci, size_t size, struct snd_dma_buffer *dmab)
+{
+	struct snd_sg_buf *sgbuf;
+	unsigned int i, pages;
+
+	dmab->area = NULL;
+	dmab->addr = 0;
+	dmab->private_data = sgbuf = kmalloc(sizeof(*sgbuf), GFP_KERNEL);
+	if (! sgbuf)
+		return NULL;
+	memset(sgbuf, 0, sizeof(*sgbuf));
+	sgbuf->pci = pci;
+	pages = snd_sgbuf_aligned_pages(size);
+	sgbuf->tblsize = sgbuf_align_table(pages);
+	sgbuf->table = kmalloc(sizeof(*sgbuf->table) * sgbuf->tblsize, GFP_KERNEL);
+	if (! sgbuf->table)
+		goto _failed;
+	memset(sgbuf->table, 0, sizeof(*sgbuf->table) * sgbuf->tblsize);
+	sgbuf->page_table = kmalloc(sizeof(*sgbuf->page_table) * sgbuf->tblsize, GFP_KERNEL);
+	if (! sgbuf->page_table)
+		goto _failed;
+	memset(sgbuf->page_table, 0, sizeof(*sgbuf->page_table) * sgbuf->tblsize);
+
+	/* allocate each page */
+	for (i = 0; i < pages; i++) {
+		void *ptr;
+		dma_addr_t addr;
+		ptr = snd_malloc_pci_page(sgbuf->pci, &addr);
+		if (! ptr)
+			goto _failed;
+		sgbuf->table[i].buf = ptr;
+		sgbuf->table[i].addr = addr;
+		sgbuf->page_table[i] = virt_to_page(ptr);
+		sgbuf->pages++;
+	}
+
+	sgbuf->size = size;
+	dmab->area = vmap(sgbuf->page_table, sgbuf->pages);
+	if (! dmab->area)
+		goto _failed;
+	return dmab->area;
+
+ _failed:
+	snd_free_sgbuf_pages(dmab); /* free the table */
+	return NULL;
+}
+
+/**
+ * snd_free_sgbuf_pages - free the sg buffer
+ * @dmab: buffer record
+ *
+ * Releases the pages and the SG-buffer table.
+ *
+ * This function is called usually from the middle-level function
+ * such as snd_pcm_lib_free_pages().
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
+int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
+{
+	struct snd_sg_buf *sgbuf = dmab->private_data;
+	int i;
+
+	if (! sgbuf)
+		return -EINVAL;
+
+	for (i = 0; i < sgbuf->pages; i++)
+		snd_free_pci_page(sgbuf->pci, sgbuf->table[i].buf, sgbuf->table[i].addr);
+	if (dmab->area)
+		vunmap(dmab->area);
+	dmab->area = NULL;
+
+	if (sgbuf->table)
+		kfree(sgbuf->table);
+	if (sgbuf->page_table)
+		kfree(sgbuf->page_table);
+	kfree(sgbuf);
+	dmab->private_data = NULL;
+	
+	return 0;
+}
diff -Nru a/sound/core/sound.c b/sound/core/sound.c
--- a/sound/core/sound.c	Sat Feb  8 12:10:48 2003
+++ b/sound/core/sound.c	Sat Mar 22 07:38:05 2003
@@ -346,7 +346,7 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
 	devfs_handle = devfs_mk_dir(NULL, "snd", 3, NULL);
 #else
-	devfs_handle = devfs_mk_dir(NULL, "snd", NULL);
+	devfs_handle = devfs_mk_dir("snd");
 #endif
 #endif
 	if (register_chrdev(major, "alsa", &snd_fops)) {
@@ -432,24 +432,6 @@
 #endif
 EXPORT_SYMBOL(snd_kcalloc);
 EXPORT_SYMBOL(snd_kmalloc_strdup);
-EXPORT_SYMBOL(snd_malloc_pages);
-EXPORT_SYMBOL(snd_malloc_pages_fallback);
-EXPORT_SYMBOL(snd_free_pages);
-#if defined(CONFIG_ISA) && ! defined(CONFIG_PCI)
-EXPORT_SYMBOL(snd_malloc_isa_pages);
-EXPORT_SYMBOL(snd_malloc_isa_pages_fallback);
-#endif
-#ifdef CONFIG_PCI
-EXPORT_SYMBOL(snd_malloc_pci_pages);
-EXPORT_SYMBOL(snd_malloc_pci_pages_fallback);
-EXPORT_SYMBOL(snd_malloc_pci_page);
-EXPORT_SYMBOL(snd_free_pci_pages);
-#endif
-#ifdef CONFIG_SBUS
-EXPORT_SYMBOL(snd_malloc_sbus_pages);
-EXPORT_SYMBOL(snd_malloc_sbus_pages_fallback);
-EXPORT_SYMBOL(snd_free_sbus_pages);
-#endif
 EXPORT_SYMBOL(copy_to_user_fromio);
 EXPORT_SYMBOL(copy_from_user_toio);
   /* init.c */
@@ -522,9 +504,6 @@
 #if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
 EXPORT_SYMBOL(snd_verbose_printd);
 #endif
-#if defined(CONFIG_SND_DEBUG) && !defined(CONFIG_SND_VERBOSE_PRINTK)
-EXPORT_SYMBOL(snd_printd);
-#endif
   /* wrappers */
 #ifdef CONFIG_SND_DEBUG_MEMORY
 EXPORT_SYMBOL(snd_wrapper_kmalloc);
@@ -532,6 +511,3 @@
 EXPORT_SYMBOL(snd_wrapper_vmalloc);
 EXPORT_SYMBOL(snd_wrapper_vfree);
 #endif
-#ifdef HACK_PCI_ALLOC_CONSISTENT
-EXPORT_SYMBOL(snd_pci_hack_alloc_consistent);
-#endif 
diff -Nru a/sound/core/timer.c b/sound/core/timer.c
--- a/sound/core/timer.c	Sun Feb 16 05:47:41 2003
+++ b/sound/core/timer.c	Thu Mar 20 08:41:13 2003
@@ -51,6 +51,7 @@
 
 typedef struct {
 	snd_timer_instance_t *timeri;
+	int tread;			/* enhanced read with timestamps and events */
 	unsigned long ticks;
 	unsigned long overrun;
 	int qhead;
@@ -58,7 +59,11 @@
 	int qused;
 	int queue_size;
 	snd_timer_read_t *queue;
+	snd_timer_tread_t *tqueue;
 	spinlock_t qlock;
+	unsigned long last_resolution;
+	unsigned int filter;
+	struct timespec tstamp;		/* trigger tstamp */
 	wait_queue_head_t qchange_sleep;
 	struct fasync_struct *fasync;
 } snd_timer_user_t;
@@ -228,8 +233,9 @@
  * open a timer instance
  * when opening a master, the slave id must be here given.
  */
-snd_timer_instance_t *snd_timer_open(char *owner, snd_timer_id_t *tid,
-				     unsigned int slave_id)
+int snd_timer_open(snd_timer_instance_t **ti,
+		   char *owner, snd_timer_id_t *tid,
+		   unsigned int slave_id)
 {
 	snd_timer_t *timer;
 	snd_timer_instance_t *timeri = NULL;
@@ -239,7 +245,7 @@
 		if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE ||
 		    tid->dev_sclass > SNDRV_TIMER_SCLASS_OSS_SEQUENCER) {
 			snd_printd("invalid slave class %i\n", tid->dev_sclass);
-			return NULL;
+			return -EINVAL;
 		}
 		down(&register_mutex);
 		timeri = snd_timer_instance_new(owner, NULL);
@@ -249,7 +255,8 @@
 		list_add_tail(&timeri->open_list, &snd_timer_slave_list);
 		snd_timer_check_slave(timeri);
 		up(&register_mutex);
-		return timeri;
+		*ti = timeri;
+		return 0;
 	}
 
 	/* open a master instance */
@@ -264,6 +271,13 @@
 	}
 #endif
 	if (timer) {
+		if (!list_empty(&timer->open_list_head)) {
+			timeri = (snd_timer_instance_t *)list_entry(timer->open_list_head.next, snd_timer_instance_t, open_list);
+			if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
+				up(&register_mutex);
+				return -EBUSY;
+			}
+		}
 		timeri = snd_timer_instance_new(owner, timer);
 		if (timeri) {
 			timeri->slave_class = tid->dev_sclass;
@@ -273,12 +287,16 @@
 			list_add_tail(&timeri->open_list, &timer->open_list_head);
 			snd_timer_check_master(timeri);
 		}
+	} else {
+		up(&register_mutex);
+		return -ENODEV;
 	}
 	up(&register_mutex);
-	return timeri;
+	*ti = timeri;
+	return 0;
 }
 
-static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag);
+static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event);
 
 /*
  * close a timer instance
@@ -307,7 +325,7 @@
 		list_for_each_safe(p, n, &timeri->slave_list_head) {
 			slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list);
 			spin_lock_irq(&slave_active_lock);
-			_snd_timer_stop(slave, 1);
+			_snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
 			list_del(p);
 			list_add_tail(p, &snd_timer_slave_list);
 			slave->master = NULL;
@@ -340,6 +358,37 @@
 	return 0;
 }
 
+static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event event)
+{
+	snd_timer_t *timer;
+	unsigned long flags;
+	unsigned long resolution = 0;
+	snd_timer_instance_t *ts;
+	struct list_head *n;
+	struct timespec tstamp;
+
+	snd_timestamp_now(&tstamp, 1);
+	snd_assert(event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE, return);
+	if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE)
+		resolution = snd_timer_resolution(ti);
+	if (ti->ccallback)
+		ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution);
+	if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
+		return;
+	timer = ti->timer;
+	if (timer == NULL)
+		return;
+	if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
+		return;
+	spin_lock_irqsave(&timer->lock, flags);
+	list_for_each(n, &ti->slave_active_head) {
+		ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list);
+		if (ts->ccallback)
+			ts->ccallback(ti, event + 100, &tstamp, resolution);
+	}
+	spin_unlock_irqrestore(&timer->lock, flags);
+}
+
 static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, unsigned long sticks)
 {
 	list_del(&timeri->active_list);
@@ -380,8 +429,11 @@
 
 	if (timeri == NULL || ticks < 1)
 		return -EINVAL;
-	if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
-		return snd_timer_start_slave(timeri);
+	if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
+		result = snd_timer_start_slave(timeri);
+		snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
+		return result;
+	}
 	timer = timeri->timer;
 	if (timer == NULL)
 		return -EINVAL;
@@ -390,17 +442,17 @@
 	timeri->pticks = 0;
 	result = snd_timer_start1(timer, timeri, ticks);
 	spin_unlock_irqrestore(&timer->lock, flags);
+	snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
 	return result;
 }
 
-static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag)
+static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event)
 {
 	snd_timer_t *timer;
 	unsigned long flags;
 
 	snd_assert(timeri != NULL, return -ENXIO);
 
-
 	timer = timeri->timer;
 	if (! timer)
 		return -EINVAL;
@@ -429,6 +481,8 @@
 	if (!keep_flag)
 		timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING|SNDRV_TIMER_IFLG_START);
 	spin_unlock_irqrestore(&timer->lock, flags);
+	if (event != SNDRV_TIMER_EVENT_RESOLUTION)
+		snd_timer_notify1(timeri, event);
 	return 0;
 }
 
@@ -439,7 +493,19 @@
  */
 int snd_timer_stop(snd_timer_instance_t * timeri)
 {
-	return _snd_timer_stop(timeri, 0);
+	snd_timer_t *timer;
+	unsigned long flags;
+	int err;
+
+	err = _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_STOP);
+	if (err < 0)
+		return err;
+	timer = timeri->timer;
+	spin_lock_irqsave(&timer->lock, flags);
+	timeri->cticks = timeri->ticks;
+	timeri->pticks = 0;
+	spin_unlock_irqrestore(&timer->lock, flags);
+	return 0;
 }
 
 /*
@@ -464,10 +530,19 @@
 	timeri->pticks = 0;
 	result = snd_timer_start1(timer, timeri, timer->sticks);
 	spin_unlock_irqrestore(&timer->lock, flags);
+	snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE);
 	return result;
 }
 
 /*
+ * pause.. remember the ticks left
+ */
+int snd_timer_pause(snd_timer_instance_t * timeri)
+{
+	return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE);
+}
+
+/*
  * reschedule the timer
  *
  * start pending instances and check the scheduling ticks.
@@ -774,6 +849,35 @@
 	return snd_timer_unregister(timer);
 }
 
+void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp)
+{
+	unsigned long flags;
+	unsigned long resolution = 0;
+	snd_timer_instance_t *ti, *ts;
+	struct list_head *p, *n;
+
+	snd_runtime_check(timer->hw.flags & SNDRV_TIMER_HW_SLAVE, return);	
+	snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MPAUSE, return);
+	spin_lock_irqsave(&timer->lock, flags);
+	if (event == SNDRV_TIMER_EVENT_MSTART || event == SNDRV_TIMER_EVENT_MCONTINUE) {
+		if (timer->hw.c_resolution)
+			resolution = timer->hw.c_resolution(timer);
+		else
+			resolution = timer->hw.resolution;
+	}
+	list_for_each(p, &timer->active_list_head) {
+		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
+		if (ti->ccallback)
+			ti->ccallback(ti, event, tstamp, resolution);
+		list_for_each(n, &ti->slave_active_head) {
+			ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list);
+			if (ts->ccallback)
+				ts->ccallback(ts, event, tstamp, resolution);
+		}
+	}
+	spin_unlock_irqrestore(&timer->lock, flags);
+}
+
 /*
  * exported functions for global timers
  */
@@ -938,9 +1042,17 @@
 {
 	snd_timer_user_t *tu = snd_magic_cast(snd_timer_user_t, timeri->callback_data, return);
 	snd_timer_read_t *r;
-	int _wake = 0;
+	int prev;
 	
 	spin_lock(&tu->qlock);
+	if (tu->qused > 0) {
+		prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
+		r = &tu->queue[prev];
+		if (r->resolution == resolution) {
+			r->ticks += ticks;
+			goto __wake;
+		}
+	}
 	if (tu->qused >= tu->queue_size) {
 		tu->overrun++;
 	} else {
@@ -949,15 +1061,95 @@
 		r->resolution = resolution;
 		r->ticks = ticks;
 		tu->qused++;
-		_wake++;
 	}
+      __wake:
 	spin_unlock(&tu->qlock);
-	if (_wake) {
-		kill_fasync(&tu->fasync, SIGIO, POLL_IN);
-		wake_up(&tu->qchange_sleep);
+	kill_fasync(&tu->fasync, SIGIO, POLL_IN);
+	wake_up(&tu->qchange_sleep);
+}
+
+static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, snd_timer_tread_t *tread)
+{
+	if (tu->qused >= tu->queue_size) {
+		tu->overrun++;
+	} else {
+		memcpy(&tu->queue[tu->qtail++], tread, sizeof(*tread));
+		tu->qused++;
 	}
 }
 
+static void snd_timer_user_ccallback(snd_timer_instance_t *timeri,
+				     enum sndrv_timer_event event,
+				     struct timespec *tstamp,
+				     unsigned long resolution)
+{
+	snd_timer_user_t *tu = snd_magic_cast(snd_timer_user_t, timeri->callback_data, return);
+	snd_timer_tread_t r1;
+
+	if (event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE)
+		tu->tstamp = *tstamp;
+	if ((tu->filter & (1 << event)) == 0 || !tu->tread)
+		return;
+	r1.event = event;
+	r1.tstamp = *tstamp;
+	r1.val = resolution;
+	spin_lock(&tu->qlock);
+	snd_timer_user_append_to_tqueue(tu, &r1);
+	spin_unlock(&tu->qlock);
+}
+
+static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri,
+				      unsigned long resolution,
+				      unsigned long ticks)
+{
+	snd_timer_user_t *tu = snd_magic_cast(snd_timer_user_t, timeri->callback_data, return);
+	snd_timer_tread_t *r, r1;
+	struct timespec tstamp;
+	int prev, append = 0;
+
+	snd_timestamp_zero(&tstamp);
+	spin_lock(&tu->qlock);
+	if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION)|(1 << SNDRV_TIMER_EVENT_TICK))) == 0) {
+		spin_unlock(&tu->qlock);
+		return;
+	}
+	if (tu->last_resolution != resolution || ticks > 0)
+		snd_timestamp_now(&tstamp, 1);
+	if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) {
+		r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
+		r1.tstamp = tstamp;
+		r1.val = resolution;
+		snd_timer_user_append_to_tqueue(tu, &r1);
+		tu->last_resolution = resolution;
+		append++;
+	}
+	if ((tu->filter & (1 << SNDRV_TIMER_EVENT_TICK)) == 0)
+		goto __wake;
+	if (ticks == 0)
+		goto __wake;
+	if (tu->qused > 0) {
+		prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
+		r = &tu->tqueue[prev];
+		if (r->event == SNDRV_TIMER_EVENT_TICK) {
+			r->tstamp = tstamp;
+			r->val += ticks;
+			append++;
+			goto __wake;
+		}
+	}
+	r1.event = SNDRV_TIMER_EVENT_TICK;
+	r1.tstamp = tstamp;
+	r1.val = ticks;
+	snd_timer_user_append_to_tqueue(tu, &r1);
+	append++;
+      __wake:
+	spin_unlock(&tu->qlock);
+	if (append == 0)
+		return;
+	kill_fasync(&tu->fasync, SIGIO, POLL_IN);
+	wake_up(&tu->qchange_sleep);
+}
+
 static int snd_timer_user_open(struct inode *inode, struct file *file)
 {
 	snd_timer_user_t *tu;
@@ -990,6 +1182,8 @@
 			snd_timer_close(tu->timeri);
 		if (tu->queue)
 			kfree(tu->queue);
+		if (tu->tqueue)
+			kfree(tu->tqueue);
 		snd_magic_kfree(tu);
 	}
 	return 0;
@@ -1104,11 +1298,110 @@
 	return 0;
 } 
 
+static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t *_ginfo)
+{
+	snd_timer_ginfo_t ginfo;
+	snd_timer_id_t tid;
+	snd_timer_t *t;
+	struct list_head *p;
+	int err = 0;
+
+	if (copy_from_user(&ginfo, _ginfo, sizeof(ginfo)))
+		return -EFAULT;
+	tid = ginfo.tid;
+	memset(&ginfo, 0, sizeof(ginfo));
+	ginfo.tid = tid;
+	down(&register_mutex);
+	t = snd_timer_find(&tid);
+	if (t != NULL) {
+		ginfo.card = t->card ? t->card->number : -1;
+		if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
+			ginfo.flags |= SNDRV_TIMER_FLG_SLAVE;
+		strncpy(ginfo.id, t->id, sizeof(ginfo.id)-1);
+		strncpy(ginfo.name, t->name, sizeof(ginfo.name)-1);
+		ginfo.resolution = t->hw.resolution;
+		if (t->hw.resolution_min > 0) {
+			ginfo.resolution_min = t->hw.resolution_min;
+			ginfo.resolution_max = t->hw.resolution_max;
+		}
+		list_for_each(p, &t->open_list_head) {
+			ginfo.clients++;
+		}
+	} else {
+		err = -ENODEV;
+	}
+	up(&register_mutex);
+	if (err >= 0 && copy_to_user(_ginfo, &ginfo, sizeof(ginfo)))
+		err = -EFAULT;
+	return err;
+}
+
+static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t *_gparams)
+{
+	snd_timer_gparams_t gparams;
+	snd_timer_t *t;
+	int err;
+
+	if (copy_from_user(&gparams, _gparams, sizeof(gparams)))
+		return -EFAULT;
+	down(&register_mutex);
+	t = snd_timer_find(&gparams.tid);
+	if (t != NULL) {
+		if (list_empty(&t->open_list_head)) {
+			if (t->hw.set_period)
+				err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
+			else
+				err = -ENOSYS;
+		} else {
+			err = -EBUSY;
+		}
+	} else {
+		err = -ENODEV;
+	}
+	up(&register_mutex);
+	return err;
+}
+
+static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t *_gstatus)
+{
+	snd_timer_gstatus_t gstatus;
+	snd_timer_id_t tid;
+	snd_timer_t *t;
+	int err = 0;
+
+	if (copy_from_user(&gstatus, _gstatus, sizeof(gstatus)))
+		return -EFAULT;
+	tid = gstatus.tid;
+	memset(&gstatus, 0, sizeof(gstatus));
+	gstatus.tid = tid;
+	down(&register_mutex);
+	t = snd_timer_find(&tid);
+	if (t != NULL) {
+		if (t->hw.c_resolution)
+			gstatus.resolution = t->hw.c_resolution(t);
+		else
+			gstatus.resolution = t->hw.resolution;
+		if (t->hw.precise_resolution) {
+			t->hw.precise_resolution(t, &gstatus.resolution_num, &gstatus.resolution_den);
+		} else {
+			gstatus.resolution_num = 1;
+			gstatus.resolution_den = gstatus.resolution;
+		}
+	} else {
+		err = -ENODEV;
+	}
+	up(&register_mutex);
+	if (err >= 0 && copy_from_user(_gstatus, &gstatus, sizeof(gstatus)))
+		err = -EFAULT;
+	return err;
+}
+
 static int snd_timer_user_tselect(struct file *file, snd_timer_select_t *_tselect)
 {
 	snd_timer_user_t *tu;
 	snd_timer_select_t tselect;
 	char str[32];
+	int err;
 	
 	tu = snd_magic_cast(snd_timer_user_t, file->private_data, return -ENXIO);
 	if (tu->timeri)
@@ -1118,10 +1411,34 @@
 	sprintf(str, "application %i", current->pid);
 	if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
 		tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION;
-	if ((tu->timeri = snd_timer_open(str, &tselect.id, current->pid)) == NULL)
-		return -ENODEV;
+	if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0)
+		return err;
+
+	if (tu->queue) {
+		kfree(tu->queue);
+		tu->queue = NULL;
+	}
+	if (tu->tqueue) {
+		kfree(tu->tqueue);
+		tu->tqueue = NULL;
+	}
+	if (tu->tread) {
+		tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL);
+		if (tu->tqueue == NULL) {
+			snd_timer_close(tu->timeri);
+			return -ENOMEM;
+		}
+	} else {
+		tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
+		if (tu->queue == NULL) {
+			snd_timer_close(tu->timeri);
+			return -ENOMEM;
+		}
+	}
+	
 	tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
-	tu->timeri->callback = snd_timer_user_interrupt;
+	tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
+	tu->timeri->ccallback = snd_timer_user_ccallback;
 	tu->timeri->callback_data = (void *)tu;
 	return 0;
 }
@@ -1142,7 +1459,6 @@
 		info.flags |= SNDRV_TIMER_FLG_SLAVE;
 	strncpy(info.id, t->id, sizeof(info.id)-1);
 	strncpy(info.name, t->name, sizeof(info.name)-1);
-	info.ticks = t->hw.ticks;
 	info.resolution = t->hw.resolution;
 	if (copy_to_user(_info, &info, sizeof(*_info)))
 		return -EFAULT;
@@ -1156,6 +1472,7 @@
 	snd_timer_params_t params;
 	snd_timer_t *t;
 	snd_timer_read_t *tr;
+	snd_timer_tread_t *ttr;
 	int err;
 	
 	tu = snd_magic_cast(snd_timer_user_t, file->private_data, return -ENXIO);
@@ -1172,6 +1489,19 @@
 		err = -EINVAL;
 		goto _end;
 	}
+	if (params.filter & ~((1<<SNDRV_TIMER_EVENT_RESOLUTION)|
+			      (1<<SNDRV_TIMER_EVENT_TICK)|
+			      (1<<SNDRV_TIMER_EVENT_START)|
+			      (1<<SNDRV_TIMER_EVENT_STOP)|
+			      (1<<SNDRV_TIMER_EVENT_CONTINUE)|
+			      (1<<SNDRV_TIMER_EVENT_PAUSE)|
+			      (1<<SNDRV_TIMER_EVENT_MSTART)|
+			      (1<<SNDRV_TIMER_EVENT_MSTOP)|
+			      (1<<SNDRV_TIMER_EVENT_MCONTINUE)|
+			      (1<<SNDRV_TIMER_EVENT_MPAUSE))) {
+		err = -EINVAL;
+		goto _end;
+	}
 	snd_timer_stop(tu->timeri);
 	spin_lock_irqsave(&t->lock, flags);
 	if (params.flags & SNDRV_TIMER_PSFLG_AUTO) {
@@ -1179,20 +1509,31 @@
 	} else {
 		tu->timeri->flags &= ~SNDRV_TIMER_IFLG_AUTO;
 	}
+	if (params.flags & SNDRV_TIMER_PSFLG_EXCLUSIVE) {
+		tu->timeri->flags |= SNDRV_TIMER_IFLG_EXCLUSIVE;
+	} else {
+		tu->timeri->flags &= ~SNDRV_TIMER_IFLG_EXCLUSIVE;
+	}
 	spin_unlock_irqrestore(&t->lock, flags);
 	if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) {
-		tr = (snd_timer_read_t *)kmalloc(params.queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
-		if (tr) {
-			kfree(tu->queue);
-			tu->queue_size = params.queue_size;
-			tu->queue = tr;
+		if (tu->tread) {
+			ttr = (snd_timer_tread_t *)kmalloc(params.queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL);
+			if (ttr) {
+				kfree(tu->tqueue);
+				tu->queue_size = params.queue_size;
+				tu->tqueue = ttr;
+			}
+		} else {
+			tr = (snd_timer_read_t *)kmalloc(params.queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
+			if (tr) {
+				kfree(tu->queue);
+				tu->queue_size = params.queue_size;
+				tu->queue = tr;
+			}
 		}
 	}
-	if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) {
-		tu->ticks = 1;
-	} else {
-		tu->ticks = params.ticks;
-	}
+	tu->filter = params.filter;
+	tu->ticks = params.ticks;
 	err = 0;
  _end:
 	if (copy_to_user(_params, &params, sizeof(params)))
@@ -1209,6 +1550,7 @@
 	tu = snd_magic_cast(snd_timer_user_t, file->private_data, return -ENXIO);
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	memset(&status, 0, sizeof(status));
+	status.tstamp = tu->tstamp;
 	status.resolution = snd_timer_resolution(tu->timeri);
 	status.lost = tu->timeri->lost;
 	status.overrun = tu->overrun;
@@ -1229,6 +1571,7 @@
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	snd_timer_stop(tu->timeri);
 	tu->timeri->lost = 0;
+	tu->last_resolution = 0;
 	return (err = snd_timer_start(tu->timeri, tu->ticks)) < 0 ? err : 0;
 }
 
@@ -1264,6 +1607,23 @@
 		return put_user(SNDRV_TIMER_VERSION, (int *)arg) ? -EFAULT : 0;
 	case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
 		return snd_timer_user_next_device((snd_timer_id_t *)arg);
+	case SNDRV_TIMER_IOCTL_TREAD:
+	{
+		int xarg;
+		
+		if (tu->timeri)		/* too late */
+			return -EBUSY;
+		if (get_user(xarg, (int *) arg))
+			return -EFAULT;
+		tu->tread = xarg ? 1 : 0;
+		return 0;
+	}
+	case SNDRV_TIMER_IOCTL_GINFO:
+		return snd_timer_user_ginfo(file, (snd_timer_ginfo_t *)arg);
+	case SNDRV_TIMER_IOCTL_GPARAMS:
+		return snd_timer_user_gparams(file, (snd_timer_gparams_t *)arg);
+	case SNDRV_TIMER_IOCTL_GSTATUS:
+		return snd_timer_user_gstatus(file, (snd_timer_gstatus_t *)arg);
 	case SNDRV_TIMER_IOCTL_SELECT:
 		return snd_timer_user_tselect(file, (snd_timer_select_t *)arg);
 	case SNDRV_TIMER_IOCTL_INFO:
@@ -1297,12 +1657,13 @@
 static ssize_t snd_timer_user_read(struct file *file, char *buffer, size_t count, loff_t *offset)
 {
 	snd_timer_user_t *tu;
-	long result = 0;
+	long result = 0, unit;
 	int err = 0;
 	
 	tu = snd_magic_cast(snd_timer_user_t, file->private_data, return -ENXIO);
+	unit = tu->tread ? sizeof(snd_timer_tread_t) : sizeof(snd_timer_read_t);
 	spin_lock_irq(&tu->qlock);
-	while (count - result >= sizeof(snd_timer_read_t)) {
+	while ((long)count - result >= unit) {
 		while (!tu->qused) {
 			wait_queue_t wait;
 
@@ -1331,15 +1692,22 @@
 		if (err < 0)
 			break;
 
-		if (copy_to_user(buffer, &tu->queue[tu->qhead++], sizeof(snd_timer_read_t))) {
-			err = -EFAULT;
-			break;
+		if (tu->tread) {
+			if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], sizeof(snd_timer_tread_t))) {
+				err = -EFAULT;
+				break;
+			}
+		} else {
+			if (copy_to_user(buffer, &tu->queue[tu->qhead++], sizeof(snd_timer_read_t))) {
+				err = -EFAULT;
+				break;
+			}
 		}
 
 		tu->qhead %= tu->queue_size;
 
-		result += sizeof(snd_timer_read_t);
-		buffer += sizeof(snd_timer_read_t);
+		result += unit;
+		buffer += unit;
 
 		spin_lock_irq(&tu->qlock);
 		tu->qused--;
@@ -1442,7 +1810,9 @@
 EXPORT_SYMBOL(snd_timer_start);
 EXPORT_SYMBOL(snd_timer_stop);
 EXPORT_SYMBOL(snd_timer_continue);
+EXPORT_SYMBOL(snd_timer_pause);
 EXPORT_SYMBOL(snd_timer_new);
+EXPORT_SYMBOL(snd_timer_notify);
 EXPORT_SYMBOL(snd_timer_global_new);
 EXPORT_SYMBOL(snd_timer_global_free);
 EXPORT_SYMBOL(snd_timer_global_register);
diff -Nru a/sound/core/wrappers.c b/sound/core/wrappers.c
--- a/sound/core/wrappers.c	Tue Oct 22 07:40:03 2002
+++ b/sound/core/wrappers.c	Thu Mar 20 08:41:13 2003
@@ -49,59 +49,3 @@
 }
 #endif
 
-
-/* check the condition in <sound/core.h> !! */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
-#if defined(__i386__) || defined(__ppc__) || defined(__x86_64__)
-
-#include <linux/pci.h>
-
-/* to be sure... */
-#ifdef HACK_PCI_ALLOC_CONSISTENT
-#error pci_alloc_consistent hack is already defined!!
-#endif
-
-/*
- * A dirty hack... when the kernel code is fixed this should be removed.
- *
- * since pci_alloc_consistent always tries GFP_DMA when the requested
- * pci memory region is below 32bit, it happens quite often that even
- * 2 order of pages cannot be allocated.
- *
- * so in the following, we allocate at first without dma_mask, so that
- * allocation will be done without GFP_DMA.  if the area doesn't match
- * with the requested region, then realloate with the original dma_mask
- * again.
- */
-
-void *snd_pci_hack_alloc_consistent(struct pci_dev *hwdev, size_t size,
-				    dma_addr_t *dma_handle)
-{
-	void *ret;
-	u64 dma_mask;
-	unsigned long rmask;
-
-	if (hwdev == NULL)
-		return pci_alloc_consistent(hwdev, size, dma_handle);
-	dma_mask = hwdev->dma_mask;
-	rmask = ~((unsigned long)dma_mask);
-	hwdev->dma_mask = 0xffffffff; /* do without masking */
-	ret = pci_alloc_consistent(hwdev, size, dma_handle);
-	hwdev->dma_mask = dma_mask; /* restore */
-	if (ret) {
-		/* obtained address is out of range? */
-		if (((unsigned long)*dma_handle + size - 1) & rmask) {
-			/* reallocate with the proper mask */
-			pci_free_consistent(hwdev, size, ret, *dma_handle);
-			ret = pci_alloc_consistent(hwdev, size, dma_handle);
-		}
-	} else {
-		/* wish to success now with the proper mask... */
-		if (dma_mask != 0xffffffff)
-			ret = pci_alloc_consistent(hwdev, size, dma_handle);
-	}
-	return ret;
-}
-
-#endif
-#endif
diff -Nru a/sound/drivers/dummy.c b/sound/drivers/dummy.c
--- a/sound/drivers/dummy.c	Sat Feb  8 12:10:48 2003
+++ b/sound/drivers/dummy.c	Thu Mar 20 08:41:13 2003
@@ -54,6 +54,15 @@
 #define USE_PERIODS_MAX		2
 #endif
 
+#if 0 /* ICE1712 emulation */
+#define MAX_BUFFER_SIZE		(256 * 1024)
+#define USE_FORMATS		SNDRV_PCM_FMTBIT_S32_LE
+#define USE_CHANNELS_MIN	12
+#define USE_CHANNELS_MAX	12
+#define USE_PERIODS_MIN		1
+#define USE_PERIODS_MAX		1024
+#endif
+
 #if 0 /* UDA1341 emulation */
 #define MAX_BUFFER_SIZE		(16380)
 #define USE_FORMATS		SNDRV_PCM_FMTBIT_S16_LE
diff -Nru a/sound/drivers/mpu401/Makefile b/sound/drivers/mpu401/Makefile
--- a/sound/drivers/mpu401/Makefile	Mon Feb  3 14:19:39 2003
+++ b/sound/drivers/mpu401/Makefile	Thu Mar  6 15:28:34 2003
@@ -37,5 +37,6 @@
 obj-$(CONFIG_SND_ALI5451) += snd-mpu401-uart.o
 obj-$(CONFIG_SND_TRIDENT) += snd-mpu401-uart.o
 obj-$(CONFIG_SND_YMFPCI) += snd-mpu401-uart.o
+obj-$(CONFIG_SND_PC98_CS4232) += snd-mpu401-uart.o
 
 obj-m := $(sort $(obj-m))
diff -Nru a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
--- a/sound/drivers/mpu401/mpu401_uart.c	Mon Jan 27 11:00:12 2003
+++ b/sound/drivers/mpu401/mpu401_uart.c	Thu Mar 20 08:41:13 2003
@@ -21,6 +21,11 @@
  *   along with this program; if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  *
+ *   13-03-2003:
+ *      Added support for different kind of hardware I/O. Build in choices
+ *      are port and mmio. For other kind of I/O, set mpu->read and
+ *      mpu->write to your own I/O functions.
+ *
  */
 
 #include <sound/driver.h>
@@ -45,21 +50,43 @@
 
  */
 
-#define snd_mpu401_input_avail(mpu)	(!(inb(MPU401C(mpu)) & 0x80))
-#define snd_mpu401_output_ready(mpu)	(!(inb(MPU401C(mpu)) & 0x40))
+#define snd_mpu401_input_avail(mpu)	(!(mpu->read(mpu, MPU401C(mpu)) & 0x80))
+#define snd_mpu401_output_ready(mpu)	(!(mpu->read(mpu, MPU401C(mpu)) & 0x40))
 
 #define MPU401_RESET		0xff
 #define MPU401_ENTER_UART	0x3f
 #define MPU401_ACK		0xfe
 
+/* Build in lowlevel io */
+static void mpu401_write_port(mpu401_t *mpu, unsigned char data, unsigned long addr)
+{
+	outb(data, addr);
+}
+
+static unsigned char mpu401_read_port(mpu401_t *mpu, unsigned long addr)
+{
+	return inb(addr);
+}
+
+static void mpu401_write_mmio(mpu401_t *mpu, unsigned char data, unsigned long addr)
+{
+	writeb(data, (unsigned long*)addr);
+}
+
+static unsigned char mpu401_read_mmio(mpu401_t *mpu, unsigned long addr)
+{
+	return readb((unsigned long*)addr);
+}
+/*  */
+
 static void snd_mpu401_uart_clear_rx(mpu401_t *mpu)
 {
 	int timeout = 100000;
 	for (; timeout > 0 && snd_mpu401_input_avail(mpu); timeout--)
-		inb(MPU401D(mpu));
+		mpu->read(mpu, MPU401D(mpu));
 #ifdef CONFIG_SND_DEBUG
 	if (timeout <= 0)
-		snd_printk("cmd: clear rx timeout (status = 0x%x)\n", inb(MPU401C(mpu)));
+		snd_printk("cmd: clear rx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu)));
 #endif
 }
 
@@ -163,7 +190,7 @@
 
 	spin_lock_irqsave(&mpu->input_lock, flags);
 	if (mpu->hardware != MPU401_HW_TRID4DWAVE) {
-		outb(0x00, MPU401D(mpu));
+		mpu->write(mpu, 0x00, MPU401D(mpu));
 		/*snd_mpu401_uart_clear_rx(mpu);*/
 	}
 	/* ok. standard MPU-401 initialization */
@@ -172,28 +199,28 @@
 			udelay(10);
 #ifdef CONFIG_SND_DEBUG
 		if (!timeout)
-			snd_printk("cmd: tx timeout (status = 0x%x)\n", inb(MPU401C(mpu)));
+			snd_printk("cmd: tx timeout (status = 0x%x)\n", mpu->read(mpu, MPU401C(mpu)));
 #endif
 	}
-	outb(cmd, MPU401C(mpu));
+	mpu->write(mpu, cmd, MPU401C(mpu));
 	if (ack) {
 		ok = 0;
 		timeout = 10000;
 		while (!ok && timeout-- > 0) {
 			if (snd_mpu401_input_avail(mpu)) {
-				if (inb(MPU401D(mpu)) == MPU401_ACK)
+				if (mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK)
 					ok = 1;
 			}
 		}
-		if (!ok && inb(MPU401D(mpu)) == MPU401_ACK)
+		if (!ok && mpu->read(mpu, MPU401D(mpu)) == MPU401_ACK)
 			ok = 1;
 	} else {
 		ok = 1;
 	}
 	spin_unlock_irqrestore(&mpu->input_lock, flags);
 	if (! ok)
-		snd_printk("cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, inb(MPU401C(mpu)), inb(MPU401D(mpu)));
-	// snd_printk("cmd: 0x%x at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, inb(MPU401C(mpu)), inb(MPU401D(mpu)));
+		snd_printk("cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu)));
+	// snd_printk("cmd: 0x%x at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu)));
 }
 
 /*
@@ -275,7 +302,7 @@
 		if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) {
 			/* first time - flush FIFO */
 			while (max-- > 0)
-				inb(MPU401D(mpu));
+				mpu->read(mpu, MPU401D(mpu));
 			if (mpu->irq < 0)
 				snd_mpu401_uart_add_timer(mpu, 1);
 		}
@@ -306,7 +333,7 @@
 
 	while (max-- > 0) {
 		if (snd_mpu401_input_avail(mpu)) {
-			byte = inb(MPU401D(mpu));
+			byte = mpu->read(mpu, MPU401D(mpu));
 			if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode))
 				snd_rawmidi_receive(mpu->substream_input, &byte, 1);
 		} else {
@@ -336,7 +363,7 @@
 		if (snd_rawmidi_transmit_peek(mpu->substream_output, &byte, 1) == 1) {
 			for (timeout = 100; timeout > 0; timeout--) {
 				if (snd_mpu401_output_ready(mpu)) {
-					outb(byte, MPU401D(mpu));
+					mpu->write(mpu, byte, MPU401D(mpu));
 					snd_rawmidi_transmit_ack(mpu->substream_output, 1);
 					break;
 				}
@@ -460,6 +487,16 @@
 			return -EBUSY;
 		}
 	}
+	switch (hardware) {
+	case MPU401_HW_AUREAL:
+		mpu->write = mpu401_write_mmio;
+		mpu->read = mpu401_read_mmio;
+		break;
+	default:
+		mpu->write = mpu401_write_port;
+		mpu->read = mpu401_read_port;
+		break;
+	}
 	mpu->port = port;
 	if (hardware == MPU401_HW_PC98II)
 		mpu->cport = port + 2;
@@ -474,7 +511,10 @@
 	}
 	mpu->irq = irq;
 	mpu->irq_flags = irq_flags;
-	strcpy(rmidi->name, "MPU-401 (UART)");
+	if (card->shortname[0])
+		snprintf(rmidi->name, sizeof(rmidi->name), "%s MPU-401", card->shortname);
+	else
+		sprintf(rmidi->name, "MPU-401 (UART) %d-%d", card->number, device);
 	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mpu401_uart_output);
 	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mpu401_uart_input);
 	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
diff -Nru a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
--- a/sound/drivers/mtpav.c	Tue Feb 25 02:51:06 2003
+++ b/sound/drivers/mtpav.c	Wed Mar 19 09:22:05 2003
@@ -802,7 +802,7 @@
 
 #ifndef MODULE
 
-/* format is: snd-mtpav=snd_enable,index,id,
+/* format is: snd-mtpav=enable,index,id,
 			port,irq,hwports */
 
 static int __init alsa_card_mtpav_setup(char *str)
diff -Nru a/sound/drivers/opl3/Makefile b/sound/drivers/opl3/Makefile
--- a/sound/drivers/opl3/Makefile	Mon Feb  3 14:19:39 2003
+++ b/sound/drivers/opl3/Makefile	Thu Mar  6 15:28:34 2003
@@ -24,6 +24,7 @@
 obj-$(CONFIG_SND_OPL3SA2) += $(OPL3_OBJS)
 obj-$(CONFIG_SND_AD1816A) += $(OPL3_OBJS)
 obj-$(CONFIG_SND_CS4232) += $(OPL3_OBJS)
+obj-$(CONFIG_SND_PC98_CS4232) += $(OPL3_OBJS)
 obj-$(CONFIG_SND_CS4236) += $(OPL3_OBJS)
 obj-$(CONFIG_SND_ES1688) += $(OPL3_OBJS)
 obj-$(CONFIG_SND_GUSEXTREME) += $(OPL3_OBJS)
diff -Nru a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c
--- a/sound/drivers/opl3/opl3_oss.c	Sat Feb  8 12:10:49 2003
+++ b/sound/drivers/opl3/opl3_oss.c	Thu Mar 20 08:41:13 2003
@@ -101,7 +101,7 @@
 							  SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
 							  SNDRV_SEQ_PORT_TYPE_MIDI_GM |
 							  SNDRV_SEQ_PORT_TYPE_SYNTH,
-							  voices,
+							  voices, voices,
 							  name);
 	if (opl3->oss_chset->port < 0) {
 		snd_midi_channel_free_set(opl3->oss_chset);
diff -Nru a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c
--- a/sound/drivers/opl3/opl3_seq.c	Sat Feb  8 12:10:49 2003
+++ b/sound/drivers/opl3/opl3_seq.c	Thu Mar 20 08:41:13 2003
@@ -179,8 +179,10 @@
 {
 	snd_seq_port_callback_t callbacks;
 	char name[32];
-	int opl_ver;
+	int voices, opl_ver;
 
+	voices = (opl3->hardware < OPL3_HW_OPL3) ?
+		MAX_OPL2_VOICES : MAX_OPL3_VOICES;
 	opl3->chset = snd_midi_channel_alloc_set(16);
 	if (opl3->chset == NULL)
 		return -ENOMEM;
@@ -204,7 +206,7 @@
 						      SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
 						      SNDRV_SEQ_PORT_TYPE_MIDI_GM |
 						      SNDRV_SEQ_PORT_TYPE_SYNTH,
-						      16,
+						      16, voices,
 						      name);
 	if (opl3->chset->port < 0) {
 		snd_midi_channel_free_set(opl3->chset);
diff -Nru a/sound/isa/Kconfig b/sound/isa/Kconfig
--- a/sound/isa/Kconfig	Tue Oct 29 17:16:55 2002
+++ b/sound/isa/Kconfig	Thu Mar  6 15:28:34 2003
@@ -39,6 +39,12 @@
 	  Say 'Y' or 'M' to include support for CS4235,CS4236,CS4237B,CS4238B,CS4239
 	  chips from Cirrus Logic - Crystal Semiconductors.
 
+config SND_PC98_CS4232
+	tristate "NEC PC9800 CS4232 driver"
+	depends on SND
+	help
+	  Say 'Y' or 'M' to include support for NEC PC-9801/PC-9821 sound cards
+
 config SND_ES968
 	tristate "Generic ESS ES968 driver"
 	depends on SND && ISAPNP
diff -Nru a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
--- a/sound/isa/ad1816a/ad1816a.c	Tue Oct 22 06:04:00 2002
+++ b/sound/isa/ad1816a/ad1816a.c	Thu Mar 20 08:41:13 2003
@@ -109,8 +109,8 @@
 #define ISAPNP_AD1816A(_va, _vb, _vc, _device, _fa, _fb, _fc, _audio, _mpu401) \
 	{ \
 		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-		devs : { ISAPNP_DEVICE_ID(_fa, _fb, _fc, _audio), \
-			 ISAPNP_DEVICE_ID(_fa, _fb, _fc, _mpu401), } \
+		.devs = { ISAPNP_DEVICE_ID(_fa, _fb, _fc, _audio), \
+			  ISAPNP_DEVICE_ID(_fa, _fb, _fc, _mpu401), } \
 	}
 
 static struct isapnp_card_id snd_ad1816a_pnpids[] __devinitdata = {
diff -Nru a/sound/isa/azt2320.c b/sound/isa/azt2320.c
--- a/sound/isa/azt2320.c	Tue Oct 22 06:04:00 2002
+++ b/sound/isa/azt2320.c	Thu Mar 20 08:41:13 2003
@@ -125,8 +125,8 @@
 #define ISAPNP_AZT2320(_va, _vb, _vc, _device, _audio, _mpu401) \
 	{ \
 		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-		devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), \
-			 ISAPNP_DEVICE_ID(_va, _vb, _vc, _mpu401), } \
+		.devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), \
+			  ISAPNP_DEVICE_ID(_va, _vb, _vc, _mpu401), } \
 	}
 
 static struct isapnp_card_id snd_azt2320_pnpids[] __devinitdata = {
diff -Nru a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
--- a/sound/isa/cmi8330.c	Sat Feb  8 12:10:50 2003
+++ b/sound/isa/cmi8330.c	Thu Mar 20 08:41:13 2003
@@ -30,7 +30,7 @@
  *
  *  To quickly load the module,
  *
- *  modprobe -a snd-card-cmi8330 sbport=0x220 sbirq=5 sbdma8=1
+ *  modprobe -a snd-cmi8330 sbport=0x220 sbirq=5 sbdma8=1
  *    sbdma16=5 wssport=0x530 wssirq=11 wssdma=0
  *
  *  This card has two mixers and two PCM devices.  I've cheesed it such
@@ -182,8 +182,8 @@
 #define ISAPNP_CMI8330(_va, _vb, _vc, _device, _audio1, _audio2) \
 	{ \
 		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-		devs : { ISAPNP_DEVICE_ID('@', '@', '@', _audio1), \
-			 ISAPNP_DEVICE_ID('@', 'X', '@', _audio2), } \
+		.devs = { ISAPNP_DEVICE_ID('@', '@', '@', _audio1), \
+			  ISAPNP_DEVICE_ID('@', 'X', '@', _audio2), } \
 	}
 
 static struct isapnp_card_id snd_cmi8330_pnpids[] __devinitdata =
diff -Nru a/sound/isa/cs423x/Makefile b/sound/isa/cs423x/Makefile
--- a/sound/isa/cs423x/Makefile	Mon Feb  3 14:19:39 2003
+++ b/sound/isa/cs423x/Makefile	Thu Mar  6 15:28:34 2003
@@ -8,6 +8,7 @@
 snd-cs4231-objs := cs4231.o
 snd-cs4232-objs := cs4232.o
 snd-cs4236-objs := cs4236.o
+snd-pc98-cs4232-objs := pc98.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_AZT2320) += snd-cs4231-lib.o
@@ -20,5 +21,6 @@
 obj-$(CONFIG_SND_INTERWAVE_STB) += snd-cs4231-lib.o
 obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-cs4231-lib.o
 obj-$(CONFIG_SND_WAVEFRONT) += snd-cs4231-lib.o
+obj-$(CONFIG_SND_PC98_CS4232) += snd-pc98-cs4232.o snd-cs4231-lib.o
 
 obj-m := $(sort $(obj-m))
diff -Nru a/sound/isa/cs423x/pc98.c b/sound/isa/cs423x/pc98.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/sound/isa/cs423x/pc98.c	Thu Mar 20 10:43:51 2003
@@ -0,0 +1,466 @@
+/*
+ *  Driver for CS4232 on NEC PC9800 series
+ *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ *                   Osamu Tomita <tomita@cinet.co.jp>
+ *                   Takashi Iwai <tiwai@suse.de>
+ *
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <sound/driver.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/cs4231.h>
+#include <sound/mpu401.h>
+#include <sound/opl3.h>
+#define SNDRV_GET_ID
+#include <sound/initval.h>
+#include "sound_pc9800.h"
+
+#define chip_t cs4231_t
+
+MODULE_AUTHOR("Osamu Tomita <tomita@cinet.co.jp>");
+MODULE_LICENSE("GPL");
+MODULE_CLASSES("{sound}");
+MODULE_DESCRIPTION("NEC PC9800 CS4232");
+MODULE_DEVICES("{{NEC,PC9800}}");
+
+#define IDENT "PC98-CS4232"
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
+static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* PnP setup */
+#if 0 /* NOT USED */
+static long cport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* PnP setup */
+#endif
+static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;/* PnP setup */
+static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* PnP setup */
+static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* 5,7,9,11,12,15 */
+static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* 9,11,12,15 */
+static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;	/* 0,1,3,5,6,7 */
+static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;	/* 0,1,3,5,6,7 */
+static int pc98ii[SNDRV_CARDS];				/* PC98II */
+
+MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(index, "Index value for " IDENT " soundcard.");
+MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
+MODULE_PARM(id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
+MODULE_PARM_DESC(id, "ID string for " IDENT " soundcard.");
+MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
+MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(enable, "Enable " IDENT " soundcard.");
+MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
+MODULE_PARM(port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
+MODULE_PARM_DESC(port, "Port # for " IDENT " driver.");
+MODULE_PARM_SYNTAX(port, SNDRV_PORT12_DESC);
+#if 0 /* NOT USED */
+MODULE_PARM(cport, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
+MODULE_PARM_DESC(cport, "Control port # for " IDENT " driver.");
+MODULE_PARM_SYNTAX(cport, SNDRV_PORT12_DESC);
+#endif
+MODULE_PARM(mpu_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
+MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " IDENT " driver.");
+MODULE_PARM_SYNTAX(mpu_port, SNDRV_PORT12_DESC);
+MODULE_PARM(fm_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
+MODULE_PARM_DESC(fm_port, "FM port # for " IDENT " driver.");
+MODULE_PARM_SYNTAX(fm_port, SNDRV_PORT12_DESC);
+MODULE_PARM(irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(irq, "IRQ # for " IDENT " driver.");
+MODULE_PARM_SYNTAX(irq, SNDRV_IRQ_DESC);
+MODULE_PARM(mpu_irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " IDENT " driver.");
+MODULE_PARM_SYNTAX(mpu_irq, SNDRV_IRQ_DESC);
+MODULE_PARM(dma1, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(dma1, "DMA1 # for " IDENT " driver.");
+MODULE_PARM_SYNTAX(dma1, SNDRV_DMA_DESC);
+MODULE_PARM(dma2, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
+MODULE_PARM_SYNTAX(dma2, SNDRV_DMA_DESC);
+MODULE_PARM(pc98ii, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(pc98ii, "Roland MPU-PC98II support.");
+MODULE_PARM_SYNTAX(pc98ii, SNDRV_BOOLEAN_FALSE_DESC);
+
+
+static snd_card_t *snd_pc98_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+
+/*
+ * initialize MPU401-UART
+ */
+
+static int __init pc98_mpu401_init(int irq)
+{
+#include "pc9801_118_magic.h"
+#define outp118(reg,data) outb((reg),0x148e);outb((data),0x148f)
+#define WAIT118 outb(0x00,0x5f)
+	int	mpu_intr, count;
+#ifdef OOKUBO_ORIGINAL
+	int	err = 0;
+#endif /* OOKUBO_ORIGINAL */
+
+	switch (irq) {
+	case 3:
+		mpu_intr = 3;
+		break;
+	case 5:
+		mpu_intr = 2;
+		break;
+	case 6:
+		mpu_intr = 1;
+		break;
+	case 10:
+		mpu_intr = 0;
+		break;
+	default:
+		snd_printk(KERN_ERR IDENT ": Bad IRQ %d\n", irq);
+		return -EINVAL;
+	}
+
+	outp118(0x21, mpu_intr);
+	WAIT118;
+	outb(0x00, 0x148e);
+	if (inb(0x148f) & 0x08) {
+		snd_printk(KERN_INFO IDENT ": No MIDI daughter board found\n");
+		return 0;
+	}
+
+	outp118(0x20, 0x00);
+	outp118(0x05, 0x04);
+	for (count = 0; count < 35000; count ++)
+		WAIT118;
+	outb(0x05, 0x148e);
+	for (count = 0; count < 65000; count ++)
+		if (inb(0x148f) == 0x04)
+			goto set_mode_118;
+	snd_printk(KERN_ERR IDENT ": MIDI daughter board initialize failed at stage1\n\n");
+	return -EINVAL;
+
+ set_mode_118:
+	outp118(0x05, 0x0c);
+	outb(0xaa, 0x485);
+	outb(0x99, 0x485);
+	outb(0x2a, 0x485);
+	for (count = 0; count < sizeof(Data0485_99); count ++) {
+		outb(Data0485_99[count], 0x485);
+		WAIT118;
+	}
+
+	outb(0x00, 0x486);
+	outb(0xaa, 0x485);
+	outb(0x9e, 0x485);
+	outb(0x2a, 0x485);
+	for (count = 0; count < sizeof(Data0485_9E); count ++)
+		if (inb(0x485) != Data0485_9E[count]) {
+#ifdef OOKUBO_ORIGINAL
+			err = 1;
+#endif /* OOKUBO_ORIGINAL */
+			break;
+		}
+	outb(0x00, 0x486);
+	for (count = 0; count < 2000; count ++)
+		WAIT118;
+#ifdef OOKUBO_ORIGINAL
+	if (!err) {
+		outb(0xaa, 0x485);
+		outb(0x36, 0x485);
+		outb(0x28, 0x485);
+		for (count = 0; count < sizeof(Data0485_36); count ++)
+			outb(Data0485_36[count], 0x485);
+		outb(0x00, 0x486);
+		for (count = 0; count < 1500; count ++)
+			WAIT118;
+		outp118(0x05, inb(0x148f) | 0x08);
+		outb(0xff, 0x148c);
+		outp118(0x05, inb(0x148f) & 0xf7);
+		for (count = 0; count < 1500; count ++)
+			WAIT118;
+	}
+#endif /* OOKUBO_ORIGINAL */
+
+	outb(0xaa, 0x485);
+	outb(0xa9, 0x485);
+	outb(0x21, 0x485);
+	for (count = 0; count < sizeof(Data0485_A9); count ++) {
+		outb(Data0485_A9[count], 0x485);
+		WAIT118;
+	}
+
+	outb(0x00, 0x486);
+	outb(0xaa, 0x485);
+	outb(0x0c, 0x485);
+	outb(0x20, 0x485);
+	for (count = 0; count < sizeof(Data0485_0C); count ++) {
+		outb(Data0485_0C[count], 0x485);
+		WAIT118;
+	}
+
+	outb(0x00, 0x486);
+	outb(0xaa, 0x485);
+	outb(0x66, 0x485);
+	outb(0x20, 0x485);
+	for (count = 0; count < sizeof(Data0485_66); count ++) {
+		outb(Data0485_66[count], 0x485);
+		WAIT118;
+	}
+
+	outb(0x00, 0x486);
+	outb(0xaa, 0x485);
+	outb(0x60, 0x485);
+	outb(0x20, 0x485);
+	for (count = 0; count < sizeof(Data0485_60); count ++) {
+		outb(Data0485_60[count], 0x485);
+		WAIT118;
+	}
+
+	outb(0x00, 0x486);
+	outp118(0x05, 0x04);
+	outp118(0x05, 0x00);
+	for (count = 0; count < 35000; count ++)
+		WAIT118;
+	outb(0x05, 0x148e);
+	for (count = 0; count < 65000; count ++)
+		if (inb(0x148f) == 0x00)
+			goto end_mode_118;
+	snd_printk(KERN_ERR IDENT ": MIDI daughter board initialize failed at stage2\n");
+	return -EINVAL;
+
+ end_mode_118:
+	outb(0x3f, 0x148d);
+	snd_printk(KERN_INFO IDENT ": MIDI daughter board initialized\n");
+	return 0;
+}
+
+static int __init pc98_cs4231_chip_init(int dev)
+{
+	int intr_bits, intr_bits2, dma_bits;
+
+	switch (irq[dev]) {
+	case 3:
+		intr_bits = 0x08;
+		intr_bits2 = 0x03;
+		break;
+	case 5:
+		intr_bits = 0x10;
+		intr_bits2 = 0x08;
+		break;
+	case 10:
+		intr_bits = 0x18;
+		intr_bits2 = 0x02;
+		break;
+	case 12:
+		intr_bits = 0x20;
+		intr_bits2 = 0x00;
+		break;
+	default:
+		snd_printk(KERN_ERR IDENT ": Bad IRQ %d\n", irq[dev]);
+		return -EINVAL;
+	}
+
+	switch (dma1[dev]) {
+	case 0:
+		dma_bits = 0x01;
+		break;
+	case 1:
+		dma_bits = 0x02;
+		break;
+	case 3:
+		dma_bits = 0x03;
+		break;
+	default:
+		snd_printk(KERN_ERR IDENT ": Bad DMA %d\n", dma1[dev]);
+		return -EINVAL;
+	}
+
+	if (dma2[dev] >= 2) {
+		snd_printk(KERN_ERR IDENT ": Bad DMA %d\n", dma2[dev]);
+		return -EINVAL;
+	}
+	if (dma1[dev] != dma2[dev] && dma2[dev] >= 0)
+		intr_bits |= 0x04;
+
+	if (PC9800_SOUND_ID() == PC9800_SOUND_ID_118) {
+		/* Set up CanBe control registers. */
+		snd_printd(KERN_INFO "Setting up CanBe Sound System\n");
+		outb(inb(PC9800_SOUND_IO_ID) | 0x03, PC9800_SOUND_IO_ID);
+		outb(0x01, 0x0f4a);
+		outb(intr_bits2, 0x0f4b);
+	}
+
+	outb(intr_bits | dma_bits, 0xf40);
+	return 0;
+}
+
+
+static int __init snd_card_pc98_probe(int dev)
+{
+	snd_card_t *card;
+	snd_pcm_t *pcm = NULL;
+	cs4231_t *chip;
+	opl3_t *opl3;
+	int err;
+
+	if (port[dev] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR IDENT ": specify port\n");
+		return -EINVAL;
+	}
+	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	if (card == NULL)
+		return -ENOMEM;
+	if (mpu_port[dev] < 0 || mpu_irq[dev] < 0)
+		mpu_port[dev] = SNDRV_AUTO_PORT;
+	if (fm_port[dev] < 0)
+		fm_port[dev] = SNDRV_AUTO_PORT;
+
+	if ((err = pc98_cs4231_chip_init(dev)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	if ((err = snd_cs4231_create(card,
+				     port[dev],
+				     -1,
+				     irq[dev],
+				     dma1[dev],
+				     dma2[dev],
+				     CS4231_HW_DETECT,
+				     0,
+				     &chip)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	if ((err = snd_cs4231_mixer(chip)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	if (fm_port[dev] != SNDRV_AUTO_PORT) {
+		/* ??? */
+		outb(0x00, fm_port[dev] + 6);
+		inb(fm_port[dev] + 7);
+		/* Enable OPL-3 Function */
+		outb(inb(PC9800_SOUND_IO_ID) | 0x03, PC9800_SOUND_IO_ID);
+		if (snd_opl3_create(card,
+				    fm_port[dev], fm_port[dev] + 2,
+				    OPL3_HW_OPL3_PC98, 0, &opl3) < 0) {
+			printk(KERN_ERR IDENT ": OPL3 not detected\n");
+		} else {
+			if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+				snd_card_free(card);
+				return err;
+			}
+		}
+	}
+
+	if (mpu_port[dev] != SNDRV_AUTO_PORT) {
+		err = pc98_mpu401_init(mpu_irq[dev]);
+		if (! err) {
+			err = snd_mpu401_uart_new(card, 0,
+						  pc98ii[dev] ? MPU401_HW_PC98II : MPU401_HW_MPU401,
+						  mpu_port[dev], 0,
+						  mpu_irq[dev], SA_INTERRUPT, NULL);
+			if (err < 0)
+				snd_printk(KERN_INFO IDENT ": MPU401 not detected\n");
+		}
+	}
+
+	strcpy(card->driver, pcm->name);
+	strcpy(card->shortname, pcm->name);
+	sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i",
+		pcm->name,
+		chip->port,
+		irq[dev],
+		dma1[dev]);
+	if (dma1[dev] >= 0)
+		sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
+	if ((err = snd_card_register(card)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	snd_pc98_cards[dev] = card;
+	return 0;
+}
+
+static int __init alsa_card_pc98_init(void)
+{
+	int dev, cards = 0;
+
+	for (dev = 0; dev < SNDRV_CARDS; dev++) {
+		if (!enable[dev])
+			continue;
+		if (snd_card_pc98_probe(dev) >= 0)
+			cards++;
+	}
+	if (!cards) {
+#ifdef MODULE
+		printk(KERN_ERR IDENT " soundcard not found or device busy\n");
+#endif
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static void __exit alsa_card_pc98_exit(void)
+{
+	int idx;
+
+	for (idx = 0; idx < SNDRV_CARDS; idx++)
+		snd_card_free(snd_pc98_cards[idx]);
+}
+
+module_init(alsa_card_pc98_init)
+module_exit(alsa_card_pc98_exit)
+
+#ifndef MODULE
+
+/* format is: snd-pc98-cs4232=enable,index,id,port,
+			 mpu_port,fm_port,
+			 irq,mpu_irq,dma1,dma2,pc98ii */
+
+static int __init alsa_card_pc98_setup(char *str)
+{
+	static unsigned __initdata nr_dev = 0;
+
+	if (nr_dev >= SNDRV_CARDS)
+		return 0;
+	(void)(get_option(&str,&enable[nr_dev]) == 2 &&
+	       get_option(&str,&index[nr_dev]) == 2 &&
+	       get_id(&str,&id[nr_dev]) == 2 &&
+	       get_option(&str,(int *)&port[nr_dev]) == 2 &&
+	       get_option(&str,(int *)&mpu_port[nr_dev]) == 2 &&
+	       get_option(&str,(int *)&fm_port[nr_dev]) == 2 &&
+	       get_option(&str,&irq[nr_dev]) == 2 &&
+	       get_option(&str,&mpu_irq[nr_dev]) == 2 &&
+	       get_option(&str,&dma1[nr_dev]) == 2 &&
+	       get_option(&str,&dma2[nr_dev]) == 2 &&
+	       get_option(&str,&pc98ii[nr_dev]) == 2);
+	nr_dev++;
+	return 1;
+}
+
+__setup("snd-pc98-cs4232=", alsa_card_pc98_setup);
+
+#endif /* ifndef MODULE */
diff -Nru a/sound/isa/cs423x/pc9801_118_magic.h b/sound/isa/cs423x/pc9801_118_magic.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/sound/isa/cs423x/pc9801_118_magic.h	Thu Mar  6 15:28:34 2003
@@ -0,0 +1,411 @@
+		static unsigned char	Data0485_A9[] = {
+		0x12, 0x03, 0x90, 0xc2, 0x2a, 0x75, 0x1e, 0x20,
+		0xe4, 0x12, 0x2b, 0x9b, 0x22, 0xa9, 0x16, 0x77,
+		0x33, 0xe9, 0x04, 0x54, 0x03, 0x44, 0xa8, 0xf5,
+		0x16, 0xc2, 0x2f, 0x22, 0xa9, 0x16, 0x77, 0x42,
+		0xe9, 0x04, 0x54, 0x03, 0x44, 0xa8, 0xf9, 0x77,
+		0xf8, 0x04, 0x54, 0x03, 0x44, 0xa8, 0xf5, 0x16,
+		0xc2, 0x2f, 0x22, 0x90, 0x25, 0x9f, 0x30, 0x04,
+		0x05, 0xc2, 0x04, 0x12, 0x1f, 0x62, 0x30, 0x00,
+		0x05, 0xc2, 0x00, 0x12, 0x15, 0xe6, 0x30, 0x01,
+		0x05, 0xc2, 0x01, 0x12, 0x29, 0xaf, 0x30, 0x02,
+		0x05, 0xc2, 0x02, 0x12, 0x29, 0xaf, 0x30, 0x05,
+		0x05, 0xc2, 0x05, 0x12, 0x16, 0x65, 0x30, 0x06,
+		0x08, 0xc2, 0x06, 0x12, 0x16, 0xb1, 0x12, 0x29,
+		0xaf, 0x30, 0x07, 0x08, 0xc2, 0x07, 0x12, 0x16,
+		0xe9, 0x12, 0x29, 0xaf, 0x22, 0x20, 0x97, 0x09,
+		0x53, 0xa8, 0xfb, 0x12, 0x04, 0x2c, 0x43, 0xa8,
+		0x04, 0x22, 0x71, 0xb8, 0x71, 0xb8, 0x71, 0xb8,
+		0x22, 0x20, 0x4b, 0x04, 0x75, 0x4e, 0x02, 0x22,
+		0xe5, 0x35, 0x24, 0xff, 0xf5, 0x35, 0xe5, 0x36,
+		0x34, 0xff, 0xf5, 0x36, 0x75, 0x4e, 0x02, 0x22,
+		0x10, 0x19, 0x02, 0x80, 0x08, 0x78, 0x00, 0xe2,
+		0x78, 0x07, 0xf2, 0x61, 0x9b, 0x78, 0x11, 0xe2,
+		0xc0, 0x01, 0xc0, 0xf0, 0xc0, 0xd0, 0xc0, 0x02,
+		0x71, 0x14, 0xe5, 0x30, 0xb4, 0x01, 0x02, 0x61,
+		0x93, 0x43, 0x08, 0x40, 0x12, 0x2a, 0x53, 0x61,
+		0x93, 0x79, 0x03, 0xe3, 0xa2, 0xe2, 0x92, 0x26,
+		0xa2, 0xe3, 0x92, 0x27, 0x22, 0xad, 0x2b, 0xbd,
+		0x04, 0x07, 0xf5, 0x72, 0x78, 0x27, 0x02, 0x11,
+		0x76, 0x02, 0x11, 0x30, 0x00, 0x00, 0x00, 0x12,
+		0x28, 0xba, 0x79, 0x01, 0xe3, 0x75, 0x21, 0x3f,
+		0x75, 0x49, 0x11, 0x75, 0x4c, 0x11, 0x31, 0xdc,
+		0x75, 0x1a, 0x80, 0x51, 0x72, 0x75, 0x81, 0xe3,
+		0x12, 0x25, 0xc9, 0x43, 0xa8, 0x01, 0x00, 0x53,
+		0xa8, 0xfe, 0x10, 0x50, 0x02, 0x80, 0x03, 0x12,
+		0x1a, 0x8d, 0xd1, 0x28, 0x12, 0x03, 0xd9, 0xd1,
+		0xf2, 0x12, 0x2d, 0xf0, 0xb0, 0x11, 0x92, 0xe0,
+		0xa2, 0x2a, 0xa0, 0xb5, 0x82, 0xe0, 0x50, 0x03,
+		0x79, 0x0f, 0xe3, 0x71, 0xca, 0x51, 0x1e, 0x91,
+		0xe4, 0x53, 0xa8, 0xfb, 0x10, 0x10, 0x02, 0x80,
+		0x26, 0xc2, 0x8e, 0xd2, 0xab, 0xa2, 0x1c, 0x40,
+		0x13, 0xa2, 0x1d, 0x50, 0x0a, 0x43, 0x08, 0x40,
+		0x12, 0x1a, 0x01, 0xd1, 0xd7, 0x80, 0x0b, 0x12,
+		0x26, 0x04, 0x61, 0x08, 0x43, 0x08, 0x40, 0x12,
+		0x1a, 0x01, 0xd2, 0x1f, 0x12, 0x17, 0x7f, 0x43,
+		0xa8, 0x04, 0x51, 0x1e, 0x91, 0xe4, 0x12, 0x13,
+		0x34, 0x80, 0x98, 0xa2, 0x17, 0x72, 0x16, 0x72,
+		0x15, 0x72, 0x2d, 0x50, 0x06, 0xfa, 0x12, 0x13,
+		0x66, 0x80, 0x25, 0xc2, 0x13, 0x30, 0x28, 0x05,
+		0x12, 0x02, 0xbe, 0x80, 0x1b, 0xb4, 0x10, 0x12,
+		0x78, 0x00, 0xf2, 0xe5, 0x30, 0xb4, 0x01, 0x06,
+		0x12, 0x03, 0x90, 0xd2, 0x19, 0x22, 0x12, 0x00,
+		0xdd, 0x22, 0x75, 0x30, 0x00, 0x12, 0x00, 0xa1,
+		0x22, 0x00, 0x00, 0x75, 0x1e, 0x00, 0x74, 0x0c,
+		0x12, 0x2b, 0x9b, 0x74, 0x40, 0x79, 0x05, 0xf3,
+		0x74, 0x49, 0x12, 0x2b, 0x9b, 0x74, 0x04, 0x79,
+		0x05, 0xf3, 0x75, 0x15, 0x04, 0x74, 0x10, 0x12,
+		0x2b, 0x9b, 0x74, 0x00, 0x79, 0x05, 0xf3, 0x74,
+		0x17, 0x12, 0x2b, 0x9b, 0x74, 0x00, 0x79, 0x05,
+		0xf3, 0x74, 0x1a, 0x12, 0x2b, 0x9b, 0x74, 0x00,
+		0x79, 0x05, 0xf3, 0x74, 0x0a, 0x12, 0x2b, 0x9b,
+		0x74, 0x20, 0x79, 0x05, 0xf3, 0x79, 0xe0, 0x77,
+		0x20, 0x22, 0xd0, 0x02, 0xd0, 0xd0, 0xd0, 0xf0,
+		0xd0, 0x01, 0xe5, 0x5f, 0xd0, 0xa8, 0x22, 0x00,
+		0x00, 0x90, 0x25, 0x9f, 0x75, 0x26, 0xff, 0x75,
+		0x27, 0xff, 0x75, 0x28, 0x03, 0x75, 0x13, 0xff,
+		0x75, 0x1f, 0x00, 0x75, 0x14, 0xff, 0x22, 0x79,
+		0x06, 0xe5, 0x29, 0x60, 0x0b, 0xe3, 0x30, 0xe1,
+		0xf8, 0xe5, 0x4f, 0x64, 0x80, 0x79, 0x07, 0xf3,
+		0x22, 0x10, 0x4c, 0x01, 0x22, 0x30, 0x4b, 0x0a,
+		0xc2, 0x4b, 0xe5, 0x4d, 0x64, 0x80, 0xf5, 0x4f,
+		0x80, 0x1d, 0xe5, 0x15, 0xa2, 0xe0, 0x82, 0xe6,
+		0x40, 0x02, 0x80, 0x35, 0x30, 0x4a, 0x04, 0xb1,
+		0xe6, 0x80, 0x0c, 0x30, 0x49, 0x04, 0x51, 0x2b,
+		0x80, 0x05, 0x30, 0x48, 0x24, 0x91, 0x7e, 0x79,
+		0x06, 0xe3, 0x30, 0xe0, 0x1a, 0x79, 0x06, 0xf3,
+		0xe5, 0x4e, 0x24, 0xff, 0x50, 0x04, 0xf5, 0x4e,
+		0x80, 0x0d, 0x79, 0x0f, 0xf3, 0x20, 0x2a, 0x07,
+		0x12, 0x2b, 0x32, 0x75, 0x29, 0x00, 0x22, 0x91,
+		0x1b, 0x22, 0x79, 0x0f, 0xe3, 0xc0, 0xa8, 0x75,
+		0xa8, 0x00, 0x30, 0x2b, 0x03, 0xd0, 0xa8, 0x22,
+		0x79, 0x0e, 0xf3, 0xd0, 0xa8, 0x22, 0x8a, 0xf0,
+		0xe5, 0x50, 0x10, 0xf3, 0x10, 0x23, 0x23, 0x23,
+		0x25, 0xf0, 0x12, 0x2c, 0xb8, 0xa2, 0xe7, 0x92,
+		0xe4, 0xc2, 0xe7, 0x80, 0x08, 0x23, 0x23, 0x23,
+		0x25, 0xf0, 0x12, 0x2c, 0x19, 0x25, 0x4f, 0x20,
+		0xd2, 0x04, 0xf5, 0x4f, 0x80, 0x0a, 0x40, 0x05,
+		0x75, 0x4f, 0x7f, 0x80, 0x03, 0x75, 0x4f, 0xff,
+		0xea, 0x12, 0x2c, 0x3c, 0x25, 0x50, 0x20, 0xe7,
+		0x05, 0xb4, 0x03, 0x07, 0x80, 0x0c, 0x75, 0x50,
+		0x00, 0x80, 0x09, 0x40, 0x05, 0x75, 0x50, 0x03,
+		0x80, 0x02, 0xf5, 0x50, 0x22, 0xe5, 0x4d, 0xc4,
+		0x54, 0x0c, 0x03, 0x03, 0xfa, 0x91, 0xa9, 0x71,
+		0xb8, 0xe5, 0x4d, 0xc4, 0x54, 0x03, 0xfa, 0x91,
+		0xa9, 0x71, 0xb8, 0xe5, 0x4d, 0x54, 0x0c, 0x03,
+		0x03, 0xfa, 0x91, 0xa9, 0x71, 0xb8, 0xe5, 0x4d,
+		0x54, 0x03, 0xfa, 0x91, 0xa9, 0x71, 0xb8, 0x22,
+		0x8a, 0xf0, 0xe5, 0x50, 0x23, 0x23, 0x25, 0xf0,
+		0x12, 0x2b, 0xf6, 0x25, 0x4f, 0x20, 0xd2, 0x04,
+		0xf5, 0x4f, 0x80, 0x0a, 0x40, 0x05, 0x75, 0x4f,
+		0x7f, 0x80, 0x03, 0x75, 0x4f, 0xff, 0xea, 0x12,
+		0x2c, 0x40, 0x25, 0x50, 0x20, 0xe7, 0x05, 0xb4,
+		0x05, 0x07, 0x80, 0x0c, 0x75, 0x50, 0x00, 0x80,
+		0x09, 0x40, 0x05, 0x75, 0x50, 0x05, 0x80, 0x02,
+		0xf5, 0x50, 0x22, 0x30, 0x26, 0x03, 0x12, 0x1e,
+		0xf5, 0x30, 0x27, 0x03, 0x12, 0x1f, 0x37, 0x30,
+		0x25, 0x09, 0x12, 0x1f, 0x4e, 0x30, 0x23, 0x03,
+		0x12, 0x1f, 0x1e, 0x10, 0x22, 0x02, 0x80, 0x0a,
+		0xe5, 0x3b, 0xb4, 0xff, 0x02, 0xc2, 0x20, 0x12,
+		0x1e, 0x79, 0x22, 0x78, 0x11, 0xe2, 0x20, 0xe0,
+		0x07, 0xc0, 0x01, 0x12, 0x28, 0xba, 0xd0, 0x01,
+		0x78, 0x00, 0xf2, 0x61, 0x9b, 0x12, 0x2b, 0x32,
+		0x12, 0x17, 0x7f, 0x78, 0x00, 0xf2, 0xaa, 0x35,
+		0xab, 0x36, 0xea, 0x24, 0xff, 0xfa, 0xeb, 0x34,
+		0xff, 0xfb, 0x50, 0x03, 0xd2, 0x10, 0x22, 0x75,
+		0x37, 0x01, 0x75, 0x38, 0x00, 0x75, 0x39, 0x00,
+		0x12, 0x04, 0x04, 0xd2, 0x8e, 0x22, 0xa8, 0x2b,
+		0xb8, 0x00, 0x02, 0x80, 0x03, 0x02, 0x11, 0xbd,
+		0xf5, 0x74, 0x78, 0x2a, 0x12, 0x11, 0xec, 0xe5,
+		0x74, 0x78, 0x29, 0x12, 0x11, 0xec, 0x22, 0xfa,
+		0xe5, 0x2b, 0x60, 0x01, 0x22, 0xea, 0x78, 0x2b,
+		0xf5, 0x75, 0x12, 0x11, 0xec, 0x22, 0x74, 0x10,
+		0x12, 0x2b, 0x9b, 0x74, 0x20, 0x78, 0x05, 0xf2,
+		0x74, 0x09, 0x12, 0x17, 0x75, 0xe5, 0x15, 0x44,
+		0x80, 0x79, 0x05, 0xf3, 0xf5, 0x15, 0x12, 0x17,
+		0x7f, 0x22, 0x12, 0x03, 0x84, 0x79, 0x0f, 0xe3,
+		0x78, 0x00, 0xf2, 0x12, 0x2b, 0x28, 0xe5, 0x81,
+		0x24, 0xfc, 0xf5, 0x81, 0x61, 0x93, 0xd2, 0x07,
+		0x78, 0x11, 0xe2, 0x44, 0x11, 0xf5, 0x4c, 0xc2,
+		0x0f, 0x12, 0x29, 0xa3, 0x61, 0x93, 0x02, 0x1b,
+		0x77, 0x00, 0xe1, 0x81, 0xe1, 0x9a, 0xd2, 0x2c,
+		0xa1, 0x0c, 0x20, 0x20, 0x02, 0xd2, 0x26, 0x02,
+		0x1e, 0x35, 0x02, 0x1e, 0x61, 0x02, 0x1d, 0x8f,
+		0xc2, 0x8e, 0x75, 0xa8, 0x9e, 0x22, 0x41, 0x49,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x02, 0x29, 0x91, 0x00, 0x00, 0x00, 0xa1, 0xbb,
+		0xa1, 0xc3, 0x02, 0x1e, 0x6b, 0xe5, 0x4d, 0xc4,
+		0x54, 0x0f, 0xfa, 0x91, 0x2f, 0x71, 0xb8, 0xe5,
+		0x4d, 0x54, 0x0f, 0xfa, 0x91, 0x2f, 0x71, 0xb8,
+		0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xc6,
+		0x02, 0x1d, 0x8f, 0xc2, 0x8e, 0xd2, 0xab, 0xc2,
+		0x10, 0x79, 0x0f, 0xf3, 0x22, 0x00, 0x02, 0x2a,
+		0x84, 0x00, 0xe1, 0xbc, 0xe1, 0xc8, 0x02, 0x1e,
+		0x27, 0x00, 0x78, 0x00, 0xf2, 0x78, 0x0b, 0xe2,
+		0xf4, 0xf5, 0x4d, 0xd2, 0x4c, 0x61, 0x9b, 0x30,
+		0xb5, 0x02, 0xc2, 0x11, 0x22, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x79, 0xbd, 0xf1, 0x3d, 0x83,
+		0x22, 0xdd, 0xbd, 0xbd, 0xbd, 0x61, 0xbd, 0x8d,
+		0x7a, 0xbd, 0xbd, 0xbd, 0xbd, 0x30, 0xbd, 0xbd,
+		0xbd, 0x55, 0xbd, 0xbd, 0xbd, 0x52, 0xbd, 0xb6,
+		0xb6, 0xbd, 0xbd, 0xbd, 0xbd, 0x00, 0xbd, 0xbd,
+		0xbd, 0xe8, 0xda, 0xbd, 0xbd, 0xcf, 0xb9, 0xbd,
+		0xc4, 0xf1, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
+		0xbd, 0x7b, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
+		0xbd, 0x70, 0x6a, 0x57, 0x47, 0x34, 0xbd, 0xbd,
+		0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0x29, 0xbd,
+		0xbd, 0xbd, 0xb6, 0xb6, 0xbd, 0xbd, 0xbd, 0xbd,
+		0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0x2e, 0x25,
+		0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xfe, 0xf5,
+		0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0x19, 0xbd,
+		0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0x21, 0x8f,
+		0x09, 0xbd, 0xf9, 0x86, 0xbd, 0xbd, 0xbd, 0xd7,
+		0xbd, 0xa9, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0x9b,
+		0xd1, 0x9d, 0xbd, 0xae, 0xbd, 0xbd, 0xbd, 0xcb,
+		0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
+		0xb6, 0xa5, 0xbd, 0xc5, 0xbd, 0xbd, 0xbd, 0xc3,
+		0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0x74, 0x10,
+		0x12, 0x2b, 0x9b, 0xe4, 0x78, 0x05, 0xf2, 0x74,
+		0x09, 0x12, 0x17, 0x75, 0xe5, 0x15, 0x54, 0x7f,
+		0x79, 0x05, 0xf3, 0xf5, 0x15, 0x12, 0x17, 0x7f,
+		0x22, 0x30, 0x51, 0x01, 0x22, 0x53, 0xa8, 0xfb,
+		0x12, 0x2d, 0xf0, 0x50, 0x22, 0x79, 0x03, 0xe3,
+		0x20, 0xe4, 0x1c, 0xaa, 0x35, 0xab, 0x36, 0xea,
+		0x24, 0xf0, 0xfa, 0xeb, 0x34, 0xff, 0xfb, 0x50,
+		0x0e, 0x10, 0x1f, 0x02, 0x80, 0x09, 0x20, 0x2a,
+		0x03, 0x12, 0x2b, 0x32, 0x12, 0x2d, 0xd6, 0x43,
+		0xa8, 0x04, 0x22, 0xa2, 0x1c, 0x72, 0x1d, 0x40,
+		0x07, 0x53, 0x08, 0xbf, 0x78, 0x00, 0xf2, 0x22,
+		0xb1, 0x1e, 0x22, 0x00, 0x79, 0x02, 0x12, 0x27,
+		0x3d, 0x02, 0x2d, 0x37, 0x14, 0x54, 0xf0, 0x60,
+		0x21, 0xe5, 0xf0, 0x24, 0xb6, 0xe5, 0xf0, 0x50,
+		0x16, 0x24, 0x8b, 0x50, 0x15, 0xe5, 0xf0, 0x24,
+		0x56, 0xe5, 0xf0, 0x50, 0x08, 0x24, 0x2f, 0x50,
+		0x09, 0xe5, 0xf0, 0x24, 0xd9, 0x24, 0xd5, 0x24,
+		0xf0, 0x22, 0x15, 0x81, 0x15, 0x81, 0xe9, 0x22,
+		0x78, 0x13, 0x74, 0x00, 0xf2, 0x75, 0x2e, 0x01,
+		0xd2, 0x6a, 0xc2, 0x69, 0xc2, 0x68, 0xc2, 0x6c,
+		0x90, 0x25, 0x9f, 0x75, 0xb8, 0x07, 0x41, 0xa4,
+		0xc0, 0x01, 0xc0, 0xf0, 0xc0, 0xd0, 0xc0, 0x02,
+		0xe5, 0x3d, 0x54, 0x7d, 0x03, 0x10, 0xe5, 0x05,
+		0x90, 0x28, 0x4b, 0x80, 0x03, 0x90, 0x2b, 0x7c,
+		0x73, 0xe5, 0x3d, 0x30, 0xe5, 0x07, 0x74, 0xfd,
+		0x78, 0x00, 0xf2, 0x61, 0x9b, 0x90, 0x1a, 0x97,
+		0x74, 0xb6, 0xc0, 0xe0, 0x74, 0x27, 0xc0, 0xe0,
+		0xc0, 0xa8, 0x02, 0x1b, 0xab, 0x90, 0x25, 0x9f,
+		0xd0, 0xa8, 0x22, 0x90, 0x27, 0xb6, 0xc0, 0x82,
+		0xc0, 0x83, 0xc0, 0xa8, 0x02, 0x1d, 0xa6, 0x90,
+		0x27, 0xb6, 0xc0, 0x82, 0xc0, 0x83, 0xc0, 0xa8,
+		0x02, 0x1e, 0x0a, 0xea, 0x24, 0xf0, 0xfa, 0xeb,
+		0x34, 0xff, 0xfb, 0x50, 0x2e, 0x20, 0x0b, 0x05,
+		0x85, 0x44, 0xe0, 0x80, 0x03, 0x75, 0xe0, 0x00,
+		0x30, 0xe1, 0x20, 0xe5, 0x35, 0x24, 0xff, 0xf5,
+		0x35, 0xe5, 0x36, 0x34, 0xff, 0xf5, 0x36, 0xc3,
+		0xe5, 0x36, 0x13, 0xf5, 0x36, 0xe5, 0x35, 0x13,
+		0xf5, 0x35, 0x75, 0x3a, 0x10, 0x12, 0x1a, 0x77,
+		0x02, 0x18, 0x77, 0x75, 0x3a, 0x00, 0x12, 0x1a,
+		0x77, 0x02, 0x18, 0x1b, 0x20, 0x4b, 0x04, 0x75,
+		0x4e, 0x03, 0x22, 0xe5, 0x35, 0x24, 0xff, 0xf5,
+		0x35, 0xe5, 0x36, 0x34, 0xff, 0xf5, 0x36, 0x75,
+		0x4e, 0x03, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x02, 0x2c,
+		0x70, 0xd2, 0x00, 0x78, 0x11, 0xe2, 0x44, 0x11,
+		0xf5, 0x3f, 0xc2, 0x08, 0x12, 0x29, 0xa3, 0x02,
+		0x23, 0x93, 0x21, 0x62, 0x61, 0x40, 0x01, 0x3a,
+		0x01, 0x73, 0x21, 0x76, 0x61, 0xa8, 0x21, 0x39,
+		0x21, 0x4a, 0x02, 0x2a, 0x7b, 0x79, 0x06, 0xf3,
+		0xc0, 0xd0, 0x12, 0x03, 0xd9, 0x78, 0x00, 0xf2,
+		0xd0, 0xd0, 0x22, 0x00, 0x00, 0x00, 0x00, 0x02,
+		0x2c, 0xb4, 0x78, 0x11, 0xe2, 0x44, 0x11, 0x54,
+		0x0f, 0xf8, 0xc4, 0x48, 0xd2, 0x05, 0xf5, 0x48,
+		0xc2, 0x0d, 0x31, 0xa3, 0x02, 0x23, 0x93, 0x20,
+		0x4b, 0x04, 0x75, 0x4e, 0x01, 0x22, 0xe5, 0x35,
+		0x24, 0xff, 0xf5, 0x35, 0xe5, 0x36, 0x34, 0xff,
+		0xf5, 0x36, 0x75, 0x4e, 0x01, 0x22, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x79, 0xd0, 0x77, 0x1b, 0x79, 0xd1, 0x77, 0x18,
+		0x79, 0xd2, 0x77, 0x77, 0x79, 0xd3, 0x77, 0x18,
+		0x22, 0x75, 0x29, 0x00, 0x75, 0x25, 0x00, 0x75,
+		0x34, 0x03, 0x75, 0x22, 0x00, 0x75, 0x23, 0x05,
+		0x75, 0x4f, 0x00, 0x75, 0x50, 0x00, 0x75, 0x30,
+		0x00, 0x79, 0xdc, 0x77, 0x03, 0xc2, 0x8e, 0x75,
+		0x17, 0xa8, 0x75, 0x16, 0xa8, 0x74, 0xaa, 0x79,
+		0x01, 0xf3, 0x79, 0xd7, 0x77, 0x74, 0x79, 0xd8,
+		0x77, 0xff, 0x79, 0xd9, 0x77, 0x07, 0x79, 0xda,
+		0x77, 0x00, 0x12, 0x25, 0x6f, 0x43, 0x08, 0x40,
+		0x71, 0x32, 0x79, 0x0e, 0xe3, 0x10, 0x51, 0x1c,
+		0x74, 0x06, 0x71, 0x9b, 0xe5, 0x11, 0x44, 0x80,
+		0x79, 0x05, 0xf3, 0xf5, 0x11, 0x74, 0x07, 0x71,
+		0x9b, 0xe5, 0x12, 0x44, 0x80, 0x79, 0x05, 0xf3,
+		0xf5, 0x12, 0x80, 0x18, 0x53, 0x27, 0xa0, 0x53,
+		0x28, 0x01, 0x75, 0x20, 0xf7, 0x12, 0x23, 0x4c,
+		0x75, 0x11, 0x80, 0x75, 0x12, 0x80, 0x12, 0x1f,
+		0xc0, 0x12, 0x21, 0xdc, 0x79, 0x06, 0xf3, 0x22,
+		0xd2, 0x02, 0x78, 0x11, 0xe2, 0x44, 0x11, 0xf5,
+		0x43, 0xc2, 0x0a, 0x12, 0x29, 0xa3, 0x02, 0x23,
+		0x93, 0x78, 0x11, 0xe2, 0x44, 0x11, 0xf5, 0x44,
+		0xc2, 0x0b, 0x12, 0x29, 0xa3, 0x02, 0x23, 0x93,
+		0x78, 0x00, 0xe2, 0x90, 0x25, 0x9f, 0x02, 0x23,
+		0x93, 0x78, 0x11, 0xe2, 0x75, 0x20, 0xf7, 0x75,
+		0x21, 0x3f, 0x75, 0x49, 0x11, 0x75, 0x4c, 0x11,
+		0x31, 0xa3, 0x02, 0x23, 0x93, 0x78, 0x11, 0xe2,
+		0x44, 0x11, 0x54, 0x0f, 0xf8, 0xc4, 0x48, 0xf8,
+		0xe5, 0x49, 0x45, 0x3f, 0x58, 0xf5, 0x49, 0xd2,
+		0x06, 0xc2, 0x0e, 0x31, 0xa3, 0x02, 0x23, 0x93,
+		0xc0, 0x01, 0x20, 0x2a, 0x04, 0x71, 0x32, 0xc2,
+		0x11, 0x11, 0x5e, 0xc2, 0x1f, 0xd0, 0x01, 0x02,
+		0x23, 0x9b, 0x12, 0x21, 0xdc, 0x78, 0x00, 0xf2,
+		0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xda,
+		0xe7, 0x70, 0x2b, 0x20, 0x0a, 0x05, 0x85, 0x43,
+		0xe0, 0x80, 0x03, 0x75, 0xe0, 0x00, 0x30, 0xe1,
+		0x1d, 0x20, 0xe2, 0x1f, 0x74, 0xe0, 0xca, 0x74,
+		0x00, 0x71, 0x9b, 0xca, 0x79, 0x05, 0xf3, 0xf5,
+		0x09, 0xca, 0x74, 0x01, 0x71, 0x9b, 0xca, 0x79,
+		0x05, 0xf3, 0xf5, 0x0a, 0x80, 0x43, 0x12, 0x15,
+		0x3e, 0x80, 0x3e, 0xe5, 0x0b, 0xb4, 0x17, 0x02,
+		0x80, 0x0b, 0x50, 0x09, 0x74, 0x17, 0xc3, 0x95,
+		0x0b, 0x44, 0x60, 0x80, 0x02, 0x74, 0x60, 0xca,
+		0x74, 0x00, 0x71, 0x9b, 0xca, 0x79, 0x05, 0xf3,
+		0xf5, 0x09, 0xe5, 0x0c, 0xb4, 0x17, 0x02, 0x80,
+		0x0b, 0x50, 0x09, 0x74, 0x17, 0xc3, 0x95, 0x0c,
+		0x44, 0x60, 0x80, 0x02, 0x74, 0x60, 0xca, 0x74,
+		0x01, 0x71, 0x9b, 0xca, 0x79, 0x05, 0xf3, 0xf5,
+		0x0a, 0x22, 0xd2, 0x04, 0x78, 0x11, 0xe2, 0x44,
+		0x11, 0xf5, 0x46, 0xc2, 0x0c, 0x31, 0xa3, 0x02,
+		0x23, 0x93, 0xd2, 0x05, 0x78, 0x11, 0xe2, 0x44,
+		0x11, 0xf5, 0x48, 0xc2, 0x0d, 0x31, 0xa3, 0x02,
+		0x23, 0x93, 0xd2, 0x06, 0x78, 0x11, 0xe2, 0x44,
+		0x11, 0xf5, 0x49, 0xc2, 0x0e, 0x31, 0xa3, 0x02,
+		0x23, 0x93, 0x30, 0x1c, 0x21, 0x20, 0x4d, 0x1e,
+		0xe5, 0x29, 0x60, 0x1a, 0xc2, 0x1c, 0x12, 0x19,
+		0xec, 0x12, 0x13, 0xcf, 0xd2, 0x4d, 0x12, 0x17,
+		0x7f, 0x78, 0x00, 0xf2, 0x79, 0x06, 0xf3, 0x43,
+		0xa8, 0x04, 0x12, 0x24, 0x1b, 0x22, 0x12, 0x27,
+		0x24, 0x22, 0x78, 0x00, 0xe2, 0x90, 0x25, 0x9f,
+		0x02, 0x23, 0x93, 0x78, 0x00, 0xe2, 0xa2, 0xe7,
+		0x72, 0xe3, 0x92, 0xe7, 0x02, 0x1d, 0x85, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x79, 0x04, 0xe3, 0x54, 0x80, 0x70, 0xf9, 0x22,
+		0xe5, 0x29, 0x79, 0xde, 0xf7, 0x75, 0x29, 0x00,
+		0x70, 0x12, 0xe5, 0x15, 0x79, 0xdd, 0xf7, 0x12,
+		0x2d, 0xf0, 0x40, 0x08, 0x20, 0x1c, 0x07, 0x20,
+		0x1d, 0x04, 0x80, 0x02, 0x71, 0x32, 0x30, 0xb5,
+		0x0c, 0x79, 0x06, 0xf3, 0x20, 0x2a, 0x06, 0x79,
+		0xdd, 0xe7, 0x54, 0xfc, 0xf7, 0xd2, 0x2b, 0x12,
+		0x25, 0x6f, 0x22, 0x00, 0x00, 0x00, 0x00, 0xe5,
+		0x15, 0xa2, 0xe0, 0xb0, 0xe6, 0x40, 0x31, 0xa2,
+		0xe1, 0xb0, 0xe7, 0x40, 0x38, 0x10, 0x2b, 0x02,
+		0x80, 0x26, 0x79, 0xde, 0xe7, 0x70, 0x0b, 0x79,
+		0xdd, 0xe7, 0x20, 0xe0, 0x12, 0x20, 0xe1, 0x28,
+		0x80, 0x16, 0xf5, 0x29, 0x30, 0x4d, 0x11, 0x20,
+		0x4c, 0x0e, 0x12, 0x24, 0x1b, 0x80, 0x09, 0x43,
+		0x08, 0x40, 0x12, 0x13, 0xcf, 0x12, 0x17, 0x7f,
+		0xe5, 0x13, 0x20, 0xe4, 0x05, 0x12, 0x18, 0x1b,
+		0x80, 0x03, 0x12, 0x18, 0x77, 0xc2, 0x2b, 0x22,
+		0x12, 0x26, 0xd7, 0x12, 0x13, 0xb7, 0x22, 0x78,
+		0x04, 0x79, 0x00, 0xd9, 0xfe, 0xd8, 0xfa, 0x22,
+		0x00, 0x74, 0x09, 0x71, 0x9b, 0xe5, 0x15, 0x54,
+		0xfc, 0x79, 0x05, 0xf3, 0xf5, 0x15, 0x22, 0x78,
+		0x11, 0xe2, 0x44, 0x11, 0x54, 0x0f, 0xf8, 0xc4,
+		0x48, 0xf5, 0x46, 0xc2, 0x0c, 0xd2, 0x04, 0x31,
+		0xa3, 0x02, 0x23, 0x93, 0x12, 0x26, 0xd7, 0x12,
+		0x00, 0xb7, 0x22, 0x00, 0x79, 0x06, 0xf3, 0x74,
+		0x0a, 0x71, 0x9b, 0x79, 0xe0, 0xe7, 0x44, 0x02,
+		0xf7, 0x79, 0x05, 0xf3, 0x22, 0x74, 0x0a, 0x71,
+		0x9b, 0x79, 0xe0, 0xe7, 0x54, 0xfd, 0xf7, 0x79,
+		0x05, 0xf3, 0x22, 0x21, 0x59, 0x41, 0x23, 0x21,
+		0x59, 0x41, 0x33, 0x41, 0x43, 0x21, 0x59, 0x21,
+		0x59, 0x02, 0x25, 0x9f, 0x00, 0x74, 0x0d, 0x71,
+		0x9b, 0x74, 0x4d, 0x79, 0x05, 0xf3, 0xd2, 0x52,
+		0x22, 0x00, 0x53, 0x08, 0x40, 0x45, 0x08, 0x45,
+		0x1e, 0x79, 0x04, 0xf3, 0xf5, 0x08, 0x22, 0xd2,
+		0x01, 0x78, 0x11, 0xe2, 0x44, 0x11, 0xf5, 0x42,
+		0xc2, 0x09, 0x31, 0xa3, 0x02, 0x23, 0x93, 0x00,
+		0x00, 0x00, 0x00, 0x71, 0x6e, 0x74, 0x09, 0x12,
+		0x17, 0x75, 0xe5, 0x15, 0x44, 0x40, 0x79, 0x05,
+		0xf3, 0xf5, 0x15, 0x75, 0x3a, 0x00, 0x12, 0x1a,
+		0x77, 0x02, 0x18, 0x1b, 0xf5, 0x38, 0xe5, 0x37,
+		0x24, 0x01, 0xf5, 0x37, 0xe5, 0x38, 0x34, 0x00,
+		0xf5, 0x38, 0x40, 0x05, 0x75, 0x39, 0x00, 0x80,
+		0x03, 0x75, 0x39, 0x01, 0x12, 0x04, 0x04, 0xd2,
+		0x8e, 0x02, 0x03, 0x8d, 0x00, 0xb4, 0x0d, 0x03,
+		0x74, 0x14, 0x22, 0x04, 0x83, 0x22, 0x00, 0x02,
+		0xff, 0x01, 0x00, 0x05, 0xfe, 0xff, 0x00, 0x0a,
+		0xfc, 0xfe, 0x00, 0xc0, 0xf8, 0xfc, 0x00, 0x28,
+		0xf0, 0xf8, 0x00, 0x30, 0xe0, 0xd0, 0x01, 0x88,
+		0x04, 0x83, 0x22, 0x00, 0xff, 0xfe, 0xfd, 0xfc,
+		0xfc, 0xfb, 0xfa, 0xfe, 0xfd, 0xfb, 0xf9, 0xf7,
+		0xf7, 0xf5, 0xf3, 0xfc, 0xfa, 0xf6, 0xf2, 0xee,
+		0xee, 0xea, 0xe6, 0xf8, 0xf4, 0xec, 0xe4, 0xdc,
+		0xd4, 0xcc, 0xc4, 0x24, 0x21, 0x83, 0x22, 0x04,
+		0x83, 0x22, 0xff, 0x01, 0xff, 0x01, 0x00, 0x00,
+		0x00, 0x02, 0x22, 0x32, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+		0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0xff,
+		0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x83,
+		0x22, 0x8a, 0x01, 0x20, 0x01, 0x0b, 0xea, 0xf3,
+		0xf9, 0x8b, 0x7e, 0x6b, 0xd5, 0x01, 0x00, 0x01,
+		0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x01, 0x3a, 0x01, 0x38, 0x01, 0x4b, 0x01,
+		0x49, 0x01, 0x5c, 0x01, 0x5a, 0x01, 0x08, 0x08,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x01, 0x15, 0x24, 0x48, 0x83, 0x22, 0x04,
+		0x83, 0x22, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06,
+		0x07, 0x08, 0x00, 0x03, 0x05, 0x07, 0x09, 0x0d,
+		0x0f, 0x81, 0x00, 0x06, 0x0a, 0x0e, 0x82, 0x8a,
+		0x8e, 0x22, 0x00, 0x0c, 0x84, 0x8c, 0x24, 0x2c,
+		0xa4, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0xaa, 0x35, 0xab, 0x36,
+		0x02, 0x27, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+		0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x25,
+		0x03, 0x03, 0x2b, 0x03, 0x00, 0x03, 0x00, 0x03,
+		0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x83, 0x22,
+		0x00, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02,
+		0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02,
+		0x2b, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02,
+		0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02,
+		0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x01,
+		0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+		0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+		0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+		0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+		0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+		0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+		0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x02,
+		0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+		0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02,
+		0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x02,
+		0x21, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x00,
+		0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0x00, 0x02,
+		0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x21,
+		0x01, 0x02, 0x21, 0x02, 0x02, 0x02, 0x00, 0x02,
+		0x02, 0x02, 0x02, 0x02, 0x02, 0x20, 0xb5, 0x05,
+		0x79, 0x0f, 0xf3, 0xc2, 0x11, 0x22, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5,
+		0x15, 0xa2, 0xe0, 0xb0, 0xe6, 0x50, 0x01, 0x22,
+		0xa2, 0xe1, 0xb0, 0xe7, 0x22, 0x02, 0x00};
+		static unsigned char	Data0485_0C[] = {
+		0x02, 0x27, 0x69};
+		static unsigned char	Data0485_66[] = {
+		0x02, 0x25, 0x47, 0x02, 0x25, 0x60};
+		static unsigned char	Data0485_60[] = {
+		0x02, 0x22, 0x7e};
+		static unsigned char	Data0485_99[] = {
+		0xc2, 0x53, 0x02, 0x12, 0x86};
+		static unsigned char	Data0485_9E[] = {
+		0x70, 0xf9, 0x22};
+#ifdef OOKUBO_ORIGINAL
+		static unsigned char	Data0485_36[] = {
+		0x78, 0x00, 0xf2, 0xc2, 0x53, 0x74, 0x86, 0xc0,
+		0xe0, 0x74, 0x12, 0xc0,	0xe0, 0x32};
+#endif /* OOKUBO_ORIGINAL */
diff -Nru a/sound/isa/cs423x/sound_pc9800.h b/sound/isa/cs423x/sound_pc9800.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/sound/isa/cs423x/sound_pc9800.h	Thu Mar  6 15:28:34 2003
@@ -0,0 +1,23 @@
+#ifndef _SOUND_PC9800_H_
+#define _SOUND_PC9800_H_
+
+#include <asm/io.h>
+
+#define PC9800_SOUND_IO_ID	0xa460
+
+/* Sound Functions ID. */
+#define PC9800_SOUND_ID()	((inb(PC9800_SOUND_IO_ID) >> 4) & 0x0f)
+
+#define PC9800_SOUND_ID_DO	0x0	/* PC-98DO+ Internal */
+#define PC9800_SOUND_ID_GS	0x1	/* PC-98GS Internal */
+#define PC9800_SOUND_ID_73	0x2	/* PC-9801-73 (base 0x18x) */
+#define PC9800_SOUND_ID_73A	0x3	/* PC-9801-73/76 (base 0x28x) */
+#define PC9800_SOUND_ID_86	0x4	/* PC-9801-86 and compatible (base 0x18x) */
+#define PC9800_SOUND_ID_86A	0x5	/* PC-9801-86 (base 0x28x) */
+#define PC9800_SOUND_ID_NF	0x6	/* PC-9821Nf/Np Internal */
+#define PC9800_SOUND_ID_XMATE	0x7	/* X-Mate Internal and compatible */
+#define PC9800_SOUND_ID_118	0x8	/* PC-9801-118 and compatible(CanBe Internal, etc.) */
+
+#define PC9800_SOUND_ID_UNKNOWN	0xf	/* Unknown (No Sound System or PC-9801-26) */
+
+#endif
diff -Nru a/sound/isa/dt019x.c b/sound/isa/dt019x.c
--- a/sound/isa/dt019x.c	Tue Oct 22 06:04:00 2002
+++ b/sound/isa/dt019x.c	Thu Mar 20 08:41:13 2003
@@ -111,7 +111,7 @@
 	/* DT0196 / ALS-007 */
 	{
 		ISAPNP_CARD_ID('A','L','S',0x0007),
-		devs: { ISAPNP_DEVICE_ID('@','@','@',0x0001),
+		.devs = { ISAPNP_DEVICE_ID('@','@','@',0x0001),
 			ISAPNP_DEVICE_ID('@','X','@',0x0001),
 			ISAPNP_DEVICE_ID('@','H','@',0x0001) }
 	},
@@ -379,7 +379,7 @@
 
 #ifndef MODULE
 
-/* format is: snd-dt019x=enable,index,id,snd_isapnp,
+/* format is: snd-dt019x=enable,index,id,
 			  port,mpu_port,fm_port,
 			  irq,mpu_irq,dma8,dma8_size */
 
diff -Nru a/sound/isa/es18xx.c b/sound/isa/es18xx.c
--- a/sound/isa/es18xx.c	Sat Feb  8 12:10:50 2003
+++ b/sound/isa/es18xx.c	Thu Mar 20 08:41:13 2003
@@ -1950,8 +1950,8 @@
 #define ISAPNP_ES18XX(_va, _vb, _vc, _device, _audio, _control) \
         { \
                 ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-                devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), \
-                         ISAPNP_DEVICE_ID(_va, _vb, _vc, _control) } \
+                .devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), \
+                          ISAPNP_DEVICE_ID(_va, _vb, _vc, _control) } \
         }
 
 static struct isapnp_card_id snd_audiodrive_pnpids[] __devinitdata = {
diff -Nru a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
--- a/sound/isa/gus/gus_pcm.c	Sat Feb  8 12:10:51 2003
+++ b/sound/isa/gus/gus_pcm.c	Thu Mar 20 08:41:13 2003
@@ -620,7 +620,7 @@
 static snd_pcm_hardware_t snd_gf1_pcm_playback =
 {
 	.info =			SNDRV_PCM_INFO_NONINTERLEAVED,
-	formats:		(SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
+	.formats		= (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
 				 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
 	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
 	.rate_min =		5510,
diff -Nru a/sound/isa/gus/gus_synth.c b/sound/isa/gus/gus_synth.c
--- a/sound/isa/gus/gus_synth.c	Sat Feb  8 12:10:51 2003
+++ b/sound/isa/gus/gus_synth.c	Thu Mar 20 08:41:13 2003
@@ -197,7 +197,7 @@
 						   SNDRV_SEQ_PORT_TYPE_MIDI_GS |
 						   SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
 						   SNDRV_SEQ_PORT_TYPE_SYNTH,
-						   16,
+						   16, 0,
 						   name);
 	if (p->chset->port < 0) {
 		result = p->chset->port;
diff -Nru a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
--- a/sound/isa/gus/interwave.c	Sun Feb 16 05:47:42 2003
+++ b/sound/isa/gus/interwave.c	Thu Mar 20 08:41:13 2003
@@ -148,12 +148,12 @@
 #define ISAPNP_INTERWAVE(_va, _vb, _vc, _device, _audio) \
 	{ \
 		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-		devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), } \
+		.devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), } \
 	}
 #define ISAPNP_INTERWAVE_STB(_va, _vb, _vc, _device, _audio, _tone) \
 	{ \
 		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-		devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), \
+		.devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), \
 			 ISAPNP_DEVICE_ID(_va, _vb, _vc, _tone), } \
 	}
 
diff -Nru a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
--- a/sound/isa/opti9xx/opti92x-ad1848.c	Sat Feb  8 12:10:51 2003
+++ b/sound/isa/opti9xx/opti92x-ad1848.c	Thu Mar  6 15:59:15 2003
@@ -326,11 +326,11 @@
 static long snd_legacy_find_free_ioport(long *port_table, long size)
 {
 	while (*port_table != -1) {
-		if (!check_region(*port_table, size))
+		if (request_region(*port_table, size, "opti92x-ad1848"))
 			return *port_table;
 		port_table++;
 	}
-	return -1;
+	return SNDRV_AUTO_PORT;
 }
 
 static int __init snd_opti9xx_init(opti9xx_t *chip, unsigned short hardware)
@@ -987,9 +987,11 @@
 			s = s->link_next;
 		} while (s != substream);
 		spin_lock(&chip->lock);
-		if (cmd == SNDRV_PCM_TRIGGER_START)
+		if (cmd == SNDRV_PCM_TRIGGER_START) {
 			snd_opti93x_out_mask(chip, OPTi93X_IFACE_CONF, what, what);
-		else
+			if (what & OPTi93X_CAPTURE_ENABLE)
+				udelay(50);
+		} else
 			snd_opti93x_out_mask(chip, OPTi93X_IFACE_CONF, what, 0x00);
 		spin_unlock(&chip->lock);
 		break;
@@ -1207,6 +1209,7 @@
 		return error;
 	runtime->hw = snd_opti93x_capture;
 	snd_pcm_set_sync(substream);
+	chip->capture_substream = substream;
 	snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
 	return error;
@@ -1914,6 +1917,10 @@
 #ifdef __ISAPNP__
 		snd_card_opti9xx_deactivate(chip);
 #endif	/* __ISAPNP__ */
+		if (chip->wss_base != SNDRV_AUTO_PORT)
+			release_region(chip->wss_base, 4);
+		if (chip->mpu_port != SNDRV_AUTO_PORT)
+			release_region(chip->mpu_port, 2);
 		if (chip->res_mc_base) {
 			release_resource(chip->res_mc_base);
 			kfree_nocheck(chip->res_mc_base);
@@ -1959,6 +1966,16 @@
 	card->private_free = snd_card_opti9xx_free;
 	chip = (opti9xx_t *)card->private_data;
 
+	chip->wss_base = port;
+	chip->fm_port = fm_port;
+	chip->mpu_port = mpu_port;
+	chip->irq = irq;
+	chip->mpu_irq = mpu_irq;
+	chip->dma1 = dma1;
+#if defined(CS4231) || defined(OPTi93X)
+	chip->dma2 = dma2;
+#endif
+
 #ifdef __ISAPNP__
 	if (isapnp && (hw = snd_card_opti9xx_isapnp(chip)) > 0) {
 		switch (hw) {
@@ -1997,28 +2014,18 @@
 		return -ENOMEM;
 	}
 
-	chip->wss_base = port;
-	chip->fm_port = fm_port;
-	chip->mpu_port = mpu_port;
-	chip->irq = irq;
-	chip->mpu_irq = mpu_irq;
-	chip->dma1 = dma1;
-#if defined(CS4231) || defined(OPTi93X)
-	chip->dma2 = dma2;
-#endif
-
 #ifdef __ISAPNP__
 	if (!isapnp) {
 #endif
 	if (chip->wss_base == SNDRV_AUTO_PORT) {
-		if ((chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4)) < 0) {
+		if ((chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4)) == SNDRV_AUTO_PORT) {
 			snd_card_free(card);
 			snd_printk("unable to find a free WSS port\n");
 			return -EBUSY;
 		}
 	}
 	if (chip->mpu_port == SNDRV_AUTO_PORT) {
-		if ((chip->mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
+		if ((chip->mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) == SNDRV_AUTO_PORT) {
 			snd_card_free(card);
 			snd_printk("unable to find a free MPU401 port\n");
 			return -EBUSY;
diff -Nru a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c
--- a/sound/isa/sb/es968.c	Tue Oct 22 06:04:00 2002
+++ b/sound/isa/sb/es968.c	Thu Mar 20 10:13:41 2003
@@ -23,11 +23,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/time.h>
-#ifndef LINUX_ISAPNP_H
-#include <linux/isapnp.h>
-#define isapnp_card pci_bus
-#define isapnp_dev pci_dev
-#endif
+#include <linux/pnp.h>
 #include <sound/core.h>
 #define SNDRV_GET_ID
 #include <sound/initval.h>
@@ -35,6 +31,8 @@
 
 #define chip_t sb_t
 
+#define PFX "es968: "
+
 MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
 MODULE_DESCRIPTION("ESS AudioDrive ES968");
 MODULE_LICENSE("GPL");
@@ -68,32 +66,18 @@
 MODULE_PARM_SYNTAX(dma8, SNDRV_DMA8_DESC);
 
 struct snd_card_es968 {
-#ifdef __ISAPNP__
-	struct isapnp_dev *dev;
-#endif	/* __ISAPNP__ */
+	struct pnp_dev *dev;
 };
 
-static snd_card_t *snd_es968_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-
-#ifdef __ISAPNP__
-static struct isapnp_card *snd_es968_isapnp_cards[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PTR;
-static const struct isapnp_card_id *snd_es968_isapnp_id[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PTR;
-
-static struct isapnp_card_id snd_es968_pnpids[] __devinitdata = {
-        {
-                ISAPNP_CARD_ID('E','S','S',0x0968),
-                .devs = { ISAPNP_DEVICE_ID('E','S','S',0x0968), }
-        },
-        { ISAPNP_CARD_END, }
+static struct pnp_card_id snd_es968_pnpids[] __devinitdata = {
+	{ .id = "ESS0968", .devs = { { "@@@0968" }, } },
+	{ .id = "", } /* end */
 };
 
-ISAPNP_CARD_TABLE(snd_es968_pnpids);
-
-#endif	/* __ISAPNP__ */
+MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids);
 
 #define	DRIVER_NAME	"snd-card-es968"
 
-
 static void snd_card_es968_interrupt(int irq, void *dev_id,
 				     struct pt_regs *regs)
 {
@@ -106,64 +90,50 @@
 	}
 }
 
-#ifdef __ISAPNP__
-static int __init snd_card_es968_isapnp(int dev, struct snd_card_es968 *acard)
-{
-	const struct isapnp_card_id *id = snd_es968_isapnp_id[dev];
-	struct isapnp_card *card = snd_es968_isapnp_cards[dev];
-	struct isapnp_dev *pdev;
-
-	acard->dev = isapnp_find_dev(card, id->devs[0].vendor, id->devs[0].function, NULL);
-	if (acard->dev->active) {
-		acard->dev = NULL;
-		return -EBUSY;
+static int __devinit snd_card_es968_isapnp(int dev, struct snd_card_es968 *acard,
+					struct pnp_card_link *card,
+					const struct pnp_card_id *id)
+{
+	struct pnp_dev *pdev;
+	struct pnp_resource_table * cfg = kmalloc(GFP_ATOMIC, sizeof(struct pnp_resource_table));
+	int err;
+	if (!cfg)
+		return -ENOMEM;
+	acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
+	if (acard->dev == NULL) {
+		kfree(cfg);
+		return -ENODEV;
 	}
 
 	pdev = acard->dev;
-	if (pdev->prepare(pdev)<0)
-		return -EAGAIN;
 
+	pnp_init_resource_table(cfg);
+
+	/* override resources */
 	if (port[dev] != SNDRV_AUTO_PORT)
-		isapnp_resource_change(&pdev->resource[0], port[dev], 16);
+		pnp_resource_change(&cfg->port_resource[0], port[dev], 16);
 	if (dma8[dev] != SNDRV_AUTO_DMA)
-		isapnp_resource_change(&pdev->dma_resource[0], dma8[dev],
-			1);
+		pnp_resource_change(&cfg->dma_resource[0], dma8[dev], 1);
 	if (irq[dev] != SNDRV_AUTO_IRQ)
-		isapnp_resource_change(&pdev->irq_resource[0], irq[dev], 1);
-
-	if (pdev->activate(pdev)<0) {
-		snd_printk("AUDIO isapnp configure failure\n");
-		return -EBUSY;
-	}
-
-	port[dev] = pdev->resource[0].start;
-	dma8[dev] = pdev->dma_resource[0].start;
-	irq[dev] = pdev->irq_resource[0].start;
+		pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1);
+	if ((pnp_manual_config_dev(pdev, cfg, 0)) < 0)
+		printk(KERN_ERR PFX "AUDIO the requested resources are invalid, using auto config\n");
+	err = pnp_activate_dev(pdev);
+	if (err < 0) {
+		printk(KERN_ERR PFX "AUDIO pnp configure failure\n");
+		return err;
+	}
+	port[dev] = pnp_port_start(pdev, 0);
+	dma8[dev] = pnp_dma(pdev, 1);
+	irq[dev] = pnp_irq(pdev, 0);
 
+	kfree(cfg);
 	return 0;
 }
 
-static void snd_card_es968_deactivate(struct snd_card_es968 *acard)
-{
-	if (acard->dev) {
-		acard->dev->deactivate(acard->dev);
-		acard->dev = NULL;
-	}
-}
-#endif	/* __ISAPNP__ */
-
-static void snd_card_es968_free(snd_card_t *card)
-{
-	struct snd_card_es968 *acard = (struct snd_card_es968 *)card->private_data;
-
-	if (acard) {
-#ifdef __ISAPNP__
-		snd_card_es968_deactivate(acard);
-#endif	/* __ISAPNP__ */
-	}
-}
-
-static int __init snd_card_es968_probe(int dev)
+static int __init snd_card_es968_probe(int dev,
+					struct pnp_card_link *pcard,
+					const struct pnp_card_id *pid)
 {
 	int error;
 	sb_t *chip;
@@ -174,18 +144,10 @@
 				 sizeof(struct snd_card_es968))) == NULL)
 		return -ENOMEM;
 	acard = (struct snd_card_es968 *)card->private_data;
-	card->private_free = snd_card_es968_free;
-
-#ifdef __ISAPNP__
-	if ((error = snd_card_es968_isapnp(dev, acard))) {
+	if ((error = snd_card_es968_isapnp(dev, acard, pcard, pid))) {
 		snd_card_free(card);
 		return error;
 	}
-#else
-	snd_printk("you have to enable PnP support ...\n");
-	snd_card_free(card);
-	return -ENOSYS;
-#endif	/* __ISAPNP__ */
 
 	if ((error = snd_sbdsp_create(card, port[dev],
 				      irq[dev],
@@ -221,13 +183,12 @@
 		snd_card_free(card);
 		return error;
 	}
-	snd_es968_cards[dev] = card;
+	pnp_set_card_drvdata(pcard, card);
 	return 0;
 }
 
-#ifdef __ISAPNP__
-static int __init snd_es968_isapnp_detect(struct isapnp_card *card,
-                                          const struct isapnp_card_id *id)
+static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card,
+                                          const struct pnp_card_id *id)
 {
 	static int dev;
 	int res;
@@ -235,9 +196,7 @@
 	for ( ; dev < SNDRV_CARDS; dev++) {
 		if (!enable[dev])
 			continue;
-		snd_es968_isapnp_cards[dev] = card;
-		snd_es968_isapnp_id[dev] = id;
-		res = snd_card_es968_probe(dev);
+		res = snd_card_es968_probe(dev, card, id);
 		if (res < 0)
 			return res;
 		dev++;
@@ -245,30 +204,31 @@
         }
         return -ENODEV;
 }
-#endif /* __ISAPNP__ */
 
-static int __init alsa_card_es968_init(void)
+static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
 {
-	int cards = 0;
+	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
 
-#ifdef __ISAPNP__
-	cards += isapnp_probe_cards(snd_es968_pnpids, snd_es968_isapnp_detect);
-#else
-	snd_printk("you have to enable ISA PnP support.\n");
-#endif
-#ifdef MODULE
-	if (!cards)
-		snd_printk("no ES968 based soundcards found\n");
-#endif
-	return cards ? 0 : -ENODEV;
+	snd_card_disconnect(card);
+	snd_card_free_in_thread(card);
 }
 
-static void __exit alsa_card_es968_exit(void)
+static struct pnp_card_driver es968_pnpc_driver = {
+	.flags		= PNP_DRIVER_RES_DISABLE,
+	.name		= "es968",
+	.id_table	= snd_es968_pnpids,
+	.probe		= snd_es968_pnp_detect,
+	.remove		= __devexit_p(snd_es968_pnp_remove),
+};
+
+static int __init alsa_card_es968_init(void)
 {
-	int dev;
+	return (pnp_register_card_driver(&es968_pnpc_driver) ? 0 : -ENODEV);
+}
 
-	for (dev = 0; dev < SNDRV_CARDS; dev++)
-		snd_card_free(snd_es968_cards[dev]);
+static void __exit alsa_card_es968_exit(void)
+{
+	pnp_unregister_card_driver(&es968_pnpc_driver);
 }
 
 module_init(alsa_card_es968_init)
@@ -277,7 +237,7 @@
 #ifndef MODULE
 
 /* format is: snd-es968=enable,index,id,
-			port,irq,snd_dma1 */
+			port,irq,dma1 */
 
 static int __init alsa_card_es968_setup(char *str)
 {
diff -Nru a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
--- a/sound/isa/sb/sb16.c	Mon Jan 27 11:00:12 2003
+++ b/sound/isa/sb/sb16.c	Thu Mar 20 08:41:13 2003
@@ -168,12 +168,12 @@
 #define ISAPNP_SB16(_va, _vb, _vc, _device, _audio) \
 	{ \
 		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-		devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), } \
+		.devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), } \
 	}
 #define ISAPNP_SBAWE(_va, _vb, _vc, _device, _audio, _awe) \
 	{ \
 		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-		devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), \
+		.devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), \
 			 ISAPNP_DEVICE_ID(_va, _vb, _vc, _awe), } \
 	}
 
@@ -636,9 +636,9 @@
 #ifdef MODULE
 		printk(KERN_ERR "Sound Blaster 16 soundcard not found or device busy\n");
 #ifdef SNDRV_SBAWE_EMU8000
-		printk(KERN_ERR "In case, if you have non-AWE card, try snd-card-sb16 module\n");
+		printk(KERN_ERR "In case, if you have non-AWE card, try snd-sb16 module\n");
 #else
-		printk(KERN_ERR "In case, if you have AWE card, try snd-card-sbawe module\n");
+		printk(KERN_ERR "In case, if you have AWE card, try snd-sbawe module\n");
 #endif
 #endif
 		return -ENODEV;
diff -Nru a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c
--- a/sound/isa/sb/sb16_csp.c	Mon Jan 27 09:30:52 2003
+++ b/sound/isa/sb/sb16_csp.c	Tue Feb 25 05:46:06 2003
@@ -213,7 +213,10 @@
 		info.run_width = p->run_width;
 		info.version = p->version;
 		info.state = p->running;
-		err = copy_to_user((void *) arg, &info, sizeof(info));
+		if (copy_to_user((void *) arg, &info, sizeof(info)))
+			err = -EFAULT;
+		else
+			err = 0;
 		break;
 
 		/* load CSP microcode */
diff -Nru a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
--- a/sound/isa/sb/sb8.c	Tue Oct 22 06:04:00 2002
+++ b/sound/isa/sb/sb8.c	Thu Mar 20 08:41:13 2003
@@ -123,10 +123,10 @@
 	if (chip->hardware >= SB_HW_16) {
 		snd_card_free(card);
 		if (chip->hardware == SB_HW_ALS100)
-			snd_printdd("ALS100 chip detected at 0x%lx, try snd-card-als100 module\n",
+			snd_printdd("ALS100 chip detected at 0x%lx, try snd-als100 module\n",
 				    port[dev]);
 		else
-			snd_printdd("SB 16 chip detected at 0x%lx, try snd-card-sb16 module\n",
+			snd_printdd("SB 16 chip detected at 0x%lx, try snd-sb16 module\n",
 				    port[dev]);
 		return -ENODEV;
 	}
diff -Nru a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
--- a/sound/isa/sb/sb8_main.c	Sat Feb  8 12:10:51 2003
+++ b/sound/isa/sb/sb8_main.c	Thu Mar 20 08:41:13 2003
@@ -97,7 +97,7 @@
 {
 	snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	if (r->min > SB8_RATE(22050) || r->max <= SB8_RATE(11025)) {
-		snd_interval_t t = { min: 1, max: 1 };
+		snd_interval_t t = { .min = 1, .max = 1 };
 		return snd_interval_refine(hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS), &t);
 	}
 	return 0;
diff -Nru a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c
--- a/sound/isa/sgalaxy.c	Sat Feb  8 12:10:51 2003
+++ b/sound/isa/sgalaxy.c	Tue Feb 25 05:46:06 2003
@@ -44,7 +44,7 @@
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	/* Enable this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	/* Enable this card */
 static long sbport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* 0x220,0x240 */
 static long wssport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* 0x530,0xe80,0xf40,0x604 */
 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* 7,9,10,11 */
@@ -300,7 +300,7 @@
 {
 	int dev, cards;
 
-	for (dev = cards = 0; dev < SNDRV_CARDS && snd_enable[dev]; dev++) {
+	for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) {
 		if (snd_sgalaxy_probe(dev) >= 0)
 			cards++;
 	}
@@ -327,7 +327,7 @@
 
 #ifndef MODULE
 
-/* format is: snd-sgalaxy=snd_enable,index,id,
+/* format is: snd-sgalaxy=enable,index,id,
 			  sbport,wssport,
 			  irq,dma1 */
 
@@ -337,7 +337,7 @@
 
 	if (nr_dev >= SNDRV_CARDS)
 		return 0;
-	(void)(get_option(&str,&snd_enable[nr_dev]) == 2 &&
+	(void)(get_option(&str,&enable[nr_dev]) == 2 &&
 	       get_option(&str,&index[nr_dev]) == 2 &&
 	       get_id(&str,&id[nr_dev]) == 2 &&
 	       get_option(&str,(int *)&sbport[nr_dev]) == 2 &&
diff -Nru a/sound/oss/Kconfig b/sound/oss/Kconfig
--- a/sound/oss/Kconfig	Tue Feb 18 18:58:58 2003
+++ b/sound/oss/Kconfig	Mon Mar  3 13:09:18 2003
@@ -113,15 +113,17 @@
 	  Say Y or M if you have a PCI sound card using the EMU10K1 chipset,
 	  such as the Creative SBLive!, SB PCI512 or Emu-APS.
 
-	  For more information on this driver and the degree of support for the
-	  different card models please check <http://opensource.creative.com/>.
+	  For more information on this driver and the degree of support for
+	  the different card models please check:
+
+	        <http://sourceforge.net/projects/emu10k1/>
 
 	  It is now possible to load dsp microcode patches into the EMU10K1
 	  chip.  These patches are used to implement real time sound
 	  processing effects which include for example: signal routing,
 	  bass/treble control, AC3 passthrough, ...
 	  Userspace tools to create new patches and load/unload them can be
-	  found at <http://opensource.creative.com/dist.html>.
+	  found in the emu-tools package at the above URL.
 
 config MIDI_EMU10K1
 	bool "Creative SBLive! MIDI (EXPERIMENTAL)"
diff -Nru a/sound/oss/audio_syms.c b/sound/oss/audio_syms.c
--- a/sound/oss/audio_syms.c	Sun Feb 10 18:50:11 2002
+++ b/sound/oss/audio_syms.c	Thu Mar 13 16:52:26 2003
@@ -1,9 +1,7 @@
 /*
  * Exported symbols for audio driver.
- * __NO_VERSION__ because this is still part of sound.o.
  */
 
-#define __NO_VERSION__
 #include <linux/module.h>
 
 char audio_syms_symbol;
diff -Nru a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c
--- a/sound/oss/awe_wave.c	Mon Feb 24 09:56:47 2003
+++ b/sound/oss/awe_wave.c	Thu Mar 20 18:25:40 2003
@@ -757,7 +757,7 @@
 	return 0;
 }
 
-static void __exit
+static void
 awe_release_region(void)
 {
 	if (! port_setuped) return;
diff -Nru a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c
--- a/sound/oss/cs46xx.c	Tue Feb 25 09:57:23 2003
+++ b/sound/oss/cs46xx.c	Thu Mar  6 14:01:50 2003
@@ -4314,7 +4314,7 @@
     {
         offset = ClrStat[i].BA1__DestByteOffset;
         count  = ClrStat[i].BA1__SourceSize;
-        for(  temp1 = offset; temp1<(offset+count); temp1+=4 );
+        for(  temp1 = offset; temp1<(offset+count); temp1+=4 )
               writel(0, pBA1+temp1);
     }
 
diff -Nru a/sound/oss/emu10k1/audio.c b/sound/oss/emu10k1/audio.c
--- a/sound/oss/emu10k1/audio.c	Sun Feb 10 18:50:09 2002
+++ b/sound/oss/emu10k1/audio.c	Thu Mar 13 16:52:26 2003
@@ -30,7 +30,6 @@
  **********************************************************************
  */
 
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/poll.h>
 #include <linux/slab.h>
@@ -983,11 +982,11 @@
 	unsigned long pgoff;
 	int rd, wr;
 
-	DPF(4, "emu10k1_mm_nopage()\n");
-	DPD(4, "addr: %#lx\n", address);
+	DPF(3, "emu10k1_mm_nopage()\n");
+	DPD(3, "addr: %#lx\n", address);
 
 	if (address > vma->vm_end) {
-		DPF(2, "EXIT, returning NOPAGE_SIGBUS\n");
+		DPF(1, "EXIT, returning NOPAGE_SIGBUS\n");
 		return NOPAGE_SIGBUS; /* Disallow mremap */
 	}
 
@@ -1009,14 +1008,14 @@
 			pgoff -= woinst->buffer.pages;
 			dmapage = virt_to_page ((u8 *) wiinst->buffer.addr + pgoff * PAGE_SIZE);
 		} else
-			dmapage = virt_to_page (woinst->buffer.mem[0].addr[pgoff]);
+			dmapage = virt_to_page (woinst->voice[0].mem.addr[pgoff]);
 	} else {
 		dmapage = virt_to_page ((u8 *) wiinst->buffer.addr + pgoff * PAGE_SIZE);
 	}
 
 	get_page (dmapage);
 
-	DPD(4, "page: %#lx\n", dmapage);
+	DPD(3, "page: %#lx\n", (unsigned long) dmapage);
 	return dmapage;
 }
 
@@ -1083,8 +1082,8 @@
 	n_pages = ((vma->vm_end - vma->vm_start) + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	pgoffset = vma->vm_pgoff;
 
-	DPD(3, "vma_start: %#lx, vma_end: %#lx, vma_offset: %d\n", vma->vm_start, vma->vm_end, pgoffset);
-	DPD(3, "n_pages: %d, max_pages: %d\n", n_pages, max_pages);
+	DPD(2, "vma_start: %#lx, vma_end: %#lx, vma_offset: %ld\n", vma->vm_start, vma->vm_end, pgoffset);
+	DPD(2, "n_pages: %ld, max_pages: %ld\n", n_pages, max_pages);
 
 	if (pgoffset + n_pages > max_pages)
 		return -EINVAL;
@@ -1092,7 +1091,6 @@
 	vma->vm_flags |= VM_RESERVED;
 	vma->vm_ops = &emu10k1_mm_ops;
 	vma->vm_private_data = wave_dev;
-
 	return 0;
 }
 
@@ -1136,7 +1134,8 @@
 
 		if ((wiinst = (struct wiinst *) kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) {
 			ERROR();
-			return -ENODEV;
+			kfree(wave_dev);
+			return -ENOMEM;
 		}
 
 		wiinst->recsrc = card->wavein.recsrc;
@@ -1162,6 +1161,8 @@
 			wiinst->format.channels = hweight32(wiinst->fxwc);
 			break;
 		default:
+			kfree(wave_dev);
+			kfree(wiinst);
 			BUG();
 			break;
 		}
@@ -1211,7 +1212,7 @@
 		woinst->num_voices = 1;
 		for (i = 0; i < WAVEOUT_MAXVOICES; i++) {
 			woinst->voice[i].usage = VOICE_USAGE_FREE;
-			woinst->buffer.mem[i].emupageindex = -1;
+			woinst->voice[i].mem.emupageindex = -1;
 		}
 
 		init_waitqueue_head(&woinst->wait_queue);
@@ -1330,23 +1331,13 @@
 	if (file->f_mode & FMODE_READ) {
 		spin_lock_irqsave(&wiinst->lock, flags);
 
-		if (wiinst->state == WAVE_STATE_CLOSED) {
-			calculate_ifrag(wiinst);
-			if (emu10k1_wavein_open(wave_dev) < 0) {
-				spin_unlock_irqrestore(&wiinst->lock, flags);
-				return (mask |= POLLERR);
-			}
-		}
+		if (wiinst->state & WAVE_STATE_OPEN) {
+			emu10k1_wavein_update(wave_dev->card, wiinst);
+			emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
 
-		if (!(wiinst->state & WAVE_STATE_STARTED)) {
-			wave_dev->enablebits |= PCM_ENABLE_INPUT;
-			emu10k1_wavein_start(wave_dev);
+			if (bytestocopy >= wiinst->buffer.fragment_size)
+				mask |= POLLIN | POLLRDNORM;
 		}
-		emu10k1_wavein_update(wave_dev->card, wiinst);
-		emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
-
-		if (bytestocopy >= wiinst->buffer.fragment_size)
-			mask |= POLLIN | POLLRDNORM;
 
 		spin_unlock_irqrestore(&wiinst->lock, flags);
 	}
@@ -1376,6 +1367,13 @@
 
 	buffer->fragment_size = 1 << buffer->ossfragshift;
 
+	while (buffer->fragment_size * WAVEOUT_MINFRAGS > WAVEOUT_MAXBUFSIZE)
+		buffer->fragment_size >>= 1;
+
+	/* now we are sure that:
+	 (2^WAVEOUT_MINFRAGSHIFT) <= (fragment_size = 2^n) <= (WAVEOUT_MAXBUFSIZE / WAVEOUT_MINFRAGS)
+	*/
+
 	if (!buffer->numfrags) {
 		u32 numfrags;
 
@@ -1390,19 +1388,14 @@
 		}
 	}
 
-	if (buffer->numfrags < MINFRAGS)
-		buffer->numfrags = MINFRAGS;
+	if (buffer->numfrags < WAVEOUT_MINFRAGS)
+		buffer->numfrags = WAVEOUT_MINFRAGS;
 
-	if (buffer->numfrags * buffer->fragment_size > WAVEOUT_MAXBUFSIZE) {
+	if (buffer->numfrags * buffer->fragment_size > WAVEOUT_MAXBUFSIZE)
 		buffer->numfrags = WAVEOUT_MAXBUFSIZE / buffer->fragment_size;
 
-		if (buffer->numfrags < MINFRAGS) {
-			buffer->numfrags = MINFRAGS;
-			buffer->fragment_size = WAVEOUT_MAXBUFSIZE / MINFRAGS;
-		}
-
-	} else if (buffer->numfrags * buffer->fragment_size < WAVEOUT_MINBUFSIZE)
-		buffer->numfrags = WAVEOUT_MINBUFSIZE / buffer->fragment_size;
+	if (buffer->numfrags < WAVEOUT_MINFRAGS)
+		BUG();
 
 	buffer->size = buffer->fragment_size * buffer->numfrags;
 	buffer->pages = buffer->size / PAGE_SIZE + ((buffer->size % PAGE_SIZE) ? 1 : 0);
@@ -1436,24 +1429,29 @@
 
 	buffer->fragment_size = 1 << buffer->ossfragshift;
 
+	while (buffer->fragment_size * WAVEIN_MINFRAGS > WAVEIN_MAXBUFSIZE)
+		buffer->fragment_size >>= 1;
+
+	/* now we are sure that:
+	   (2^WAVEIN_MINFRAGSHIFT) <= (fragment_size = 2^n) <= (WAVEIN_MAXBUFSIZE / WAVEIN_MINFRAGS)
+        */
+
+
 	if (!buffer->numfrags)
 		buffer->numfrags = (wiinst->format.bytespersec * WAVEIN_DEFAULTBUFLEN) / (buffer->fragment_size * 1000) - 1;
 
-	if (buffer->numfrags < MINFRAGS)
-		buffer->numfrags = MINFRAGS;
+	if (buffer->numfrags < WAVEIN_MINFRAGS)
+		buffer->numfrags = WAVEIN_MINFRAGS;
 
-	if (buffer->numfrags * buffer->fragment_size > WAVEIN_MAXBUFSIZE) {
+	if (buffer->numfrags * buffer->fragment_size > WAVEIN_MAXBUFSIZE)
 		buffer->numfrags = WAVEIN_MAXBUFSIZE / buffer->fragment_size;
 
-		if (buffer->numfrags < MINFRAGS) {
-			buffer->numfrags = MINFRAGS;
-			buffer->fragment_size = WAVEIN_MAXBUFSIZE / MINFRAGS;
-		}
-	} else if (buffer->numfrags * buffer->fragment_size < WAVEIN_MINBUFSIZE)
-		buffer->numfrags = WAVEIN_MINBUFSIZE / buffer->fragment_size;
+	if (buffer->numfrags < WAVEIN_MINFRAGS)
+		BUG();
 
 	bufsize = buffer->fragment_size * buffer->numfrags;
 
+	/* the buffer size for recording is restricted to certain values, adjust it now */
 	if (bufsize >= 0x10000) {
 		buffer->size = 0x10000;
 		buffer->sizeregval = 0x1f;
@@ -1479,10 +1477,12 @@
 		}
 	}
 
+	/* adjust the fragment size so that buffer size is an integer multiple */
+	while (buffer->size % buffer->fragment_size)
+		buffer->fragment_size >>= 1;
+
 	buffer->numfrags = buffer->size / buffer->fragment_size;
 	buffer->pages =  buffer->size / PAGE_SIZE + ((buffer->size % PAGE_SIZE) ? 1 : 0);
-	if (buffer->size % buffer->fragment_size)
-		BUG();
 
 	DPD(2, " calculated recording fragment_size -> %d\n", buffer->fragment_size);
 	DPD(2, " calculated recording numfrags -> %d\n", buffer->numfrags);
diff -Nru a/sound/oss/emu10k1/audio.h b/sound/oss/emu10k1/audio.h
--- a/sound/oss/emu10k1/audio.h	Sun Feb 10 18:50:15 2002
+++ b/sound/oss/emu10k1/audio.h	Sun Feb 16 16:30:06 2003
@@ -33,8 +33,6 @@
 #ifndef _AUDIO_H
 #define _AUDIO_H
 
-#define MINFRAGS	2	/* _don't_ got bellow 2 */
-
 struct emu10k1_wavedevice
 {
         struct emu10k1_card *card;
diff -Nru a/sound/oss/emu10k1/cardwi.c b/sound/oss/emu10k1/cardwi.c
--- a/sound/oss/emu10k1/cardwi.c	Sat May 18 22:57:47 2002
+++ b/sound/oss/emu10k1/cardwi.c	Sun Feb 16 16:30:06 2003
@@ -96,6 +96,7 @@
 	wave_fmt->bytesperchannel = wave_fmt->bitsperchannel >> 3;
 	wave_fmt->bytespersample = wave_fmt->channels * wave_fmt->bytesperchannel;
 	wave_fmt->bytespersec = wave_fmt->bytespersample * wave_fmt->samplingrate;
+	wave_fmt->bytespervoicesample = wave_fmt->bytespersample;
 }
 
 static int alloc_buffer(struct emu10k1_card *card, struct wavein_buffer *buffer)
@@ -120,7 +121,7 @@
 	struct emu10k1_card *card = wave_dev->card;
 	struct wiinst *wiinst = wave_dev->wiinst;
 	struct wiinst **wiinst_tmp = NULL;
-	u32 delay;
+	u16 delay;
 	unsigned long flags;
 
 	DPF(2, "emu10k1_wavein_open()\n");
@@ -169,6 +170,12 @@
 
 	emu10k1_set_record_src(card, wiinst);
 
+	emu10k1_reset_record(card, &wiinst->buffer);
+
+	wiinst->buffer.hw_pos = 0;
+	wiinst->buffer.pos = 0;
+	wiinst->buffer.bytestocopy = 0;
+
 	delay = (48000 * wiinst->buffer.fragment_size) / wiinst->format.bytespersec;
 
 	emu10k1_timer_install(card, &wiinst->timer, delay / 2);
@@ -222,10 +229,6 @@
 	emu10k1_start_record(card, &wiinst->buffer);
 	emu10k1_timer_enable(wave_dev->card, &wiinst->timer);
 
-	wiinst->buffer.hw_pos = 0;
-	wiinst->buffer.pos = 0;
-	wiinst->buffer.bytestocopy = 0;
-
 	wiinst->state |= WAVE_STATE_STARTED;
 }
 
@@ -249,7 +252,7 @@
 {
 	struct emu10k1_card *card = wave_dev->card;
 	struct wiinst *wiinst = wave_dev->wiinst;
-	u32 delay;
+	u16 delay;
 
 	DPF(2, "emu10k1_wavein_setformat()\n");
 
@@ -304,10 +307,9 @@
 
 static void copy_block(u8 *dst, u8 * src, u32 str, u32 len, u8 cov)
 {
-	if (cov == 1) {
-		if (__copy_to_user(dst, src + str, len))
-			return;
-	} else {
+	if (cov == 1)
+		__copy_to_user(dst, src + str, len);
+	else {
 		u8 byte;
 		u32 i;
 
@@ -315,8 +317,7 @@
 
 		for (i = 0; i < len; i++) {
 			byte = src[2 * i] ^ 0x80;
-			if (__copy_to_user(dst + i, &byte, 1))
-				return;
+			__copy_to_user(dst + i, &byte, 1);
 		}
 	}
 }
diff -Nru a/sound/oss/emu10k1/cardwi.h b/sound/oss/emu10k1/cardwi.h
--- a/sound/oss/emu10k1/cardwi.h	Sun Feb 10 18:50:15 2002
+++ b/sound/oss/emu10k1/cardwi.h	Sun Feb 16 16:30:06 2003
@@ -69,13 +69,14 @@
 	u16 fxwc;
 };
 
-#define WAVEIN_MAXBUFSIZE         65536
-#define WAVEIN_MINBUFSIZE	  368
+#define WAVEIN_MAXBUFSIZE	65536
+#define WAVEIN_MINBUFSIZE	368
 
-#define WAVEIN_DEFAULTFRAGLEN     100 
-#define WAVEIN_DEFAULTBUFLEN      1000
+#define WAVEIN_DEFAULTFRAGLEN	100 
+#define WAVEIN_DEFAULTBUFLEN	1000
 
-#define WAVEIN_MINFRAGSHIFT   	  8 
+#define WAVEIN_MINFRAGSHIFT	8 
+#define WAVEIN_MINFRAGS		2
 
 int emu10k1_wavein_open(struct emu10k1_wavedevice *);
 void emu10k1_wavein_close(struct emu10k1_wavedevice *);
diff -Nru a/sound/oss/emu10k1/cardwo.c b/sound/oss/emu10k1/cardwo.c
--- a/sound/oss/emu10k1/cardwo.c	Sat May 18 22:57:47 2002
+++ b/sound/oss/emu10k1/cardwo.c	Sun Feb 16 16:30:06 2003
@@ -108,95 +108,20 @@
 	}
 
 	wave_fmt->bytesperchannel = wave_fmt->bitsperchannel >> 3;
+	wave_fmt->bytespersample = wave_fmt->channels * wave_fmt->bytesperchannel;
+	wave_fmt->bytespersec = wave_fmt->bytespersample * wave_fmt->samplingrate;
 
 	if (wave_fmt->channels == 2)
 		wave_fmt->bytespervoicesample = wave_fmt->channels * wave_fmt->bytesperchannel;
 	else
 		wave_fmt->bytespervoicesample = wave_fmt->bytesperchannel;
-
-	wave_fmt->bytespersample = wave_fmt->channels * wave_fmt->bytesperchannel;
-	wave_fmt->bytespersec = wave_fmt->bytespersample * wave_fmt->samplingrate;
-}
-
-/**
- * alloc_buffer -
- *
- * allocates the memory buffer for a voice. Two page tables are kept for each buffer.
- * One (dma_handle) keeps track of the host memory pages used and the other (virtualpagetable)
- * is passed to the device so that it can do DMA to host memory. 
- *
- */
-static int alloc_buffer(struct emu10k1_card *card, struct waveout_buffer *buffer, unsigned int voicenum)
-{
-	u32 pageindex, pagecount;
-	unsigned long busaddx;
-	int i;
-
-	DPD(2, "requested pages is: %d\n", buffer->pages);
-
-	if ((buffer->mem[voicenum].emupageindex =
-	 emu10k1_addxmgr_alloc(buffer->pages * PAGE_SIZE, card)) < 0)
-		return -1;
-
-	/* Fill in virtual memory table */
-	for (pagecount = 0; pagecount < buffer->pages; pagecount++) {
-		if ((buffer->mem[voicenum].addr[pagecount] =
-		 pci_alloc_consistent(card->pci_dev, PAGE_SIZE,
-		 &buffer->mem[voicenum].dma_handle[pagecount])) == NULL) {
-			buffer->pages = pagecount;
-			return -1;
-		}
-
-		DPD(2, "Virtual Addx: %p\n", buffer->mem[voicenum].addr[pagecount]);
-
-		for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
-			busaddx = buffer->mem[voicenum].dma_handle[pagecount] + i * EMUPAGESIZE;
-
-			DPD(3, "Bus Addx: %#lx\n", busaddx);
-
-			pageindex = buffer->mem[voicenum].emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
-
-			((u32 *) card->virtualpagetable.addr)[pageindex] = cpu_to_le32((busaddx * 2) | pageindex);
-		}
-	}
-
-	return 0;
-}
-
-/**
- * free_buffer -
- *
- * frees the memory buffer for a voice.
- */
-static void free_buffer(struct emu10k1_card *card, struct waveout_buffer *buffer, unsigned int voicenum)
-{
-	u32 pagecount, pageindex;
-	int i;
-
-	if (buffer->mem[voicenum].emupageindex < 0)
-		return;
-
-	for (pagecount = 0; pagecount < buffer->pages; pagecount++) {
-		pci_free_consistent(card->pci_dev, PAGE_SIZE,
-		 buffer->mem[voicenum].addr[pagecount],
-		 buffer->mem[voicenum].dma_handle[pagecount]);
-
-		for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
-			pageindex = buffer->mem[voicenum].emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
-			((u32 *) card->virtualpagetable.addr)[pageindex] =
-			 cpu_to_le32((card->silentpage.dma_handle * 2) | pageindex);
-		}
-	}
-
-	emu10k1_addxmgr_free(card, buffer->mem[voicenum].emupageindex);
-	buffer->mem[voicenum].emupageindex = -1;
 }
 
 static int get_voice(struct emu10k1_card *card, struct woinst *woinst, unsigned int voicenum)
 {
 	struct emu_voice *voice = &woinst->voice[voicenum];
-	/* Allocate voices here, if no voices available, return error.
-	 * Init voice_allocdesc first.*/
+
+	/* Allocate voices here, if no voices available, return error. */
 
 	voice->usage = VOICE_USAGE_PLAYBACK;
 
@@ -219,7 +144,7 @@
 
 	DPD(2, "Initial pitch --> %#x\n", voice->initial_pitch);
 
-	voice->startloop = (woinst->buffer.mem[voicenum].emupageindex << 12) /
+	voice->startloop = (voice->mem.emupageindex << 12) /
 	 woinst->format.bytespervoicesample;
 	voice->endloop = voice->startloop + woinst->buffer.size / woinst->format.bytespervoicesample;
 	voice->start = voice->startloop;
@@ -297,12 +222,12 @@
 	struct woinst *woinst = wave_dev->woinst;
 	struct waveout_buffer *buffer = &woinst->buffer;
 	unsigned int voicenum;
-	u32 delay;
+	u16 delay;
 
 	DPF(2, "emu10k1_waveout_open()\n");
 
 	for (voicenum = 0; voicenum < woinst->num_voices; voicenum++) {
-		if (alloc_buffer(card, buffer, voicenum) < 0) {
+		if (emu10k1_voice_alloc_buffer(card, &woinst->voice[voicenum].mem, woinst->buffer.pages) < 0) {
 			ERROR();
 			emu10k1_waveout_close(wave_dev);
 			return -1;
@@ -324,7 +249,7 @@
 	delay = (48000 * woinst->buffer.fragment_size) /
 		 (woinst->format.samplingrate * woinst->format.bytespervoicesample);
 
-	emu10k1_timer_install(card, &woinst->timer, delay / 2);
+	emu10k1_timer_install(card, &woinst->timer, delay);
 
 	woinst->state = WAVE_STATE_OPEN;
 
@@ -345,7 +270,7 @@
 
 	for (voicenum = 0; voicenum < woinst->num_voices; voicenum++) {
 		emu10k1_voice_free(&woinst->voice[voicenum]);
-		free_buffer(card, &woinst->buffer, voicenum);
+		emu10k1_voice_free_buffer(card, &woinst->voice[voicenum].mem);
 	}
 
 	woinst->state = WAVE_STATE_CLOSED;
@@ -371,7 +296,7 @@
 	struct emu10k1_card *card = wave_dev->card;
 	struct woinst *woinst = wave_dev->woinst;
 	unsigned int voicenum;
-	u32 delay;
+	u16 delay;
 
 	DPF(2, "emu10k1_waveout_setformat()\n");
 
@@ -404,7 +329,7 @@
 		delay = (48000 * woinst->buffer.fragment_size) /
 			 (woinst->format.samplingrate * woinst->format.bytespervoicesample);
 
-		emu10k1_timer_install(card, &woinst->timer, delay / 2);
+		emu10k1_timer_install(card, &woinst->timer, delay);
 	}
 
 	return 0;
@@ -449,7 +374,7 @@
 
 	pending_bytes = buffer->size - buffer->free_bytes;
 
-	buffer->fill_silence = (pending_bytes < (signed) buffer->fragment_size) ? 1 : 0;
+	buffer->fill_silence = (pending_bytes < (signed) buffer->fragment_size * 2) ? 1 : 0;
 
 	if (pending_bytes > (signed) buffer->silence_bytes) {
 		*total_free_bytes = (buffer->free_bytes + buffer->silence_bytes);
@@ -483,17 +408,14 @@
 
 	if (len > PAGE_SIZE - pgoff) {
 		k = PAGE_SIZE - pgoff;
-		if (__copy_from_user((u8 *)dst[pg] + pgoff, src, k))
-			return;
+		__copy_from_user((u8 *)dst[pg] + pgoff, src, k);
 		len -= k;
 		while (len > PAGE_SIZE) {
-			if (__copy_from_user(dst[++pg], src + k, PAGE_SIZE))
-				return;
+			__copy_from_user(dst[++pg], src + k, PAGE_SIZE);
 			k += PAGE_SIZE;
 			len -= PAGE_SIZE;
 		}
-		if (__copy_from_user(dst[++pg], src + k, len))
-			return;
+		__copy_from_user(dst[++pg], src + k, len);
 
 	} else
 		__copy_from_user((u8 *)dst[pg] + pgoff, src, len);
@@ -511,15 +433,14 @@
         unsigned int pg;
 	unsigned int pgoff;
 	unsigned int voice_num;
-	struct waveout_mem *mem = woinst->buffer.mem;
+	struct emu_voice *voice = woinst->voice;
 
 	pg = str / PAGE_SIZE;
 	pgoff = str % PAGE_SIZE;
 
 	while (len) { 
 		for (voice_num = 0; voice_num < woinst->num_voices; voice_num++) {
-			if (__copy_from_user((u8 *)(mem[voice_num].addr[pg]) + pgoff, src, woinst->format.bytespervoicesample))
-				return;
+			__copy_from_user((u8 *)(voice[voice_num].mem.addr[pg]) + pgoff, src, woinst->format.bytespervoicesample);
 			src += woinst->format.bytespervoicesample;
 		}
 
@@ -544,7 +465,7 @@
 	unsigned int pg;
 	unsigned int pgoff;
 	unsigned int voice_num;
-        struct waveout_mem *mem = woinst->buffer.mem;
+        struct emu_voice *voice = woinst->voice;
 	unsigned int  k;
 
 	pg = str / PAGE_SIZE;
@@ -553,22 +474,22 @@
 	if (len > PAGE_SIZE - pgoff) {
 		k = PAGE_SIZE - pgoff;
 		for (voice_num = 0; voice_num < woinst->num_voices; voice_num++)
-			memset((u8 *)mem[voice_num].addr[pg] + pgoff, data, k);
+			memset((u8 *)voice[voice_num].mem.addr[pg] + pgoff, data, k);
 		len -= k;
 		while (len > PAGE_SIZE) {
 			pg++;
 			for (voice_num = 0; voice_num < woinst->num_voices; voice_num++)
-				memset(mem[voice_num].addr[pg], data, PAGE_SIZE);
+				memset(voice[voice_num].mem.addr[pg], data, PAGE_SIZE);
 
 			len -= PAGE_SIZE;
 		}
 		pg++;
 		for (voice_num = 0; voice_num < woinst->num_voices; voice_num++)
-			memset(mem[voice_num].addr[pg], data, len);
+			memset(voice[voice_num].mem.addr[pg], data, len);
 
 	} else {
 		for (voice_num = 0; voice_num < woinst->num_voices; voice_num++)
-			memset((u8 *)mem[voice_num].addr[pg] + pgoff, data, len);
+			memset((u8 *)voice[voice_num].mem.addr[pg] + pgoff, data, len);
 	}
 }
 
@@ -582,6 +503,7 @@
 void emu10k1_waveout_xferdata(struct woinst *woinst, u8 *data, u32 *size)
 {
 	struct waveout_buffer *buffer = &woinst->buffer;
+	struct voice_mem *mem = &woinst->voice[0].mem;
 	u32 sizetocopy, sizetocopy_now, start;
 	unsigned long flags;
 
@@ -610,14 +532,14 @@
 			copy_ilv_block(woinst, start, data, sizetocopy_now);
 			copy_ilv_block(woinst, 0, data + sizetocopy_now * woinst->num_voices, sizetocopy);
 		} else {
-			copy_block(buffer->mem[0].addr, start, data, sizetocopy_now);
-			copy_block(buffer->mem[0].addr, 0, data + sizetocopy_now, sizetocopy);
+			copy_block(mem->addr, start, data, sizetocopy_now);
+			copy_block(mem->addr, 0, data + sizetocopy_now, sizetocopy);
 		}
 	} else {
 		if (woinst->num_voices > 1)
 			copy_ilv_block(woinst, start, data, sizetocopy);
 		else
-			copy_block(buffer->mem[0].addr, start, data, sizetocopy);
+			copy_block(mem->addr, start, data, sizetocopy);
 	}
 }
 
@@ -674,7 +596,7 @@
 {
 	u32 hw_pos;
 	u32 diff;
-	
+
 	/* There is no actual start yet */
 	if (!(woinst->state & WAVE_STATE_STARTED)) {
 		hw_pos = woinst->buffer.hw_pos;
diff -Nru a/sound/oss/emu10k1/cardwo.h b/sound/oss/emu10k1/cardwo.h
--- a/sound/oss/emu10k1/cardwo.h	Sun Feb 10 18:50:11 2002
+++ b/sound/oss/emu10k1/cardwo.h	Sun Feb 16 16:30:06 2003
@@ -39,20 +39,13 @@
 
 /* setting this to other than a power of two may break some applications */
 #define WAVEOUT_MAXBUFSIZE	MAXBUFSIZE
-#define WAVEOUT_MINBUFSIZE	64
 
 #define WAVEOUT_DEFAULTFRAGLEN	20 /* Time to play a fragment in ms (latency) */
 #define WAVEOUT_DEFAULTBUFLEN	500 /* Time to play the entire buffer in ms */
 
-#define WAVEOUT_MINFRAGSHIFT	6
-#define WAVEOUT_MAXVOICES 6
-
-/* waveout_mem is cardwo internal */
-struct waveout_mem {
-	int emupageindex;
-	void *addr[BUFMAXPAGES];
-	dma_addr_t dma_handle[BUFMAXPAGES];
-};
+#define WAVEOUT_MINFRAGSHIFT	6 /* Minimum fragment size in bytes is 2^6 */
+#define WAVEOUT_MINFRAGS	3 /* _don't_ go bellow 3, it would break silence filling */
+#define WAVEOUT_MAXVOICES	6
 
 struct waveout_buffer {
 	u16 ossfragshift;
@@ -60,7 +53,6 @@
 	u32 fragment_size;	/* in bytes units */
 	u32 size;		/* in bytes units */
 	u32 pages;		/* buffer size in page units*/
-	struct waveout_mem mem[WAVEOUT_MAXVOICES];
 	u32 silence_pos;	/* software cursor position (including silence bytes) */
 	u32 hw_pos;		/* hardware cursor position */
 	u32 free_bytes;		/* free bytes available on the buffer (not including silence bytes) */
diff -Nru a/sound/oss/emu10k1/efxmgr.c b/sound/oss/emu10k1/efxmgr.c
--- a/sound/oss/emu10k1/efxmgr.c	Sun Feb 10 18:50:09 2002
+++ b/sound/oss/emu10k1/efxmgr.c	Sun Feb 16 16:30:06 2003
@@ -38,7 +38,7 @@
         struct dsp_patch *patch;
 	struct dsp_rpatch *rpatch;
 	char s[PATCH_NAME_SIZE + 4];
-	u32 *gpr_used;
+	unsigned long *gpr_used;
 	int i;
 
 	DPD(2, "emu10k1_find_control_gpr(): %s %s\n", patch_name, gpr_name);
@@ -103,7 +103,7 @@
 
 	card->ac97.mixer_state[oss_mixer] = (right << 8) | left;
 
-	if (!card->isaps)
+	if (!card->is_aps)
 		card->ac97.write_mixer(&card->ac97, oss_mixer, left, right);
 	
 	emu10k1_set_volume_gpr(card, card->mgr.ctrl_gpr[oss_mixer][0], left,
@@ -171,9 +171,8 @@
 {
 	struct patch_manager *mgr = &card->mgr;
 	unsigned long flags;
-	int muting;
 
-	const s32 log2lin[5] ={                  //  attenuation (dB)
+	static const s32 log2lin[4] ={           //  attenuation (dB)
 		0x7fffffff,                      //       0.0         
 		0x7fffffff * 0.840896415253715 , //       1.5          
 		0x7fffffff * 0.707106781186548,  //       3.0
@@ -183,12 +182,10 @@
 	if (addr < 0)
 		return;
 
-	muting = (scale == 0x10) ? 0x7f: scale;
-	
 	vol = (100 - vol ) * scale / 100;
 
 	// Thanks to the comp.dsp newsgroup for this neat trick:
-	vol = (vol >= muting) ? 0 : (log2lin[vol & 3] >> (vol >> 2));
+	vol = (vol >= scale) ? 0 : (log2lin[vol & 3] >> (vol >> 2));
 
 	spin_lock_irqsave(&mgr->lock, flags);
 	emu10k1_set_control_gpr(card, addr, vol, 0);
diff -Nru a/sound/oss/emu10k1/efxmgr.h b/sound/oss/emu10k1/efxmgr.h
--- a/sound/oss/emu10k1/efxmgr.h	Sun Feb 10 18:50:16 2002
+++ b/sound/oss/emu10k1/efxmgr.h	Sun Feb 16 16:30:06 2003
@@ -35,9 +35,9 @@
 #define WRITE_EFX(a, b, c) sblive_writeptr((a), MICROCODEBASE + (b), 0, (c))
 
 #define OP(op, z, w, x, y) \
-        do { WRITE_EFX(card, (pc) * 2, ((x) << 10) | (y)); \
-        WRITE_EFX(card, (pc) * 2 + 1, ((op) << 20) | ((z) << 10) | (w)); \
-        ++pc; } while (0)
+	do { WRITE_EFX(card, (pc) * 2, ((x) << 10) | (y)); \
+	WRITE_EFX(card, (pc) * 2 + 1, ((op) << 20) | ((z) << 10) | (w)); \
+	++pc; } while (0)
 
 #define NUM_INPUTS 0x20
 #define NUM_OUTPUTS 0x20
@@ -47,52 +47,52 @@
 
 struct dsp_rpatch {
 	char name[PATCH_NAME_SIZE];
-        u16 code_start;
-        u16 code_size;
+	u16 code_start;
+	u16 code_size;
 
-        u32 gpr_used[NUM_GPRS / 32];
-        u32 gpr_input[NUM_GPRS / 32];
-        u32 route[NUM_OUTPUTS];
-        u32 route_v[NUM_OUTPUTS];
+	unsigned long gpr_used[NUM_GPRS / (sizeof(unsigned long) * 8) + 1];
+	unsigned long gpr_input[NUM_GPRS / (sizeof(unsigned long) * 8) + 1];
+	unsigned long route[NUM_OUTPUTS];
+	unsigned long route_v[NUM_OUTPUTS];
 };
 
 struct dsp_patch {
-        char name[PATCH_NAME_SIZE];
-        u8 id;
-        u32 input;                      /* bitmap of the lines used as inputs */
-	u32 output;                     /* bitmap of the lines used as outputs */
-        u16 code_start;
-        u16 code_size;
-
-        u32 gpr_used[NUM_GPRS / 32];    /* bitmap of used gprs */
-        u32 gpr_input[NUM_GPRS / 32];
-        u8 traml_istart;  /* starting address of the internal tram lines used */
-        u8 traml_isize;   /* number of internal tram lines used */
-
-        u8 traml_estart;
-        u8 traml_esize;
-
-        u16 tramb_istart;        /* starting address of the internal tram memory used */
-        u16 tramb_isize;         /* amount of internal memory used */
-        u32 tramb_estart;
-        u32 tramb_esize;
+	char name[PATCH_NAME_SIZE];
+	u8 id;
+	unsigned long input;	/* bitmap of the lines used as inputs */
+	unsigned long output;	/* bitmap of the lines used as outputs */
+	u16 code_start;
+	u16 code_size;
+
+	unsigned long gpr_used[NUM_GPRS / (sizeof(unsigned long) * 8) + 1];	/* bitmap of used gprs */
+	unsigned long gpr_input[NUM_GPRS / (sizeof(unsigned long) * 8) + 1];
+	u8 traml_istart;	/* starting address of the internal tram lines used */
+	u8 traml_isize;		/* number of internal tram lines used */
+
+	u8 traml_estart;
+	u8 traml_esize;
+
+	u16 tramb_istart;        /* starting address of the internal tram memory used */
+	u16 tramb_isize;         /* amount of internal memory used */
+	u32 tramb_estart;
+	u32 tramb_esize;
 };
 
 struct dsp_gpr {
-        u8 type;                      /* gpr type, STATIC, DYNAMIC, INPUT, OUTPUT, CONTROL */
-        char name[GPR_NAME_SIZE];       /* gpr value, only valid for control gprs */
-        s32 min, max;         /* value range for this gpr, only valid for control gprs */
-        u8 line;                    /* which input/output line is the gpr attached, only valid for input/output gprs */
-        u8 usage;
+	u8 type;			/* gpr type, STATIC, DYNAMIC, INPUT, OUTPUT, CONTROL */
+	char name[GPR_NAME_SIZE];	/* gpr value, only valid for control gprs */
+	s32 min, max;			/* value range for this gpr, only valid for control gprs */
+	u8 line;			/* which input/output line is the gpr attached, only valid for input/output gprs */
+	u8 usage;
 };
 
 enum {
-        GPR_TYPE_NULL = 0,
-        GPR_TYPE_IO,
-        GPR_TYPE_STATIC,
-        GPR_TYPE_DYNAMIC,
-        GPR_TYPE_CONTROL,
-        GPR_TYPE_CONSTANT
+	GPR_TYPE_NULL = 0,
+	GPR_TYPE_IO,
+	GPR_TYPE_STATIC,
+	GPR_TYPE_DYNAMIC,
+	GPR_TYPE_CONTROL,
+	GPR_TYPE_CONSTANT
 };
 
 #define GPR_BASE 0x100
@@ -101,14 +101,13 @@
 #define MAX_PATCHES_PAGES 32
 
 struct patch_manager {
-        void *patch[MAX_PATCHES_PAGES];
+	void *patch[MAX_PATCHES_PAGES];
 	int current_pages;
-        struct dsp_rpatch rpatch;
-        struct dsp_gpr gpr[NUM_GPRS];   /* gpr usage table */
+	struct dsp_rpatch rpatch;
+	struct dsp_gpr gpr[NUM_GPRS];   /* gpr usage table */
 	spinlock_t lock;
 	s16 ctrl_gpr[SOUND_MIXER_NRDEVICES][2];
 };
-
 
 #define PATCHES_PER_PAGE (PAGE_SIZE / sizeof(struct dsp_patch))
 
diff -Nru a/sound/oss/emu10k1/hwaccess.c b/sound/oss/emu10k1/hwaccess.c
--- a/sound/oss/emu10k1/hwaccess.c	Sun Feb 10 18:50:13 2002
+++ b/sound/oss/emu10k1/hwaccess.c	Sun Feb 16 16:30:06 2003
@@ -187,6 +187,15 @@
 	}
 }
 
+void emu10k1_timer_set(struct emu10k1_card * card, u16 data)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&card->lock, flags);
+	outw(data & TIMER_RATE_MASK, card->iobase + TIMER);
+	spin_unlock_irqrestore(&card->lock, flags);
+}
+
 /************************************************************************
 * write/read Emu10k1 pointer-offset register set, accessed through      *
 *  the PTR and DATA registers                                           *
diff -Nru a/sound/oss/emu10k1/hwaccess.h b/sound/oss/emu10k1/hwaccess.h
--- a/sound/oss/emu10k1/hwaccess.h	Sun Feb 10 18:50:14 2002
+++ b/sound/oss/emu10k1/hwaccess.h	Sun Feb 16 16:30:06 2003
@@ -126,6 +126,7 @@
 #define CMD_SETMCH_FX		_IOW('D', 17, struct mixer_private_ioctl)
 #define CMD_SETPASSTHROUGH	_IOW('D', 18, struct mixer_private_ioctl)
 #define CMD_PRIVATE3_VERSION	_IOW('D', 19, struct mixer_private_ioctl)
+#define CMD_AC97_BOOST		_IOW('D', 20, struct mixer_private_ioctl)
 
 //up this number when breaking compatibility
 #define PRIVATE3_VERSION 1
@@ -144,7 +145,7 @@
 	u16			emupagetable[MAXPAGES];
 
 	struct list_head	timers;
-	unsigned		timer_delay;
+	u16			timer_delay;
 	spinlock_t		timer_lock;
 
 	struct pci_dev		*pci_dev;
@@ -181,7 +182,7 @@
 
 	u8 chiprev;                    /* Chip revision                */
 
-	int isaps;
+	u8 is_aps;
 
 	struct patch_manager mgr;
 	struct pt_data pt;
@@ -190,8 +191,6 @@
 int emu10k1_addxmgr_alloc(u32, struct emu10k1_card *);
 void emu10k1_addxmgr_free(struct emu10k1_card *, int);
 
-
-
 int emu10k1_find_control_gpr(struct patch_manager *, const char *, const char *);
 void emu10k1_set_control_gpr(struct emu10k1_card *, int , s32, int );
 
@@ -211,12 +210,14 @@
 
 /* Hardware Abstraction Layer access functions */
 
-void emu10k1_writefn0(struct emu10k1_card *, u32 , u32 );
-u32 emu10k1_readfn0(struct emu10k1_card *, u32 );
+void emu10k1_writefn0(struct emu10k1_card *, u32, u32);
+u32 emu10k1_readfn0(struct emu10k1_card *, u32);
+
+void emu10k1_timer_set(struct emu10k1_card *, u16);
 
-void sblive_writeptr(struct emu10k1_card *, u32 , u32 , u32 );
-void sblive_writeptr_tag(struct emu10k1_card *card, u32 channel, ...);
-#define TAGLIST_END 0
+void sblive_writeptr(struct emu10k1_card *, u32, u32, u32);
+void sblive_writeptr_tag(struct emu10k1_card *, u32, ...);
+#define TAGLIST_END	0
 
 u32 sblive_readptr(struct emu10k1_card *, u32 , u32 );
 
diff -Nru a/sound/oss/emu10k1/irqmgr.c b/sound/oss/emu10k1/irqmgr.c
--- a/sound/oss/emu10k1/irqmgr.c	Sun Feb 10 18:50:07 2002
+++ b/sound/oss/emu10k1/irqmgr.c	Sun Feb 16 16:30:06 2003
@@ -1,4 +1,3 @@
-
 /*
  **********************************************************************
  *     irqmgr.c - IRQ manager for emu10k1 driver
@@ -41,7 +40,7 @@
 void emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct emu10k1_card *card = (struct emu10k1_card *) dev_id;
-	u32 irqstatus;
+	u32 irqstatus, irqstatus_tmp;
 
 	DPD(4, "emu10k1_interrupt called, irq =  %u\n", irq);
 
@@ -60,8 +59,7 @@
 	while ((irqstatus = inl(card->iobase + IPR))) {
 		DPD(4, "irq status %#x\n", irqstatus);
 
-		/* acknowledge interrupt */
-		outl(irqstatus, card->iobase + IPR);
+		irqstatus_tmp = irqstatus;
 
 		if (irqstatus & IRQTYPE_TIMER) {
 			emu10k1_timer_irqhandler(card);
@@ -98,7 +96,15 @@
 			irqstatus &=~IPR_VOLDECR;
 		}
 
-		if (irqstatus)
-			emu10k1_irq_disable(card, irqstatus);
+		if (irqstatus){
+			printk(KERN_ERR "emu10k1: Warning, unhandled interrupt: %#08x\n", irqstatus);
+			//make sure any interrupts we don't handle are disabled:
+			emu10k1_irq_disable(card, ~(INTE_MIDIRXENABLE | INTE_MIDITXENABLE | INTE_INTERVALTIMERENB |
+						INTE_VOLDECRENABLE | INTE_VOLINCRENABLE | INTE_MUTEENABLE |
+						INTE_FXDSPENABLE));
+		}
+
+		/* acknowledge interrupt */
+                outl(irqstatus_tmp, card->iobase + IPR);
 	}
 }
diff -Nru a/sound/oss/emu10k1/main.c b/sound/oss/emu10k1/main.c
--- a/sound/oss/emu10k1/main.c	Wed Feb 13 13:20:55 2002
+++ b/sound/oss/emu10k1/main.c	Sun Feb 16 16:30:06 2003
@@ -1,4 +1,4 @@
-/*
+ /*
  **********************************************************************
  *     main.c - Creative EMU10K1 audio driver
  *     Copyright 1999, 2000 Creative Labs, Inc.
@@ -69,7 +69,20 @@
  *     0.16 Mixer improvements, added old treble/bass support (Daniel Bertrand)
  *          Small code format cleanup.
  *          Deadlock bug fix for emu10k1_volxxx_irqhandler().
- *
+ *     0.17 Fix for mixer SOUND_MIXER_INFO ioctl.
+ *	    Fix for HIGHMEM machines (emu10k1 can only do 31 bit bus master) 
+ *	    midi poll initial implementation.
+ *	    Small mixer fixes/cleanups.
+ *	    Improved support for 5.1 cards.
+ *     0.18 Fix for possible leak in pci_alloc_consistent()
+ *          Cleaned up poll() functions (audio and midi). Don't start input.
+ *	    Restrict DMA pages used to 512Mib range.
+ *	    New AC97_BOOST mixer ioctl.
+ *     0.19 Real fix for kernel with highmem support (cast dma_handle to u32).
+ *	    Fix recording buffering parameters calculation.
+ *	    Use unsigned long for variables in bit ops.
+ *     0.20 Fixed recording startup
+ *	    Fixed timer rate setting (it's a 16-bit register)
  *********************************************************************/
 
 /* These are only included once per module */
@@ -102,11 +115,10 @@
 #define SNDCARD_EMU10K1 46
 #endif
  
-#define DRIVER_VERSION "0.16"
+#define DRIVER_VERSION "0.20"
 
-/* FIXME: is this right? */
-/* does the card support 32 bit bus master?*/
-#define EMU10K1_DMA_MASK                0xffffffff	/* DMA buffer mask for pci_alloc_consist */
+/* the emu10k1 _seems_ to only supports 29 bit (512MiB) bit bus master */
+#define EMU10K1_DMA_MASK                0x1fffffff	/* DMA buffer mask for pci_alloc_consist */
 
 #ifndef PCI_VENDOR_ID_CREATIVE
 #define PCI_VENDOR_ID_CREATIVE 0x1102
@@ -188,7 +200,7 @@
 
 	/* Assign default recording parameters */
 	/* FIXME */
-	if(card->isaps)
+	if (card->is_aps)
 		card->wavein.recsrc = WAVERECORD_FX;
 	else
 		card->wavein.recsrc = WAVERECORD_AC97;
@@ -211,6 +223,8 @@
 static int __devinit emu10k1_mixer_init(struct emu10k1_card *card)
 {
 	char s[32];
+
+	struct ac97_codec *codec = &card->ac97;
 	card->ac97.dev_mixer = register_sound_mixer(&emu10k1_mixer_fops, -1);
 	if (card->ac97.dev_mixer < 0) {
 		printk(KERN_ERR "emu10k1: cannot register mixer device\n");
@@ -219,7 +233,7 @@
 
 	card->ac97.private_data = card;
 
-	if (!card->isaps) {
+	if (!card->is_aps) {
 		card->ac97.id = 0;
 		card->ac97.codec_read = emu10k1_ac97_read;
         	card->ac97.codec_write = emu10k1_ac97_write;
@@ -228,11 +242,14 @@
 			printk(KERN_ERR "emu10k1: unable to probe AC97 codec\n");
 			goto err_out;
 		}
-		/* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
-			does not support this, it shouldn't do any harm */
-		sblive_writeptr(card, AC97SLOT, 0, AC97SLOT_CNTR | AC97SLOT_LFE);
+		/* 5.1: Enable the additional AC97 Slots and unmute extra channels on AC97 codec */
+		if (codec->codec_read(codec, AC97_EXTENDED_ID) & 0x0080){
+			printk(KERN_INFO "emu10k1: SBLive! 5.1 card detected\n"); 
+			sblive_writeptr(card, AC97SLOT, 0, AC97SLOT_CNTR | AC97SLOT_LFE);
+			codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0);
+		}
 
-		// Force 5bit
+		// Force 5bit:		    
 		//card->ac97.bit_resolution=5;
 
 		if (!proc_mkdir ("driver/emu10k1", 0)) {
@@ -274,7 +291,7 @@
 {
 	char s[32];
 
-	if (!card->isaps) {
+	if (!card->is_aps) {
 		sprintf(s, "driver/emu10k1/%s/ac97", card->pci_dev->slot_name);
 		remove_proc_entry(s, NULL);
 
@@ -586,15 +603,15 @@
 	CONNECT(PCM1_IN_R, ANALOG_REAR_R);
 
 	/* Digital In + PCM + AC97 In + MULTI_FRONT --> Digital out */
-	OP(6, 0x10b, 0x100, 0x102, 0x10c);
-	OP(6, 0x10b, 0x10b, 0x113, 0x40);
+	OP(6, 0x10a, 0x100, 0x102, 0x10c);
+	OP(6, 0x10a, 0x10a, 0x113, 0x40);
 
 	CONNECT(MULTI_FRONT_L, DIGITAL_OUT_L);
 	CONNECT(PCM_IN_L, DIGITAL_OUT_L);
 	CONNECT(AC97_IN_L, DIGITAL_OUT_L);
 	CONNECT(SPDIF_CD_L, DIGITAL_OUT_L);
 
-	OP(6, 0x10a, 0x101, 0x103, 0x10e);
+	OP(6, 0x10b, 0x101, 0x103, 0x10e);
 	OP(6, 0x10b, 0x10b, 0x114, 0x40);
 
 	CONNECT(MULTI_FRONT_R, DIGITAL_OUT_R);
@@ -768,7 +785,7 @@
 				    VTFT, 0xffff,
 				    CVCF, 0xffff,
 				    PTRX, 0,
-				    CPF, 0,
+				    //CPF, 0,
 				    CCR, 0,
 
 				    PSST, 0,
@@ -794,7 +811,9 @@
 				    ENVVOL, 0,
 				    ENVVAL, 0,
                                     TAGLIST_END);
+		sblive_writeptr(card, CPF, nCh, 0);
 	}
+	
 
 	/*
 	 ** Init to 0x02109204 :
@@ -852,19 +871,19 @@
 	}
 
 	for (pagecount = 0; pagecount < MAXPAGES; pagecount++)
-		((u32 *) card->virtualpagetable.addr)[pagecount] = cpu_to_le32((card->silentpage.dma_handle * 2) | pagecount);
+		((u32 *) card->virtualpagetable.addr)[pagecount] = cpu_to_le32(((u32) card->silentpage.dma_handle * 2) | pagecount);
 
 	/* Init page table & tank memory base register */
 	sblive_writeptr_tag(card, 0,
-			    PTB, card->virtualpagetable.dma_handle,
+			    PTB, (u32) card->virtualpagetable.dma_handle,
 			    TCB, 0,
 			    TCBS, 0,
 			    TAGLIST_END);
 
 	for (nCh = 0; nCh < NUM_G; nCh++) {
 		sblive_writeptr_tag(card, nCh,
-				    MAPA, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
-				    MAPB, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
+				    MAPA, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
+				    MAPB, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
 				    TAGLIST_END);
 	}
 
@@ -951,8 +970,9 @@
 				    VTFT, 0,
 				    CVCF, 0,
 				    PTRX, 0,
-				    CPF, 0,
+				    //CPF, 0,
 				    TAGLIST_END);
+		sblive_writeptr(card, CPF, ch, 0);
 	}
 
 	/* Disable audio and lock cache */
@@ -999,7 +1019,7 @@
 	int ret;
 
 	if (pci_set_dma_mask(pci_dev, EMU10K1_DMA_MASK)) {
-		printk(KERN_ERR "emu10k1: architecture does not support 32bit PCI busmaster DMA\n");
+		printk(KERN_ERR "emu10k1: architecture does not support 29bit PCI busmaster DMA\n");
 		return -ENODEV;
 	}
 
@@ -1038,12 +1058,12 @@
 	pci_read_config_byte(pci_dev, PCI_REVISION_ID, &card->chiprev);
 	pci_read_config_word(pci_dev, PCI_SUBSYSTEM_ID, &card->model);
 
-	printk(KERN_INFO "emu10k1: %s rev %d model 0x%x found, IO at 0x%04lx-0x%04lx, IRQ %d\n",
+	printk(KERN_INFO "emu10k1: %s rev %d model %#04x found, IO at %#04lx-%#04lx, IRQ %d\n",
 		card_names[pci_id->driver_data], card->chiprev, card->model, card->iobase,
 		card->iobase + card->length - 1, card->irq);
 
 	pci_read_config_dword(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &subsysvid);
-	card->isaps = (subsysvid == EMU_APS_SUBID);
+	card->is_aps = (subsysvid == EMU_APS_SUBID);
 
 	spin_lock_init(&card->lock);
 	init_MUTEX(&card->open_sem);
@@ -1074,7 +1094,7 @@
 		goto err_emu10k1_init;
 	}
 
-	if (card->isaps)
+	if (card->is_aps)
 		emu10k1_ecard_init(card);
 
 	list_add(&card->list, &emu10k1_devs);
@@ -1119,7 +1139,7 @@
 	pci_set_drvdata(pci_dev, NULL);
 }
 
-MODULE_AUTHOR("Bertrand Lee, Cai Ying. (Email to: emu10k1-devel@opensource.creative.com)");
+MODULE_AUTHOR("Bertrand Lee, Cai Ying. (Email to: emu10k1-devel@lists.sourceforge.net)");
 MODULE_DESCRIPTION("Creative EMU10K1 PCI Audio Driver v" DRIVER_VERSION "\nCopyright (C) 1999 Creative Technology Ltd.");
 MODULE_LICENSE("GPL");
 
diff -Nru a/sound/oss/emu10k1/midi.c b/sound/oss/emu10k1/midi.c
--- a/sound/oss/emu10k1/midi.c	Sun Feb 10 18:50:17 2002
+++ b/sound/oss/emu10k1/midi.c	Thu Mar 13 16:52:26 2003
@@ -29,8 +29,8 @@
  **********************************************************************
  */
 
-#define __NO_VERSION__
 #include <linux/module.h>
+#include <linux/poll.h>
 #include <linux/slab.h>
 #include <linux/version.h>
 #include <linux/sched.h>
@@ -371,8 +371,32 @@
 
 static unsigned int emu10k1_midi_poll(struct file *file, struct poll_table_struct *wait)
 {
+	struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
+	unsigned long flags;
+	unsigned int mask = 0;
+
 	DPF(4, "emu10k1_midi_poll() called\n");
-	return 0;
+
+	if (file->f_mode & FMODE_WRITE)
+		poll_wait(file, &midi_dev->oWait, wait);
+
+	if (file->f_mode & FMODE_READ)
+		poll_wait(file, &midi_dev->iWait, wait);
+
+	spin_lock_irqsave(&midi_spinlock, flags);
+
+	if (file->f_mode & FMODE_WRITE)
+		mask |= POLLOUT | POLLWRNORM;
+
+	if (file->f_mode & FMODE_READ) {
+		if (midi_dev->mistate == MIDIIN_STATE_STARTED)
+			if (midi_dev->icnt > 0)
+				mask |= POLLIN | POLLRDNORM;
+	}
+
+	spin_unlock_irqrestore(&midi_spinlock, flags);
+
+	return mask;
 }
 
 int emu10k1_midi_callback(unsigned long msg, unsigned long refdata, unsigned long *pmsg)
diff -Nru a/sound/oss/emu10k1/mixer.c b/sound/oss/emu10k1/mixer.c
--- a/sound/oss/emu10k1/mixer.c	Sun Feb 10 18:50:10 2002
+++ b/sound/oss/emu10k1/mixer.c	Thu Mar 13 16:52:26 2003
@@ -30,7 +30,6 @@
  **********************************************************************
  */
 
-#define __NO_VERSION__		/* Kernel version only defined once */
 #include <linux/module.h>
 #include <linux/version.h>
 #include <asm/uaccess.h>
@@ -251,7 +250,7 @@
 		case CMD_SETRECSRC:
 			switch (ctl->val[0]) {
 			case WAVERECORD_AC97:
-				if (card->isaps) {
+				if (card->is_aps) {
 					ret = -EINVAL;
 					break;
 				}
@@ -444,6 +443,7 @@
 
 		case CMD_SETGPR2OSS:
 			id = ctl->val[0];
+			/* 0 == left, 1 == right */
 			ch = ctl->val[1];
 			addr = ctl->val[2];
 
@@ -454,19 +454,19 @@
 
 			card->mgr.ctrl_gpr[id][ch] = addr;
 
-			if (card->isaps)
+			if (card->is_aps)
 				break;
 
 			if (addr >= 0) {
 				unsigned int state = card->ac97.mixer_state[id];
 
-				if (ch) {
+				if (ch == 1) {
 					state >>= 8;
 					card->ac97.stereo_mixers |= (1 << id);
-				} else {
-					card->ac97.supported_mixers |= (1 << id);
 				}
 
+				card->ac97.supported_mixers |= (1 << id);
+
 				if (id == SOUND_MIXER_TREBLE) {
 					set_treble(card, card->ac97.mixer_state[id] & 0xff, (card->ac97.mixer_state[id] >> 8) & 0xff);
 				} else if (id == SOUND_MIXER_BASS) {
@@ -475,10 +475,10 @@
 					emu10k1_set_volume_gpr(card, addr, state & 0xff,
 							       volume_params[id]);
 			} else {
-				if (ch) {
-					card->ac97.stereo_mixers &= ~(1 << id);
-					card->ac97.stereo_mixers |= card->ac97_stereo_mixers;
-				} else {
+				card->ac97.stereo_mixers &= ~(1 << id);
+				card->ac97.stereo_mixers |= card->ac97_stereo_mixers;
+
+				if (ch == 0) {
 					card->ac97.supported_mixers &= ~(1 << id);
 					card->ac97.supported_mixers |= card->ac97_supported_mixers;
 				}
@@ -499,6 +499,12 @@
 				ret = -EFAULT;
 			break;
 
+		case CMD_AC97_BOOST:
+			if(ctl->val[0])
+				emu10k1_ac97_write(&card->ac97, 0x18, 0x0);	
+			else
+				emu10k1_ac97_write(&card->ac97, 0x18, 0x0808);
+			break;
 		default:
 			ret = -EINVAL;
 			break;
@@ -551,7 +557,7 @@
 
 				card->tankmem.size = size;
 
-				sblive_writeptr_tag(card, 0, TCB, card->tankmem.dma_handle, TCBS, size_reg, TAGLIST_END);
+				sblive_writeptr_tag(card, 0, TCB, (u32) card->tankmem.dma_handle, TCBS, size_reg, TAGLIST_END);
 
 				emu10k1_writefn0(card, HCFG_LOCKTANKCACHE, 0);
 			}
@@ -572,6 +578,8 @@
 	int val;
 	int scale;
 
+	card->ac97.modcnt++;
+
 	if (get_user(val, (int *)arg))
 		return -EFAULT;
 
@@ -612,7 +620,7 @@
 	unsigned int oss_mixer = _IOC_NR(cmd);
 	
 	ret = -EINVAL;
-	if (!card->isaps) {
+	if (!card->is_aps) {
 		if (cmd == SOUND_MIXER_INFO) {
 			mixer_info info;
 
@@ -626,7 +634,7 @@
 			return 0;
 		}
 
-		if ((_IOC_DIR(cmd) == (_IOC_WRITE|_IOC_READ)) && oss_mixer <= SOUND_MIXER_NRDEVICES)
+		if ((_SIOC_DIR(cmd) == (_SIOC_WRITE|_SIOC_READ)) && oss_mixer <= SOUND_MIXER_NRDEVICES)
 			ret = emu10k1_dsp_mixer(card, oss_mixer, arg);
 		else
 			ret = card->ac97.mixer_ioctl(&card->ac97, cmd, arg);
diff -Nru a/sound/oss/emu10k1/passthrough.c b/sound/oss/emu10k1/passthrough.c
--- a/sound/oss/emu10k1/passthrough.c	Sat May 18 22:57:47 2002
+++ b/sound/oss/emu10k1/passthrough.c	Thu Mar 13 16:52:26 2003
@@ -29,7 +29,6 @@
  **********************************************************************
  */
                        
-#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/poll.h>
 #include <linux/slab.h>
@@ -165,15 +164,12 @@
 
 		DPD(3, "prepend size %d, prepending %d bytes\n", pt->prepend_size, needed);
 		if (count < needed) {
-			if (copy_from_user(pt->buf + pt->prepend_size, buffer,
-					   count))
-				return -EFAULT;
+			copy_from_user(pt->buf + pt->prepend_size, buffer, count);
 			pt->prepend_size += count;
 			DPD(3, "prepend size now %d\n", pt->prepend_size);
 			return count;
 		}
-		if (copy_from_user(pt->buf + pt->prepend_size, buffer, needed))
-			return -EFAULT;
+		copy_from_user(pt->buf + pt->prepend_size, buffer, needed);
 		r = pt_putblock(wave_dev, (u16 *) pt->buf, nonblock);
 		if (r)
 			return r;
@@ -184,8 +180,7 @@
 	blocks_copied = 0;
 	while (blocks > 0) {
 		u16 *bufptr = (u16 *) buffer + (bytes_copied/2);
-		if (copy_from_user(pt->buf, bufptr, PT_BLOCKSIZE))
-			return -EFAULT;
+		copy_from_user(pt->buf, bufptr, PT_BLOCKSIZE);
 		bufptr = (u16 *) pt->buf;
 		r = pt_putblock(wave_dev, bufptr, nonblock);
 		if (r) {
@@ -201,8 +196,7 @@
 	i = count - bytes_copied;
 	if (i) {
 		pt->prepend_size = i;
-		if (copy_from_user(pt->buf, buffer + bytes_copied, i))
-			return -EFAULT;
+		copy_from_user(pt->buf, buffer + bytes_copied, i);
 		bytes_copied += i;
 		DPD(3, "filling prepend buffer with %d bytes", i);
 	}
diff -Nru a/sound/oss/emu10k1/recmgr.c b/sound/oss/emu10k1/recmgr.c
--- a/sound/oss/emu10k1/recmgr.c	Sun Feb 10 18:50:17 2002
+++ b/sound/oss/emu10k1/recmgr.c	Sun Feb 16 16:30:06 2003
@@ -29,19 +29,28 @@
  **********************************************************************
  */
 
+#include <asm/delay.h>
 #include "8010.h"
 #include "recmgr.h"
 
+void emu10k1_reset_record(struct emu10k1_card *card, struct wavein_buffer *buffer)
+{
+	DPF(2, "emu10k1_reset_record()\n");
+
+	sblive_writeptr(card, buffer->sizereg, 0, ADCBS_BUFSIZE_NONE);
+
+	sblive_writeptr(card, buffer->sizereg, 0, buffer->sizeregval);	
+
+	while (sblive_readptr(card, buffer->idxreg, 0))
+		udelay(5);
+}
+
 void emu10k1_start_record(struct emu10k1_card *card, struct wavein_buffer *buffer)
 {
 	DPF(2, "emu10k1_start_record()\n");
 
-	sblive_writeptr(card, buffer->sizereg, 0, buffer->sizeregval);
-
 	if (buffer->adcctl)
 		sblive_writeptr(card, ADCCR, 0, buffer->adcctl);
-
-	return;
 }
 
 void emu10k1_stop_record(struct emu10k1_card *card, struct wavein_buffer *buffer)
@@ -51,10 +60,6 @@
 	/* Disable record transfer */
 	if (buffer->adcctl)
 		sblive_writeptr(card, ADCCR, 0, 0);
-
-	sblive_writeptr(card, buffer->sizereg, 0, ADCBS_BUFSIZE_NONE);
-
-	return;
 }
 
 void emu10k1_set_record_src(struct emu10k1_card *card, struct wiinst *wiinst)
@@ -130,9 +135,7 @@
 		break;
 	}
 
-	DPD(2, "bus addx: %#x\n", buffer->dma_handle);
-
-	sblive_writeptr(card, buffer->addrreg, 0, buffer->dma_handle);
+	DPD(2, "bus addx: %#lx\n", (unsigned long) buffer->dma_handle);
 
-	return;
+	sblive_writeptr(card, buffer->addrreg, 0, (u32)buffer->dma_handle);
 }
diff -Nru a/sound/oss/emu10k1/recmgr.h b/sound/oss/emu10k1/recmgr.h
--- a/sound/oss/emu10k1/recmgr.h	Sun Feb 10 18:50:16 2002
+++ b/sound/oss/emu10k1/recmgr.h	Sun Feb 16 16:30:06 2003
@@ -40,9 +40,9 @@
 #define WAVERECORD_MIC		0x02
 #define WAVERECORD_FX		0x03
 
+void emu10k1_reset_record(struct emu10k1_card *card, struct wavein_buffer *buffer);
 void emu10k1_start_record(struct emu10k1_card *, struct wavein_buffer *);
 void emu10k1_stop_record(struct emu10k1_card *, struct wavein_buffer *);
 void emu10k1_set_record_src(struct emu10k1_card *, struct wiinst *wiinst);
-
 
 #endif /* _RECORDMGR_H */
diff -Nru a/sound/oss/emu10k1/timer.c b/sound/oss/emu10k1/timer.c
--- a/sound/oss/emu10k1/timer.c	Sun Feb 10 18:50:11 2002
+++ b/sound/oss/emu10k1/timer.c	Sun Feb 16 16:30:06 2003
@@ -59,7 +59,7 @@
 	return;
 }
 
-void emu10k1_timer_install(struct emu10k1_card *card, struct emu_timer *timer, u32 delay)
+void emu10k1_timer_install(struct emu10k1_card *card, struct emu_timer *timer, u16 delay)
 {
 	struct emu_timer *t;
 	struct list_head *entry;
@@ -85,7 +85,7 @@
 		card->timer_delay = delay;
 		delay = (delay < 1024 ? delay : 1024);
 
-		emu10k1_writefn0(card, TIMER_RATE, delay);
+		emu10k1_timer_set(card, delay);
 
 		list_for_each(entry, &card->timers) {
 			t = list_entry(entry, struct emu_timer, list);
@@ -108,7 +108,7 @@
 {
 	struct emu_timer *t;
 	struct list_head *entry;
-	u32 delay = TIMER_STOPPED;
+	u16 delay = TIMER_STOPPED;
 	unsigned long flags;
 
 	if (timer->state == TIMER_STATE_UNINSTALLED)
@@ -133,7 +133,7 @@
 		else {
 			delay = (delay < 1024 ? delay : 1024);
 
-			emu10k1_writefn0(card, TIMER_RATE, delay);
+			emu10k1_timer_set(card, delay);
 
 			list_for_each(entry, &card->timers) {
 				t = list_entry(entry, struct emu_timer, list);
diff -Nru a/sound/oss/emu10k1/timer.h b/sound/oss/emu10k1/timer.h
--- a/sound/oss/emu10k1/timer.h	Sun Feb 10 18:50:09 2002
+++ b/sound/oss/emu10k1/timer.h	Sun Feb 16 16:30:06 2003
@@ -36,17 +36,17 @@
 	struct list_head list;
 	struct tasklet_struct tasklet;
 	u8 state; 
-	u32 count;				/* current number of interrupts */
-	u32 count_max;				/* number of interrupts needed to schedule the bh */
-	u32 delay;                              /* timer delay */
+	u16 count;				/* current number of interrupts */
+	u16 count_max;				/* number of interrupts needed to schedule the bh */
+	u16 delay;                              /* timer delay */
 };
 
-void emu10k1_timer_install(struct emu10k1_card *, struct emu_timer *, u32);
+void emu10k1_timer_install(struct emu10k1_card *, struct emu_timer *, u16);
 void emu10k1_timer_uninstall(struct emu10k1_card *, struct emu_timer *);
 void emu10k1_timer_enable(struct emu10k1_card *, struct emu_timer *);
 void emu10k1_timer_disable(struct emu10k1_card *, struct emu_timer *);
 
-#define TIMER_STOPPED 			0xffffffff 
+#define TIMER_STOPPED 			0xffff 
 #define TIMER_STATE_INSTALLED 		0x01
 #define TIMER_STATE_ACTIVE		0x02
 #define TIMER_STATE_UNINSTALLED 	0x04
diff -Nru a/sound/oss/emu10k1/voicemgr.c b/sound/oss/emu10k1/voicemgr.c
--- a/sound/oss/emu10k1/voicemgr.c	Sun Feb 10 18:50:08 2002
+++ b/sound/oss/emu10k1/voicemgr.c	Sun Feb 16 16:30:06 2003
@@ -32,6 +32,84 @@
 #include "voicemgr.h"
 #include "8010.h"
 
+/**
+ * emu10k1_voice_alloc_buffer -
+ *
+ * allocates the memory buffer for a voice. Two page tables are kept for each buffer.
+ * One (dma_handle) keeps track of the host memory pages used and the other (virtualpagetable)
+ * is passed to the device so that it can do DMA to host memory.
+ *
+ */
+int emu10k1_voice_alloc_buffer(struct emu10k1_card *card, struct voice_mem *mem, u32 pages)
+{
+	u32 pageindex, pagecount;
+	u32 busaddx;
+	int i;
+
+	DPD(2, "requested pages is: %d\n", pages);
+
+	if ((mem->emupageindex = emu10k1_addxmgr_alloc(pages * PAGE_SIZE, card)) < 0)
+	{
+		DPF(1, "couldn't allocate emu10k1 address space\n");
+		return -1;
+	}
+
+	/* Fill in virtual memory table */
+	for (pagecount = 0; pagecount < pages; pagecount++) {
+		if ((mem->addr[pagecount] = pci_alloc_consistent(card->pci_dev, PAGE_SIZE, &mem->dma_handle[pagecount]))
+			== NULL) {
+			mem->pages = pagecount;
+			DPF(1, "couldn't allocate dma memory\n");
+			return -1;
+		}
+
+		DPD(2, "Virtual Addx: %p\n", mem->addr[pagecount]);
+
+		for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
+			busaddx = (u32) mem->dma_handle[pagecount] + i * EMUPAGESIZE;
+
+			DPD(3, "Bus Addx: %#x\n", busaddx);
+
+			pageindex = mem->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
+
+			((u32 *) card->virtualpagetable.addr)[pageindex] = cpu_to_le32((busaddx * 2) | pageindex);
+		}
+	}
+
+	mem->pages = pagecount;
+
+	return 0;
+}
+
+/**
+ * emu10k1_voice_free_buffer -
+ *
+ * frees the memory buffer for a voice.
+ */
+void emu10k1_voice_free_buffer(struct emu10k1_card *card, struct voice_mem *mem)
+{
+	u32 pagecount, pageindex;
+	int i;
+
+	if (mem->emupageindex < 0)
+		return;
+
+	for (pagecount = 0; pagecount < mem->pages; pagecount++) {
+		pci_free_consistent(card->pci_dev, PAGE_SIZE,
+					mem->addr[pagecount],
+					mem->dma_handle[pagecount]);
+
+		for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
+			pageindex = mem->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
+			((u32 *) card->virtualpagetable.addr)[pageindex] =
+				cpu_to_le32(((u32) card->silentpage.dma_handle * 2) | pageindex);
+		}
+	}
+
+	emu10k1_addxmgr_free(card, mem->emupageindex);
+	mem->emupageindex = -1;
+}
+
 int emu10k1_voice_alloc(struct emu10k1_card *card, struct emu_voice *voice)
 {
 	u8 *voicetable = card->voicetable;
@@ -96,8 +174,10 @@
 							VTFT, 0x0000ffff,
 							PTRX_PITCHTARGET, 0,
 							CVCF, 0x0000ffff,
-							CPF, 0,
+							//CPF, 0,
 							TAGLIST_END);
+		
+		sblive_writeptr(card, CPF, voice->num + i, 0);
 	}
 
 	voice->usage = VOICE_USAGE_FREE;
@@ -151,8 +231,8 @@
 				    Z1, 0,
 				    Z2, 0,
 				    /* Invalidate maps */
-				    MAPA, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
-				    MAPB, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
+				    MAPA, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
+				    MAPB, MAP_PTI_MASK | ((u32) card->silentpage.dma_handle * 2),
 				/* modulation envelope */
 				    CVCF, 0x0000ffff,
 				    VTFT, 0x0000ffff,
diff -Nru a/sound/oss/emu10k1/voicemgr.h b/sound/oss/emu10k1/voicemgr.h
--- a/sound/oss/emu10k1/voicemgr.h	Sun Feb 10 18:50:08 2002
+++ b/sound/oss/emu10k1/voicemgr.h	Sun Feb 16 16:30:06 2003
@@ -64,6 +64,12 @@
 	u32 byampl_env_decay;
 };
 
+struct voice_mem {
+	int emupageindex;
+	void *addr[BUFMAXPAGES];
+	dma_addr_t dma_handle[BUFMAXPAGES];
+	u32 pages;
+};
 
 struct emu_voice
 {
@@ -72,16 +78,20 @@
 	u8 num;			/* Voice ID */
 	u8 flags;		/* Stereo/mono, 8/16 bit */
 
-        u32 startloop;
-        u32 endloop;
+	u32 startloop;
+	u32 endloop;
 	u32 start;
 
 	u32 initial_pitch;
 	u32 pitch_target;
 
 	struct voice_param params[2];
+
+	struct voice_mem mem;
 };
 
+int emu10k1_voice_alloc_buffer(struct emu10k1_card *, struct voice_mem *, u32);
+void emu10k1_voice_free_buffer(struct emu10k1_card *, struct voice_mem *);
 int emu10k1_voice_alloc(struct emu10k1_card *, struct emu_voice *);
 void emu10k1_voice_free(struct emu_voice *);
 void emu10k1_voice_playback_setup(struct emu_voice *);
diff -Nru a/sound/oss/gus_midi.c b/sound/oss/gus_midi.c
--- a/sound/oss/gus_midi.c	Sat Sep 28 18:38:50 2002
+++ b/sound/oss/gus_midi.c	Sun Mar  2 03:03:33 2003
@@ -179,7 +179,7 @@
 		qhead++;
 	}
 	spin_unlock_irqrestore(&lock,flags);
-	return (qlen > 0) | !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY);
+	return (qlen > 0) || !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY);
 }
 
 #define MIDI_SYNTH_NAME	"Gravis Ultrasound Midi"
diff -Nru a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c
--- a/sound/oss/i810_audio.c	Thu Feb  6 07:33:48 2003
+++ b/sound/oss/i810_audio.c	Thu Mar  6 15:20:44 2003
@@ -2406,9 +2406,9 @@
 				i810_set_dac_channels ( state, channels );
 
 				/* check that they really got turned on */
-				if ( !state->card->ac97_status & SURR_ON )
+				if (!(state->card->ac97_status & SURR_ON))
 					val &= ~DSP_BIND_SURR;
-				if ( !state->card->ac97_status & CENTER_LFE_ON )
+				if (!(state->card->ac97_status & CENTER_LFE_ON))
 					val &= ~DSP_BIND_CENTER_LFE;
 			}
 		}
diff -Nru a/sound/oss/maestro.c b/sound/oss/maestro.c
--- a/sound/oss/maestro.c	Tue Feb 25 09:45:51 2003
+++ b/sound/oss/maestro.c	Thu Mar  6 15:19:08 2003
@@ -3367,7 +3367,7 @@
 	/* check to see if we have a capabilities list in
 		the config register */
 	pci_read_config_word(pcidev, PCI_STATUS, &w);
-	if(! w & PCI_STATUS_CAP_LIST) return 0;
+	if(!(w & PCI_STATUS_CAP_LIST)) return 0;
 
 	/* walk the list, starting at the head. */
 	pci_read_config_byte(pcidev,PCI_CAPABILITY_LIST,&next);
diff -Nru a/sound/oss/midi_syms.c b/sound/oss/midi_syms.c
--- a/sound/oss/midi_syms.c	Sun Feb 10 18:50:10 2002
+++ b/sound/oss/midi_syms.c	Thu Mar 13 16:52:26 2003
@@ -1,9 +1,7 @@
 /*
  * Exported symbols for midi driver.
- * __NO_VERSION__ because this is still part of sound.o.
  */
 
-#define __NO_VERSION__
 #include <linux/module.h>
 
 char midi_syms_symbol;
diff -Nru a/sound/oss/mpu401.c b/sound/oss/mpu401.c
--- a/sound/oss/mpu401.c	Sun Dec 29 19:18:41 2002
+++ b/sound/oss/mpu401.c	Thu Mar  6 15:55:25 2003
@@ -1762,13 +1762,13 @@
 
 static struct address_info cfg;
 
-static int __initdata io = -1;
-static int __initdata irq = -1;
+static int io = -1;
+static int irq = -1;
 
 MODULE_PARM(irq, "i");
 MODULE_PARM(io, "i");
 
-int __init init_mpu401(void)
+static int __init init_mpu401(void)
 {
 	int ret;
 	/* Can be loaded either for module use or to provide functions
@@ -1785,7 +1785,7 @@
 	return 0;
 }
 
-void __exit cleanup_mpu401(void)
+static void __exit cleanup_mpu401(void)
 {
 	if (io != -1 && irq != -1) {
 		/* Check for use by, for example, sscape driver */
diff -Nru a/sound/oss/nm256_audio.c b/sound/oss/nm256_audio.c
--- a/sound/oss/nm256_audio.c	Thu Nov 21 10:06:21 2002
+++ b/sound/oss/nm256_audio.c	Thu Mar 13 16:52:26 2003
@@ -19,7 +19,6 @@
  *		Ported to 2.4 PCI API.
  */
 
-#define __NO_VERSION__
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
diff -Nru a/sound/oss/opl3sa2.c b/sound/oss/opl3sa2.c
--- a/sound/oss/opl3sa2.c	Tue Feb 25 02:09:05 2003
+++ b/sound/oss/opl3sa2.c	Sat Mar 22 12:43:27 2003
@@ -851,20 +851,20 @@
 	opl3sa2_activated[card] = 1;
 
 	/* Our own config: */
-	cfg[card].io_base = dev->io_resource[4].start;
-	cfg[card].irq     = dev->irq_resource[0].start;
-	cfg[card].dma     = dev->dma_resource[0].start;
-	cfg[card].dma2    = dev->dma_resource[1].start;
+	cfg[card].io_base = pnp_port_start(dev, 4);
+	cfg[card].irq     = pnp_irq(dev, 0);
+	cfg[card].dma     = pnp_dma(dev, 0);
+	cfg[card].dma2    = pnp_dma(dev, 1);
 
 	/* The MSS config: */
-	cfg_mss[card].io_base      = dev->io_resource[1].start;
-	cfg_mss[card].irq          = dev->irq_resource[0].start;
-	cfg_mss[card].dma          = dev->dma_resource[0].start;
-	cfg_mss[card].dma2         = dev->dma_resource[1].start;
+	cfg_mss[card].io_base      = pnp_port_start(dev, 1);
+	cfg_mss[card].irq          = pnp_irq(dev, 0);
+	cfg_mss[card].dma          = pnp_dma(dev, 0);
+	cfg_mss[card].dma2         = pnp_dma(dev, 1);
 	cfg_mss[card].card_subtype = 1; /* No IRQ or DMA setup */
 
-	cfg_mpu[card].io_base       = dev->io_resource[3].start;
-	cfg_mpu[card].irq           = dev->irq_resource[0].start;
+	cfg_mpu[card].io_base       = pnp_port_start(dev, 3);
+	cfg_mpu[card].irq           = pnp_irq(dev, 0);
 	cfg_mpu[card].dma           = -1;
 	cfg_mpu[card].dma2          = -1;
 	cfg_mpu[card].always_detect = 1; /* It's there, so use shared IRQs */
diff -Nru a/sound/oss/sequencer_syms.c b/sound/oss/sequencer_syms.c
--- a/sound/oss/sequencer_syms.c	Sun Feb 10 18:50:14 2002
+++ b/sound/oss/sequencer_syms.c	Thu Mar 13 16:52:26 2003
@@ -1,9 +1,7 @@
 /*
  * Exported symbols for sequencer driver.
- * __NO_VERSION__ because this is still part of sound.o.
  */
 
-#define __NO_VERSION__
 #include <linux/module.h>
 
 char sequencer_syms_symbol;
diff -Nru a/sound/pci/Kconfig b/sound/pci/Kconfig
--- a/sound/pci/Kconfig	Mon Jan 27 10:41:40 2003
+++ b/sound/pci/Kconfig	Thu Mar 20 08:41:13 2003
@@ -149,6 +149,15 @@
 	  Delta 66/44, Audiophile 24/96; Hoontech SoundTrack DSP 24 (Value);
 	  TerraTec - EWX 24/96, EWS 88MT, EWS 88D, DMX 6Fire.
 
+config SND_ICE1724
+	tristate "ICE/VT1724 (Envy24HT)"
+	depends on SND
+	help
+	  Say 'Y' or 'M' to include support for ICE/VT1724 (Envy24HT) based
+	  soundcards.
+	  Currently supported hardware is: MidiMan M Audio - Revolution 7.1,
+	  AMP Ltd AUDIO2000.
+
 config SND_INTEL8X0
 	tristate "Intel i8x0/MX440, SiS 7012; Ali 5455; NForce Audio; AMD768/8111"
 	depends on SND
diff -Nru a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
--- a/sound/pci/ac97/ac97_codec.c	Wed Mar  5 21:39:37 2003
+++ b/sound/pci/ac97/ac97_codec.c	Fri Mar 21 10:24:37 2003
@@ -51,115 +51,115 @@
 
  */
 
-static void snd_ac97_proc_init(snd_card_t * card, ac97_t * ac97);
+static void snd_ac97_proc_init(snd_card_t * card, ac97_t * ac97, const char *prefix);
 
 typedef struct {
 	unsigned int id;
 	unsigned int mask;
-	char *name;
+	const char *name;
 	int (*patch)(ac97_t *ac97);
+	int (*mpatch)(ac97_t *ac97);
 } ac97_codec_id_t;
 
 static const ac97_codec_id_t snd_ac97_codec_id_vendors[] = {
-{ 0x414b4d00, 0xffffff00, "Asahi Kasei",	NULL },
-{ 0x41445300, 0xffffff00, "Analog Devices",	NULL },
-{ 0x414c4300, 0xffffff00, "Realtek",		NULL },
-{ 0x414c4700, 0xffffff00, "Avance Logic",	NULL },
-{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL },
-{ 0x43525900, 0xffffff00, "Cirrus Logic",	NULL },
-{ 0x43585400, 0xffffff00, "Conexant",           NULL },
-{ 0x44543000, 0xffffff00, "Diamond Technology", NULL },
-{ 0x454d4300, 0xffffff00, "eMicro",		NULL },
-{ 0x45838300, 0xffffff00, "ESS Technology",	NULL },
-{ 0x48525300, 0xffffff00, "Intersil",		NULL },
-{ 0x49434500, 0xffffff00, "ICEnsemble",		NULL },
-{ 0x49544500, 0xffffff00, "ITE Tech.Inc",	NULL },
-{ 0x4e534300, 0xffffff00, "National Semiconductor", NULL },
-{ 0x50534300, 0xffffff00, "Philips",		NULL },
-{ 0x53494c00, 0xffffff00, "Silicon Laboratory",	NULL },
-{ 0x54524100, 0xffffff00, "TriTech",		NULL },
-{ 0x54584e00, 0xffffff00, "Texas Instruments",	NULL },
-{ 0x56494100, 0xffffff00, "VIA Technologies",   NULL },
-{ 0x57454300, 0xffffff00, "Winbond",		NULL },
-{ 0x574d4c00, 0xffffff00, "Wolfson",		NULL },
-{ 0x594d4800, 0xffffff00, "Yamaha",		NULL },
-{ 0x83847600, 0xffffff00, "SigmaTel",		NULL },
-{ 0,	      0, 	  NULL,			NULL }
+{ 0x414b4d00, 0xffffff00, "Asahi Kasei",	NULL,	NULL },
+{ 0x41445300, 0xffffff00, "Analog Devices",	NULL,	NULL },
+{ 0x414c4300, 0xffffff00, "Realtek",		NULL,	NULL },
+{ 0x414c4700, 0xffffff00, "Avance Logic",	NULL,	NULL },
+{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL,	NULL },
+{ 0x43525900, 0xffffff00, "Cirrus Logic",	NULL,	NULL },
+{ 0x43585400, 0xffffff00, "Conexant",           NULL,	NULL },
+{ 0x44543000, 0xffffff00, "Diamond Technology", NULL,	NULL },
+{ 0x454d4300, 0xffffff00, "eMicro",		NULL,	NULL },
+{ 0x45838300, 0xffffff00, "ESS Technology",	NULL,	NULL },
+{ 0x48525300, 0xffffff00, "Intersil",		NULL,	NULL },
+{ 0x49434500, 0xffffff00, "ICEnsemble",		NULL,	NULL },
+{ 0x49544500, 0xffffff00, "ITE Tech.Inc",	NULL,	NULL },
+{ 0x4e534300, 0xffffff00, "National Semiconductor", NULL, NULL },
+{ 0x50534300, 0xffffff00, "Philips",		NULL,	NULL },
+{ 0x53494c00, 0xffffff00, "Silicon Laboratory",	NULL,	NULL },
+{ 0x54524100, 0xffffff00, "TriTech",		NULL,	NULL },
+{ 0x54584e00, 0xffffff00, "Texas Instruments",	NULL,	NULL },
+{ 0x56494100, 0xffffff00, "VIA Technologies",   NULL,	NULL },
+{ 0x57454300, 0xffffff00, "Winbond",		NULL,	NULL },
+{ 0x574d4c00, 0xffffff00, "Wolfson",		NULL,	NULL },
+{ 0x594d4800, 0xffffff00, "Yamaha",		NULL,	NULL },
+{ 0x83847600, 0xffffff00, "SigmaTel",		NULL,	NULL },
+{ 0,	      0, 	  NULL,			NULL,	NULL }
 };
 
 static const ac97_codec_id_t snd_ac97_codec_ids[] = {
-{ 0x014b0502, 0xffffffff, "NM256AV",		NULL }, // FIXME: which real one?
-{ 0x414b4d00, 0xffffffff, "AK4540",		NULL },
-{ 0x414b4d01, 0xffffffff, "AK4542",		NULL },
-{ 0x414b4d02, 0xffffffff, "AK4543",		NULL },
-{ 0x414b4d06, 0xffffffff, "AK4544A",		NULL },
-{ 0x414b4d07, 0xffffffff, "AK4545",		NULL },
-{ 0x41445303, 0xffffffff, "AD1819",		patch_ad1819 },
-{ 0x41445340, 0xffffffff, "AD1881",		patch_ad1881 },
-{ 0x41445348, 0xffffffff, "AD1881A",		patch_ad1881 },
-{ 0x41445360, 0xffffffff, "AD1885",		patch_ad1885 },
-{ 0x41445361, 0xffffffff, "AD1886",		patch_ad1886 },
-{ 0x41445362, 0xffffffff, "AD1887",		patch_ad1881 },
-{ 0x41445363, 0xffffffff, "AD1886A",		patch_ad1881 },
-{ 0x41445370, 0xffffffff, "AD1980",		patch_ad1980 },
-{ 0x41445372, 0xffffffff, "AD1981A",		patch_ad1881 },
-{ 0x414c4300, 0xfffffff0, "RL5306",	 	NULL },
-{ 0x414c4310, 0xfffffff0, "RL5382", 		NULL },
-{ 0x414c4320, 0xfffffff0, "RL5383", 		NULL },
-{ 0x414c4710, 0xfffffff0, "ALC200/200P",	NULL },
-{ 0x414c4720, 0xfffffff0, "ALC650",		patch_alc650 },
-{ 0x414c4730, 0xffffffff, "ALC101",		NULL },
-{ 0x414c4740, 0xfffffff0, "ALC202",		NULL },
-{ 0x414c4750, 0xfffffff0, "ALC250",		NULL },
-{ 0x434d4941, 0xffffffff, "CMI9738",		NULL },
-{ 0x434d4961, 0xffffffff, "CMI9739",		NULL },
-{ 0x43525900, 0xfffffff8, "CS4297",		NULL },
-{ 0x43525910, 0xfffffff8, "CS4297A",		patch_cirrus_spdif },
-{ 0x43525920, 0xfffffff8, "CS4294/4298",	NULL },
-{ 0x43525928, 0xfffffff8, "CS4294",		NULL },
-{ 0x43525930, 0xfffffff8, "CS4299",		patch_cirrus_cs4299 },
-{ 0x43525948, 0xfffffff8, "CS4201",		NULL },
-{ 0x43525958, 0xfffffff8, "CS4205",		patch_cirrus_spdif },
-{ 0x43525960, 0xfffffff8, "CS4291",		NULL },
-{ 0x43585421, 0xffffffff, "HSD11246",		NULL },	// SmartMC II
-{ 0x43585428, 0xfffffff8, "Cx20468",		patch_conexant }, // SmartAMC fixme: the mask might be different
-{ 0x44543031, 0xfffffff0, "DT0398",		NULL },
-{ 0x454d4328, 0xffffffff, "28028",		NULL },  // same as TR28028?
-{ 0x45838308, 0xffffffff, "ESS1988",		NULL },
-{ 0x48525300, 0xffffff00, "HMP9701",		NULL },
-{ 0x49434501, 0xffffffff, "ICE1230",		NULL },
-{ 0x49434511, 0xffffffff, "ICE1232",		NULL }, // alias VIA VT1611A?
-{ 0x49434551, 0xffffffff, "VT1616", 		NULL }, 
-{ 0x49544520, 0xffffffff, "IT2226E",		NULL },
-{ 0x4e534300, 0xffffffff, "LM4540/43/45/46/48",	NULL }, // only guess --jk
-{ 0x4e534331, 0xffffffff, "LM4549",		NULL },
-{ 0x50534304, 0xffffffff, "UCB1400",		NULL },
-{ 0x53494c22, 0xffffffff, "Si3036",		NULL },
-{ 0x53494c23, 0xffffffff, "Si3038",		NULL },
-{ 0x54524102, 0xffffffff, "TR28022",		NULL },
-{ 0x54524106, 0xffffffff, "TR28026",		NULL },
-{ 0x54524108, 0xffffffff, "TR28028",		patch_tritech_tr28028 }, // added by xin jin [07/09/99]
-{ 0x54524123, 0xffffffff, "TR28602",		NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
-{ 0x54584e20, 0xffffffff, "TLC320AD9xC",	NULL },
-{ 0x56494161, 0xffffffff, "VIA1612A",		NULL }, // modified ICE1232 with S/PDIF
-{ 0x57454301, 0xffffffff, "W83971D",		NULL },
-{ 0x574d4c00, 0xffffffff, "WM9701A",		patch_wolfson00 },
-{ 0x574d4c03, 0xffffffff, "WM9703/9707",	patch_wolfson03 },
-{ 0x574d4c04, 0xffffffff, "WM9704/quad",	patch_wolfson04 },
-{ 0x574d4c05, 0xffffffff, "WM9705",		NULL },	// patch?
-{ 0x594d4800, 0xffffffff, "YMF743",		NULL },
-{ 0x594d4802, 0xffffffff, "YMF752",		NULL },
-{ 0x594d4803, 0xffffffff, "YMF753",		patch_yamaha_ymf753 },
-{ 0x83847600, 0xffffffff, "STAC9700/83/84",	NULL },
-{ 0x83847604, 0xffffffff, "STAC9701/3/4/5",	NULL },
-{ 0x83847605, 0xffffffff, "STAC9704",		NULL },
-{ 0x83847608, 0xffffffff, "STAC9708/11",	patch_sigmatel_stac9708 },
-{ 0x83847609, 0xffffffff, "STAC9721/23",	patch_sigmatel_stac9721 },
-{ 0x83847644, 0xffffffff, "STAC9744",		patch_sigmatel_stac9744 },
-{ 0x83847650, 0xffffffff, "STAC9750/51",	NULL },	// patch?
-{ 0x83847656, 0xffffffff, "STAC9756/57",	patch_sigmatel_stac9756 },
-{ 0x83847666, 0xffffffff, "STAC9766/67",	NULL }, // patch?
-{ 0, 	      0,	  NULL,			NULL }
+{ 0x014b0502, 0xffffffff, "NM256AV",		NULL,		NULL }, // FIXME: which real one?
+{ 0x414b4d00, 0xffffffff, "AK4540",		NULL,		NULL },
+{ 0x414b4d01, 0xffffffff, "AK4542",		NULL,		NULL },
+{ 0x414b4d02, 0xffffffff, "AK4543",		NULL,		NULL },
+{ 0x414b4d06, 0xffffffff, "AK4544A",		NULL,		NULL },
+{ 0x414b4d07, 0xffffffff, "AK4545",		NULL,		NULL },
+{ 0x41445303, 0xffffffff, "AD1819",		patch_ad1819,	NULL },
+{ 0x41445340, 0xffffffff, "AD1881",		patch_ad1881,	NULL },
+{ 0x41445348, 0xffffffff, "AD1881A",		patch_ad1881,	NULL },
+{ 0x41445360, 0xffffffff, "AD1885",		patch_ad1885,	NULL },
+{ 0x41445361, 0xffffffff, "AD1886",		patch_ad1886,	NULL },
+{ 0x41445362, 0xffffffff, "AD1887",		patch_ad1881,	NULL },
+{ 0x41445363, 0xffffffff, "AD1886A",		patch_ad1881,	NULL },
+{ 0x41445370, 0xffffffff, "AD1980",		patch_ad1980,	NULL },
+{ 0x41445372, 0xffffffff, "AD1981A",		patch_ad1881,	NULL },
+{ 0x414c4300, 0xfffffff0, "RL5306",	 	NULL,		NULL },
+{ 0x414c4310, 0xfffffff0, "RL5382", 		NULL,		NULL },
+{ 0x414c4320, 0xfffffff0, "RL5383", 		NULL,		NULL },
+{ 0x414c4710, 0xfffffff0, "ALC200/200P",	NULL,		NULL },
+{ 0x414c4720, 0xfffffff0, "ALC650",		patch_alc650,	NULL },
+{ 0x414c4730, 0xffffffff, "ALC101",		NULL,		NULL },
+{ 0x414c4740, 0xfffffff0, "ALC202",		NULL,		NULL },
+{ 0x414c4750, 0xfffffff0, "ALC250",		NULL,		NULL },
+{ 0x434d4941, 0xffffffff, "CMI9738",		NULL,		NULL },
+{ 0x434d4961, 0xffffffff, "CMI9739",		NULL,		NULL },
+{ 0x43525900, 0xfffffff8, "CS4297",		NULL,		NULL },
+{ 0x43525910, 0xfffffff8, "CS4297A",		patch_cirrus_spdif,	NULL },
+{ 0x43525920, 0xfffffff8, "CS4294/4298",	NULL,		NULL },
+{ 0x43525928, 0xfffffff8, "CS4294",		NULL,		NULL },
+{ 0x43525930, 0xfffffff8, "CS4299",		patch_cirrus_cs4299,	NULL },
+{ 0x43525948, 0xfffffff8, "CS4201",		NULL,		NULL },
+{ 0x43525958, 0xfffffff8, "CS4205",		patch_cirrus_spdif,	NULL },
+{ 0x43525960, 0xfffffff8, "CS4291",		NULL,		NULL },
+{ 0x43585421, 0xffffffff, "HSD11246",		NULL,		NULL },	// SmartMC II
+{ 0x43585428, 0xfffffff8, "Cx20468",		patch_conexant,	NULL }, // SmartAMC fixme: the mask might be different
+{ 0x44543031, 0xfffffff0, "DT0398",		NULL,		NULL },
+{ 0x454d4328, 0xffffffff, "28028",		NULL,		NULL },  // same as TR28028?
+{ 0x45838308, 0xffffffff, "ESS1988",		NULL,		NULL },
+{ 0x48525300, 0xffffff00, "HMP9701",		NULL,		NULL },
+{ 0x49434501, 0xffffffff, "ICE1230",		NULL,		NULL },
+{ 0x49434511, 0xffffffff, "ICE1232",		NULL,		NULL }, // alias VIA VT1611A?
+{ 0x49434551, 0xffffffff, "VT1616", 		NULL,		NULL }, 
+{ 0x49544520, 0xffffffff, "IT2226E",		NULL,		NULL },
+{ 0x4e534300, 0xffffffff, "LM4540/43/45/46/48",	NULL,		NULL }, // only guess --jk
+{ 0x4e534331, 0xffffffff, "LM4549",		NULL,		NULL },
+{ 0x50534304, 0xffffffff, "UCB1400",		NULL,		NULL },
+{ 0x53494c20, 0xffffffe0, "Si3036/8",		NULL,		NULL },
+{ 0x54524102, 0xffffffff, "TR28022",		NULL,		NULL },
+{ 0x54524106, 0xffffffff, "TR28026",		NULL,		NULL },
+{ 0x54524108, 0xffffffff, "TR28028",		patch_tritech_tr28028,	NULL }, // added by xin jin [07/09/99]
+{ 0x54524123, 0xffffffff, "TR28602",		NULL,		NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
+{ 0x54584e20, 0xffffffff, "TLC320AD9xC",	NULL,		NULL },
+{ 0x56494161, 0xffffffff, "VIA1612A",		NULL,		NULL }, // modified ICE1232 with S/PDIF
+{ 0x57454301, 0xffffffff, "W83971D",		NULL,		NULL },
+{ 0x574d4c00, 0xffffffff, "WM9701A",		patch_wolfson00,NULL },
+{ 0x574d4c03, 0xffffffff, "WM9703/9707",	patch_wolfson03,NULL },
+{ 0x574d4c04, 0xffffffff, "WM9704/quad",	patch_wolfson04,NULL },
+{ 0x574d4c05, 0xffffffff, "WM9705",		NULL,		NULL },	// patch?
+{ 0x594d4800, 0xffffffff, "YMF743",		NULL,		NULL },
+{ 0x594d4802, 0xffffffff, "YMF752",		NULL,		NULL },
+{ 0x594d4803, 0xffffffff, "YMF753",		patch_yamaha_ymf753,	NULL },
+{ 0x83847600, 0xffffffff, "STAC9700/83/84",	NULL,		NULL },
+{ 0x83847604, 0xffffffff, "STAC9701/3/4/5",	NULL,		NULL },
+{ 0x83847605, 0xffffffff, "STAC9704",		NULL,		NULL },
+{ 0x83847608, 0xffffffff, "STAC9708/11",	patch_sigmatel_stac9708,	NULL },
+{ 0x83847609, 0xffffffff, "STAC9721/23",	patch_sigmatel_stac9721,	NULL },
+{ 0x83847644, 0xffffffff, "STAC9744",		patch_sigmatel_stac9744,	NULL },
+{ 0x83847650, 0xffffffff, "STAC9750/51",	NULL,		NULL },	// patch?
+{ 0x83847656, 0xffffffff, "STAC9756/57",	patch_sigmatel_stac9756,	NULL },
+{ 0x83847666, 0xffffffff, "STAC9766/67",	NULL,		NULL }, // patch?
+{ 0, 	      0,	  NULL,			NULL,		NULL }
 };
 
 static const char *snd_ac97_stereo_enhancements[] =
@@ -325,7 +325,7 @@
  * Compares the value with the register cache and updates the value
  * only when the value is changed.
  *
- * Retruns 1 if the value is changed, 0 if no change, or a negative
+ * Returns 1 if the value is changed, 0 if no change, or a negative
  * code on failure.
  */
 int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value)
@@ -352,7 +352,7 @@
  * @mask: the bit-mask to change
  * @value: the value to set
  *
- * Updates the masked-bits on the given register onle when the value
+ * Updates the masked-bits on the given register only when the value
  * is changed.
  *
  * Returns 1 if the bits are changed, 0 if no change, or a negative
@@ -1022,6 +1022,50 @@
 AD18XX_PCM_BITS("LFE Playback Volume", 2, 0, 31)
 };
 
+static int snd_ac97_ad1980_spdif_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[2] = { "AC-Link", "A/D Converter" };
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 2;
+	if (uinfo->value.enumerated.item > 1)
+		uinfo->value.enumerated.item = 1;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_ac97_ad1980_spdif_source_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	unsigned short val;
+
+	val = ac97->regs[AC97_AD_SERIAL_CFG];
+	ucontrol->value.enumerated.item[0] = (val >> 2) & 1;
+	return 0;
+}
+
+static int snd_ac97_ad1980_spdif_source_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	unsigned short val;
+
+	if (ucontrol->value.enumerated.item[0] > 1)
+		return -EINVAL;
+	val = ucontrol->value.enumerated.item[0] << 2;
+	return snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x0004, val);
+}
+
+static const snd_kcontrol_new_t snd_ac97_ad1980_spdif_source =
+	{
+		iface: SNDRV_CTL_ELEM_IFACE_MIXER,
+		name: SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
+		info: snd_ac97_ad1980_spdif_source_info,
+		get: snd_ac97_ad1980_spdif_source_get,
+		put: snd_ac97_ad1980_spdif_source_put,
+	};
+
+
 /*
  * ALC650
  */
@@ -1032,11 +1076,12 @@
 	AC97_SINGLE("Exchange Center/LFE", AC97_ALC650_MULTICH, 3, 1, 0),
 	/* 4: Analog Input To Surround */
 	/* 5: Analog Input To Center/LFE */
-	/* 6: Indepedent Master Volume Right */
-	/* 7: Indepedent Master Volume Left */
+	/* 6: Independent Master Volume Right */
+	/* 7: Independent Master Volume Left */
 	/* 8: reserved */
 	AC97_SINGLE("Line-In As Surround", AC97_ALC650_MULTICH, 9, 1, 0),
 	AC97_SINGLE("Mic As Center/LFE", AC97_ALC650_MULTICH, 10, 1, 0),
+	AC97_SINGLE("Swap Surround Slot", AC97_ALC650_MULTICH, 14, 1, 0),
 #if 0 /* always set in patch_alc650 */
 	AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0),
 	AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0),
@@ -1097,11 +1142,11 @@
 
 static const snd_kcontrol_new_t snd_ac97_ymf753_controls_speaker =
 {
-	iface: SNDRV_CTL_ELEM_IFACE_MIXER,
-	name: "3D Control - Speaker",
-	info: snd_ac97_ymf753_info_speaker,
-	get: snd_ac97_ymf753_get_speaker,
-	put: snd_ac97_ymf753_put_speaker,
+	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name	= "3D Control - Speaker",
+	.info	= snd_ac97_ymf753_info_speaker,
+	.get	= snd_ac97_ymf753_get_speaker,
+	.put	= snd_ac97_ymf753_put_speaker,
 };
 
 /* It is possible to indicate to the Yamaha YMF753 the source to direct to the S/PDIF output. */
@@ -1140,7 +1185,7 @@
 }
 
 /* The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
-   The YMF753 will ouput the S/PDIF signal to pin 43, 47 (EAPD), or 48.
+   The YMF753 will output the S/PDIF signal to pin 43, 47 (EAPD), or 48.
    By default, no output pin is selected, and the S/PDIF signal is not output.
    There is also a bit to mute S/PDIF output in a vendor-specific register. */
 static int snd_ac97_ymf753_spdif_output_pin_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
@@ -1182,18 +1227,18 @@
 
 static const snd_kcontrol_new_t snd_ac97_ymf753_controls_spdif[3] = {
 	{
-		iface: SNDRV_CTL_ELEM_IFACE_MIXER,
-		name: SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
-		info: snd_ac97_ymf753_spdif_source_info,
-		get: snd_ac97_ymf753_spdif_source_get,
-		put: snd_ac97_ymf753_spdif_source_put,
+		.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name	= SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
+		.info	= snd_ac97_ymf753_spdif_source_info,
+		.get	= snd_ac97_ymf753_spdif_source_get,
+		.put	= snd_ac97_ymf753_spdif_source_put,
 	},
 	{
-		iface: SNDRV_CTL_ELEM_IFACE_MIXER,
-		name: SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Output Pin",
-		info: snd_ac97_ymf753_spdif_output_pin_info,
-		get: snd_ac97_ymf753_spdif_output_pin_get,
-		put: snd_ac97_ymf753_spdif_output_pin_put,
+		.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name	= SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Output Pin",
+		.info	= snd_ac97_ymf753_spdif_output_pin_info,
+		.get	= snd_ac97_ymf753_spdif_output_pin_get,
+		.put	= snd_ac97_ymf753_spdif_output_pin_put,
 	},
 	AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",NONE,NONE) "Mute", AC97_YMF753_DIT_CTRL2, 2, 1, 1)
 };
@@ -1680,6 +1725,9 @@
 				for (idx = 0; idx < 3; idx++)
 					if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_ymf753_controls_spdif[idx], ac97))) < 0)
 						return err;
+			} else if (ac97->id == AC97_ID_AD1980) {
+				if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_ad1980_spdif_source, ac97))) < 0)
+					return err;
 			}
 			/* set default PCM S/PDIF params */
 			/* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
@@ -1735,6 +1783,12 @@
 	return 0;
 }
 
+static int snd_ac97_modem_build(snd_card_t * card, ac97_t * ac97)
+{
+	/* TODO */
+	return 0;
+}
+
 static int snd_ac97_test_rate(ac97_t *ac97, int reg, int rate)
 {
 	unsigned short val;
@@ -1771,7 +1825,7 @@
 	*r_result = result;
 }
 
-static void snd_ac97_get_name(ac97_t *ac97, unsigned int id, char *name)
+static void snd_ac97_get_name(ac97_t *ac97, unsigned int id, char *name, int modem)
 {
 	const ac97_codec_id_t *pid;
 
@@ -1782,8 +1836,12 @@
 	for (pid = snd_ac97_codec_id_vendors; pid->id; pid++)
 		if (pid->id == (id & pid->mask)) {
 			strcpy(name, pid->name);
-			if (ac97 && pid->patch)
-				pid->patch(ac97);
+			if (ac97) {
+				if (!modem && pid->patch)
+					pid->patch(ac97);
+				else if (modem && pid->mpatch)
+					pid->mpatch(ac97);
+			} 
 			goto __vendor_ok;
 		}
 	return;
@@ -1795,8 +1853,12 @@
 			strcat(name, pid->name);
 			if (pid->mask != 0xffffffff)
 				sprintf(name + strlen(name), " rev %d", id & ~pid->mask);
-			if (ac97 && pid->patch)
-				pid->patch(ac97);
+			if (ac97) {
+				if (!modem && pid->patch)
+					pid->patch(ac97);
+				else if (modem && pid->mpatch)
+					pid->mpatch(ac97);
+			}
 			return;
 		}
 	sprintf(name + strlen(name), " id %x", id & 0xff);
@@ -1850,7 +1912,7 @@
  * The template must include the valid callbacks (at least read and
  * write), the codec number (num) and address (addr), and the private
  * data (private_data).  The other callbacks, wait and reset, are not
- * mandantory.
+ * mandatory.
  * 
  * The clock is set to 48000.  If another clock is needed, reset
  * ac97->clock manually afterwards.
@@ -1858,9 +1920,11 @@
  * The ac97 instance is registered as a low-level device, so you don't
  * have to release it manually.
  *
- * Returns zero if sucessful, or a negative error code on failure.
+ * The MCs (Modem Codecs only) are only detected but valid. The PCM driver
+ * have to check for MCs using the !ac97_is_audio() function.
+ *
+ * Returns zero if successful, or a negative error code on failure.
  */
-
 int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97)
 {
 	int err;
@@ -1929,8 +1993,8 @@
 		goto __ready_ok;
 
 	/* FIXME: add powerdown control */
-	/* nothing should be in powerdown mode */
-	if (ac97->scaps & AC97_SCAP_AUDIO) {
+	if (ac97_is_audio(ac97)) {
+		/* nothing should be in powerdown mode */
 		snd_ac97_write_cache_test(ac97, AC97_POWERDOWN, 0);
 		snd_ac97_write_cache_test(ac97, AC97_RESET, 0);		/* reset to defaults */
 		udelay(100);
@@ -1950,7 +2014,7 @@
       __ready_ok:
 	if (ac97->clock == 0)
 		ac97->clock = 48000;	/* standard value */
-	if (ac97->scaps & AC97_SCAP_AUDIO)
+	if (ac97_is_audio(ac97))
 		ac97->addr = (ac97->ext_id & AC97_EI_ADDR_MASK) >> AC97_EI_ADDR_SHIFT;
 	else
 		ac97->addr = (ac97->ext_mid & AC97_MEI_ADDR_MASK) >> AC97_MEI_ADDR_SHIFT;
@@ -1985,33 +2049,216 @@
 	/* additional initializations */
 	if (ac97->init)
 		ac97->init(ac97);
-	snd_ac97_get_name(ac97, ac97->id, name);
-	snd_ac97_get_name(NULL, ac97->id, name);  // ac97->id might be changed in the special setup code
-	if (card->mixername[0] == '\0') {
-		strcpy(card->mixername, name);
-	} else {
-		if (strlen(card->mixername) + 1 + strlen(name) + 1 <= sizeof(card->mixername)) {
-			strcat(card->mixername, ",");
-			strcat(card->mixername, name);
+	snd_ac97_get_name(ac97, ac97->id, name, 0);
+	snd_ac97_get_name(NULL, ac97->id, name, 0);  // ac97->id might be changed in the special setup code
+	if (ac97_is_audio(ac97)) {
+		if (card->mixername[0] == '\0') {
+			strcpy(card->mixername, name);
+		} else {
+			if (strlen(card->mixername) + 1 + strlen(name) + 1 <= sizeof(card->mixername)) {
+				strcat(card->mixername, ",");
+				strcat(card->mixername, name);
+			}
 		}
-	}
-	if (ac97->scaps & AC97_SCAP_AUDIO) {
 		if ((err = snd_component_add(card, "AC97a")) < 0) {
 			snd_ac97_free(ac97);
 			return err;
 		}
 	}
+	if (ac97_is_audio(ac97) && snd_ac97_mixer_build(card, ac97) < 0) {
+		snd_ac97_free(ac97);
+		return -ENOMEM;
+	}
+	snd_ac97_proc_init(card, ac97, "ac97");
+	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ac97, &ops)) < 0) {
+		snd_ac97_free(ac97);
+		return err;
+	}
+	*rac97 = ac97;
+	return 0;
+}
+
+/* wait for a while until registers are accessible after RESET
+ * return 0 if ok, negative not ready
+ */
+static int ac97_modem_reset_wait(ac97_t *ac97, int timeout)
+{
+	unsigned long end_time;
+	end_time = jiffies + timeout;
+	do {
+		unsigned short ext_mid;
+		
+		/* use preliminary reads to settle the communication */
+		snd_ac97_read(ac97, AC97_EXTENDED_MID);
+		snd_ac97_read(ac97, AC97_VENDOR_ID1);
+		snd_ac97_read(ac97, AC97_VENDOR_ID2);
+		ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
+		if (ext_mid != 0xffff && (ext_mid & 1) != 0)
+			return 0;
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(HZ/100);
+	} while (time_after_eq(end_time, jiffies));
+	return -ENODEV;
+}
+
+/**
+ * snd_ac97_modem - create an MC97 codec component
+ * @card: the card instance
+ * @_ac97: the template of ac97, including index, callbacks and
+ *         the private data.
+ * @rac97: the pointer to store the new ac97 instance.
+ *
+ * Creates an MC97 codec component.  An ac97_t instance is newly
+ * allocated and initialized from the template (_ac97).  The codec
+ * is then initialized by the standard procedure.
+ *
+ * The template must include the valid callbacks (at least read and
+ * write), the codec number (num) and address (addr), and the private
+ * data (private_data).  The other callbacks, wait and reset, are not
+ * mandatory.
+ * 
+ * The clock is set to 48000.  If another clock is needed, reset
+ * ac97->clock manually afterwards.
+ *
+ * The ac97 instance is registered as a low-level device, so you don't
+ * have to release it manually.
+ *
+ * The ACs (Audio Codecs only) are only detected but valid. The PCM driver
+ * have to check for ACs using the !ac97_is_modem() function.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
+int snd_ac97_modem(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97)
+{
+	int err;
+	ac97_t *ac97;
+	char name[64];
+	unsigned long end_time;
+	unsigned short tmp;
+	static snd_device_ops_t ops = {
+		.dev_free =	snd_ac97_dev_free,
+	};
+
+	snd_assert(rac97 != NULL, return -EINVAL);
+	*rac97 = NULL;
+	snd_assert(card != NULL && _ac97 != NULL, return -EINVAL);
+	ac97 = snd_magic_kcalloc(ac97_t, 0, GFP_KERNEL);
+	if (ac97 == NULL)
+		return -ENOMEM;
+	*ac97 = *_ac97;
+	ac97->card = card;
+	spin_lock_init(&ac97->reg_lock);
+
+	if (ac97->reset) {
+		ac97->reset(ac97);
+		goto __access_ok;
+	}
+
+	snd_ac97_write(ac97, AC97_EXTENDED_MID, 0);	/* reset to defaults */
+	if (ac97->wait)
+		ac97->wait(ac97);
+	else {
+		udelay(50);
+		if (ac97_modem_reset_wait(ac97, HZ/2) < 0) {
+			snd_printk("MC'97 %d:%d does not respond - MODEM RESET\n", ac97->num, ac97->addr);
+			snd_ac97_free(ac97);
+			return -ENXIO;
+		}
+	}
+      __access_ok:
+	ac97->id = snd_ac97_read(ac97, AC97_VENDOR_ID1) << 16;
+	ac97->id |= snd_ac97_read(ac97, AC97_VENDOR_ID2);
+	if (ac97->id == 0x00000000 || ac97->id == 0xffffffff) {
+		snd_printk("MC'97 %d:%d access is not valid [0x%x], removing modem controls.\n", ac97->num, ac97->addr, ac97->id);
+		snd_ac97_free(ac97);
+		return -EIO;
+	}
+	
+	/* test for MC'97 */
+	ac97->ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
+	if (ac97->ext_mid == 0xffff)	/* invalid combination */
+		ac97->ext_mid = 0;
+	if (ac97->ext_mid & 1)
+		ac97->scaps |= AC97_SCAP_MODEM;
+
+	/* non-destructive test for AC'97 */
+	tmp = snd_ac97_read(ac97, AC97_RESET);
+	if (tmp == 0 || tmp == 0xffff) {
+		tmp = snd_ac97_read(ac97, AC97_EXTENDED_ID);
+		if (tmp == 0 || tmp == 0xffff) {
+			tmp = snd_ac97_read(ac97, AC97_REC_GAIN);
+			if (tmp == 0 || tmp == 0xffff)
+				tmp = snd_ac97_read(ac97, AC97_POWERDOWN);
+		}
+	}
+	if ((tmp != 0 && tmp != 0xffff) || !(ac97->scaps & AC97_SCAP_MODEM))
+		ac97->scaps |= AC97_SCAP_AUDIO;
+
+	if (ac97->reset) // FIXME: always skipping?
+		goto __ready_ok;
+
+	/* FIXME: add powerdown control */
 	if (ac97->scaps & AC97_SCAP_MODEM) {
+		/* nothing should be in powerdown mode */
+		/* note: it's important to set the rate at first */
+		tmp = AC97_MEA_GPIO;
+		if (ac97->ext_mid & AC97_MEI_LINE1) {
+			snd_ac97_write_cache_test(ac97, AC97_LINE1_RATE, 12000);
+			tmp |= AC97_MEA_ADC1 | AC97_MEA_DAC1;
+		}
+		if (ac97->ext_mid & AC97_MEI_LINE2) {
+			snd_ac97_write_cache_test(ac97, AC97_LINE2_RATE, 12000);
+			tmp |= AC97_MEA_ADC2 | AC97_MEA_DAC2;
+		}
+		if (ac97->ext_mid & AC97_MEI_HANDSET) {
+			snd_ac97_write_cache_test(ac97, AC97_HANDSET_RATE, 12000);
+			tmp |= AC97_MEA_HADC | AC97_MEA_HDAC;
+		}
+		snd_ac97_write_cache_test(ac97, AC97_EXTENDED_MSTATUS, 0xff00 & ~(tmp << 8));
+		udelay(100);
+		/* nothing should be in powerdown mode */
+		snd_ac97_write_cache_test(ac97, AC97_EXTENDED_MSTATUS, 0xff00 & ~(tmp << 8));
+		end_time = jiffies + (HZ / 10);
+		do {
+			if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp)
+				goto __ready_ok;
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(HZ/10);
+		} while (time_after_eq(end_time, jiffies));
+		snd_printk("MC'97 %d:%d converters and GPIO not ready (0x%x)\n", ac97->num, ac97->addr, snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS));
+	}
+
+      __ready_ok:
+	/* additional initializations */
+	/* FIXME: ADD MODEM INITALIZATION */
+	if (ac97_is_modem(ac97))
+		ac97->addr = (ac97->ext_mid & AC97_MEI_ADDR_MASK) >> AC97_MEI_ADDR_SHIFT;
+	else
+		ac97->addr = (ac97->ext_id & AC97_EI_ADDR_MASK) >> AC97_EI_ADDR_SHIFT;
+
+	if (ac97->init)
+		ac97->init(ac97);
+	snd_ac97_get_name(ac97, ac97->id, name, 1);
+	snd_ac97_get_name(NULL, ac97->id, name, 1);  // ac97->id might be changed in the special setup code
+	if (ac97_is_modem(ac97)) {
+		if (card->mixername[0] == '\0') {
+			strcpy(card->mixername, name);
+		} else {
+			if (strlen(card->mixername) + 1 + strlen(name) + 1 <= sizeof(card->mixername)) {
+				strcat(card->mixername, ",");
+				strcat(card->mixername, name);
+			}
+		}
 		if ((err = snd_component_add(card, "AC97m")) < 0) {
 			snd_ac97_free(ac97);
 			return err;
 		}
 	}
-	if (snd_ac97_mixer_build(card, ac97) < 0) {
+	if (ac97_is_modem(ac97) && snd_ac97_modem_build(card, ac97) < 0) {
 		snd_ac97_free(ac97);
 		return -ENOMEM;
 	}
-	snd_ac97_proc_init(card, ac97);
+	snd_ac97_proc_init(card, ac97, "mc97");
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ac97, &ops)) < 0) {
 		snd_ac97_free(ac97);
 		return err;
@@ -2035,7 +2282,7 @@
 
 	id = snd_ac97_read(ac97, AC97_VENDOR_ID1) << 16;
 	id |= snd_ac97_read(ac97, AC97_VENDOR_ID2);
-	snd_ac97_get_name(NULL, id, name);
+	snd_ac97_get_name(NULL, id, name, 0);
 	snd_iprintf(buffer, "%d-%d/%d: %s\n\n", ac97->addr, ac97->num, subidx, name);
 	if ((ac97->scaps & AC97_SCAP_AUDIO) == 0)
 		goto __modem;
@@ -2165,9 +2412,39 @@
 			(mext & AC97_MEI_ADDR_MASK) >> AC97_MEI_ADDR_SHIFT,
 			mext & AC97_MEI_CID2 ? " CID2" : "",
 			mext & AC97_MEI_CID1 ? " CID1" : "",
-			mext & AC97_MEI_HEADSET ? " HSET" : "",
+			mext & AC97_MEI_HANDSET ? " HSET" : "",
 			mext & AC97_MEI_LINE2 ? " LIN2" : "",
 			mext & AC97_MEI_LINE1 ? " LIN1" : "");
+	val = snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS);
+	snd_iprintf(buffer, "Modem status     :%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+			val & AC97_MEA_GPIO ? " GPIO" : "",
+			val & AC97_MEA_MREF ? " MREF" : "",
+			val & AC97_MEA_ADC1 ? " ADC1" : "",
+			val & AC97_MEA_DAC1 ? " DAC1" : "",
+			val & AC97_MEA_ADC2 ? " ADC2" : "",
+			val & AC97_MEA_DAC2 ? " DAC2" : "",
+			val & AC97_MEA_HADC ? " HADC" : "",
+			val & AC97_MEA_HDAC ? " HDAC" : "",
+			val & AC97_MEA_PRA ? " PRA(GPIO)" : "",
+			val & AC97_MEA_PRB ? " PRB(res)" : "",
+			val & AC97_MEA_PRC ? " PRC(ADC1)" : "",
+			val & AC97_MEA_PRD ? " PRD(DAC1)" : "",
+			val & AC97_MEA_PRE ? " PRE(ADC2)" : "",
+			val & AC97_MEA_PRF ? " PRF(DAC2)" : "",
+			val & AC97_MEA_PRG ? " PRG(HADC)" : "",
+			val & AC97_MEA_PRH ? " PRH(HDAC)" : "");
+	if (mext & AC97_MEI_LINE1) {
+		val = snd_ac97_read(ac97, AC97_LINE1_RATE);
+		snd_iprintf(buffer, "Line1 rate       : %iHz\n", val);
+	}
+	if (mext & AC97_MEI_LINE2) {
+		val = snd_ac97_read(ac97, AC97_LINE2_RATE);
+		snd_iprintf(buffer, "Line2 rate       : %iHz\n", val);
+	}
+	if (mext & AC97_MEI_HANDSET) {
+		val = snd_ac97_read(ac97, AC97_HANDSET_RATE);
+		snd_iprintf(buffer, "Headset rate     : %iHz\n", val);
+	}
 }
 
 static void snd_ac97_proc_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
@@ -2235,21 +2512,21 @@
 	}	
 }
 
-static void snd_ac97_proc_init(snd_card_t * card, ac97_t * ac97)
+static void snd_ac97_proc_init(snd_card_t * card, ac97_t * ac97, const char *prefix)
 {
 	snd_info_entry_t *entry;
 	char name[32];
 
 	if (ac97->num)
-		sprintf(name, "ac97#%d-%d", ac97->addr, ac97->num);
+		sprintf(name, "%s#%d-%d", prefix, ac97->addr, ac97->num);
 	else
-		sprintf(name, "ac97#%d", ac97->addr);
+		sprintf(name, "%s#%d", prefix, ac97->addr);
 	if (! snd_card_proc_new(card, name, &entry))
 		snd_info_set_text_ops(entry, ac97, snd_ac97_proc_read);
 	if (ac97->num)
-		sprintf(name, "ac97#%d-%dregs", ac97->addr, ac97->num);
+		sprintf(name, "%s#%d-%dregs", prefix, ac97->addr, ac97->num);
 	else
-		sprintf(name, "ac97#%dregs", ac97->addr);
+		sprintf(name, "%s#%dregs", prefix, ac97->addr);
 	if (! snd_card_proc_new(card, name, &entry))
 		snd_info_set_text_ops(entry, ac97, snd_ac97_proc_regs_read);
 }
@@ -2430,6 +2707,7 @@
 	snd_ctl_elem_id_t id;
 	memset(&id, 0, sizeof(id));
 	strcpy(id.name, name);
+	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	return snd_ctl_remove_id(ac97->card, &id);
 }
 
@@ -2438,8 +2716,10 @@
 	snd_ctl_elem_id_t sid, did;
 	memset(&sid, 0, sizeof(sid));
 	strcpy(sid.name, src);
+	sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	memset(&did, 0, sizeof(did));
 	strcpy(did.name, dst);
+	did.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	return snd_ctl_rename_id(ac97->card, &sid, &did);
 }
 
@@ -2476,19 +2756,21 @@
 {
 	unsigned short vendor, device;
 
+	snd_assert(quirk, return -EINVAL);
+
 	pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
 	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &device);
 
 	for (; quirk->vendor; quirk++) {
 		if (quirk->vendor == vendor && quirk->device == device) {
-			snd_printdd("ac97 quirk for %04x:%04x\n", vendor, device);
+			snd_printdd("ac97 quirk for %s (%04x:%04x)\n", quirk->name, vendor, device);
 			switch (quirk->type) {
 			case AC97_TUNE_HP_ONLY:
 				return swap_headphone(ac97, 1);
 			case AC97_TUNE_SWAP_HP:
 				return swap_headphone(ac97, 0);
 			}
-			snd_printk(KERN_ERR "invalid quirk type %d\n", quirk->type);
+			snd_printk(KERN_ERR "invalid quirk type %d for %s\n", quirk->type, quirk->name);
 			return -EINVAL;
 		}
 	}
@@ -2506,6 +2788,7 @@
 EXPORT_SYMBOL(snd_ac97_update);
 EXPORT_SYMBOL(snd_ac97_update_bits);
 EXPORT_SYMBOL(snd_ac97_mixer);
+EXPORT_SYMBOL(snd_ac97_modem);
 EXPORT_SYMBOL(snd_ac97_set_rate);
 EXPORT_SYMBOL(snd_ac97_tune_hardware);
 #ifdef CONFIG_PM
diff -Nru a/sound/pci/ac97/ac97_id.h b/sound/pci/ac97/ac97_id.h
--- a/sound/pci/ac97/ac97_id.h	Thu Dec  5 11:39:44 2002
+++ b/sound/pci/ac97/ac97_id.h	Tue Feb 25 05:46:06 2003
@@ -31,6 +31,7 @@
 #define AC97_ID_AD1886		0x41445361
 #define AC97_ID_AD1887		0x41445362
 #define AC97_ID_AD1886A		0x41445363
+#define AC97_ID_AD1980 		0x41445370
 #define AC97_ID_TR28028		0x54524108
 #define AC97_ID_STAC9700	0x83847600
 #define AC97_ID_STAC9704	0x83847604
diff -Nru a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
--- a/sound/pci/ac97/ac97_patch.c	Sat Feb  8 12:10:52 2003
+++ b/sound/pci/ac97/ac97_patch.c	Thu Mar 20 08:41:14 2003
@@ -366,7 +366,7 @@
 
 	val = snd_ac97_read(ac97, AC97_ALC650_MULTICH);
 	val &= ~0xc000; /* slot: 3,4,7,8,6,9 */
-	snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, val | 0x03);
+	snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, val);
 
 	/* full DAC volume */
 	snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
diff -Nru a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
--- a/sound/pci/cs46xx/cs46xx_lib.c	Tue Feb 25 02:51:52 2003
+++ b/sound/pci/cs46xx/cs46xx_lib.c	Thu Mar 20 21:50:22 2003
@@ -321,6 +321,7 @@
 #include "imgs/cwcasync.h"
 #include "imgs/cwcsnoop.h"
 #include "imgs/cwcbinhack.h"
+#include "imgs/cwcdma.h"
 
 int snd_cs46xx_clear_BA1(cs46xx_t *chip,
                          unsigned long offset,
@@ -672,28 +673,21 @@
  *  PCM part
  */
 
-static int snd_cs46xx_playback_transfer(snd_pcm_substream_t *substream, 
-					snd_pcm_uframes_t frames)
+static int snd_cs46xx_playback_transfer(snd_pcm_substream_t *substream)
 {
 	/* cs46xx_t *chip = snd_pcm_substream_chip(substream); */
 	snd_pcm_runtime_t *runtime = substream->runtime;
+	cs46xx_pcm_t * cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return -ENXIO);
 	snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
-	snd_pcm_sframes_t diff;
-	cs46xx_pcm_t * cpcm;
-	int buffer_size;
-
-	cpcm = snd_magic_cast(cs46xx_pcm_t, substream->runtime->private_data, return -ENXIO);
-
-	buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift;
+	snd_pcm_sframes_t diff = appl_ptr - cpcm->appl_ptr;
+	int buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift;
 
-	diff = appl_ptr - cpcm->appl_ptr;
 	if (diff) {
 		if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
 			diff += runtime->boundary;
-		frames += diff;
+		cpcm->sw_ready += diff * (1 << cpcm->shift);
+		cpcm->appl_ptr = appl_ptr;
 	}
-	cpcm->sw_ready += frames << cpcm->shift;
-	cpcm->appl_ptr = appl_ptr + frames;
 	while (cpcm->hw_ready < buffer_size && 
 	       cpcm->sw_ready > 0) {
 		size_t hw_to_end = buffer_size - cpcm->hw_data;
@@ -720,21 +714,20 @@
 	return 0;
 }
 
-static int snd_cs46xx_capture_transfer(snd_pcm_substream_t *substream, 
-				       snd_pcm_uframes_t frames)
+static int snd_cs46xx_capture_transfer(snd_pcm_substream_t *substream)
 {
 	cs46xx_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
 	snd_pcm_sframes_t diff = appl_ptr - chip->capt.appl_ptr;
 	int buffer_size = runtime->period_size * CS46XX_FRAGS << chip->capt.shift;
+
 	if (diff) {
 		if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
 			diff += runtime->boundary;
-		frames += diff;
+		chip->capt.sw_ready -= diff * (1 << chip->capt.shift);
+		chip->capt.appl_ptr = appl_ptr;
 	}
-	chip->capt.sw_ready -= frames << chip->capt.shift;
-	chip->capt.appl_ptr = appl_ptr + frames;
 	while (chip->capt.hw_ready > 0 && 
 	       chip->capt.sw_ready < (int)chip->capt.sw_bufsize) {
 		size_t hw_to_end = buffer_size - chip->capt.hw_data;
@@ -802,7 +795,7 @@
 	cpcm->sw_io += bytes;
 	if (cpcm->sw_io >= cpcm->sw_bufsize)
 		cpcm->sw_io -= cpcm->sw_bufsize;
-	snd_cs46xx_playback_transfer(substream, 0);
+	snd_cs46xx_playback_transfer(substream);
 	return cpcm->sw_io >> cpcm->shift;
 }
 
@@ -827,57 +820,10 @@
 	chip->capt.sw_io += bytes;
 	if (chip->capt.sw_io >= chip->capt.sw_bufsize)
 		chip->capt.sw_io -= chip->capt.sw_bufsize;
-	snd_cs46xx_capture_transfer(substream, 0);
+	snd_cs46xx_capture_transfer(substream);
 	return chip->capt.sw_io >> chip->capt.shift;
 }
 
-static int snd_cs46xx_playback_copy(snd_pcm_substream_t *substream,
-				    int channel,
-				    snd_pcm_uframes_t hwoff,
-				    void *src,
-				    snd_pcm_uframes_t frames)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	/*cs46xx_t *chip = snd_pcm_substream_chip(substream); */
-	size_t hwoffb;
-	size_t bytes;
-	char *hwbuf;
-	cs46xx_pcm_t *cpcm = snd_magic_cast(cs46xx_pcm_t, substream->runtime->private_data, return -ENXIO);
-
-	snd_assert(runtime->dma_area, return -EINVAL);
-
-	hwoffb = hwoff << cpcm->shift;
-	bytes = frames << cpcm->shift;
-	hwbuf = runtime->dma_area + hwoffb;
-
-	if (copy_from_user(hwbuf, src, bytes))
-		return -EFAULT;
-
-	spin_lock_irq(&runtime->lock);
-	snd_cs46xx_playback_transfer(substream, frames);
-	spin_unlock_irq(&runtime->lock);
-	return 0;
-}
-	
-static int snd_cs46xx_capture_copy(snd_pcm_substream_t *substream,
-				   int channel,
-				   snd_pcm_uframes_t hwoff,
-				   void *dst,
-				   snd_pcm_uframes_t frames)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
-	size_t hwoffb = hwoff << chip->capt.shift;
-	size_t bytes = frames << chip->capt.shift;
-	char *hwbuf = runtime->dma_area + hwoffb;
-	if (copy_to_user(dst, hwbuf, bytes))
-		return -EFAULT;
-	spin_lock_irq(&runtime->lock);
-	snd_cs46xx_capture_transfer(substream, frames);
-	spin_unlock_irq(&runtime->lock);
-	return 0;
-}
-	
 static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream,
 				       int cmd)
 {
@@ -909,10 +855,10 @@
 			cs46xx_dsp_pcm_link(chip,cpcm->pcm_channel);
 
 		if (substream->runtime->periods != CS46XX_FRAGS)
-			snd_cs46xx_playback_transfer(substream, 0);
+			snd_cs46xx_playback_transfer(substream);
 #else
 		if (substream->runtime->periods != CS46XX_FRAGS)
-			snd_cs46xx_playback_transfer(substream, 0);
+			snd_cs46xx_playback_transfer(substream);
 		{ unsigned int tmp;
 		tmp = snd_cs46xx_peek(chip, BA1_PCTL);
 		tmp &= 0x0000ffff;
@@ -1018,13 +964,14 @@
 static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream,
 					 snd_pcm_hw_params_t * hw_params)
 {
-	/*cs46xx_t *chip = snd_pcm_substream_chip(substream);*/
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	cs46xx_pcm_t *cpcm;
 	int err;
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
 	cs46xx_t *chip = snd_pcm_substream_chip(substream);
 	int sample_rate = params_rate(hw_params);
 	int period_size = params_period_bytes(hw_params);
+#endif
 	cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return -ENXIO);
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
@@ -1211,10 +1158,9 @@
 	cs46xx_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	int err;
-	int period_size = params_period_bytes(hw_params);
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-	cs46xx_dsp_pcm_ostream_set_period (chip,period_size);
+	cs46xx_dsp_pcm_ostream_set_period (chip, params_period_bytes(hw_params));
 #endif
 	if (runtime->periods == CS46XX_FRAGS) {
 		if (runtime->dma_area != chip->capt.hw_area)
@@ -1399,6 +1345,8 @@
 	.fifo_size =		0,
 };
 
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+
 static unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 };
 
 #define PERIOD_SIZES sizeof(period_sizes) / sizeof(period_sizes[0])
@@ -1409,6 +1357,8 @@
 	.mask = 0
 };
 
+#endif
+
 static void snd_cs46xx_pcm_free_substream(snd_pcm_runtime_t *runtime)
 {
 	cs46xx_pcm_t * cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return);
@@ -1587,8 +1537,8 @@
 	.hw_free =		snd_cs46xx_playback_hw_free,
 	.prepare =		snd_cs46xx_playback_prepare,
 	.trigger =		snd_cs46xx_playback_trigger,
-	.copy =			snd_cs46xx_playback_copy,
 	.pointer =		snd_cs46xx_playback_indirect_pointer,
+	.ack =			snd_cs46xx_playback_transfer,
 };
 
 snd_pcm_ops_t snd_cs46xx_playback_iec958_ops = {
@@ -1610,8 +1560,8 @@
 	.hw_free =		snd_cs46xx_playback_hw_free,
 	.prepare =		snd_cs46xx_playback_prepare,
 	.trigger =		snd_cs46xx_playback_trigger,
-	.copy =			snd_cs46xx_playback_copy,
 	.pointer =		snd_cs46xx_playback_indirect_pointer,
+	.ack =			snd_cs46xx_playback_transfer,
 };
 
 #endif
@@ -1635,8 +1585,8 @@
 	.hw_free =		snd_cs46xx_playback_hw_free,
 	.prepare =		snd_cs46xx_playback_prepare,
 	.trigger =		snd_cs46xx_playback_trigger,
-	.copy =			snd_cs46xx_playback_copy,
 	.pointer =		snd_cs46xx_playback_indirect_pointer,
+	.ack =			snd_cs46xx_playback_transfer,
 };
 
 snd_pcm_ops_t snd_cs46xx_capture_ops = {
@@ -1658,8 +1608,8 @@
 	.hw_free =		snd_cs46xx_capture_hw_free,
 	.prepare =		snd_cs46xx_capture_prepare,
 	.trigger =		snd_cs46xx_capture_trigger,
-	.copy =			snd_cs46xx_capture_copy,
 	.pointer =		snd_cs46xx_capture_indirect_pointer,
+	.ack =			snd_cs46xx_capture_transfer,
 };
 
 static void snd_cs46xx_pcm_free(snd_pcm_t *pcm)
@@ -1941,7 +1891,8 @@
 		res = (change != chip->dsp_spos_instance->spdif_status_in);
 		break;
 	default:
-		snd_assert(0, return -EINVAL);
+		res = -EINVAL;
+		snd_assert(0, (void)0);
 	}
 
 	return res;
@@ -2365,7 +2316,7 @@
 
 static void snd_cs46xx_sec_codec_reset (ac97_t * ac97)
 {
-	signed long end_time;
+	unsigned long end_time;
 	int err;
 
 	/* reset to defaults */
@@ -2401,7 +2352,7 @@
 		schedule_timeout(HZ/100);
 	} while (time_after_eq(end_time, jiffies));
 
-	snd_printk("CS46xx secondary codec don't respond!\n");  
+	snd_printk("CS46xx secondary codec dont respond!\n");  
 }
 #endif
 
@@ -2505,9 +2456,6 @@
 	strcpy(id.name, "External Amplifier Power Down");
 	chip->eapd_switch = snd_ctl_find_id(chip->card, &id);
     
-	/* turn on amplifier */
-	chip->amplifier_ctrl(chip, 1);
-
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 	/* do soundcard specific mixer setup */
 	if (chip->mixer_init) {
@@ -2515,6 +2463,9 @@
 		chip->mixer_init(chip);
 	}
 #endif
+
+ 	/* turn on amplifier */
+	chip->amplifier_ctrl(chip, 1);
     
 	return 0;
 }
@@ -2919,10 +2870,6 @@
 		kfree(chip->gameport);
 	}
 #endif
-#ifdef CONFIG_PM
-	if (chip->pm_dev)
-		pm_unregister(chip->pm_dev);
-#endif
 	if (chip->amplifier_ctrl)
 		chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */
 	
@@ -3227,6 +3174,11 @@
 		return -EIO;
 	}
 
+	if (cs46xx_dsp_load_module(chip, &cwcdma_module) < 0) {
+		snd_printk(KERN_ERR "image download error [cwcdma]\n");
+		return -EIO;
+	}
+
 	if (cs46xx_dsp_scb_and_task_init(chip) < 0)
 		return -EIO;
 #else
@@ -3436,10 +3388,10 @@
 	oval = snd_cs46xx_codec_read(chip, AC97_POWERDOWN,
 				     CS46XX_PRIMARY_CODEC_INDEX);
 	val = oval;
-	if (chip->amplifier && !old) {
+	if (chip->amplifier) {
 		/* Turn the EAPD amp on */
 		val |= 0x8000;
-	} else if (old && !chip->amplifier) {
+	} else {
 		/* Turn the EAPD amp off */
 		val &= ~0x8000;
 	}
@@ -3574,23 +3526,23 @@
  
 static void clkrun_hack(cs46xx_t *chip, int change)
 {
-	u16 control;
-	int old;
+	u16 control, nval;
 	
 	if (chip->acpi_dev == NULL)
 		return;
 
-	old = chip->amplifier;
 	chip->amplifier += change;
 	
 	/* Read ACPI port */	
-	control = inw(chip->acpi_port + 0x10);
+	nval = control = inw(chip->acpi_port + 0x10);
 
 	/* Flip CLKRUN off while running */
-	if (! chip->amplifier && old)
-		outw(control | 0x2000, chip->acpi_port + 0x10);
-	else if (chip->amplifier && ! old)
-		outw(control & ~0x2000, chip->acpi_port + 0x10);
+	if (! chip->amplifier)
+		nval |= 0x2000;
+	else
+		nval &= ~0x2000;
+	if (nval != control)
+		outw(nval, chip->acpi_port + 0x10);
 }
 
 	
diff -Nru a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h
--- a/sound/pci/cs46xx/cs46xx_lib.h	Wed Dec 11 10:35:33 2002
+++ b/sound/pci/cs46xx/cs46xx_lib.h	Thu Mar 20 08:41:14 2003
@@ -156,7 +156,8 @@
                                                        u16 src_buffer_addr,
                                                        u16 src_delay_buffer_addr,u32 dest,
                                                        dsp_scb_descriptor_t * parent_scb,
-                                                       int scb_child_type);
+                                                       int scb_child_type,
+						       int pass_through);
 dsp_scb_descriptor_t *  cs46xx_dsp_create_mix_only_scb(cs46xx_t * chip,char * scb_name,
                                                        u16 mix_buffer_addr,u32 dest,
                                                        dsp_scb_descriptor_t * parent_scb,
diff -Nru a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
--- a/sound/pci/cs46xx/dsp_spos.c	Sat Feb  8 12:10:53 2003
+++ b/sound/pci/cs46xx/dsp_spos.c	Thu Mar 20 08:41:14 2003
@@ -1371,11 +1371,11 @@
 
 	/* SPDIF input sampel rate converter */
 	src_task_scb = cs46xx_dsp_create_src_task_scb(chip,"SrcTaskSCB_SPDIFI",
-						      48000,
+						      ins->spdif_in_sample_rate,
 						      SRC_OUTPUT_BUF1,
 						      SRC_DELAY_BUF1,SRCTASK_SCB_ADDR,
 						      master_mix_scb,
-						      SCB_ON_PARENT_SUBLIST_SCB);
+						      SCB_ON_PARENT_SUBLIST_SCB,0);
 
 	if (!src_task_scb) goto _fail_end;
 
@@ -1564,9 +1564,32 @@
 	return 0;
 }
 
+
+static void cs46xx_dsp_disable_spdif_hw (cs46xx_t *chip)
+{
+	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+
+	/* set SPDIF output FIFO slot */
+	snd_cs46xx_pokeBA0(chip, BA0_ASER_FADDR, 0);
+
+	/* SPDIF output MASTER ENABLE */
+	cs46xx_poke_via_dsp (chip,SP_SPDOUT_CONTROL, 0);
+
+	/* right and left validate bit */
+	/*cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, ins->spdif_csuv_default);*/
+	cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV, 0x0);
+
+	/* monitor state */
+	ins->spdif_status_out &= ~DSP_SPDIF_STATUS_HW_ENABLED;
+}
+
 int cs46xx_dsp_enable_spdif_hw (cs46xx_t *chip)
 {
 	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+
+	/* if hw-ctrl already enabled, turn off to reset logic ... */
+	cs46xx_dsp_disable_spdif_hw (chip);
+	udelay(50);
 
 	/* set SPDIF output FIFO slot */
 	snd_cs46xx_pokeBA0(chip, BA0_ASER_FADDR, ( 0x8000 | ((SP_SPDOUT_FIFO >> 4) << 4) ));
diff -Nru a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c	Tue Feb 25 02:51:59 2003
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c	Thu Mar 20 08:41:14 2003
@@ -584,7 +584,8 @@
                                u16 src_buffer_addr,
                                u16 src_delay_buffer_addr,u32 dest,
                                dsp_scb_descriptor_t * parent_scb,
-                               int scb_child_type)
+                               int scb_child_type,
+	                       int pass_through)
 {
 
 	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
@@ -659,10 +660,22 @@
 		/* clear buffers */
 		_dsp_clear_sample_buffer (chip,src_buffer_addr,8);
 		_dsp_clear_sample_buffer (chip,src_delay_buffer_addr,32);
-		
-		scb = _dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb,
-					      dest,ins->s16_up,parent_scb,
-					      scb_child_type);
+				
+		if (pass_through) {
+			/* wont work with any other rate than
+			   the native DSP rate */
+			snd_assert (rate = 48000);
+
+			scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb,
+							    dest,"DMAREADER",parent_scb,
+							    scb_child_type);
+		} else {
+			scb = _dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb,
+						      dest,ins->s16_up,parent_scb,
+						      scb_child_type);
+		}
+
+
 	}
 
 	return scb;
@@ -835,10 +848,10 @@
 
 		RSCONFIG_SAMPLE_16STEREO + RSCONFIG_MODULO_16,
 		0,
-		0,input_scb->address,
+      /* 0xD */ 0,input_scb->address,
 		{
-			0x8000,0x8000,
-			0x8000,0x8000
+      /* 0xE */   0x8000,0x8000,
+      /* 0xF */	  0x8000,0x8000
 		}
 	};
 
@@ -1134,9 +1147,9 @@
 	dsp_scb_descriptor_t * src_scb = NULL,* pcm_scb, * mixer_scb = NULL;
 	dsp_scb_descriptor_t * src_parent_scb = NULL;
 
-	/*dsp_scb_descriptor_t * pcm_parent_scb;*/
+	/* dsp_scb_descriptor_t * pcm_parent_scb; */
 	char scb_name[DSP_MAX_SCB_NAME];
-	int i,pcm_index = -1, insert_point, src_index = -1;
+	int i,pcm_index = -1, insert_point, src_index = -1,pass_through = 0;
 	unsigned long flags;
 
 	switch (pcm_channel_id) {
@@ -1163,7 +1176,8 @@
 		   alter the raw data stream ...) */
 		if (sample_rate == 48000) {
 			snd_printdd ("IEC958 pass through\n");
-			src_parent_scb = ins->asynch_tx_scb;
+			/* Hack to bypass creating a new SRC */
+			pass_through = 1;
 		}
 		break;
 	default:
@@ -1216,18 +1230,16 @@
 		snd_assert (src_index != -1,return NULL);
 
 		/* we need to create a new SRC SCB */
-		if (src_parent_scb == NULL) {
-			if (mixer_scb->sub_list_ptr == ins->the_null_scb) {
-				src_parent_scb = mixer_scb;
-				insert_point = SCB_ON_PARENT_SUBLIST_SCB;
-			} else {
-				src_parent_scb = find_next_free_scb(chip,mixer_scb->sub_list_ptr);
-				insert_point = SCB_ON_PARENT_NEXT_SCB;
-			}
-		} else insert_point = SCB_ON_PARENT_NEXT_SCB;
+		if (mixer_scb->sub_list_ptr == ins->the_null_scb) {
+			src_parent_scb = mixer_scb;
+			insert_point = SCB_ON_PARENT_SUBLIST_SCB;
+		} else {
+			src_parent_scb = find_next_free_scb(chip,mixer_scb->sub_list_ptr);
+			insert_point = SCB_ON_PARENT_NEXT_SCB;
+		}
 
 		snprintf (scb_name,DSP_MAX_SCB_NAME,"SrcTask_SCB%d",src_index);
-
+		
 		snd_printdd( "dsp_spos: creating SRC \"%s\"\n",scb_name);
 		src_scb = cs46xx_dsp_create_src_task_scb(chip,scb_name,
 							 sample_rate,
@@ -1236,7 +1248,8 @@
 							 /* 0x400 - 0x600 source SCBs */
 							 0x400 + (src_index * 0x10) ,
 							 src_parent_scb,
-							 insert_point);
+							 insert_point,
+							 pass_through);
 
 		if (!src_scb) {
 			snd_printk (KERN_ERR "dsp_spos: failed to create SRCtaskSCB\n");
@@ -1268,19 +1281,6 @@
 		snd_printk (KERN_ERR "dsp_spos: failed to create PCMreaderSCB\n");
 		return NULL;
 	}
-
-	if (pcm_channel_id == DSP_IEC958_CHANNEL && sample_rate == 48000) {
-		snd_assert (ins->spdif_pcm_input_scb == NULL);
-		
-		/* a hack to make the skip the SRC and pass the stream 
-		   directly to the SPDIF task */
-		ins->spdif_pcm_input_scb = 
-			cs46xx_dsp_create_pcm_serial_input_scb(chip,"PCMSerialInput_PCM",
-							       PCMSERIALINII_SCB_ADDR,
-							       pcm_scb,
-							       ins->asynch_tx_scb,
-							       SCB_ON_PARENT_SUBLIST_SCB);		
-	}
 	
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	ins->pcm_channels[pcm_index].sample_rate = sample_rate;
@@ -1540,7 +1540,7 @@
 		cs46xx_dsp_enable_spdif_hw (chip);
 	}
 
-	/* don't touch anything if SPDIF is open */
+	/* dont touch anything if SPDIF is open */
 	if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) {
 		/* when cs46xx_iec958_post_close(...) is called it
 		   will call this function if necessary depending on
@@ -1584,7 +1584,7 @@
 {
 	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
 
-	/* don't touch anything if SPDIF is open */
+	/* dont touch anything if SPDIF is open */
 	if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) {
 		ins->spdif_status_out &= ~DSP_SPDIF_STATUS_OUTPUT_ENABLED;
 		return -EBUSY;
@@ -1625,7 +1625,7 @@
 	}
 	
 	/* if not enabled already */
-	if (ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) {
+	if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) ) {
 		cs46xx_dsp_enable_spdif_hw (chip);
 	}
 
@@ -1669,7 +1669,6 @@
 	_dsp_clear_sample_buffer(chip,SPDIFO_IP_OUTPUT_BUFFER1,256);
 
 	/* restore state */
-
 	if ( ins->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED ) {
 		cs46xx_dsp_enable_spdif_out (chip);
 	}
diff -Nru a/sound/pci/cs46xx/imgs/cwcdma.asp b/sound/pci/cs46xx/imgs/cwcdma.asp
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/sound/pci/cs46xx/imgs/cwcdma.asp	Thu Mar 20 08:41:18 2003
@@ -0,0 +1,169 @@
+// 
+//  Copyright(c) by Benny Sjostrand (benny@hostmobility.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+
+
+//
+// This code runs inside the DSP (cs4610, cs4612, cs4624, or cs4630),
+// to compile it you need a tool named SPASM 3.0 and DSP code owned by 
+// Cirrus Logic(R). The SPASM program will generate a object file (cwcdma.osp),
+// the "ospparser"  tool will genereate the cwcdma.h file it's included from
+// the cs46xx_lib.c file.
+//
+//
+// The purpose of this code is very simple: make it possible to tranfser
+// the samples 'as they are' with no alteration from a PCMreader SCB (DMA from host)
+// to any other SCB. This is useful for AC3 throug SPDIF. SRC (source rate converters) 
+// task always alters the samples in some how, however it's from 48khz -> 48khz. The
+// alterations are not audible, but AC3 wont work. 
+//
+//        ...
+//         |
+// +---------------+
+// | AsynchFGTxSCB |
+// +---------------+
+//        |
+//    subListPtr
+//        |
+// +--------------+
+// |   DMAReader  |
+// +--------------+
+//        |
+//    subListPtr
+//        |
+// +-------------+
+// | PCMReader   |
+// +-------------+
+// (DMA from host)
+//
+
+struct dmaSCB
+  {
+    long  dma_reserved1[3];
+
+    short dma_reserved2:dma_outBufPtr;
+
+    short dma_unused1:dma_unused2;
+
+    long  dma_reserved3[4];
+
+    short dma_subListPtr:dma_nextSCB;
+    short dma_SPBptr:dma_entryPoint;
+
+    long  dma_strmRsConfig;
+    long  dma_strmBufPtr;
+
+    long  dma_reserved4;
+
+    VolumeControl s2m_volume;
+  };
+
+#export DMAReader
+void DMAReader()
+{
+  execChild();
+  r2 = r0->dma_subListPtr;
+  r1 = r0->nextSCB;
+	
+  rsConfig01 = r2->strmRsConfig;
+  // Load rsConfig for input buffer
+
+  rsDMA01 = r2->basicReq.daw,       ,                   tb = Z(0 - rf);
+  // Load rsDMA in case input buffer is a DMA buffer    Test to see if there is any data to transfer
+
+  if (tb) goto execSibling_2ind1 after {
+      r5 = rf + (-1);
+      r6 = r1->dma_entryPoint;           // r6 = entry point of sibling task
+      r1 = r1->dma_SPBptr,               // r1 = pointer to sibling task's SPB
+          ,   ind = r6;                  // Load entry point of sibling task
+  }
+
+  rsConfig23 = r0->dma_strmRsConfig;
+  // Load rsConfig for output buffer (never a DMA buffer)
+
+  r4 = r0->dma_outBufPtr;
+
+  rsa0 = r2->strmBufPtr;
+  // rsa0 = input buffer pointer                        
+
+  for (i = r5; i >= 0; --i)
+    after {
+      rsa2 = r4;
+      // rsa2 = output buffer pointer
+
+      nop;
+      nop;
+    }
+  //*****************************
+  // TODO: cycles to this point *
+  //*****************************
+    {
+      acc0 =  (rsd0 = *rsa0++1);
+      // get sample
+
+      nop;  // Those "nop"'s are really uggly, but there's
+      nop;  // something with DSP's pipelines which I don't
+      nop;  // understand, resulting this code to fail without
+            // having those "nop"'s (Benny)
+
+      rsa0?reqDMA = r2;
+      // Trigger DMA transfer on input stream, 
+      // if needed to replenish input buffer
+
+      nop;
+      // Yet another magic "nop" to make stuff work
+
+      ,,r98 = acc0 $+>> 0;
+      // store sample in ALU
+
+      nop;
+      // latency on load register.
+      // (this one is understandable)
+
+      *rsa2++1 = r98;
+      // store sample in output buffer
+
+      nop; // The same story
+      nop; // as above again ...
+      nop;
+    }
+  // TODO: cycles per loop iteration
+
+  r2->strmBufPtr = rsa0,,   ;
+  // Update the modified buffer pointers
+
+  r4 = rsa2;
+  // Load output pointer position into r4
+
+  r2 = r0->nextSCB;
+  // Sibling task
+
+  goto execSibling_2ind1 // takes 6 cycles
+    after {
+      r98 = r2->thisSPB:entryPoint;
+      // Load child routine entry and data address 
+
+      r1 = r9;
+      // r9 is r2->thisSPB
+
+      r0->dma_outBufPtr = r4,,
+      // Store updated output buffer pointer
+
+      ind = r8;
+      // r8 is r2->entryPoint
+    }
+}
diff -Nru a/sound/pci/cs46xx/imgs/cwcdma.h b/sound/pci/cs46xx/imgs/cwcdma.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/sound/pci/cs46xx/imgs/cwcdma.h	Thu Mar 20 08:41:19 2003
@@ -0,0 +1,68 @@
+/* generated from cwcdma.osp DO NOT MODIFY */
+
+#ifndef __HEADER_cwcdma_H__
+#define __HEADER_cwcdma_H__
+
+symbol_entry_t cwcdma_symbols[] = {
+  { 0x8000, "EXECCHILD",0x03 },
+  { 0x8001, "EXECCHILD_98",0x03 },
+  { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
+  { 0x8008, "EXECSIBLING",0x03 },
+  { 0x800a, "EXECSIBLING_298",0x03 },
+  { 0x800b, "EXECSIBLING_2IND1",0x03 },
+  { 0x8010, "TIMINGMASTER",0x03 },
+  { 0x804f, "S16_CODECINPUTTASK",0x03 },
+  { 0x805e, "PCMSERIALINPUTTASK",0x03 },
+  { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
+  { 0x809a, "S16_MIX",0x03 },
+  { 0x80bb, "S16_UPSRC",0x03 },
+  { 0x813b, "MIX3_EXP",0x03 },
+  { 0x8164, "DECIMATEBYPOW2",0x03 },
+  { 0x8197, "VARIDECIMATE",0x03 },
+  { 0x81f2, "_3DINPUTTASK",0x03 },
+  { 0x820a, "_3DPRLGCINPTASK",0x03 },
+  { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
+  { 0x8242, "_3DOUTPUTTASK",0x03 },
+  { 0x82c4, "HRTF_MORPH_TASK",0x03 },
+  { 0x82c6, "WAIT4DATA",0x03 },
+  { 0x82fa, "PROLOGIC",0x03 },
+  { 0x8496, "DECORRELATOR",0x03 },
+  { 0x84a4, "STEREO2MONO",0x03 },
+  { 0x0000, "OVERLAYBEGINADDRESS",0x00 },
+  { 0x0000, "DMAREADER",0x03 },
+  { 0x0018, "#CODE_END",0x00 },
+}; /* cwcdma symbols */
+
+u32 cwcdma_code[] = {
+/* OVERLAYBEGINADDRESS */
+/* 0000 */ 0x00002731,0x00001400,0x0004c108,0x000e5044,
+/* 0002 */ 0x0005f608,0x00000000,0x000007ae,0x000be300,
+/* 0004 */ 0x00058630,0x00001400,0x0007afb0,0x000e9584,
+/* 0006 */ 0x00007301,0x000a9840,0x0005e708,0x000cd104,
+/* 0008 */ 0x00067008,0x00000000,0x000902a0,0x00001000,
+/* 000A */ 0x00012a01,0x000c0000,0x00000000,0x00000000,
+/* 000C */ 0x00021843,0x000c0000,0x00000000,0x000c0000,
+/* 000E */ 0x0000e101,0x000c0000,0x00000cac,0x00000000,
+/* 0010 */ 0x00080000,0x000e5ca1,0x00000000,0x000c0000,
+/* 0012 */ 0x00000000,0x00000000,0x00000000,0x00092c00,
+/* 0014 */ 0x000122c1,0x000e5084,0x00058730,0x00001400,
+/* 0016 */ 0x000d7488,0x000e4782,0x00007401,0x0001c100
+};
+
+/* #CODE_END */
+
+segment_desc_t cwcdma_segments[] = {
+  { SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000030, cwcdma_code },
+};
+
+dsp_module_desc_t cwcdma_module = {
+  "cwcdma",
+  {
+    27,
+    cwcdma_symbols
+  },
+  1,
+  cwcdma_segments,
+};
+
+#endif /* __HEADER_cwcdma_H__ */
diff -Nru a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
--- a/sound/pci/emu10k1/emu10k1_main.c	Mon Jan 27 11:00:13 2003
+++ b/sound/pci/emu10k1/emu10k1_main.c	Thu Mar 20 08:41:14 2003
@@ -222,12 +222,21 @@
 		outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
 
 	if (enable_ir) {	/* enable IR for SB Live */
-		unsigned int reg = inl(emu->port + HCFG);
-		outl(reg | HCFG_GPOUT2, emu->port + HCFG);
-		udelay(500);
-		outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);
-		udelay(100);
-		outl(reg, emu->port + HCFG);
+		if (emu->audigy) {
+			unsigned int reg = inl(emu->port + A_IOCFG);
+			outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
+			udelay(500);
+			outl(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
+			udelay(100);
+			outl(reg, emu->port + A_IOCFG);
+		} else {
+			unsigned int reg = inl(emu->port + HCFG);
+			outl(reg | HCFG_GPOUT2, emu->port + HCFG);
+			udelay(500);
+			outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);
+			udelay(100);
+			outl(reg, emu->port + HCFG);
+ 		}
 	}
 	
 	if (!emu->APS) {	/* enable analog output */
@@ -581,22 +590,17 @@
 	/* enable PCI device */
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
-	/* set the DMA transfer mask */
-	if (is_audigy) {
-		if (pci_set_dma_mask(pci, 0xffffffff) < 0) {
-			snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n");
-			return -ENXIO;
-		}
-	} else {
-		if (pci_set_dma_mask(pci, 0x1fffffff) < 0) {
-			snd_printk(KERN_ERR "architecture does not support 29bit PCI busmaster DMA\n");
-			return -ENXIO;
-		}
-	}
 
 	emu = snd_magic_kcalloc(emu10k1_t, 0, GFP_KERNEL);
 	if (emu == NULL)
 		return -ENOMEM;
+	/* set the DMA transfer mask */
+	emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
+	if (pci_set_dma_mask(pci, emu->dma_mask) < 0) {
+		snd_printk(KERN_ERR "architecture does not support PCI busmaster DMA with mask 0x%lx\n", emu->dma_mask);
+		snd_magic_kfree(emu);
+		return -ENXIO;
+	}
 	emu->card = card;
 	spin_lock_init(&emu->reg_lock);
 	spin_lock_init(&emu->emu_lock);
diff -Nru a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
--- a/sound/pci/emu10k1/emufx.c	Sun Feb 16 05:47:43 2003
+++ b/sound/pci/emu10k1/emufx.c	Tue Feb 25 05:46:06 2003
@@ -520,8 +520,7 @@
 	*tram_pos -= frames;
 }
 
-static int snd_emu10k1_fx8010_playback_transfer(snd_pcm_substream_t *substream,
-						snd_pcm_uframes_t frames)
+static int snd_emu10k1_fx8010_playback_transfer(snd_pcm_substream_t *substream)
 {
 	emu10k1_t *emu = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -529,13 +528,13 @@
 	snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
 	snd_pcm_sframes_t diff = appl_ptr - pcm->appl_ptr;
 	snd_pcm_uframes_t buffer_size = pcm->buffer_size / 2;
+
 	if (diff) {
 		if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
 			diff += runtime->boundary;
-		frames += diff;
+		pcm->sw_ready += diff;
+		pcm->appl_ptr = appl_ptr;
 	}
-	pcm->sw_ready += frames;
-	pcm->appl_ptr = appl_ptr + frames;
 	while (pcm->hw_ready < buffer_size &&
 	       pcm->sw_ready > 0) {
 	       	size_t hw_to_end = buffer_size - pcm->hw_data;
@@ -632,7 +631,7 @@
 		result = snd_emu10k1_fx8010_register_irq_handler(emu, snd_emu10k1_fx8010_playback_irq, pcm->gpr_running, substream, &pcm->irq);
 		if (result < 0)
 			goto __err;
-		snd_emu10k1_fx8010_playback_transfer(substream, 0);	/* roll the ball */
+		snd_emu10k1_fx8010_playback_transfer(substream);	/* roll the ball */
 		snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 1);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
@@ -670,28 +669,10 @@
 	pcm->sw_io += frames;
 	if (pcm->sw_io > runtime->buffer_size)
 		pcm->sw_io -= runtime->buffer_size;
-	snd_emu10k1_fx8010_playback_transfer(substream, 0);
+	snd_emu10k1_fx8010_playback_transfer(substream);
 	return pcm->sw_io;
 }
 
-static int snd_emu10k1_fx8010_playback_copy(snd_pcm_substream_t *substream,
-					    int channel,
-					    snd_pcm_uframes_t hwoff,
-					    void *src,
-					    snd_pcm_uframes_t frames)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	size_t hwoffb = hwoff << 2;
-	size_t bytes = frames << 2;
-	char *hwbuf = runtime->dma_area + hwoffb;
-	if (copy_from_user(hwbuf, src, bytes))
-		return -EFAULT;
-	spin_lock_irq(&runtime->lock);
-	snd_emu10k1_fx8010_playback_transfer(substream, frames);
-	spin_unlock_irq(&runtime->lock);
-	return 0;
-}
-
 static snd_pcm_hardware_t snd_emu10k1_fx8010_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
@@ -748,8 +729,8 @@
 	.hw_free =		snd_emu10k1_fx8010_playback_hw_free,
 	.prepare =		snd_emu10k1_fx8010_playback_prepare,
 	.trigger =		snd_emu10k1_fx8010_playback_trigger,
-	.copy =			snd_emu10k1_fx8010_playback_copy,
 	.pointer =		snd_emu10k1_fx8010_playback_pointer,
+	.ack =			snd_emu10k1_fx8010_playback_transfer,
 };
 
 static void snd_emu10k1_fx8010_pcm_free(snd_pcm_t *pcm)
@@ -1221,7 +1202,7 @@
 	ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
 	ctl->min = 0;
 	ctl->max = 100;
-	ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;	
+	ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
 }
 
 static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
@@ -1252,12 +1233,14 @@
  * initial DSP configuration for Audigy
  */
 
+#define A_GPR_ACCU 0xd6
+
 static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
 {
-	int err, i, gpr, tmp, playback, capture, nctl;
+	int err, i, z, gpr, tmp, playback, capture, nctl;
 	u32 ptr;
 	emu10k1_fx8010_code_t *icode;
-	emu10k1_fx8010_control_gpr_t *controls;
+	emu10k1_fx8010_control_gpr_t *controls, *ctl;
 	mm_segment_t seg;
 
 	spin_lock_init(&emu->fx8010.irq_lock);
@@ -1269,7 +1252,7 @@
 		kfree(icode);
 		return -ENOMEM;
 	}
-	
+
 	/* clear free GPRs */
 	for (i = 0; i < 256; i++)
 		set_bit(i, icode->gpr_valid);
@@ -1278,10 +1261,10 @@
 	ptr = 0;
 	nctl = 0;
 	playback = 10;
-	capture = playback + 10; /* we reserve 10 voices */
+	capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
 	gpr = capture + 10;
-	tmp = 0x80;
-	
+	tmp = 0x88;
+
 	/* stop FX processor */
 	snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
 
@@ -1422,21 +1405,111 @@
 #define A_PUT_STEREO_OUTPUT(out1,out2,src) \
 	{A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
 
+#define _A_SWITCH(icode, ptr, dst, src, sw) \
+	A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
+#define A_SWITCH(icode, ptr, dst, src, sw) \
+		_A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
+#define _A_SWITCH_NEG(icode, ptr, dst, src) \
+	A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
+#define A_SWITCH_NEG(icode, ptr, dst, src) \
+		_A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
+
+
+	/*
+	 *  Process tone control
+	 */
+	A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
+	A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
+	A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), A_GPR(playback + 2), A_C_00000000, A_C_00000000); /* rear left */
+	A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), A_GPR(playback + 3), A_C_00000000, A_C_00000000); /* rear right */
+	A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
+	A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
+
+	ctl = &controls[nctl + 0];
+	ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	strcpy(ctl->id.name, "Tone Control - Bass");
+	ctl->vcount = 2;
+	ctl->count = 10;
+	ctl->min = 0;
+	ctl->max = 40;
+	ctl->value[0] = ctl->value[1] = 20;
+	ctl->translation = EMU10K1_GRP_TRANSLATION_BASS;
+	ctl = &controls[nctl + 1];
+	ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	strcpy(ctl->id.name, "Tone Control - Treble");
+	ctl->vcount = 2;
+	ctl->count = 10;
+	ctl->min = 0;
+	ctl->max = 40;
+	ctl->value[0] = ctl->value[1] = 20;
+	ctl->translation = EMU10K1_GRP_TRANSLATION_TREBLE;
+
+#define BASS_GPR	0x8c
+#define TREBLE_GPR	0x96
+
+	for (z = 0; z < 5; z++) {
+		int j;
+		for (j = 0; j < 2; j++) {
+			controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
+			controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
+		}
+	}
+	for (z = 0; z < 3; z++) {		/* front/rear/center-lfe */
+		int j, k, l, d;
+		for (j = 0; j < 2; j++) {	/* left/right */
+			k = 0xb0 + (z * 8) + (j * 4);
+			l = 0xe0 + (z * 8) + (j * 4);
+			d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
+
+			A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
+			A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
+			A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
+			A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
+			A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
+			A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
+
+			A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
+			A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
+			A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
+			A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
+			A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
+			A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
+
+			A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
+
+			if (z == 2)	/* center */
+				break;
+		}
+	}
+	nctl += 2;
+
+#undef BASS_GPR
+#undef TREBLE_GPR
+
+	for (z = 0; z < 6; z++) {
+		A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
+		A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
+		A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
+		A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
+	}
+	snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
+	gpr += 2;
+
 	/* digital outputs */
-	A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback);
-	A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2);
-	A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4);
-	A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5);
+	A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
+	A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
+	A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
+	A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
 
 	/* analog speakers */
-	//A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback);
-	A_PUT_STEREO_OUTPUT(A_EXTOUT_AC97_L, A_EXTOUT_AC97_R, playback);
-	A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2);
-	A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4);
-	A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5);
+	//A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
+	A_PUT_STEREO_OUTPUT(A_EXTOUT_AC97_L, A_EXTOUT_AC97_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
+	A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
+	A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
+	A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
 
 	/* headphone */
-	A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback);
+	A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
 
 	/* ADC buffer */
 	A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
@@ -1561,7 +1634,7 @@
 	gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
 	tmp = 0x88;	/* we need 4 temporary GPR */
 	/* from 0x8c to 0xff is the area for tone control */
-	
+
 	/* stop FX processor */
 	snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
 
@@ -1608,7 +1681,7 @@
 	icode->gpr_map[gpr + 12] = 0;
 
 	/* if the trigger flag is not set, skip */
-	/* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000); 
+	/* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
 	/* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
 	/* if the running flag is set, we're running */
 	/* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
diff -Nru a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
--- a/sound/pci/emu10k1/emupcm.c	Sun Feb 16 05:47:43 2003
+++ b/sound/pci/emu10k1/emupcm.c	Thu Mar 20 08:41:14 2003
@@ -32,7 +32,6 @@
 #include <linux/init.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
-#include <sound/pcm_sgbuf.h>
 
 #define chip_t emu10k1_t
 
diff -Nru a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
--- a/sound/pci/emu10k1/emuproc.c	Mon Jan 27 09:30:53 2003
+++ b/sound/pci/emu10k1/emuproc.c	Thu Mar 20 08:41:14 2003
@@ -232,7 +232,7 @@
 }
 
 static struct snd_info_entry_ops snd_emu10k1_proc_ops_fx8010 = {
-	read: snd_emu10k1_fx8010_read,
+	.read = snd_emu10k1_fx8010_read,
 };
 
 int __devinit snd_emu10k1_proc_init(emu10k1_t * emu)
diff -Nru a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
--- a/sound/pci/emu10k1/memory.c	Sun Feb 16 05:47:43 2003
+++ b/sound/pci/emu10k1/memory.c	Thu Mar 20 08:41:14 2003
@@ -25,7 +25,6 @@
 #include <linux/time.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
-#include <sound/pcm_sgbuf.h>
 
 /* page arguments of these two macros are Emu page (4096 bytes), not like
  * aligned pages in others
@@ -229,10 +228,10 @@
 /*
  * check if the given pointer is valid for pages
  */
-static int is_valid_page(dma_addr_t addr)
+static int is_valid_page(emu10k1_t *emu, dma_addr_t addr)
 {
-	if (addr & ~0x7fffffffUL) {
-		snd_printk("max memory size is 2GB (addr = 0x%lx)!!\n", (unsigned long)addr);
+	if (addr & ~emu->dma_mask) {
+		snd_printk("max memory size is 0x%lx (addr = 0x%lx)!!\n", emu->dma_mask, (unsigned long)addr);
 		return 0;
 	}
 	if (addr & (EMUPAGESIZE-1)) {
@@ -291,18 +290,20 @@
 snd_util_memblk_t *
 snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream)
 {
-	struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, _snd_pcm_substream_sgbuf(substream), return NULL);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_sg_buf *sgbuf = runtime->dma_private;
 	snd_util_memhdr_t *hdr;
 	emu10k1_memblk_t *blk;
 	int page, err, idx;
 
 	snd_assert(emu, return NULL);
-	snd_assert(sgbuf->size > 0 && sgbuf->size < MAXPAGES * EMUPAGESIZE, return NULL);
+	snd_assert(substream->dma_device.type == SNDRV_DMA_TYPE_PCI_SG, return NULL);
+	snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes < MAXPAGES * EMUPAGESIZE, return NULL);
 	hdr = emu->memhdr;
 	snd_assert(hdr, return NULL);
 
 	down(&hdr->block_mutex);
-	blk = search_empty(emu, sgbuf->size);
+	blk = search_empty(emu, runtime->dma_bytes);
 	if (blk == NULL) {
 		up(&hdr->block_mutex);
 		return NULL;
@@ -322,7 +323,7 @@
 		}
 #endif
 		addr = sgbuf->table[idx].addr;
-		if (! is_valid_page(addr)) {
+		if (! is_valid_page(emu, addr)) {
 			printk(KERN_ERR "emu: failure page = %d\n", idx);
 			up(&hdr->block_mutex);
 			return NULL;
@@ -445,7 +446,7 @@
 		ptr = snd_malloc_pci_page(emu->pci, &addr);
 		if (ptr == NULL)
 			goto __fail;
-		if (! is_valid_page(addr)) {
+		if (! is_valid_page(emu, addr)) {
 			snd_free_pci_page(emu->pci, ptr, addr);
 			goto __fail;
 		}
diff -Nru a/sound/pci/es1968.c b/sound/pci/es1968.c
--- a/sound/pci/es1968.c	Tue Feb 25 10:47:57 2003
+++ b/sound/pci/es1968.c	Thu Mar 20 08:41:14 2003
@@ -555,9 +555,8 @@
 	unsigned int clock;		/* clock */
 
 	/* buffer */
-	void *dma_buf;
-	dma_addr_t dma_buf_addr;
-	unsigned long dma_buf_size;
+	struct snd_dma_device dma_dev;
+	struct snd_dma_buffer dma;
 
 	/* Resources... */
 	int irq;
@@ -1076,7 +1075,7 @@
 
 		/* Offset to PCMBAR */
 		pa = es->memory->addr;
-		pa -= chip->dma_buf_addr;
+		pa -= chip->dma.addr;
 		pa >>= 1;	/* words */
 
 		pa |= 0x00400000;	/* System RAM (Bit 22) */
@@ -1222,7 +1221,7 @@
 		snd_es1968_program_wavecache(chip, es, channel, pa, 1);
 
 		/* Offset to PCMBAR */
-		pa -= chip->dma_buf_addr;
+		pa -= chip->dma.addr;
 		pa >>= 1;	/* words */
 
 		/* base offset of dma calcs when reading the pointer
@@ -1499,9 +1498,9 @@
 {
 	struct list_head *p;
 
-	if (! chip->dma_buf)
+	if (! chip->dma.area)
 		return;
-	snd_free_pci_pages(chip->pci, chip->dma_buf_size, chip->dma_buf, chip->dma_buf_addr);
+	snd_dma_free_reserved(&chip->dma_dev);
 	while ((p = chip->buf_list.next) != &chip->buf_list) {
 		esm_memory_t *chunk = list_entry(p, esm_memory_t, list);
 		list_del(p);
@@ -1513,18 +1512,22 @@
 snd_es1968_init_dmabuf(es1968_t *chip)
 {
 	esm_memory_t *chunk;
-	chip->dma_buf = snd_malloc_pci_pages_fallback(chip->pci, chip->total_bufsize,
-						      &chip->dma_buf_addr, &chip->dma_buf_size);
-	//snd_printd("es1968: allocated buffer size %ld at %p\n", chip->dma_buf_size, chip->dma_buf);
-	if (chip->dma_buf == NULL) {
-		snd_printk("es1968: can't allocate dma pages for size %d\n",
-			   chip->total_bufsize);
-		return -ENOMEM;
-	}
-	if ((chip->dma_buf_addr + chip->dma_buf_size - 1) & ~((1 << 28) - 1)) {
-		snd_es1968_free_dmabuf(chip);
-		snd_printk("es1968: DMA buffer beyond 256MB.\n");
-		return -ENOMEM;
+
+	snd_dma_device_pci(&chip->dma_dev, chip->pci, 0);
+	if (! snd_dma_get_reserved(&chip->dma_dev, &chip->dma)) {
+		chip->dma.area = snd_malloc_pci_pages_fallback(chip->pci, chip->total_bufsize,
+							       &chip->dma.addr, &chip->dma.bytes);
+		if (chip->dma.area == NULL) {
+			snd_printk("es1968: can't allocate dma pages for size %d\n",
+				   chip->total_bufsize);
+			return -ENOMEM;
+		}
+		if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) {
+			snd_dma_free_pages(&chip->dma_dev, &chip->dma);
+			snd_printk("es1968: DMA buffer beyond 256MB.\n");
+			return -ENOMEM;
+		}
+		snd_dma_set_reserved(&chip->dma_dev, &chip->dma);
 	}
 
 	INIT_LIST_HEAD(&chip->buf_list);
@@ -1534,10 +1537,10 @@
 		snd_es1968_free_dmabuf(chip);
 		return -ENOMEM;
 	}
-	memset(chip->dma_buf, 0, 512);
-	chunk->buf = chip->dma_buf + 512;
-	chunk->addr = chip->dma_buf_addr + 512;
-	chunk->size = chip->dma_buf_size - 512;
+	memset(chip->dma.area, 0, 512);
+	chunk->buf = chip->dma.area + 512;
+	chunk->addr = chip->dma.addr + 512;
+	chunk->size = chip->dma.bytes - 512;
 	chunk->empty = 1;
 	list_add(&chunk->list, &chip->buf_list);
 
@@ -1812,7 +1815,7 @@
 
 	wave_set_register(chip, apu << 3, (memory->addr - 0x10) & 0xfff8);
 
-	pa = (unsigned int)((memory->addr - chip->dma_buf_addr) >> 1);
+	pa = (unsigned int)((memory->addr - chip->dma.addr) >> 1);
 	pa |= 0x00400000;	/* System RAM (Bit 22) */
 
 	/* initialize apu */
@@ -1902,10 +1905,10 @@
 		return err;
 
 	/* set PCMBAR */
-	wave_set_register(chip, 0x01FC, chip->dma_buf_addr >> 12);
-	wave_set_register(chip, 0x01FD, chip->dma_buf_addr >> 12);
-	wave_set_register(chip, 0x01FE, chip->dma_buf_addr >> 12);
-	wave_set_register(chip, 0x01FF, chip->dma_buf_addr >> 12);
+	wave_set_register(chip, 0x01FC, chip->dma.addr >> 12);
+	wave_set_register(chip, 0x01FD, chip->dma.addr >> 12);
+	wave_set_register(chip, 0x01FE, chip->dma.addr >> 12);
+	wave_set_register(chip, 0x01FF, chip->dma.addr >> 12);
 
 	if ((err = snd_pcm_new(chip->card, "ESS Maestro", device,
 			       chip->playback_streams,
@@ -2329,7 +2332,7 @@
 	outb(0x88, iobase+0x1f);
 
 	/* it appears some maestros (dell 7500) only work if these are set,
-	   regardless of whether we use the assp or not. */
+	   regardless of wether we use the assp or not. */
 
 	outb(0, iobase + ASSP_CONTROL_B);
 	outb(3, iobase + ASSP_CONTROL_A);	/* M: Reserved bits... */
@@ -2443,9 +2446,9 @@
 	snd_es1968_chip_init(chip);
 
 	/* need to restore the base pointers.. */ 
-	if (chip->dma_buf_addr) {
+	if (chip->dma.addr) {
 		/* set PCMBAR */
-		wave_set_register(chip, 0x01FC, chip->dma_buf_addr >> 12);
+		wave_set_register(chip, 0x01FC, chip->dma.addr >> 12);
 	}
 
 	/* restore ac97 state */
@@ -2603,7 +2606,7 @@
 	/* just to be sure */
 	pci_set_master(pci);
 
-	if (do_pm) {
+	if (do_pm > 1) {
 		/* disable power-management if not maestro2e or
 		 * if not on the whitelist
 		 */
diff -Nru a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
--- a/sound/pci/ice1712/Makefile	Mon Feb  3 14:19:39 2003
+++ b/sound/pci/ice1712/Makefile	Thu Mar 20 08:41:14 2003
@@ -3,7 +3,9 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-snd-ice1712-objs := ice1712.o ak4524.o delta.o hoontech.o ews.o amp.o
+snd-ice1712-objs := ice1712.o ak4524.o delta.o hoontech.o ews.o
+snd-ice1724-objs := ice1724.o ak4524.o amp.o revo.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o
+obj-$(CONFIG_SND_ICE1724) += snd-ice1724.o
diff -Nru a/sound/pci/ice1712/ak4524.c b/sound/pci/ice1712/ak4524.c
--- a/sound/pci/ice1712/ak4524.c	Sat Feb  8 12:10:54 2003
+++ b/sound/pci/ice1712/ak4524.c	Thu Mar 20 08:41:14 2003
@@ -1,7 +1,7 @@
 /*
  *   ALSA driver for ICEnsemble ICE1712 (Envy24)
  *
- *   AK4524 / AK4528 / AK4529 interface
+ *   AK4524 / AK4528 / AK4529 / AK4355 / AK4381 interface
  *
  *	Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
  *
@@ -31,25 +31,25 @@
 
 
 /*
- * write AK4524 register
+ * write AK4xxx register
  */
-void snd_ice1712_ak4524_write(ice1712_t *ice, int chip,
+void snd_ice1712_akm4xxx_write(akm4xxx_t *ak, int chip,
 			      unsigned char addr, unsigned char data)
 {
-	unsigned char tmp, saved[2];
+	unsigned int tmp;
 	int idx;
 	unsigned int addrdata;
-	ak4524_t *ak = &ice->ak4524;
+	ice1712_t *ice = ak->chip;
 
 	snd_assert(chip >= 0 && chip < 4, return);
 
 	if (ak->ops.start) {
-		if (ak->ops.start(ice, saved, chip) < 0)
+		if (ak->ops.start(ak, chip) < 0)
 			return;
 	} else
-		snd_ice1712_save_gpio_status(ice, saved);
+		snd_ice1712_save_gpio_status(ice);
 
-	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
+	tmp = snd_ice1712_gpio_read(ice);
 	tmp |= ak->add_flags;
 	tmp &= ~ak->mask_flags;
 	if (ak->cs_mask == ak->cs_addr) {
@@ -57,35 +57,46 @@
 			tmp |= ak->cs_mask; /* start without chip select */
 		}  else {
 			tmp &= ~ak->cs_mask; /* chip select low */
-			snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
+			snd_ice1712_gpio_write(ice, tmp);
 			udelay(1);
 		}
 	} else {
+		/* doesn't handle cf=1 yet */
 		tmp &= ~ak->cs_mask;
 		tmp |= ak->cs_addr;
+		snd_ice1712_gpio_write(ice, tmp);
+		udelay(1);
 	}
 
 	/* build I2C address + data byte */
-	addrdata = (ak->caddr << 14) | 0x2000 | ((addr & 0x0f) << 8) | data;
+	addrdata = (ak->caddr << 6) | 0x20 | (addr & 0x1f);
+	addrdata = (addrdata << 8) | data;
 	for (idx = 15; idx >= 0; idx--) {
-		tmp &= ~(ak->data_mask | ak->clk_mask);
+		/* drop clock */
+		tmp &= ~ak->clk_mask;
+		snd_ice1712_gpio_write(ice, tmp);
+		udelay(1);
+		/* set data */
 		if (addrdata & (1 << idx))
 			tmp |= ak->data_mask;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-		//udelay(200);
+		else
+			tmp &= ~ak->data_mask;
+		snd_ice1712_gpio_write(ice, tmp);
 		udelay(1);
+		/* raise clock */
 		tmp |= ak->clk_mask;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
+		snd_ice1712_gpio_write(ice, tmp);
 		udelay(1);
 	}
 
+	/* save the data */
 	if (ak->type == SND_AK4524 || ak->type == SND_AK4528) {
 		if ((addr != 0x04 && addr != 0x05) || (data & 0x80) == 0)
 			ak->images[chip][addr] = data;
 		else
 			ak->ipga_gain[chip][addr-4] = data;
 	} else {
-		/* AK4529 */
+		/* AK4529, or else */
 		ak->images[chip][addr] = data;
 	}
 	
@@ -93,7 +104,7 @@
 		if (ak->cif) {
 			/* assert a cs pulse to trigger */
 			tmp &= ~ak->cs_mask;
-			snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
+			snd_ice1712_gpio_write(ice, tmp);
 			udelay(1);
 		}
 		tmp |= ak->cs_mask; /* chip select high to trigger */
@@ -101,48 +112,70 @@
 		tmp &= ~ak->cs_mask;
 		tmp |= ak->cs_none; /* deselect address */
 	}
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
+	snd_ice1712_gpio_write(ice, tmp);
 	udelay(1);
 
 	if (ak->ops.stop)
-		ak->ops.stop(ice, saved);
+		ak->ops.stop(ak);
 	else
-		snd_ice1712_restore_gpio_status(ice, saved);
+		snd_ice1712_restore_gpio_status(ice);
 }
 
-void snd_ice1712_ak4524_reset(ice1712_t *ice, int state)
+/*
+ * reset the AKM codecs
+ * @state: 1 = reset codec, 0 = restore the registers
+ *
+ * assert the reset operation and restores the register values to the chips.
+ */
+void snd_ice1712_akm4xxx_reset(akm4xxx_t *ak, int state)
 {
 	unsigned int chip;
 	unsigned char reg;
-	ak4524_t *ak = &ice->ak4524;
 	
 	switch (ak->type) {
 	case SND_AK4524:
 	case SND_AK4528:
 		for (chip = 0; chip < ak->num_dacs/2; chip++) {
-			snd_ice1712_ak4524_write(ice, chip, 0x01, state ? 0x00 : 0x03);
+			snd_ice1712_akm4xxx_write(ak, chip, 0x01, state ? 0x00 : 0x03);
 			if (state)
 				continue;
 			/* DAC volumes */
 			for (reg = 0x04; reg < (ak->type == SND_AK4528 ? 0x06 : 0x08); reg++)
-				snd_ice1712_ak4524_write(ice, chip, reg, ak->images[chip][reg]);
+				snd_ice1712_akm4xxx_write(ak, chip, reg, ak->images[chip][reg]);
 			if (ak->type == SND_AK4528)
 				continue;
 			/* IPGA */
 			for (reg = 0x04; reg < 0x06; reg++)
-				snd_ice1712_ak4524_write(ice, chip, reg, ak->ipga_gain[chip][reg-4]);
+				snd_ice1712_akm4xxx_write(ak, chip, reg, ak->ipga_gain[chip][reg-4]);
 		}
 		break;
 	case SND_AK4529:
 		/* FIXME: needed for ak4529? */
 		break;
+	case SND_AK4355:
+		snd_ice1712_akm4xxx_write(ak, 0, 0x01, state ? 0x02 : 0x01);
+		if (state)
+			return;
+		for (reg = 0x00; reg < 0x0a; reg++)
+			if (reg != 0x01)
+				snd_ice1712_akm4xxx_write(ak, 0, reg, ak->images[0][reg]);
+		break;
+	case SND_AK4381:
+		for (chip = 0; chip < ak->num_dacs/2; chip++) {
+			snd_ice1712_akm4xxx_write(ak, chip, 0x00, state ? 0x0c : 0x0f);
+			if (state)
+				continue;
+			for (reg = 0x01; reg < 0x05; reg++)
+				snd_ice1712_akm4xxx_write(ak, chip, reg, ak->images[chip][reg]);
+		}
+		break;
 	}
 }
 
 /*
- * initialize all the ak4524/4528 chips
+ * initialize all the ak4xxx chips
  */
-void __devinit snd_ice1712_ak4524_init(ice1712_t *ice)
+static void __devinit snd_ice1712_akm4xxx_init_chip(akm4xxx_t *ak)
 {
 	static unsigned char inits_ak4524[] = {
 		0x00, 0x07, /* 0: all power up */
@@ -184,9 +217,35 @@
 		0x08, 0x55, /* 8: deemphasis all off */
 		0xff, 0xff
 	};
+	static unsigned char inits_ak4355[] = {
+		0x01, 0x02, /* 1: reset and soft-mute */
+		0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, disable DZF, sharp roll-off, RSTN#=0 */
+		// 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */
+		0x02, 0x2e,
+		0x03, 0x01, /* 3: de-emphasis off */
+		0x04, 0x00, /* 4: LOUT1 volume muted */
+		0x05, 0x00, /* 5: ROUT1 volume muted */
+		0x06, 0x00, /* 6: LOUT2 volume muted */
+		0x07, 0x00, /* 7: ROUT2 volume muted */
+		0x08, 0x00, /* 8: LOUT3 volume muted */
+		0x09, 0x00, /* 9: ROUT3 volume muted */
+		0x0a, 0x00, /* a: DATT speed=0, ignore DZF */
+		0x01, 0x01, /* 1: un-reset, unmute */
+		0xff, 0xff
+	};
+	static unsigned char inits_ak4381[] = {
+		0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */
+		// 0x01, 0x02, /* 1: de-emphasis off, normal speed, sharp roll-off, DZF off */
+		0x01, 0x12,
+		0x02, 0x00, /* 2: DZF disabled */
+		0x03, 0x00, /* 3: LATT 0 */
+		0x04, 0x00, /* 4: RATT 0 */
+		0x00, 0x0f, /* 0: power-up, un-reset */
+		0xff, 0xff
+	};
+
 	int chip, num_chips;
 	unsigned char *ptr, reg, data, *inits;
-	ak4524_t *ak = &ice->ak4524;
 
 	switch (ak->type) {
 	case SND_AK4524:
@@ -198,10 +257,20 @@
 		num_chips = ak->num_dacs / 2;
 		break;
 	case SND_AK4529:
-	default:
 		inits = inits_ak4529;
 		num_chips = 1;
 		break;
+	case SND_AK4355:
+		inits = inits_ak4355;
+		num_chips = 1;
+		break;
+	case SND_AK4381:
+		inits = inits_ak4381;
+		num_chips = ak->num_dacs / 2;
+		break;
+	default:
+		snd_BUG();
+		return;
 	}
 
 	for (chip = 0; chip < num_chips; chip++) {
@@ -209,12 +278,23 @@
 		while (*ptr != 0xff) {
 			reg = *ptr++;
 			data = *ptr++;
-			snd_ice1712_ak4524_write(ice, chip, reg, data);
+			snd_ice1712_akm4xxx_write(ak, chip, reg, data);
 		}
 	}
 }
 
 
+/*
+ * initialize the akm4xxx_t record with the template
+ */
+void snd_ice1712_akm4xxx_init(akm4xxx_t *ak, const akm4xxx_t *temp, ice1712_t *ice)
+{
+	*ak = *temp;
+	ak->chip = ice;
+	snd_ice1712_akm4xxx_init_chip(ak);
+}
+
+
 #define AK_GET_CHIP(val)		(((val) >> 8) & 0xff)
 #define AK_GET_ADDR(val)		((val) & 0xff)
 #define AK_GET_SHIFT(val)		(((val) >> 16) & 0x7f)
@@ -223,7 +303,7 @@
 #define AK_COMPOSE(chip,addr,shift,mask) (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24))
 #define AK_INVERT 			(1<<23)
 
-static int snd_ice1712_ak4524_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ice1712_akm4xxx_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	unsigned int mask = AK_GET_MASK(kcontrol->private_value);
 
@@ -234,22 +314,22 @@
 	return 0;
 }
 
-static int snd_ice1712_ak4524_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_akm4xxx_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	akm4xxx_t *ak = _snd_kcontrol_chip(kcontrol);
 	int chip = AK_GET_CHIP(kcontrol->private_value);
 	int addr = AK_GET_ADDR(kcontrol->private_value);
 	int invert = AK_GET_INVERT(kcontrol->private_value);
 	unsigned int mask = AK_GET_MASK(kcontrol->private_value);
-	unsigned char val = ice->ak4524.images[chip][addr];
+	unsigned char val = ak->images[chip][addr];
 	
 	ucontrol->value.integer.value[0] = invert ? mask - val : val;
 	return 0;
 }
 
-static int snd_ice1712_ak4524_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_akm4xxx_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	akm4xxx_t *ak = _snd_kcontrol_chip(kcontrol);
 	int chip = AK_GET_CHIP(kcontrol->private_value);
 	int addr = AK_GET_ADDR(kcontrol->private_value);
 	int invert = AK_GET_INVERT(kcontrol->private_value);
@@ -259,13 +339,13 @@
 
 	if (invert)
 		nval = mask - nval;
-	change = ice->ak4524.images[chip][addr] != nval;
+	change = ak->images[chip][addr] != nval;
 	if (change)
-		snd_ice1712_ak4524_write(ice, chip, addr, nval);
+		snd_ice1712_akm4xxx_write(ak, chip, addr, nval);
 	return change;
 }
 
-static int snd_ice1712_ak4524_ipga_gain_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ice1712_akm4xxx_ipga_gain_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -274,28 +354,28 @@
 	return 0;
 }
 
-static int snd_ice1712_ak4524_ipga_gain_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_akm4xxx_ipga_gain_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	akm4xxx_t *ak = _snd_kcontrol_chip(kcontrol);
 	int chip = AK_GET_CHIP(kcontrol->private_value);
 	int addr = AK_GET_ADDR(kcontrol->private_value);
-	ucontrol->value.integer.value[0] = ice->ak4524.ipga_gain[chip][addr-4] & 0x7f;
+	ucontrol->value.integer.value[0] = ak->ipga_gain[chip][addr-4] & 0x7f;
 	return 0;
 }
 
-static int snd_ice1712_ak4524_ipga_gain_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_akm4xxx_ipga_gain_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	akm4xxx_t *ak = _snd_kcontrol_chip(kcontrol);
 	int chip = AK_GET_CHIP(kcontrol->private_value);
 	int addr = AK_GET_ADDR(kcontrol->private_value);
 	unsigned char nval = (ucontrol->value.integer.value[0] % 37) | 0x80;
-	int change = ice->ak4524.ipga_gain[chip][addr] != nval;
+	int change = ak->ipga_gain[chip][addr] != nval;
 	if (change)
-		snd_ice1712_ak4524_write(ice, chip, addr, nval);
+		snd_ice1712_akm4xxx_write(ak, chip, addr, nval);
 	return change;
 }
 
-static int snd_ice1712_ak4524_deemphasis_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ice1712_akm4xxx_deemphasis_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	static char *texts[4] = {
 		"44.1kHz", "Off", "48kHz", "32kHz",
@@ -309,29 +389,29 @@
 	return 0;
 }
 
-static int snd_ice1712_ak4524_deemphasis_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_akm4xxx_deemphasis_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	akm4xxx_t *ak = _snd_kcontrol_chip(kcontrol);
 	int chip = AK_GET_CHIP(kcontrol->private_value);
 	int addr = AK_GET_ADDR(kcontrol->private_value);
 	int shift = AK_GET_SHIFT(kcontrol->private_value);
-	ucontrol->value.enumerated.item[0] = (ice->ak4524.images[chip][addr] >> shift) & 3;
+	ucontrol->value.enumerated.item[0] = (ak->images[chip][addr] >> shift) & 3;
 	return 0;
 }
 
-static int snd_ice1712_ak4524_deemphasis_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_akm4xxx_deemphasis_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	akm4xxx_t *ak = _snd_kcontrol_chip(kcontrol);
 	int chip = AK_GET_CHIP(kcontrol->private_value);
 	int addr = AK_GET_ADDR(kcontrol->private_value);
 	int shift = AK_GET_SHIFT(kcontrol->private_value);
 	unsigned char nval = ucontrol->value.enumerated.item[0] & 3;
 	int change;
 	
-	nval = (nval << shift) | (ice->ak4524.images[chip][addr] & ~(3 << shift));
-	change = ice->ak4524.images[chip][addr] != nval;
+	nval = (nval << shift) | (ak->images[chip][addr] & ~(3 << shift));
+	change = ak->images[chip][addr] != nval;
 	if (change)
-		snd_ice1712_ak4524_write(ice, chip, addr, nval);
+		snd_ice1712_akm4xxx_write(ak, chip, addr, nval);
 	return change;
 }
 
@@ -339,90 +419,107 @@
  * build AK4524 controls
  */
 
-int __devinit snd_ice1712_ak4524_build_controls(ice1712_t *ice)
+int __devinit snd_ice1712_akm4xxx_build_controls(ice1712_t *ice)
 {
 	unsigned int idx;
 	int err;
-	ak4524_t *ak = &ice->ak4524;
+	unsigned int akidx;
 
-	for (idx = 0; idx < ak->num_dacs; ++idx) {
-		snd_kcontrol_t ctl;
-		memset(&ctl, 0, sizeof(ctl));
-		strcpy(ctl.id.name, "DAC Volume");
-		ctl.id.index = idx;
-		ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		ctl.info = snd_ice1712_ak4524_volume_info;
-		ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
-		ctl.get = snd_ice1712_ak4524_volume_get;
-		ctl.put = snd_ice1712_ak4524_volume_put;
-		switch (ak->type) {
-		case SND_AK4524:
-			ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127); /* register 6 & 7 */
-			break;
-		case SND_AK4528:
-			ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */
-			break;
-		case SND_AK4529: {
-			int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb; /* registers 2-7 and b,c */
-			ctl.private_value = AK_COMPOSE(0, val, 0, 255) | AK_INVERT;
-			break;
+	for (akidx = 0; akidx < ice->akm_codecs; akidx++) {
+		akm4xxx_t *ak = &ice->akm[akidx];
+		for (idx = 0; idx < ak->num_dacs; ++idx) {
+			snd_kcontrol_t ctl;
+			memset(&ctl, 0, sizeof(ctl));
+			strcpy(ctl.id.name, "DAC Volume");
+			ctl.id.index = idx + ak->idx_offset * 2;
+			ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+			ctl.info = snd_ice1712_akm4xxx_volume_info;
+			ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
+			ctl.get = snd_ice1712_akm4xxx_volume_get;
+			ctl.put = snd_ice1712_akm4xxx_volume_put;
+			switch (ak->type) {
+			case SND_AK4524:
+				ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127); /* register 6 & 7 */
+				break;
+			case SND_AK4528:
+				ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */
+				break;
+			case SND_AK4529: {
+				int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb; /* registers 2-7 and b,c */
+				ctl.private_value = AK_COMPOSE(0, val, 0, 255) | AK_INVERT;
+				break;
+			}
+			case SND_AK4355:
+				ctl.private_value = AK_COMPOSE(0, idx + 4, 0, 255); /* register 4-9, chip #0 only */
+				break;
+			case SND_AK4381:
+				ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255); /* register 3 & 4 */
+				break;
+			default:
+				return -EINVAL;
+			}
+			ctl.private_data = ak;
+			if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0)
+				return err;
 		}
+		for (idx = 0; idx < ak->num_adcs && ak->type == SND_AK4524; ++idx) {
+			snd_kcontrol_t ctl;
+			memset(&ctl, 0, sizeof(ctl));
+			strcpy(ctl.id.name, "ADC Volume");
+			ctl.id.index = idx;
+			ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+			ctl.info = snd_ice1712_akm4xxx_volume_info;
+			ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
+			ctl.get = snd_ice1712_akm4xxx_volume_get;
+			ctl.put = snd_ice1712_akm4xxx_volume_put;
+			ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */
+			ctl.private_data = ak;
+			if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0)
+				return err;
+			memset(&ctl, 0, sizeof(ctl));
+			strcpy(ctl.id.name, "IPGA Analog Capture Volume");
+			ctl.id.index = idx;
+			ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+			ctl.info = snd_ice1712_akm4xxx_ipga_gain_info;
+			ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
+			ctl.get = snd_ice1712_akm4xxx_ipga_gain_get;
+			ctl.put = snd_ice1712_akm4xxx_ipga_gain_put;
+			ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 0); /* register 4 & 5 */
+			ctl.private_data = ak;
+			if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0)
+				return err;
 		}
-		ctl.private_data = ice;
-		if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0)
-			return err;
-	}
-	for (idx = 0; idx < ak->num_adcs && ak->type == SND_AK4524; ++idx) {
-		snd_kcontrol_t ctl;
-		memset(&ctl, 0, sizeof(ctl));
-		strcpy(ctl.id.name, "ADC Volume");
-		ctl.id.index = idx;
-		ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		ctl.info = snd_ice1712_ak4524_volume_info;
-		ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
-		ctl.get = snd_ice1712_ak4524_volume_get;
-		ctl.put = snd_ice1712_ak4524_volume_put;
-		ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */
-		ctl.private_data = ice;
-		if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0)
-			return err;
-		memset(&ctl, 0, sizeof(ctl));
-		strcpy(ctl.id.name, "IPGA Analog Capture Volume");
-		ctl.id.index = idx;
-		ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		ctl.info = snd_ice1712_ak4524_ipga_gain_info;
-		ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
-		ctl.get = snd_ice1712_ak4524_ipga_gain_get;
-		ctl.put = snd_ice1712_ak4524_ipga_gain_put;
-		ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 0); /* register 4 & 5 */
-		ctl.private_data = ice;
-		if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0)
-			return err;
-	}
-	for (idx = 0; idx < ak->num_dacs/2; idx++) {
-		snd_kcontrol_t ctl;
-		memset(&ctl, 0, sizeof(ctl));
-		strcpy(ctl.id.name, "Deemphasis");
-		ctl.id.index = idx;
-		ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		ctl.info = snd_ice1712_ak4524_deemphasis_info;
-		ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
-		ctl.get = snd_ice1712_ak4524_deemphasis_get;
-		ctl.put = snd_ice1712_ak4524_deemphasis_put;
-		switch (ak->type) {
-		case SND_AK4524:
-		case SND_AK4528:
-			ctl.private_value = AK_COMPOSE(idx, 3, 0, 0); /* register 3 */
-			break;
-		case SND_AK4529: {
-			int shift = idx == 3 ? 6 : (2 - idx) * 2;
-			ctl.private_value = AK_COMPOSE(0, 8, shift, 0); /* register 8 with shift */
-			break;
-		}
+		for (idx = 0; idx < ak->num_dacs/2; idx++) {
+			snd_kcontrol_t ctl;
+			memset(&ctl, 0, sizeof(ctl));
+			strcpy(ctl.id.name, "Deemphasis");
+			ctl.id.index = idx + ak->idx_offset;
+			ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+			ctl.info = snd_ice1712_akm4xxx_deemphasis_info;
+			ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
+			ctl.get = snd_ice1712_akm4xxx_deemphasis_get;
+			ctl.put = snd_ice1712_akm4xxx_deemphasis_put;
+			switch (ak->type) {
+			case SND_AK4524:
+			case SND_AK4528:
+				ctl.private_value = AK_COMPOSE(idx, 3, 0, 0); /* register 3 */
+				break;
+			case SND_AK4529: {
+				int shift = idx == 3 ? 6 : (2 - idx) * 2;
+				ctl.private_value = AK_COMPOSE(0, 8, shift, 0); /* register 8 with shift */
+				break;
+			}
+			case SND_AK4355:
+				ctl.private_value = AK_COMPOSE(idx, 3, 0, 0);
+				break;
+			case SND_AK4381:
+				ctl.private_value = AK_COMPOSE(idx, 1, 1, 0);
+				break;
+			}
+			ctl.private_data = ak;
+			if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0)
+				return err;
 		}
-		ctl.private_data = ice;
-		if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0)
-			return err;
 	}
 	return 0;
 }
diff -Nru a/sound/pci/ice1712/amp.h b/sound/pci/ice1712/amp.h
--- a/sound/pci/ice1712/amp.h	Thu Dec  5 11:47:37 2002
+++ b/sound/pci/ice1712/amp.h	Thu Mar 20 08:41:14 2003
@@ -24,7 +24,7 @@
  *
  */      
 
-#define  AMP_AUDIO2000_DEVICE_DESC 	       "{AMP Ltd AUDIO2000},"
+#define  AMP_AUDIO2000_DEVICE_DESC 	       "{AMP Ltd,AUDIO2000},"
 
 #define VT1724_SUBDEVICE_AUDIO2000	0x12142417	/* Advanced Micro Peripherals Ltd AUDIO2000 */
 
diff -Nru a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
--- a/sound/pci/ice1712/delta.c	Thu Dec  5 11:47:36 2002
+++ b/sound/pci/ice1712/delta.c	Thu Mar 20 08:41:14 2003
@@ -232,32 +232,33 @@
 /*
  * AK4524 on Delta 44 and 66 to choose the chip mask
  */
-static int delta_ak4524_start(ice1712_t *ice, unsigned char *saved, int chip)
+static int delta_ak4524_start(akm4xxx_t *ak, int chip)
 {
-	snd_ice1712_save_gpio_status(ice, saved);
-	ice->ak4524.cs_mask =
-	ice->ak4524.cs_addr = chip == 0 ? ICE1712_DELTA_CODEC_CHIP_A :
-					  ICE1712_DELTA_CODEC_CHIP_B;
+	snd_ice1712_save_gpio_status(ak->chip);
+	ak->cs_mask =
+	ak->cs_addr = chip == 0 ? ICE1712_DELTA_CODEC_CHIP_A :
+				  ICE1712_DELTA_CODEC_CHIP_B;
 	return 0;
 }
 
 /*
  * AK4524 on Delta1010LT to choose the chip address
  */
-static int delta1010lt_ak4524_start(ice1712_t *ice, unsigned char *saved, int chip)
+static int delta1010lt_ak4524_start(akm4xxx_t *ak, int chip)
 {
-	snd_ice1712_save_gpio_status(ice, saved);
-	ice->ak4524.cs_mask = ICE1712_DELTA_1010LT_CS;
-	ice->ak4524.cs_addr = chip << 4;
+	snd_ice1712_save_gpio_status(ak->chip);
+	ak->cs_mask = ICE1712_DELTA_1010LT_CS;
+	ak->cs_addr = chip << 4;
 	return 0;
 }
 
 /*
  * change the rate of AK4524 on Delta 44/66, AP, 1010LT
  */
-static void delta_ak4524_set_rate_val(ice1712_t *ice, unsigned int rate)
+static void delta_ak4524_set_rate_val(akm4xxx_t *ak, unsigned int rate)
 {
 	unsigned char tmp, tmp2;
+	ice1712_t *ice = ak->chip;
 
 	if (rate == 0)	/* no hint - S/PDIF input is master, simply return */
 		return;
@@ -274,14 +275,14 @@
 		return;
 
 	/* do it again */
-	snd_ice1712_ak4524_reset(ice, 1);
+	snd_ice1712_akm4xxx_reset(ak, 1);
 	down(&ice->gpio_mutex);
 	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS;
 	if (rate > 48000)
 		tmp |= ICE1712_DELTA_DFS;
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
 	up(&ice->gpio_mutex);
-	snd_ice1712_ak4524_reset(ice, 0);
+	snd_ice1712_akm4xxx_reset(ak, 0);
 }
 
 
@@ -296,7 +297,7 @@
 }
 
 /* set up */
-static void delta_setup_spdif(ice1712_t *ice, snd_pcm_substream_t * substream)
+static void delta_setup_spdif(ice1712_t *ice, int rate)
 {
 	unsigned long flags;
 	unsigned int tmp;
@@ -306,7 +307,7 @@
 	tmp = ice->spdif.cs8403_stream_bits;
 	if (tmp & 0x01)		/* consumer */
 		tmp &= (tmp & 0x01) ? ~0x06 : ~0x18;
-	switch (substream->runtime->rate) {
+	switch (rate) {
 	case 32000: tmp |= (tmp & 0x01) ? 0x04 : 0x00; break;
 	case 44100: tmp |= (tmp & 0x01) ? 0x00 : 0x10; break;
 	case 48000: tmp |= (tmp & 0x01) ? 0x02 : 0x08; break;
@@ -325,10 +326,84 @@
  * initialize the chips on M-Audio cards
  */
 
+static akm4xxx_t akm_audiophile __devinitdata = {
+	.type = SND_AK4528,
+	.num_adcs = 2,
+	.num_dacs = 2,
+	.caddr = 2,
+	.cif = 0,
+	.data_mask = ICE1712_DELTA_AP_DOUT,
+	.clk_mask = ICE1712_DELTA_AP_CCLK,
+	.cs_mask = ICE1712_DELTA_AP_CS_CODEC,
+	.cs_addr = ICE1712_DELTA_AP_CS_CODEC,
+	.cs_none = 0,
+	.add_flags = ICE1712_DELTA_AP_CS_DIGITAL,
+	.mask_flags = 0,
+	.ops = {
+		.set_rate_val = delta_ak4524_set_rate_val
+	}
+};
+
+static akm4xxx_t akm_delta410 __devinitdata = {
+	.type = SND_AK4529,
+	.num_adcs = 2,
+	.num_dacs = 8,
+	.caddr = 0,
+	.cif = 0,
+	.data_mask = ICE1712_DELTA_AP_DOUT,
+	.clk_mask = ICE1712_DELTA_AP_CCLK,
+	.cs_mask = ICE1712_DELTA_AP_CS_CODEC,
+	.cs_addr = ICE1712_DELTA_AP_CS_CODEC,
+	.cs_none = 0,
+	.add_flags = ICE1712_DELTA_AP_CS_DIGITAL,
+	.mask_flags = 0,
+	.ops = {
+		.set_rate_val = delta_ak4524_set_rate_val
+	}
+};
+
+static akm4xxx_t akm_delta1010lt __devinitdata = {
+	.type = SND_AK4524,
+	.num_adcs = 8,
+	.num_dacs = 8,
+	.caddr = 2,
+	.cif = 0, /* the default level of the CIF pin from AK4524 */
+	.data_mask = ICE1712_DELTA_1010LT_DOUT,
+	.clk_mask = ICE1712_DELTA_1010LT_CCLK,
+	.cs_mask = 0,
+	.cs_addr = 0, /* set later */
+	.cs_none = ICE1712_DELTA_1010LT_CS_NONE,
+	.add_flags = 0,
+	.mask_flags = 0,
+	.ops = {
+		.start = delta1010lt_ak4524_start,
+		.set_rate_val = delta_ak4524_set_rate_val
+	}
+};
+
+static akm4xxx_t akm_delta44 __devinitdata = {
+	.type = SND_AK4524,
+	.num_adcs = 4,
+	.num_dacs = 4,
+	.caddr = 2,
+	.cif = 0, /* the default level of the CIF pin from AK4524 */
+	.data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA,
+	.clk_mask = ICE1712_DELTA_CODEC_SERIAL_CLOCK,
+	.cs_mask = 0,
+	.cs_addr = 0, /* set later */
+	.cs_none = 0,
+	.add_flags = 0,
+	.mask_flags = 0,
+	.ops = {
+		.start = delta_ak4524_start,
+		.set_rate_val = delta_ak4524_set_rate_val
+	}
+};
+
 static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
 {
 	int err;
-	ak4524_t *ak;
+	akm4xxx_t *ak;
 
 	/* determine I2C, DACs and ADCs */
 	switch (ice->eeprom.subvendor) {
@@ -366,7 +441,7 @@
 	case ICE1712_SUBDEVICE_DELTADIO2496:
 	case ICE1712_SUBDEVICE_DELTA66:
 		ice->spdif.ops.open = delta_open_spdif;
-		ice->spdif.ops.setup = delta_setup_spdif;
+		ice->spdif.ops.setup_rate = delta_setup_spdif;
 		ice->spdif.ops.default_get = delta_spdif_default_get;
 		ice->spdif.ops.default_put = delta_spdif_default_put;
 		ice->spdif.ops.stream_get = delta_spdif_stream_get;
@@ -376,60 +451,36 @@
 		break;
 	}
 
+	/* no analog? */
+	switch (ice->eeprom.subvendor) {
+	case ICE1712_SUBDEVICE_DELTA1010:
+	case ICE1712_SUBDEVICE_DELTADIO2496:
+		return 0;
+	}
+
 	/* second stage of initialization, analog parts and others */
-	ak = &ice->ak4524;
+	ak = ice->akm = kmalloc(sizeof(akm4xxx_t), GFP_KERNEL);
+	if (! ak)
+		return -ENOMEM;
+	ice->akm_codecs = 1;
+
 	switch (ice->eeprom.subvendor) {
 	case ICE1712_SUBDEVICE_AUDIOPHILE:
+		snd_ice1712_akm4xxx_init(ak, &akm_audiophile, ice);
+		break;
 	case ICE1712_SUBDEVICE_DELTA410:
-		ak->num_adcs = ak->num_dacs = 2;
-		ak->type = SND_AK4528;
-		ak->caddr = 2;
-		if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA410) {
-			ak->num_dacs = 8;
-			ak->type = SND_AK4529;
-			ak->caddr = 0;
-		}
-		ak->cif = 0; /* the default level of the CIF pin from AK4528/4529 */
-		ak->data_mask = ICE1712_DELTA_AP_DOUT;
-		ak->clk_mask = ICE1712_DELTA_AP_CCLK;
-		ak->cs_mask = ak->cs_addr = ICE1712_DELTA_AP_CS_CODEC; /* select AK4528/4529 codec */
-		ak->cs_none = 0;
-		ak->add_flags = ICE1712_DELTA_AP_CS_DIGITAL; /* assert digital high */
-		ak->mask_flags = 0;
-		ak->ops.set_rate_val = delta_ak4524_set_rate_val;
-		snd_ice1712_ak4524_init(ice);
+		snd_ice1712_akm4xxx_init(ak, &akm_delta410, ice);
 		break;
 	case ICE1712_SUBDEVICE_DELTA1010LT:
-		ak->num_adcs = ak->num_dacs = 8;
-		ak->type = SND_AK4524;
-		ak->caddr = 2;
-		ak->cif = 0; /* the default level of the CIF pin from AK4524 */
-		ak->data_mask = ICE1712_DELTA_1010LT_DOUT;
-		ak->clk_mask = ICE1712_DELTA_1010LT_CCLK;
-		ak->cs_mask = ak->cs_addr = 0; /* set later */
-		ak->cs_none = ICE1712_DELTA_1010LT_CS_NONE;
-		ak->add_flags = 0;
-		ak->mask_flags = 0;
-		ak->ops.start = delta1010lt_ak4524_start;
-		ak->ops.set_rate_val = delta_ak4524_set_rate_val;
-		snd_ice1712_ak4524_init(ice);
+		snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, ice);
 		break;
 	case ICE1712_SUBDEVICE_DELTA66:
 	case ICE1712_SUBDEVICE_DELTA44:
-		ak->num_adcs = ak->num_dacs = 4;
-		ak->type = SND_AK4524;
-		ak->caddr = 2;
-		ak->cif = 0; /* the default level of the CIF pin from AK4524 */
-		ak->data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA;
-		ak->clk_mask = ICE1712_DELTA_CODEC_SERIAL_CLOCK;
-		ak->cs_mask = ak->cs_addr = 0; /* set later */
-		ak->cs_none = 0;
-		ak->add_flags = 0;
-		ak->mask_flags = 0;
-		ak->ops.start = delta_ak4524_start;
-		ak->ops.set_rate_val = delta_ak4524_set_rate_val;
-		snd_ice1712_ak4524_init(ice);
+		snd_ice1712_akm4xxx_init(ak, &akm_delta44, ice);
 		break;
+	default:
+		snd_BUG();
+		return -EINVAL;
 	}
 
 	return 0;
@@ -510,7 +561,7 @@
 	case ICE1712_SUBDEVICE_DELTA410:
 	case ICE1712_SUBDEVICE_DELTA44:
 	case ICE1712_SUBDEVICE_DELTA66:
-		err = snd_ice1712_ak4524_build_controls(ice);
+		err = snd_ice1712_akm4xxx_build_controls(ice);
 		if (err < 0)
 			return err;
 		break;
diff -Nru a/sound/pci/ice1712/envy24ht.h b/sound/pci/ice1712/envy24ht.h
--- a/sound/pci/ice1712/envy24ht.h	Thu Dec  5 11:47:37 2002
+++ b/sound/pci/ice1712/envy24ht.h	Thu Mar 20 08:41:14 2003
@@ -29,6 +29,23 @@
 #include <sound/pcm.h>
 
 #include "ice1712.h"
+
+enum {
+	ICE_EEP2_SYSCONF = 0,	/* 06 */
+	ICE_EEP2_ACLINK,	/* 07 */
+	ICE_EEP2_I2S,		/* 08 */
+	ICE_EEP2_SPDIF,		/* 09 */
+	ICE_EEP2_GPIO_DIR,	/* 0a */
+	ICE_EEP2_GPIO_DIR1,	/* 0b */
+	ICE_EEP2_GPIO_DIR2,	/* 0c */
+	ICE_EEP2_GPIO_MASK,	/* 0d */
+	ICE_EEP2_GPIO_MASK1,	/* 0e */
+	ICE_EEP2_GPIO_MASK2,	/* 0f */
+	ICE_EEP2_GPIO_STATE,	/* 10 */
+	ICE_EEP2_GPIO_STATE1,	/* 11 */
+	ICE_EEP2_GPIO_STATE2	/* 12 */
+};
+	
 /*
  *  Direct registers
  */
@@ -72,13 +89,6 @@
 /*there is no consumer AC97 codec with the VT1724*/
 //#define VT1724_REG_AC97_INDEX		0x08	/* byte */
 //#define VT1724_REG_AC97_CMD		0x09	/* byte */
-#define   VT1724_AC97_COLD		0x80	/* cold reset */
-#define   VT1724_AC97_WARM		0x40	/* warm reset */
-#define   VT1724_AC97_WRITE		0x20	/* W: write, R: write in progress */
-#define   VT1724_AC97_READ		0x10	/* W: read, R: read in progress */
-#define   VT1724_AC97_READY		0x08	/* codec ready status bit */
-#define   VT1724_AC97_PBK_VSR		0x02	/* playback VSR */
-#define   VT1724_AC97_CAP_VSR		0x01	/* capture VSR */
 
 #define VT1724_REG_MPU_TXFIFO		0x0a	/*byte ro. number of bytes in TX fifo*/
 #define VT1724_REG_MPU_RXFIFO		0x0b	/*byte ro. number of bytes in RX fifo*/
@@ -100,12 +110,12 @@
 #define   VT1724_I2C_BUSY		0x01	/* busy bit */
 
 #define VT1724_REG_GPIO_DATA	0x14	/* word */
-#define VT1724_REG_GPIO_WRITE_MASK	0x15 /* word */
-#define VT1724_REG_GPIO_DIRECTION	0x16 /* dword? (3 bytes) 0=input 1=output. 
-							bit3 - during reset used for Eeprom power-on strapping
-							if TESTEN# pin active, bit 2 always input*/
+#define VT1724_REG_GPIO_WRITE_MASK	0x16 /* word */
+#define VT1724_REG_GPIO_DIRECTION	0x18 /* dword? (3 bytes) 0=input 1=output. 
+						bit3 - during reset used for Eeprom power-on strapping
+						if TESTEN# pin active, bit 2 always input*/
 #define VT1724_REG_POWERDOWN	0x1c
-#define VT1724_REG_GPIO_DIRECTION_22	0x1e /* byte direction for GPIO 16:22 */
+#define VT1724_REG_GPIO_DATA_22	0x1e /* byte direction for GPIO 16:22 */
 #define VT1724_REG_GPIO_WRITE_MASK_22	0x1f /* byte write mask for GPIO 16:22 */
 
 
@@ -128,15 +138,24 @@
 #define VT1724_MT_RATE			0x01	/* byte - sampling rate select */
 #define   VT1724_SPDIF_MASTER		0x10	/* S/PDIF input is master clock */
 #define VT1724_MT_I2S_FORMAT		0x02	/* byte - I2S data format */
+#define   VT1724_MT_I2S_MCLK_128X	0x08
+#define   VT1724_MT_I2S_FORMAT_MASK	0x03
+#define   VT1724_MT_I2S_FORMAT_I2S	0x00
 #define VT1724_MT_DMA_INT_MASK		0x03	/* byte -DMA Interrupt Mask */
 /* lool to VT1724_MULTI_* */
 #define VT1724_MT_AC97_INDEX		0x04	/* byte - AC'97 index */
 #define VT1724_MT_AC97_CMD		0x05	/* byte - AC'97 command & status */
-/* look to VT1724_AC97_* */
+#define   VT1724_AC97_COLD	0x80	/* cold reset */
+#define   VT1724_AC97_WARM	0x40	/* warm reset */
+#define   VT1724_AC97_WRITE	0x20	/* W: write, R: write in progress */
+#define   VT1724_AC97_READ	0x10	/* W: read, R: read in progress */
+#define   VT1724_AC97_READY	0x08	/* codec ready status bit */
+#define   VT1724_AC97_PBK_VSR	0x02	/* playback VSR */
+#define   VT1724_AC97_CAP_VSR	0x01	/* capture VSR */
 #define VT1724_MT_AC97_DATA		0x06	/* word - AC'97 data */
-#define VT1724_MT_PLAYBACK_ADDR	0x10	/* dword - playback address */
-#define VT1724_MT_PLAYBACK_SIZE	0x14	/* dword - playback size */
-#define VT1724_MT_PLAYBACK_CONTROL	0x18	/* byte - control */
+#define VT1724_MT_PLAYBACK_ADDR		0x10	/* dword - playback address */
+#define VT1724_MT_PLAYBACK_SIZE		0x14	/* dword - playback size */
+#define VT1724_MT_DMA_CONTROL		0x18	/* byte - control */
 #define   VT1724_PDMA4_START	0x80	/* SPDIF out / PDMA4 start */
 #define   VT1724_PDMA3_START	0x40	/* PDMA3 start */
 #define   VT1724_PDMA2_START	0x20	/* PDMA2 start */
@@ -145,14 +164,14 @@
 #define   VT1724_RDMA0_START	0x02	/* RMDA0 start */
 #define   VT1724_PDMA0_START	0x01	/* MC Interleave / PDMA0 start */
 #define VT1724_MT_BURST			0x19	/* Interleaved playback DMA Active streams / PCI burst size */
-#define VT1724_MT_DMA_FIFO_ERR	0x1a	/*Global playback and record DMA FIFO Underrun/Overrun */
-#define   VT1724_PDMA4_UNDERRUN	0x80
-#define   VT1724_PDMA2_UNDERRUN	0x40
-#define   VT1724_PDMA3_UNDERRUN	0x20
-#define   VT1724_PDMA1_UNDERRUN	0x10
-#define   VT1724_RDMA1_UNDERRUN	0x04
-#define   VT1724_RDMA0_UNDERRUN	0x02
-#define   VT1724_PDMA0_UNDERRUN	0x01
+#define VT1724_MT_DMA_FIFO_ERR		0x1a	/*Global playback and record DMA FIFO Underrun/Overrun */
+#define   VT1724_PDMA4_UNDERRUN		0x80
+#define   VT1724_PDMA2_UNDERRUN		0x40
+#define   VT1724_PDMA3_UNDERRUN		0x20
+#define   VT1724_PDMA1_UNDERRUN		0x10
+#define   VT1724_RDMA1_UNDERRUN		0x04
+#define   VT1724_RDMA0_UNDERRUN		0x02
+#define   VT1724_PDMA0_UNDERRUN		0x01
 #define VT1724_MT_DMA_PAUSE		0x1b	/*Global playback and record DMA FIFO pause/resume */
 #define	  VT1724_PDMA4_PAUSE	0x80
 #define	  VT1724_PDMA3_PAUSE	0x40
@@ -164,40 +183,31 @@
 #define VT1724_MT_PLAYBACK_COUNT	0x1c	/* word - playback count */
 #define VT1724_MT_CAPTURE_ADDR		0x20	/* dword - capture address */
 #define VT1724_MT_CAPTURE_SIZE		0x24	/* word - capture size */
-#define VT1724_MT_CAPTURE_COUNT	0x26	/* word - capture count */
-
-#define VT1724_MT_RDMA1_ADDR	0x30	/* dword - RDMA1 capture address */
-#define VT1724_MT_RDMA1_SIZE	0x34	/* word - RDMA1 capture size */
-#define VT1724_MT_RDMA1_COUNT	0x36	/* word - RDMA1 capture count */
+#define VT1724_MT_CAPTURE_COUNT		0x26	/* word - capture count */
 
 #define VT1724_MT_ROUTE_PLAYBACK	0x2c	/* word */
-//#define VT1724_MT_MONITOR_VOLUME	0x3f	/* word */
-//#define VT1724_MT_MONITOR_INDEX	0x3e	/* byte */
 
+#define VT1724_MT_RDMA1_ADDR		0x30	/* dword - RDMA1 capture address */
+#define VT1724_MT_RDMA1_SIZE		0x34	/* word - RDMA1 capture size */
+#define VT1724_MT_RDMA1_COUNT		0x36	/* word - RDMA1 capture count */
 
-#define VT1724_MT_PDMA4_ADDR	0x40	/* dword */
-#define VT7124_MT_PDMA4_SIZE	0x44	/* word */
-#define VT1724_MT_PDMA4_COUNT	0x46	/* word */
-#define VT1724_MT_PDMA3_ADDR	0x50	/* dword */
-#define VT7124_MT_PDMA3_SIZE	0x54	/* word */
-#define VT1724_MT_PDMA3_COUNT	0x56	/* word */
-#define VT1724_MT_PDMA2_ADDR	0x60	/* dword */
-#define VT7124_MT_PDMA2_SIZE	0x64	/* word */
-#define VT1724_MT_PDMA2_COUNT	0x66	/* word */
-#define VT1724_MT_PDMA1_ADDR	0x70	/* dword */
-#define VT7124_MT_PDMA1_SIZE	0x74	/* word */
-#define VT1724_MT_PDMA1_COUNT	0x76	/* word */
-
-
-//does VT1724 have these? don't think so
-//#define VT1724_MT_MONITOR_RATE		0x3b	/* byte */
-//#define VT1724_MT_MONITOR_ROUTECTRL	0x3c	/* byte */
-//#define   VT1724_ROUTE_AC97		0x01	/* route digital mixer output to AC'97 */
+#define VT1724_MT_SPDIF_CTRL		0x3c	/* word */
 #define VT1724_MT_MONITOR_PEAKINDEX	0x3e	/* byte */
 #define VT1724_MT_MONITOR_PEAKDATA	0x3f	/* byte */
 
-
-
+/* concurrent stereo channels */
+#define VT1724_MT_PDMA4_ADDR		0x40	/* dword */
+#define VT1724_MT_PDMA4_SIZE		0x44	/* word */
+#define VT1724_MT_PDMA4_COUNT		0x46	/* word */
+#define VT1724_MT_PDMA3_ADDR		0x50	/* dword */
+#define VT1724_MT_PDMA3_SIZE		0x54	/* word */
+#define VT1724_MT_PDMA3_COUNT		0x56	/* word */
+#define VT1724_MT_PDMA2_ADDR		0x60	/* dword */
+#define VT1724_MT_PDMA2_SIZE		0x64	/* word */
+#define VT1724_MT_PDMA2_COUNT		0x66	/* word */
+#define VT1724_MT_PDMA1_ADDR		0x70	/* dword */
+#define VT1724_MT_PDMA1_SIZE		0x74	/* word */
+#define VT1724_MT_PDMA1_COUNT		0x76	/* word */
 
 
 #endif /* __SOUND_VT1724_H */
diff -Nru a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
--- a/sound/pci/ice1712/ews.c	Sat Feb  8 12:10:54 2003
+++ b/sound/pci/ice1712/ews.c	Thu Mar 20 08:41:14 2003
@@ -83,7 +83,7 @@
 	ice1712_t *ice = snd_magic_cast(ice1712_t, bus->private_data, return);
 	unsigned char mask;
 
-	snd_ice1712_save_gpio_status(ice, (unsigned char *)&bus->private_value);
+	snd_ice1712_save_gpio_status(ice);
 	/* set RW high */
 	mask = ICE1712_EWX2496_RW;
 	switch (ice->eeprom.subvendor) {
@@ -100,7 +100,7 @@
 static void ewx_i2c_stop(snd_i2c_bus_t *bus)
 {
 	ice1712_t *ice = snd_magic_cast(ice1712_t, bus->private_data, return);
-	snd_ice1712_restore_gpio_status(ice, (unsigned char *)&bus->private_value);
+	snd_ice1712_restore_gpio_status(ice);
 }
 
 static void ewx_i2c_direction(snd_i2c_bus_t *bus, int clock, int data)
@@ -112,9 +112,9 @@
 		mask |= ICE1712_EWX2496_SERIAL_CLOCK; /* write SCL */
 	if (data)
 		mask |= ICE1712_EWX2496_SERIAL_DATA; /* write SDA */
-	ice->gpio_direction &= ~(ICE1712_EWX2496_SERIAL_CLOCK|ICE1712_EWX2496_SERIAL_DATA);
-	ice->gpio_direction |= mask;
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->gpio_direction);
+	ice->gpio.direction &= ~(ICE1712_EWX2496_SERIAL_CLOCK|ICE1712_EWX2496_SERIAL_DATA);
+	ice->gpio.direction |= mask;
+	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->gpio.direction);
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~mask);
 }
 
@@ -155,56 +155,60 @@
 }
 
 /* start callback for EWS88MT, needs to select a certain chip mask */
-static int ews88mt_ak4524_start(ice1712_t *ice, unsigned char *saved, int chip)
+static int ews88mt_ak4524_start(akm4xxx_t *ak, int chip)
 {
+	ice1712_t *ice = ak->chip;
 	unsigned char tmp;
 	/* assert AK4524 CS */
 	if (snd_ice1712_ews88mt_chip_select(ice, ~(1 << chip) & 0x0f) < 0)
 		return -EINVAL;
-	snd_ice1712_save_gpio_status(ice, saved);
+	snd_ice1712_save_gpio_status(ice);
 	tmp = ICE1712_EWS88_SERIAL_DATA |
 		ICE1712_EWS88_SERIAL_CLOCK |
 		ICE1712_EWS88_RW;
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
-			  ice->gpio_direction | tmp);
+			  ice->gpio.direction | tmp);
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
 	return 0;
 }
 
 /* stop callback for EWS88MT, needs to deselect chip mask */
-static void ews88mt_ak4524_stop(ice1712_t *ice, unsigned char *saved)
+static void ews88mt_ak4524_stop(akm4xxx_t *ak)
 {
-	snd_ice1712_restore_gpio_status(ice, saved);
+	ice1712_t *ice = ak->chip;
+	snd_ice1712_restore_gpio_status(ice);
 	udelay(1);
 	snd_ice1712_ews88mt_chip_select(ice, 0x0f);
 }
 
 /* start callback for EWX24/96 */
-static int ewx2496_ak4524_start(ice1712_t *ice, unsigned char *saved, int chip)
+static int ewx2496_ak4524_start(akm4xxx_t *ak, int chip)
 {
+	ice1712_t *ice = ak->chip;
 	unsigned char tmp;
-	snd_ice1712_save_gpio_status(ice, saved);
+	snd_ice1712_save_gpio_status(ice);
 	tmp =  ICE1712_EWX2496_SERIAL_DATA |
 		ICE1712_EWX2496_SERIAL_CLOCK |
 		ICE1712_EWX2496_AK4524_CS |
 		ICE1712_EWX2496_RW;
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
-			  ice->gpio_direction | tmp);
+			  ice->gpio.direction | tmp);
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
 	return 0;
 }
 
 /* start callback for DMX 6fire */
-static int dmx6fire_ak4524_start(ice1712_t *ice, unsigned char *saved, int chip)
+static int dmx6fire_ak4524_start(akm4xxx_t *ak, int chip)
 {
+	ice1712_t *ice = ak->chip;
 	unsigned char tmp;
-	snd_ice1712_save_gpio_status(ice, saved);
-	tmp = ice->ak4524.cs_mask = ice->ak4524.cs_addr = (1 << chip) & ICE1712_6FIRE_AK4524_CS_MASK;
+	snd_ice1712_save_gpio_status(ice);
+	tmp = ak->cs_mask = ak->cs_addr = (1 << chip) & ICE1712_6FIRE_AK4524_CS_MASK;
 	tmp |= ICE1712_6FIRE_SERIAL_DATA |
 		ICE1712_6FIRE_SERIAL_CLOCK |
 		ICE1712_6FIRE_RW;
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
-			  ice->gpio_direction | tmp);
+			  ice->gpio.direction | tmp);
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
 	return 0;
 }
@@ -221,6 +225,7 @@
 	snd_i2c_lock(ice->i2c);
 	switch (ice->eeprom.subvendor) {
 	case ICE1712_SUBDEVICE_EWS88MT:
+	case ICE1712_SUBDEVICE_EWS88MT_NEW:
 		snd_runtime_check(snd_i2c_sendbytes(ice->cs8404, &bits, 1) == 1, goto _error);
 		break;
 	case ICE1712_SUBDEVICE_EWS88D:
@@ -292,7 +297,7 @@
 }
 
 /* set up SPDIF for EWS88MT / EWS88D */
-static void ews88_setup_spdif(ice1712_t *ice, snd_pcm_substream_t * substream)
+static void ews88_setup_spdif(ice1712_t *ice, int rate)
 {
 	unsigned long flags;
 	unsigned char tmp;
@@ -302,7 +307,7 @@
 	tmp = ice->spdif.cs8403_stream_bits;
 	if (tmp & 0x10)		/* consumer */
 		tmp &= (tmp & 0x01) ? ~0x06 : ~0x60;
-	switch (substream->runtime->rate) {
+	switch (rate) {
 	case 32000: tmp |= (tmp & 0x01) ? 0x02 : 0x00; break;
 	case 44100: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
 	case 48000: tmp |= (tmp & 0x01) ? 0x04 : 0x20; break;
@@ -318,13 +323,71 @@
 
 
 /*
+ */
+static akm4xxx_t akm_ews88mt __devinitdata = {
+	.num_adcs = 8,
+	.num_dacs = 8,
+	.type = SND_AK4524,
+	.caddr = 2,
+	.cif = 1, /* CIF high */
+	.data_mask = ICE1712_EWS88_SERIAL_DATA,
+	.clk_mask = ICE1712_EWS88_SERIAL_CLOCK,
+	.cs_mask = 0,
+	.cs_addr = 0,
+	.cs_none = 0, /* no chip select on gpio */
+	.add_flags = ICE1712_EWS88_RW, /* set rw bit high */
+	.mask_flags = 0,
+	.ops = {
+		.start = ews88mt_ak4524_start,
+		.stop = ews88mt_ak4524_stop
+	}
+};
+
+static akm4xxx_t akm_ewx2496 __devinitdata = {
+	.num_adcs = 2,
+	.num_dacs = 2,
+	.type = SND_AK4524,
+	.caddr = 2,
+	.cif = 1, /* CIF high */
+	.data_mask = ICE1712_EWS88_SERIAL_DATA,
+	.clk_mask = ICE1712_EWS88_SERIAL_CLOCK,
+	.cs_mask = ICE1712_EWX2496_AK4524_CS,
+	.cs_addr = ICE1712_EWX2496_AK4524_CS,
+	.cs_none = 0,
+	.add_flags = ICE1712_EWS88_RW, /* set rw bit high */
+	.mask_flags = 0,
+	.ops = {
+		.start = ewx2496_ak4524_start
+	}
+};
+
+static akm4xxx_t akm_6fire __devinitdata = {
+	.num_adcs = 6,
+	.num_dacs = 6,
+	.type = SND_AK4524,
+	.caddr = 2,
+	.cif = 1, /* CIF high */
+	.data_mask = ICE1712_6FIRE_SERIAL_DATA,
+	.clk_mask = ICE1712_6FIRE_SERIAL_CLOCK,
+	.cs_mask = 0,
+	.cs_addr = 0, /* set later */
+	.cs_none = 0,
+	.add_flags = ICE1712_6FIRE_RW, /* set rw bit high */
+	.mask_flags = 0,
+	.ops = {
+		.start = dmx6fire_ak4524_start
+	}
+};
+
+
+/*
  * initialize the chip
  */
 
 static int __devinit snd_ice1712_ews_init(ice1712_t *ice)
 {
 	int err;
-	ak4524_t *ak;
+	akm4xxx_t *ak;
 
 	/* set the analog DACs */
 	switch (ice->eeprom.subvendor) {
@@ -332,6 +395,7 @@
 		ice->num_total_dacs = 2;
 		break;	
 	case ICE1712_SUBDEVICE_EWS88MT:
+	case ICE1712_SUBDEVICE_EWS88MT_NEW:
 		ice->num_total_dacs = 8;
 		break;
 	case ICE1712_SUBDEVICE_EWS88D:
@@ -358,6 +422,7 @@
 		}
 		break;
 	case ICE1712_SUBDEVICE_EWS88MT:
+	case ICE1712_SUBDEVICE_EWS88MT_NEW:
 		if ((err = snd_i2c_device_create(ice->i2c, "CS8404", ICE1712_EWS88MT_CS8404_ADDR, &ice->cs8404)) < 0)
 			return err;
 		if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)", ICE1712_EWS88MT_INPUT_ADDR, &ice->i2cdevs[0])) < 0)
@@ -380,16 +445,16 @@
 		if ((err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR)) < 0)
 			return err;
 		break;
-#if 0 // XXX not working...
 	case ICE1712_SUBDEVICE_DMX6FIRE:
 		if ((err = snd_ice1712_init_cs8427(ice, ICE1712_6FIRE_CS8427_ADDR)) < 0)
 			return err;
-#endif
+		break;
 	case ICE1712_SUBDEVICE_EWS88MT:
+	case ICE1712_SUBDEVICE_EWS88MT_NEW:
 	case ICE1712_SUBDEVICE_EWS88D:
 		/* set up CS8404 */
 		ice->spdif.ops.open = ews88_open_spdif;
-		ice->spdif.ops.setup = ews88_setup_spdif;
+		ice->spdif.ops.setup_rate = ews88_setup_spdif;
 		ice->spdif.ops.default_get = ews88_spdif_default_get;
 		ice->spdif.ops.default_put = ews88_spdif_default_put;
 		ice->spdif.ops.stream_get = ews88_spdif_stream_get;
@@ -399,50 +464,28 @@
 		break;
 	}
 
+	/* no analog? */
+	switch (ice->eeprom.subvendor) {
+	case ICE1712_SUBDEVICE_EWS88D:
+		return 0;
+	}
+
 	/* analog section */
-	ak = &ice->ak4524;
+	ak = ice->akm = kmalloc(sizeof(akm4xxx_t), GFP_KERNEL);
+	if (! ak)
+		return -ENOMEM;
+	ice->akm_codecs = 1;
+
 	switch (ice->eeprom.subvendor) {
 	case ICE1712_SUBDEVICE_EWS88MT:
-		ak->num_adcs = ak->num_dacs = 8;
-		ak->type = SND_AK4524;
-		ak->caddr = 2;
-		ak->cif = 1; /* CIF high */
-		ak->data_mask = ICE1712_EWS88_SERIAL_DATA;
-		ak->clk_mask = ICE1712_EWS88_SERIAL_CLOCK;
-		ak->cs_mask = ak->cs_addr = ak->cs_none = 0; /* no chip select on gpio */
-		ak->add_flags = ICE1712_EWS88_RW; /* set rw bit high */
-		ak->mask_flags = 0;
-		ak->ops.start = ews88mt_ak4524_start;
-		ak->ops.stop = ews88mt_ak4524_stop;
-		snd_ice1712_ak4524_init(ice);
+	case ICE1712_SUBDEVICE_EWS88MT_NEW:
+		snd_ice1712_akm4xxx_init(ak, &akm_ews88mt, ice);
 		break;
 	case ICE1712_SUBDEVICE_EWX2496:
-		ak->num_adcs = ak->num_dacs = 2;
-		ak->type = SND_AK4524;
-		ak->caddr = 2;
-		ak->cif = 1; /* CIF high */
-		ak->data_mask = ICE1712_EWS88_SERIAL_DATA;
-		ak->clk_mask = ICE1712_EWS88_SERIAL_CLOCK;
-		ak->cs_mask = ak->cs_addr = ICE1712_EWX2496_AK4524_CS;
-		ak->cs_none = 0;
-		ak->add_flags = ICE1712_EWS88_RW; /* set rw bit high */
-		ak->mask_flags = 0;
-		ak->ops.start = ewx2496_ak4524_start;
-		snd_ice1712_ak4524_init(ice);
+		snd_ice1712_akm4xxx_init(ak, &akm_ewx2496, ice);
 		break;
 	case ICE1712_SUBDEVICE_DMX6FIRE:
-		ak->num_adcs = ak->num_dacs = 6;
-		ak->type = SND_AK4524;
-		ak->caddr = 2;
-		ak->cif = 1; /* CIF high */
-		ak->data_mask = ICE1712_6FIRE_SERIAL_DATA;
-		ak->clk_mask = ICE1712_6FIRE_SERIAL_CLOCK;
-		ak->cs_mask = ak->cs_addr = 0; /* set later */
-		ak->cs_none = 0;
-		ak->add_flags = ICE1712_6FIRE_RW; /* set rw bit high */
-		ak->mask_flags = 0;
-		ak->ops.start = dmx6fire_ak4524_start;
-		snd_ice1712_ak4524_init(ice);
+		snd_ice1712_akm4xxx_init(ak, &akm_6fire, ice);
 		break;
 	}
 
@@ -472,11 +515,10 @@
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char mask = kcontrol->private_value & 0xff;
-	unsigned char saved[2];
 	
-	snd_ice1712_save_gpio_status(ice, saved);
+	snd_ice1712_save_gpio_status(ice);
 	ucontrol->value.enumerated.item[0] = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & mask ? 1 : 0;
-	snd_ice1712_restore_gpio_status(ice, saved);
+	snd_ice1712_restore_gpio_status(ice);
 	return 0;
 }
 
@@ -484,17 +526,16 @@
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char mask = kcontrol->private_value & 0xff;
-	unsigned char saved[2];
 	int val, nval;
 
 	if (kcontrol->private_value & (1 << 31))
 		return -EPERM;
 	nval = ucontrol->value.enumerated.item[0] ? mask : 0;
-	snd_ice1712_save_gpio_status(ice, saved);
+	snd_ice1712_save_gpio_status(ice);
 	val = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
 	nval |= val & ~mask;
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, nval);
-	snd_ice1712_restore_gpio_status(ice, saved);
+	snd_ice1712_restore_gpio_status(ice);
 	return val != nval;
 }
 
@@ -864,8 +905,9 @@
 	switch (ice->eeprom.subvendor) {
 	case ICE1712_SUBDEVICE_EWX2496:
 	case ICE1712_SUBDEVICE_EWS88MT:
+	case ICE1712_SUBDEVICE_EWS88MT_NEW:
 	case ICE1712_SUBDEVICE_DMX6FIRE:
-		err = snd_ice1712_ak4524_build_controls(ice);
+		err = snd_ice1712_akm4xxx_build_controls(ice);
 		if (err < 0)
 			return err;
 		break;
@@ -881,6 +923,7 @@
 		}
 		break;
 	case ICE1712_SUBDEVICE_EWS88MT:
+	case ICE1712_SUBDEVICE_EWS88MT_NEW:
 		for (idx = 0; idx < 8; idx++) {
 			kctl = snd_ctl_new1(&snd_ice1712_ews88mt_input_sense, ice);
 			kctl->id.index = idx;
@@ -915,25 +958,31 @@
 struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
 	{
 		ICE1712_SUBDEVICE_EWX2496,
-		"TerraTec EWX 24/96",
+		"TerraTec EWX24/96",
 		snd_ice1712_ews_init,
 		snd_ice1712_ews_add_controls,
 	},
 	{
 		ICE1712_SUBDEVICE_EWS88MT,
-		"TerraTec EWS 88MT",
+		"TerraTec EWS88MT",
+		snd_ice1712_ews_init,
+		snd_ice1712_ews_add_controls,
+	},
+	{
+		ICE1712_SUBDEVICE_EWS88MT_NEW,
+		"TerraTec EWS88MT",
 		snd_ice1712_ews_init,
 		snd_ice1712_ews_add_controls,
 	},
 	{
 		ICE1712_SUBDEVICE_EWS88D,
-		"TerraTec EWS 88D",
+		"TerraTec EWS88D",
 		snd_ice1712_ews_init,
 		snd_ice1712_ews_add_controls,
 	},
 	{
 		ICE1712_SUBDEVICE_DMX6FIRE,
-		"TerraTec DMX 6Fire",
+		"TerraTec DMX6Fire",
 		snd_ice1712_ews_init,
 		snd_ice1712_ews_add_controls,
 	},
diff -Nru a/sound/pci/ice1712/ews.h b/sound/pci/ice1712/ews.h
--- a/sound/pci/ice1712/ews.h	Tue Oct  1 10:11:34 2002
+++ b/sound/pci/ice1712/ews.h	Thu Mar 20 08:41:14 2003
@@ -33,6 +33,7 @@
 
 #define ICE1712_SUBDEVICE_EWX2496	0x3b153011
 #define ICE1712_SUBDEVICE_EWS88MT	0x3b151511
+#define ICE1712_SUBDEVICE_EWS88MT_NEW	0x3b152511
 #define ICE1712_SUBDEVICE_EWS88D	0x3b152b11
 #define ICE1712_SUBDEVICE_DMX6FIRE	0x3b153811
 
@@ -76,6 +77,6 @@
 #define ICE1712_6FIRE_RX2		0x80	/* MIDI2 */
 
 #define ICE1712_6FIRE_PCF9554_ADDR	(0x40>>1)
-#define ICE1712_6FIRE_CS8427_ADDR	(0x22>>1)
+#define ICE1712_6FIRE_CS8427_ADDR	(0x22)
 
 #endif /* __SOUND_EWS_H */
diff -Nru a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
--- a/sound/pci/ice1712/ice1712.c	Sat Feb  8 12:10:54 2003
+++ b/sound/pci/ice1712/ice1712.c	Thu Mar 20 08:41:14 2003
@@ -37,6 +37,10 @@
  *	Added support for VT1724 (Envy24HT)
  *	I have left out support for 176.4 and 192 KHz for the moment. 
  *  I also haven't done anything with the internal S/PDIF transmitter or the MPU-401
+ *
+ *  2003.02.20  Taksahi Iwai <tiwai@suse.de>
+ *	Split vt1724 part to an independent driver.
+ *	The GPIO is accessed through the callback functions now.
  */
 
 
@@ -57,13 +61,11 @@
 #include <sound/asoundef.h>
 
 #include "ice1712.h"
-#include "envy24ht.h"
 
 /* lowlevel routines */
 #include "delta.h"
 #include "ews.h"
 #include "hoontech.h"
-#include "amp.h"
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
 MODULE_DESCRIPTION("ICEnsemble ICE1712 (Envy24)");
@@ -73,11 +75,8 @@
 	       HOONTECH_DEVICE_DESC
 	       DELTA_DEVICE_DESC
 	       EWS_DEVICE_DESC
-	       AMP_AUDIO2000_DEVICE_DESC
-		"{ICEnsemble,Generic ICE1712},"
-		"{ICEnsemble,Generic Envy24},"
-		"{ICEnsemble,Generic ICE1724},"
-		"{ICEnsemble,Generic Envy24HT}}");
+	       "{ICEnsemble,Generic ICE1712},"
+	       "{ICEnsemble,Generic Envy24}}");
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
@@ -103,17 +102,9 @@
 #ifndef PCI_DEVICE_ID_ICE_1712
 #define PCI_DEVICE_ID_ICE_1712		0x1712
 #endif
-#ifndef PCI_DEVICE_ID_VT1724
-#define PCI_DEVICE_ID_VT1724		0x1724
-#endif
-
-enum {
-	TYPE_ICE1712, TYPE_VT1724
-};
 
 static struct pci_device_id snd_ice1712_ids[] __devinitdata = {
-	{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_ICE1712 },   /* ICE1712 */
-	{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_VT1724 },	   /* VT1724 */
+	{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },   /* ICE1712 */
 	{ 0, }
 };
 
@@ -130,6 +121,7 @@
  *  Basic I/O
  */
  
+/* check whether the clock mode is spdif-in */
 static inline int is_spdif_master(ice1712_t *ice)
 {
 	return (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER) ? 1 : 0;
@@ -257,6 +249,9 @@
 	return inw(ICEMT(ice, AC97_DATA));
 }
 
+/*
+ * consumer ac97 digital mix
+ */
 static int snd_ice1712_digmix_route_ac97_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
@@ -297,75 +292,27 @@
 };
 
 
-
 /*
- * set gpio direction, write mask and data
+ * gpio operations
  */
-void snd_ice1712_gpio_write_bits(ice1712_t *ice, int mask, int bits)
+static void snd_ice1712_set_gpio_dir(ice1712_t *ice, unsigned int data)
 {
-	ice->gpio_direction |= mask;
-	if (ice->vt1724) {
-
-		outw(ice->gpio_direction, ICEREG1724(ice, GPIO_DIRECTION));
-		outb((ice->gpio_direction&0xff0000)>>16, ICEREG1724(ice, GPIO_DIRECTION_22));
-
-		outw(~mask, ICEREG1724(ice, GPIO_WRITE_MASK));
-		outb((~mask & 0xff0000)>>16, ICEREG1724(ice, GPIO_WRITE_MASK_22));
-
-		outl(mask & bits, ICEREG1724(ice, GPIO_DATA));
-
-	}
-	else {
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->gpio_direction);
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~mask);
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, mask & bits);
-	}
+	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, data);
 }
 
-/*
- */
-/*
-	the VT1724 has 23 GPIO pins, so need 3 bytes for direction and 3 bytes for write mask
- */
-
-void snd_ice1712_save_gpio_status(ice1712_t *ice, unsigned char *tmp)
+static void snd_ice1712_set_gpio_mask(ice1712_t *ice, unsigned int data)
 {
-	down(&ice->gpio_mutex);
-	if (ice->vt1724) {
-		tmp[0] = ice->gpio_direction & 0xff;
-		tmp[1] = (ice->gpio_direction &0xff00)>>8;
-		tmp[2] = (ice->gpio_direction &0xff0000)>>16;
-
-		tmp[3] = ice->gpio_write_mask & 0xff;
-		tmp[4] = (ice->gpio_write_mask &0xff00)>>8;
-		tmp[5] = (ice->gpio_write_mask &0xff0000)>>16;
-	}
-	else {
-		tmp[0] = ice->gpio_direction;
-		tmp[1] = ice->gpio_write_mask;
-	}
+	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, data);
 }
 
-void snd_ice1712_restore_gpio_status(ice1712_t *ice, unsigned char *tmp)
+static unsigned int snd_ice1712_get_gpio_data(ice1712_t *ice)
 {
-	if (ice->vt1724) {
-
-		outw(tmp[0] | ((tmp[1]&0xff00)<<8), ICEREG1724(ice, GPIO_DIRECTION));
-		outb(tmp[2], ICEREG1724(ice, GPIO_DIRECTION_22));
-
-		outw(tmp[3] | ((tmp[4]&0xff00)<<8), ICEREG1724(ice, GPIO_WRITE_MASK));
-		outb(tmp[5], ICEREG1724(ice, GPIO_WRITE_MASK_22));
+	return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
+}
 
-		ice->gpio_direction=tmp[0] | ((tmp[1]<<8)&0xff00) |((tmp[2]<<16)&0xff0000);
-		ice->gpio_write_mask=tmp[3] | ((tmp[4]<<8)&0xff00) |((tmp[5]<<16)&0xff0000);
-	}
-	else {
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, tmp[0]);
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, tmp[1]);
-		ice->gpio_direction = tmp[0];
-		ice->gpio_write_mask = tmp[1];
-	}
-	up(&ice->gpio_mutex);
+static void snd_ice1712_set_gpio_data(ice1712_t *ice, unsigned int val)
+{
+	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, val);
 }
 
 
@@ -424,9 +371,9 @@
 	snd_cs8427_iec958_active(ice->cs8427, 0);
 }
 
-static void setup_cs8427(ice1712_t *ice, snd_pcm_substream_t * substream)
+static void setup_cs8427(ice1712_t *ice, int rate)
 {
-	snd_cs8427_iec958_pcm(ice->cs8427, substream->runtime->rate);
+	snd_cs8427_iec958_pcm(ice->cs8427, rate);
 }
 
 /*
@@ -442,7 +389,7 @@
 	}
 	ice->spdif.ops.open = open_cs8427;
 	ice->spdif.ops.close = close_cs8427;
-	ice->spdif.ops.setup = setup_cs8427;
+	ice->spdif.ops.setup_rate = setup_cs8427;
 	return 0;
 }
 
@@ -518,48 +465,6 @@
 }
 
 
-static void snd_vt1724_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, dev_id, return);
-	unsigned char status;
-
-	while (1) {
-		status = inb(ICEREG(ice, IRQSTAT));
-		if (status == 0)
-			break;
-		
-		/*  these should probably be separated at some point, 
-			but as we don't currently have MPU support on the board I will leave it */
-		if ((status & VT1724_IRQ_MPU_RX)||(status & VT1724_IRQ_MPU_TX)) {
-			if (ice->rmidi[0])
-				snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data, regs);
-			outb(VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX, ICEREG(ice, IRQSTAT));
-			status &= ~(VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX);
-		}
-		if (status & VT1724_IRQ_MTPCM) {
-			unsigned char mtstat = inb(ICEMT(ice, IRQ));
-			if (mtstat & VT1724_MULTI_PDMA0) {
-				if (ice->playback_pro_substream)
-					snd_pcm_period_elapsed(ice->playback_pro_substream);
-				outb(VT1724_MULTI_PDMA0, ICEMT(ice, IRQ));
-			}
-			if (mtstat & VT1724_MULTI_RDMA0) {
-				if (ice->capture_pro_substream)
-					snd_pcm_period_elapsed(ice->capture_pro_substream);
-				outb(VT1724_MULTI_RDMA0, ICEMT(ice, IRQ));
-			}
-			/* ought to really handle this properly */
-			if (mtstat & VT1724_MULTI_FIFO_ERR) {
-				unsigned char fstat = inb(ICEMT1724(ice, DMA_FIFO_ERR));
-				outb(fstat, ICEMT1724(ice, DMA_FIFO_ERR));	
-				outb(VT1724_MULTI_FIFO_ERR | inb(ICEMT1724(ice, DMA_INT_MASK)), ICEMT1724(ice, DMA_INT_MASK));	
-				/* If I don't do this, I get machine lockup due to continual interrupts */
-			}
-
-		}
-	}
-}
-
 /*
  *  PCM part - misc
  */
@@ -1040,30 +945,16 @@
 		unsigned int old;
 		if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
 			return -EINVAL;
-		if (ice->vt1724) {
-			what = VT1724_PDMA0_PAUSE;
-			snd_pcm_trigger_done(substream, substream);
-			spin_lock(&ice->reg_lock);
-			old = inl(ICEMT1724(ice, DMA_PAUSE));
-			if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
-				old |= what;
-			else
-				old &= ~what;
-			outl(old, ICEMT1724(ice, DMA_PAUSE));
-			spin_unlock(&ice->reg_lock);
-		}
-		else {
-			what = ICE1712_PLAYBACK_PAUSE;
-			snd_pcm_trigger_done(substream, substream);
-			spin_lock(&ice->reg_lock);
-			old = inl(ICEMT(ice, PLAYBACK_CONTROL));
-			if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
-				old |= what;
-			else
-				old &= ~what;
-			outl(old, ICEMT(ice, PLAYBACK_CONTROL));
-			spin_unlock(&ice->reg_lock);
-		}
+		what = ICE1712_PLAYBACK_PAUSE;
+		snd_pcm_trigger_done(substream, substream);
+		spin_lock(&ice->reg_lock);
+		old = inl(ICEMT(ice, PLAYBACK_CONTROL));
+		if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
+			old |= what;
+		else
+			old &= ~what;
+		outl(old, ICEMT(ice, PLAYBACK_CONTROL));
+		spin_unlock(&ice->reg_lock);
 		break;
 	}
 	case SNDRV_PCM_TRIGGER_START:
@@ -1078,10 +969,7 @@
 				what |= ICE1712_PLAYBACK_START;
 				snd_pcm_trigger_done(s, substream);
 			} else if (s == ice->capture_pro_substream) {
-				if (ice->vt1724)
-					what |= VT1724_RDMA0_START;
-				else
-					what |= ICE1712_CAPTURE_START_SHADOW;
+				what |= ICE1712_CAPTURE_START_SHADOW;
 				snd_pcm_trigger_done(s, substream);
 			}
 			s = s->link_next;
@@ -1108,17 +996,12 @@
 {
 	unsigned long flags;
 	unsigned char val;
+	unsigned int i;
 
 	spin_lock_irqsave(&ice->reg_lock, flags);
-	if (ice->vt1724 && 
-		((inb(ICEMT(ice, PLAYBACK_CONTROL)) & (VT1724_RDMA0_START|ICE1712_PLAYBACK_START)) || 
-		 (inb(ICEMT1724(ice, DMA_PAUSE) & VT1724_PDMA0_PAUSE)))) {
-		spin_unlock_irqrestore(&ice->reg_lock, flags);
-		return;
-	}
-	else if (!ice->vt1724 && (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW|
+	if (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW|
 						 ICE1712_PLAYBACK_PAUSE|
-						 ICE1712_PLAYBACK_START))) {
+						 ICE1712_PLAYBACK_START)) {
 		spin_unlock_irqrestore(&ice->reg_lock, flags);
 		return;
 	}
@@ -1150,8 +1033,10 @@
 
 	spin_unlock_irqrestore(&ice->reg_lock, flags);
 
-	if (ice->ak4524.ops.set_rate_val)
-		ice->ak4524.ops.set_rate_val(ice, rate);
+	for (i = 0; i < ice->akm_codecs; i++) {
+		if (ice->akm[i].ops.set_rate_val)
+			ice->akm[i].ops.set_rate_val(&ice->akm[i], rate);
+	}
 }
 
 static int snd_ice1712_playback_pro_prepare(snd_pcm_substream_t * substream)
@@ -1159,47 +1044,31 @@
 	ice1712_t *ice = snd_pcm_substream_chip(substream);
 
 	ice->playback_pro_size = snd_pcm_lib_buffer_bytes(substream);
-	snd_ice1712_set_pro_rate(ice, substream->runtime->rate, 0);
 	spin_lock(&ice->reg_lock);
 	outl(substream->runtime->dma_addr, ICEMT(ice, PLAYBACK_ADDR));
-	if (ice->vt1724) {
-		outl((ice->playback_pro_size >> 2) - 1, ICEMT(ice, PLAYBACK_SIZE));	
-		outl((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT1724(ice, PLAYBACK_COUNT));
-
-		switch(substream->runtime->channels)
-		{
-			case 8:
-				outb(0, ICEMT1724(ice, BURST));
-				break;
-			case 6:
-				outb(1, ICEMT1724(ice, BURST));
-				break;
-			case 4:
-				outb(2, ICEMT1724(ice, BURST));
-				break;
-			case 2:
-				outb(3, ICEMT1724(ice, BURST));
-				break;
-		}
-	}
-	else {
-		outw((ice->playback_pro_size >> 2) - 1, ICEMT(ice, PLAYBACK_SIZE));
-		outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, PLAYBACK_COUNT));
-	}
+	outw((ice->playback_pro_size >> 2) - 1, ICEMT(ice, PLAYBACK_SIZE));
+	outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, PLAYBACK_COUNT));
 	spin_unlock(&ice->reg_lock);
 
-	if (ice->spdif.ops.setup)
-		ice->spdif.ops.setup(ice, substream);
-
 	return 0;
 }
 
+static int snd_ice1712_playback_pro_hw_params(snd_pcm_substream_t * substream,
+					      snd_pcm_hw_params_t * hw_params)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+
+	snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0);
+	if (ice->spdif.ops.setup_rate)
+		ice->spdif.ops.setup_rate(ice, params_rate(hw_params));
+	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+}
+
 static int snd_ice1712_capture_pro_prepare(snd_pcm_substream_t * substream)
 {
 	ice1712_t *ice = snd_pcm_substream_chip(substream);
 
 	ice->capture_pro_size = snd_pcm_lib_buffer_bytes(substream);
-	snd_ice1712_set_pro_rate(ice, substream->runtime->rate, 0);
 	spin_lock(&ice->reg_lock);
 	outl(substream->runtime->dma_addr, ICEMT(ice, CAPTURE_ADDR));
 	outw((ice->capture_pro_size >> 2) - 1, ICEMT(ice, CAPTURE_SIZE));
@@ -1208,6 +1077,15 @@
 	return 0;
 }
 
+static int snd_ice1712_capture_pro_hw_params(snd_pcm_substream_t * substream,
+					     snd_pcm_hw_params_t * hw_params)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+
+	snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0);
+	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+}
+
 static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(snd_pcm_substream_t * substream)
 {
 	ice1712_t *ice = snd_pcm_substream_chip(substream);
@@ -1215,10 +1093,7 @@
 
 	if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START))
 		return 0;
-	if (ice->vt1724)
-		ptr = ice->playback_pro_size - ((inl(ICEMT(ice, PLAYBACK_SIZE))&0x7ffff) << 2);
-	else
-		ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2);
+	ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2);
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
@@ -1253,27 +1128,6 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_vt1724_playback_pro =
-{
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP_VALID |
-				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
-	.formats =		SNDRV_PCM_FMTBIT_S32_LE,
-	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,
-	.rate_min =		4000,
-	.rate_max =		96000,
-	.channels_min =		2,
-	.channels_max =		8,
-	.buffer_bytes_max =	0x7ffff0,	/* we have 18bits for the buffer size, in dwords */
-	.period_bytes_min =	8 * 4 * 2,
-	.period_bytes_max =	131040,		/* do we have 18bits for terminal count? 
-										Datasheets says bits 18:0 but only has 2 byte registers (1C-1Dh ) */
-	.periods_min =		1,
-	.periods_max =		1024,
-	.fifo_size =		0,
-};
-
 static snd_pcm_hardware_t snd_ice1712_capture_pro =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
@@ -1294,36 +1148,13 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_ice1724_capture_pro =
-{
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP_VALID |
-				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
-	.formats =		SNDRV_PCM_FMTBIT_S32_LE,
-	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,
-	.rate_min =		4000,
-	.rate_max =		96000,
-	.channels_min =		2,
-	.channels_max =		2,
-	.buffer_bytes_max =	(256*1024),
-	.period_bytes_min =	2 * 4 * 2,
-	.period_bytes_max =	131040,
-	.periods_min =		1,
-	.periods_max =		1024,
-	.fifo_size =		0,
-};
-
 static int snd_ice1712_playback_pro_open(snd_pcm_substream_t * substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	ice1712_t *ice = snd_pcm_substream_chip(substream);
 
 	ice->playback_pro_substream = substream;
-	if (ice->vt1724)
-		runtime->hw = snd_vt1724_playback_pro;
-	else
-		runtime->hw = snd_ice1712_playback_pro;
+	runtime->hw = snd_ice1712_playback_pro;
 	snd_pcm_set_sync(substream);
 	snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
@@ -1340,10 +1171,7 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
 	ice->capture_pro_substream = substream;
-	if (ice->vt1724)
-		runtime->hw = snd_ice1724_capture_pro;
-	else
-		runtime->hw = snd_ice1712_capture_pro;
+	runtime->hw = snd_ice1712_capture_pro;
 	snd_pcm_set_sync(substream);
 	snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
@@ -1384,7 +1212,7 @@
 	.open =		snd_ice1712_playback_pro_open,
 	.close =	snd_ice1712_playback_pro_close,
 	.ioctl =	snd_pcm_lib_ioctl,
-	.hw_params =	snd_ice1712_hw_params,
+	.hw_params =	snd_ice1712_playback_pro_hw_params,
 	.hw_free =	snd_ice1712_hw_free,
 	.prepare =	snd_ice1712_playback_pro_prepare,
 	.trigger =	snd_ice1712_pro_trigger,
@@ -1395,7 +1223,7 @@
 	.open =		snd_ice1712_capture_pro_open,
 	.close =	snd_ice1712_capture_pro_close,
 	.ioctl =	snd_pcm_lib_ioctl,
-	.hw_params =	snd_ice1712_hw_params,
+	.hw_params =	snd_ice1712_capture_pro_hw_params,
 	.hw_free =	snd_ice1712_hw_free,
 	.prepare =	snd_ice1712_capture_pro_prepare,
 	.trigger =	snd_ice1712_pro_trigger,
@@ -1613,7 +1441,7 @@
 {
 	int err;
 
-	if (!(ice->eeprom.codec & ICE1712_CFG_NO_CON_AC97)) {
+	if (ice_has_con_ac97(ice)) {
 		ac97_t ac97;
 		memset(&ac97, 0, sizeof(ac97));
 		ac97.write = snd_ice1712_ac97_write;
@@ -1628,8 +1456,8 @@
 			return 0;
 		}
 	}
-	/* hmm.. can we have both consumer and pro ac97 mixers? */
-	if (! (ice->eeprom.aclink & ICE1712_CFG_PRO_I2S)) {
+
+	if (! (ice->eeprom.data[ICE_EEP1_ACLINK] & ICE1712_CFG_PRO_I2S)) {
 		ac97_t ac97;
 		memset(&ac97, 0, sizeof(ac97));
 		ac97.write = snd_ice1712_pro_ac97_write;
@@ -1650,47 +1478,46 @@
  *
  */
 
+static inline unsigned int eeprom_double(ice1712_t *ice, int idx)
+{
+	return (unsigned int)ice->eeprom.data[idx] | ((unsigned int)ice->eeprom.data[idx + 1] << 8);
+}
+
 static void snd_ice1712_proc_read(snd_info_entry_t *entry, 
 				  snd_info_buffer_t * buffer)
 {
 	ice1712_t *ice = snd_magic_cast(ice1712_t, entry->private_data, return);
 	unsigned int idx;
 
-	snd_iprintf(buffer, "ICE1712\n\n");
+	snd_iprintf(buffer, "%s\n\n", ice->card->longname);
 	snd_iprintf(buffer, "EEPROM:\n");
+
 	snd_iprintf(buffer, "  Subvendor        : 0x%x\n", ice->eeprom.subvendor);
 	snd_iprintf(buffer, "  Size             : %i bytes\n", ice->eeprom.size);
 	snd_iprintf(buffer, "  Version          : %i\n", ice->eeprom.version);
-	snd_iprintf(buffer, "  Codec            : 0x%x\n", ice->eeprom.codec);
-	snd_iprintf(buffer, "  ACLink           : 0x%x\n", ice->eeprom.aclink);
-	snd_iprintf(buffer, "  I2S ID           : 0x%x\n", ice->eeprom.i2sID);
-	snd_iprintf(buffer, "  S/PDIF           : 0x%x\n", ice->eeprom.spdif);
+	snd_iprintf(buffer, "  Codec            : 0x%x\n", ice->eeprom.data[ICE_EEP1_CODEC]);
+	snd_iprintf(buffer, "  ACLink           : 0x%x\n", ice->eeprom.data[ICE_EEP1_ACLINK]);
+	snd_iprintf(buffer, "  I2S ID           : 0x%x\n", ice->eeprom.data[ICE_EEP1_I2SID]);
+	snd_iprintf(buffer, "  S/PDIF           : 0x%x\n", ice->eeprom.data[ICE_EEP1_SPDIF]);
 	snd_iprintf(buffer, "  GPIO mask        : 0x%x\n", ice->eeprom.gpiomask);
 	snd_iprintf(buffer, "  GPIO state       : 0x%x\n", ice->eeprom.gpiostate);
 	snd_iprintf(buffer, "  GPIO direction   : 0x%x\n", ice->eeprom.gpiodir);
-	snd_iprintf(buffer, "  AC'97 main       : 0x%x\n", ice->eeprom.ac97main);
-	snd_iprintf(buffer, "  AC'97 pcm        : 0x%x\n", ice->eeprom.ac97pcm);
-	snd_iprintf(buffer, "  AC'97 record     : 0x%x\n", ice->eeprom.ac97rec);
-	snd_iprintf(buffer, "  AC'97 record src : 0x%x\n", ice->eeprom.ac97recsrc);
+	snd_iprintf(buffer, "  AC'97 main       : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_MAIN_LO));
+	snd_iprintf(buffer, "  AC'97 pcm        : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_PCM_LO));
+	snd_iprintf(buffer, "  AC'97 record     : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_REC_LO));
+	snd_iprintf(buffer, "  AC'97 record src : 0x%x\n", ice->eeprom.data[ICE_EEP1_AC97_RECSRC]);
 	for (idx = 0; idx < 4; idx++)
-		snd_iprintf(buffer, "  DAC ID #%i        : 0x%x\n", idx, ice->eeprom.dacID[idx]);
+		snd_iprintf(buffer, "  DAC ID #%i        : 0x%x\n", idx, ice->eeprom.data[ICE_EEP1_DAC_ID + idx]);
 	for (idx = 0; idx < 4; idx++)
-		snd_iprintf(buffer, "  ADC ID #%i        : 0x%x\n", idx, ice->eeprom.adcID[idx]);
-	for (idx = 0x1c; idx < ice->eeprom.size && idx < 0x1c + sizeof(ice->eeprom.extra); idx++)
-		snd_iprintf(buffer, "  Extra #%02i        : 0x%x\n", idx, ice->eeprom.extra[idx - 0x1c]);
+		snd_iprintf(buffer, "  ADC ID #%i        : 0x%x\n", idx, ice->eeprom.data[ICE_EEP1_ADC_ID + idx]);
+	for (idx = 0x1c; idx < ice->eeprom.size; idx++)
+		snd_iprintf(buffer, "  Extra #%02i        : 0x%x\n", idx, ice->eeprom.data[idx]);
+
 	snd_iprintf(buffer, "\nRegisters:\n");
-	if (ice->vt1724) {
-		snd_iprintf(buffer, "  PSDOUT03         : 0x%08x\n", (unsigned)inl(ICEMT1724(ice, ROUTE_PLAYBACK)));
-		for (idx = 0x0; idx < 0x20 ; idx++)
-			snd_iprintf(buffer, "  CCS%02x         : 0x%02x\n", idx, inb(ice->port+idx));
-		for (idx = 0x0; idx < 0x30 ; idx++)
-			snd_iprintf(buffer, "  MT%02x         : 0x%02x\n", idx, inb(ice->profi_port+idx));
-	} else {
-		snd_iprintf(buffer, "  PSDOUT03         : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_PSDOUT03)));
-		snd_iprintf(buffer, "  CAPTURE          : 0x%08x\n", inl(ICEMT(ice, ROUTE_CAPTURE)));
-		snd_iprintf(buffer, "  SPDOUT           : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT)));
-		snd_iprintf(buffer, "  RATE             : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE)));
-	}
+	snd_iprintf(buffer, "  PSDOUT03         : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_PSDOUT03)));
+	snd_iprintf(buffer, "  CAPTURE          : 0x%08x\n", inl(ICEMT(ice, ROUTE_CAPTURE)));
+	snd_iprintf(buffer, "  SPDOUT           : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT)));
+	snd_iprintf(buffer, "  RATE             : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE)));
 }
 
 static void __devinit snd_ice1712_proc_init(ice1712_t * ice)
@@ -1708,7 +1535,7 @@
 static int snd_ice1712_eeprom_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
-	uinfo->count = 32;
+	uinfo->count = sizeof(ice1712_eeprom_t);
 	return 0;
 }
 
@@ -1716,7 +1543,7 @@
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
 	
-	memcpy(ucontrol->value.bytes.data, &ice->eeprom, 32);
+	memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
 	return 0;
 }
 
@@ -1866,14 +1693,10 @@
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char mask = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
-	unsigned char saved[6];
 	
-	snd_ice1712_save_gpio_status(ice, saved);
-	if (ice->vt1724)
-		ucontrol->value.integer.value[0] = (inb(ICEREG1724(ice, GPIO_DATA)) & mask ? 1 : 0) ^ invert;
-	else
-		ucontrol->value.integer.value[0] = (snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & mask ? 1 : 0) ^ invert;
-	snd_ice1712_restore_gpio_status(ice, saved);
+	snd_ice1712_save_gpio_status(ice);
+	ucontrol->value.integer.value[0] = (snd_ice1712_gpio_read(ice) & mask ? 1 : 0) ^ invert;
+	snd_ice1712_restore_gpio_status(ice);
 	return 0;
 }
 
@@ -1882,24 +1705,17 @@
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char mask = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value & (1<<24)) ? mask : 0;
-	unsigned char saved[6];
-	int val, nval;
+	unsigned int val, nval;
 
 	if (kcontrol->private_value & (1 << 31))
 		return -EPERM;
 	nval = (ucontrol->value.integer.value[0] ? mask : 0) ^ invert;
-	snd_ice1712_save_gpio_status(ice, saved);
-	if (ice->vt1724) {
-		val = inb(ICEREG1724(ice, GPIO_DATA));
-		nval |= val & ~mask;
-		outb(nval, ICEREG1724(ice, GPIO_DATA));
-	}
-	else {
-		val = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
-		nval |= val & ~mask;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, nval);
-	}
-	snd_ice1712_restore_gpio_status(ice, saved);
+	snd_ice1712_save_gpio_status(ice);
+	val = snd_ice1712_gpio_read(ice);
+	nval |= val & ~mask;
+	if (val != nval)
+		snd_ice1712_gpio_write(ice, nval);
+	snd_ice1712_restore_gpio_status(ice);
 	return val != nval;
 }
 
@@ -1985,14 +1801,19 @@
 			snd_ice1712_cs8427_set_input_clock(ice, is_spdif_master(ice));
 		}
 		/* notify ak4524 chip as well */
-		if (is_spdif_master(ice) && ice->ak4524.ops.set_rate_val)
-			ice->ak4524.ops.set_rate_val(ice, 0);
+		if (is_spdif_master(ice)) {
+			unsigned int i;
+			for (i = 0; i < ice->akm_codecs; i++) {
+				if (ice->akm[i].ops.set_rate_val)
+					ice->akm[i].ops.set_rate_val(&ice->akm[i], 0);
+			}
+		}
 	}
 
 	return change;
 }
 
-static snd_kcontrol_new_t snd_ice1712_pro_internal_clock = __devinitdata {
+static snd_kcontrol_new_t snd_ice1712_pro_internal_clock __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Internal Clock",
 	.info = snd_ice1712_pro_internal_clock_info,
@@ -2011,16 +1832,20 @@
 
 static int snd_ice1712_pro_rate_locking_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-	ucontrol->value.integer.value[0] = PRO_RATE_LOCKED ? 1 : 0;
+	ucontrol->value.integer.value[0] = PRO_RATE_LOCKED;
 	return 0;
 }
 
 static int snd_ice1712_pro_rate_locking_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-	int change = 0;
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int change = 0, nval;
 
-	change = PRO_RATE_LOCKED ? 1 : 0 != ucontrol->value.integer.value[0] ? 1 : 0;
-	PRO_RATE_LOCKED = ucontrol->value.integer.value[0] ? 1 : 0;
+	nval = ucontrol->value.integer.value[0] ? 1 : 0;
+	spin_lock_irq(&ice->reg_lock);
+	change = PRO_RATE_LOCKED != nval;
+	PRO_RATE_LOCKED = nval;
+	spin_unlock_irq(&ice->reg_lock);
 	return change;
 }
 
@@ -2043,16 +1868,20 @@
 
 static int snd_ice1712_pro_rate_reset_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-	ucontrol->value.integer.value[0] = PRO_RATE_RESET ? 1 : 0;
+	ucontrol->value.integer.value[0] = PRO_RATE_RESET;
 	return 0;
 }
 
 static int snd_ice1712_pro_rate_reset_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-	int change = 0;
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int change = 0, nval;
 
-	change = PRO_RATE_LOCKED ? 1 : 0 != ucontrol->value.integer.value[0] ? 1 : 0;
-	PRO_RATE_RESET = ucontrol->value.integer.value[0] ? 1 : 0;
+	nval = ucontrol->value.integer.value[0] ? 1 : 0;
+	spin_lock_irq(&ice->reg_lock);
+	change = PRO_RATE_RESET != nval;
+	PRO_RATE_RESET = nval;
+	spin_unlock_irq(&ice->reg_lock);
 	return change;
 }
 
@@ -2234,141 +2063,6 @@
 };
 
 
-static int snd_vt1724_pro_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	static char *texts[] = {
-		"PCM Out", /* 0 */
-		"H/W In 0", "H/W In 1", /* 1-2 */
-		"IEC958 In L", "IEC958 In R", /* 3-4 */
-	};
-	
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	uinfo->value.enumerated.items = 5;//kcontrol->id.index < 2 ? 12 : 11;
-	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
-		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
-	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
-	return 0;
-}
-
-static int snd_vt1724_pro_route_analog_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx = kcontrol->id.index;
-	unsigned long val;
-	unsigned char eitem;
-	static unsigned char xlate[8] = {
-		0, 255, 1, 2, 255, 255, 3, 4,
-	};
-
-	val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
-	val >>= ((idx % 2) * 12) + ((idx / 2) * 3)+8;
-	val &= 7;	//we now have 3 bits per output
-	eitem=xlate[val];
-	if (eitem == 255) {
-		snd_BUG();
-		eitem = 0;
-	}
-	ucontrol->value.enumerated.item[0] = eitem;
-
-	return 0;
-}
-
-static int snd_vt1724_pro_route_analog_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int change, shift;
-	int idx = kcontrol->id.index;
-	unsigned int val, old_val, nval;
-	static unsigned char xroute[8] = {
-		0, /* PCM */
-		2, /* PSDIN0 Left */
-		3, /* PSDIN0 Right */
-		6, /* SPDIN Left */
-		7,  /* SPDIN Right */
-	};
-	
-	/* update PSDOUT */
-
-	nval=xroute[ucontrol->value.enumerated.item[0]&7];
-	shift = ((idx % 2) * 12) + ((idx / 2) * 3) +8;
-	val = old_val = inw(ICEMT1724(ice, ROUTE_PLAYBACK));
-	val &= ~(0x07 << shift);
-	val |= nval << shift;
-	change = val != old_val;
-	if (change)
-		outw(val, ICEMT1724(ice, ROUTE_PLAYBACK));
-	return change;
-}
-
-static int snd_vt1724_pro_route_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx = kcontrol->id.index;
-	unsigned long val;
-	unsigned char eitem;
-	static unsigned char xlate[8] = {
-		0, 255, 1, 2, 255, 255, 3, 4,
-	};
-
-	val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
-	val >>= idx*3;	//I hope this is right
-	val &= 7;	
-
-	eitem=xlate[val];
-	if (eitem == 255) {
-		snd_BUG();
-		eitem = 0;
-	}
-	ucontrol->value.enumerated.item[0] = eitem;
-	return 0;
-}
-
-static int snd_vt1724_pro_route_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int change, shift;
-	int idx = kcontrol->id.index;
-	unsigned long val, old_val, nval;
-	static unsigned char xroute[8] = {
-		0, /* PCM */
-		2, /* PSDIN0 Left */
-		3, /* PSDIN0 Right */
-		6, /* SPDIN Left */
-		7,  /* SPDIN Right */
-	};
-	
-	/* update SPDOUT */
-	val = old_val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
-	nval = xroute[ucontrol->value.enumerated.item[0]&7];
-
-	shift = idx * 2;
-	val &= ~(0x07 << shift);
-	val |= nval << shift;
-	shift = idx * 4 + 8;
-	change = val != old_val;
-	if (change)
-		outl(val, ICEMT1724(ice, ROUTE_PLAYBACK));
-	return change;
-}
-
-static snd_kcontrol_new_t snd_vt1724_mixer_pro_analog_route __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "H/W Playback Route",
-	.info = snd_vt1724_pro_route_info,
-	.get = snd_vt1724_pro_route_analog_get,
-	.put = snd_vt1724_pro_route_analog_put,
-};
-
-static snd_kcontrol_new_t snd_vt1724_mixer_pro_spdif_route __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "IEC958 Playback Route",
-	.info = snd_vt1724_pro_route_info,
-	.get = snd_vt1724_pro_route_spdif_get,
-	.put = snd_vt1724_pro_route_spdif_put,
-};
-
-
 static int snd_ice1712_pro_volume_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -2456,7 +2150,7 @@
 static int __devinit snd_ice1712_read_eeprom(ice1712_t *ice)
 {
 	int dev = 0xa0;		/* EEPROM device address */
-	unsigned int idx;
+	unsigned int i;
 
 	if ((inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_EEPROM) == 0) {
 		snd_printk("ICE1712 has not detected EEPROM\n");
@@ -2467,39 +2161,22 @@
 				(snd_ice1712_read_i2c(ice, dev, 0x02) << 16) | 
 				(snd_ice1712_read_i2c(ice, dev, 0x03) << 24);
 	ice->eeprom.size = snd_ice1712_read_i2c(ice, dev, 0x04);
-	if (ice->eeprom.size < 28) {
+	if (ice->eeprom.size > 32) {
 		snd_printk("invalid EEPROM (size = %i)\n", ice->eeprom.size);
 		return -EIO;
 	}
 	ice->eeprom.version = snd_ice1712_read_i2c(ice, dev, 0x05);
 	if (ice->eeprom.version != 1) {
 		snd_printk("invalid EEPROM version %i\n", ice->eeprom.version);
-		return -EIO;
-	}
-	ice->eeprom.codec = snd_ice1712_read_i2c(ice, dev, 0x06);
-	if (ice->vt1724)
-		ice->eeprom.codec |= ICE1712_CFG_NO_CON_AC97;	/* little hack here */
-	ice->eeprom.aclink = snd_ice1712_read_i2c(ice, dev, 0x07);
-	ice->eeprom.i2sID = snd_ice1712_read_i2c(ice, dev, 0x08);
-	ice->eeprom.spdif = snd_ice1712_read_i2c(ice, dev, 0x09);
-	if (ice->vt1724)
-		ice->eeprom.spdif &= ~VT1724_CFG_SPDIF_OUT_EN;	/* little hack here */
-	ice->eeprom.gpiomask = snd_ice1712_read_i2c(ice, dev, 0x0a);
-	ice->eeprom.gpiostate = snd_ice1712_read_i2c(ice, dev, 0x0b);
-	ice->eeprom.gpiodir = snd_ice1712_read_i2c(ice, dev, 0x0c);
-	ice->eeprom.ac97main = (snd_ice1712_read_i2c(ice, dev, 0x0d) << 0) |
-			       (snd_ice1712_read_i2c(ice, dev, 0x0e) << 8);
-	ice->eeprom.ac97pcm = (snd_ice1712_read_i2c(ice, dev, 0x0f) << 0) |
-			      (snd_ice1712_read_i2c(ice, dev, 0x10) << 8);
-	ice->eeprom.ac97rec = (snd_ice1712_read_i2c(ice, dev, 0x11) << 0) |
-			      (snd_ice1712_read_i2c(ice, dev, 0x12) << 8);
-	ice->eeprom.ac97recsrc = snd_ice1712_read_i2c(ice, dev, 0x13) << 0;
-	for (idx = 0; idx < 4; idx++) {
-		ice->eeprom.dacID[idx] = snd_ice1712_read_i2c(ice, dev, 0x14 + idx);
-		ice->eeprom.adcID[idx] = snd_ice1712_read_i2c(ice, dev, 0x18 + idx);
+		/* return -EIO; */
 	}
-	for (idx = 0x1c; idx < ice->eeprom.size && idx < 0x1c + sizeof(ice->eeprom.extra); idx++)
-		ice->eeprom.extra[idx - 0x1c] = snd_ice1712_read_i2c(ice, dev, idx);
+	for (i = 0; i < ice->eeprom.size; i++)
+		ice->eeprom.data[i] = snd_ice1712_read_i2c(ice, dev, i + 6);
+
+	ice->eeprom.gpiomask = ice->eeprom.data[ICE_EEP1_GPIO_MASK];
+	ice->eeprom.gpiostate = ice->eeprom.data[ICE_EEP1_GPIO_STATE];
+	ice->eeprom.gpiodir = ice->eeprom.data[ICE_EEP1_GPIO_DIR];
+
 	return 0;
 }
 
@@ -2511,25 +2188,25 @@
 	udelay(200);
 	outb(ICE1712_NATIVE, ICEREG(ice, CONTROL));
 	udelay(200);
-	pci_write_config_byte(ice->pci, 0x60, ice->eeprom.codec);
-	pci_write_config_byte(ice->pci, 0x61, ice->eeprom.aclink);
-	pci_write_config_byte(ice->pci, 0x62, ice->eeprom.i2sID);
-	pci_write_config_byte(ice->pci, 0x63, ice->eeprom.spdif);
+	pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]);
+	pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]);
+	pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]);
+	pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]);
 	if (ice->eeprom.subvendor != ICE1712_SUBDEVICE_STDSP24) {
-		ice->gpio_write_mask = ice->eeprom.gpiomask;
-		ice->gpio_direction = ice->eeprom.gpiodir;
+		ice->gpio.write_mask = ice->eeprom.gpiomask;
+		ice->gpio.direction = ice->eeprom.gpiodir;
 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask);
 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir);
 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate);
 	} else {
-		ice->gpio_write_mask = 0xc0;
-		ice->gpio_direction = 0xff;
+		ice->gpio.write_mask = 0xc0;
+		ice->gpio.direction = 0xff;
 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, 0xc0);
 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, 0xff);
 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ICE1712_STDSP24_CLOCK_BIT);
 	}
 	snd_ice1712_write(ice, ICE1712_IREG_PRO_POWERDOWN, 0);
-	if (!(ice->eeprom.codec & ICE1712_CFG_NO_CON_AC97)) {
+	if (!(ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97)) {
 		outb(ICE1712_AC97_WARM, ICEREG(ice, AC97_CMD));
 		udelay(100);
 		outb(0, ICEREG(ice, AC97_CMD));
@@ -2540,28 +2217,6 @@
 	return 0;
 }
 
-static int __devinit snd_vt1724_chip_init(ice1712_t *ice)
-{
-	outb(VT1724_RESET , ICEREG(ice, CONTROL));
-	udelay(200);
-	outb(0, ICEREG(ice, CONTROL));
-	udelay(200);
-	outb(ice->eeprom.codec, ICEREG1724(ice, SYS_CFG));
-	outb(ice->eeprom.aclink&0x7f, ICEREG1724(ice, AC97_CFG));
-	outb(ice->eeprom.i2sID, ICEREG1724(ice, I2S_FEATURES));
-	outb(ice->eeprom.spdif, ICEREG1724(ice, SPDIF_CFG));
-
-	ice->gpio_write_mask = ice->eeprom.gpiomask;
-	ice->gpio_direction = ice->eeprom.gpiodir;
-	outb(ice->eeprom.gpiomask, ICEREG1724(ice, GPIO_WRITE_MASK));
-	outb(ice->eeprom.gpiodir, ICEREG1724(ice, GPIO_DIRECTION));
-	outb(ice->eeprom.gpiostate, ICEREG1724(ice, GPIO_DATA));
-
-	outb(0, ICEREG1724(ice, POWERDOWN));	
-
-	return 0;
-}
-
 int __devinit snd_ice1712_spdif_build_controls(ice1712_t *ice)
 {
 	int err;
@@ -2602,63 +2257,40 @@
 	if (err < 0)
 		return err;
 
-	if (ice->vt1724) {
-		for (idx = 0; idx < ice->num_total_dacs; idx++) {
-			kctl = snd_ctl_new1(&snd_vt1724_mixer_pro_analog_route, ice);
-			if (kctl == NULL)
-				return -ENOMEM;
-			kctl->id.index = idx;
-			err = snd_ctl_add(ice->card, kctl);
-			if (err < 0)
-				return err;
-		}
-		for (idx = 0; idx < 2; idx++) {
-			kctl = snd_ctl_new1(&snd_vt1724_mixer_pro_spdif_route, ice);
-			if (kctl == NULL)
-				return -ENOMEM;
-			kctl->id.index = idx;
-			err = snd_ctl_add(ice->card, kctl);
-			if (err < 0)
-				return err;
-		}
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice));
-		if (err < 0)
-			return err;
+	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_rate_locking, ice));
+	if (err < 0)
+		return err;
+	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_rate_reset, ice));
+	if (err < 0)
+		return err;
 
-	}
-	else {
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_rate_locking, ice));
-		if (err < 0)
-			return err;
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_rate_reset, ice));
+	for (idx = 0; idx < ice->num_total_dacs; idx++) {
+		kctl = snd_ctl_new1(&snd_ice1712_mixer_pro_analog_route, ice);
+		if (kctl == NULL)
+			return -ENOMEM;
+		kctl->id.index = idx;
+		err = snd_ctl_add(ice->card, kctl);
 		if (err < 0)
 			return err;
+	}
 
-		for (idx = 0; idx < ice->num_total_dacs; idx++) {
-			kctl = snd_ctl_new1(&snd_ice1712_mixer_pro_analog_route, ice);
-			if (kctl == NULL)
-				return -ENOMEM;
-			kctl->id.index = idx;
-			err = snd_ctl_add(ice->card, kctl);
-			if (err < 0)
-				return err;
-		}
-		for (idx = 0; idx < 2; idx++) {
-			kctl = snd_ctl_new1(&snd_ice1712_mixer_pro_spdif_route, ice);
-			if (kctl == NULL)
-				return -ENOMEM;
-			kctl->id.index = idx;
-			err = snd_ctl_add(ice->card, kctl);
-			if (err < 0)
-				return err;
-		}
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_volume_rate, ice));
-		if (err < 0)
-			return err;
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice));
+	for (idx = 0; idx < 2; idx++) {
+		kctl = snd_ctl_new1(&snd_ice1712_mixer_pro_spdif_route, ice);
+		if (kctl == NULL)
+			return -ENOMEM;
+		kctl->id.index = idx;
+		err = snd_ctl_add(ice->card, kctl);
 		if (err < 0)
 			return err;
 	}
+
+	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_volume_rate, ice));
+	if (err < 0)
+		return err;
+	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice));
+	if (err < 0)
+		return err;
+
 	return 0;
 }
 
@@ -2667,10 +2299,7 @@
 	if (ice->res_port == NULL)
 		goto __hw_end;
 	/* mask all interrupts */
-	if (ice->vt1724)
-		outb(0xff, ICEMT1724(ice, DMA_INT_MASK));
-	else
-		outb(0xc0, ICEMT(ice, IRQ));
+	outb(0xc0, ICEMT(ice, IRQ));
 	outb(0xff, ICEREG(ice, IRQMASK));
 	/* --- */
       __hw_end:
@@ -2694,6 +2323,8 @@
 		release_resource(ice->res_profi_port);
 		kfree_nocheck(ice->res_profi_port);
 	}
+	if (ice->akm)
+		kfree(ice->akm);
 	snd_magic_kfree(ice);
 	return 0;
 }
@@ -2706,7 +2337,6 @@
 
 static int __devinit snd_ice1712_create(snd_card_t * card,
 					struct pci_dev *pci,
-					int vt1724,
 					int omni,
 					ice1712_t ** r_ice1712)
 {
@@ -2721,25 +2351,24 @@
         /* enable PCI device */
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
-	/* VT1724 does not have 28bit DMA transfer limit */
-	if (! vt1724) {
-		/* check, if we can restrict PCI DMA transfers to 28 bits */
-		if (!pci_dma_supported(pci, 0x0fffffff)) {
-			snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
-			return -ENXIO;
-		}
-		pci_set_dma_mask(pci, 0x0fffffff);
+	/* check, if we can restrict PCI DMA transfers to 28 bits */
+	if (!pci_dma_supported(pci, 0x0fffffff)) {
+		snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
+		return -ENXIO;
 	}
-	else
-		pci_set_dma_mask(pci, 0xffffffff); 
+	pci_set_dma_mask(pci, 0x0fffffff);
 
 	ice = snd_magic_kcalloc(ice1712_t, 0, GFP_KERNEL);
 	if (ice == NULL)
 		return -ENOMEM;
-	ice->vt1724 = vt1724 ? 1 : 0;
 	ice->omni = omni ? 1 : 0;
 	spin_lock_init(&ice->reg_lock);
 	init_MUTEX(&ice->gpio_mutex);
+	ice->gpio.set_mask = snd_ice1712_set_gpio_mask;
+	ice->gpio.set_dir = snd_ice1712_set_gpio_dir;
+	ice->gpio.set_data = snd_ice1712_set_gpio_data;
+	ice->gpio.get_data = snd_ice1712_get_gpio_data;
+
 	ice->spdif.cs8403_bits =
 		ice->spdif.cs8403_stream_bits = (0x01 |	/* consumer format */
 						 0x10 |	/* no emphasis */
@@ -2748,101 +2377,57 @@
 	ice->pci = pci;
 	ice->irq = -1;
 	ice->port = pci_resource_start(pci, 0);
-	if (ice->vt1724) {
-		ice->profi_port = pci_resource_start(pci, 1);
-		pci_set_master(pci);
-		snd_ice1712_proc_init(ice);
-		synchronize_irq(pci->irq);
-
-		if ((ice->res_port = request_region(ice->port, 32, "ICE1724 - Controller")) == NULL) {
-			snd_ice1712_free(ice);
-			snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->port, ice->port + 32 - 1);
-			return -EIO;
-		}
+	ice->ddma_port = pci_resource_start(pci, 1);
+	ice->dmapath_port = pci_resource_start(pci, 2);
+	ice->profi_port = pci_resource_start(pci, 3);
+	pci_set_master(pci);
+	pci_write_config_word(ice->pci, 0x40, 0x807f);
+	pci_write_config_word(ice->pci, 0x42, 0x0006);
+	snd_ice1712_proc_init(ice);
+	synchronize_irq(pci->irq);
 
-		if ((ice->res_profi_port = request_region(ice->profi_port, 128, "ICE1724 - Professional")) == NULL) {
-			snd_ice1712_free(ice);
-			snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->profi_port, ice->profi_port + 16 - 1);
-			return -EIO;
-		}
-		
-		if (request_irq(pci->irq, snd_vt1724_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1724", (void *) ice)) {
-			snd_ice1712_free(ice);
-			snd_printk("unable to grab IRQ %d\n", pci->irq);
-			return -EIO;
-		}
-
-		ice->irq = pci->irq;
-
-		if (snd_ice1712_read_eeprom(ice) < 0) {
-			snd_ice1712_free(ice);
-			return -EIO;
-		}
-		if (snd_vt1724_chip_init(ice) < 0) {
-			snd_ice1712_free(ice);
-			return -EIO;
-		}
-
-		/* unmask used interrupts */
-		outb((ice->eeprom.codec & ICE1712_CFG_2xMPU401) == 0 ? (VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX) : 0 ,
-			 ICEREG(ice, IRQMASK));
-		/* don't handle FIFO overrun/underruns (just yet), since they cause machine lockups */
-		outb(VT1724_MULTI_FIFO_ERR, ICEMT1724(ice, DMA_INT_MASK));	
-	}
-	else {
-		ice->ddma_port = pci_resource_start(pci, 1);
-		ice->dmapath_port = pci_resource_start(pci, 2);
-		ice->profi_port = pci_resource_start(pci, 3);
-		pci_set_master(pci);
-		pci_write_config_word(ice->pci, 0x40, 0x807f);
-		pci_write_config_word(ice->pci, 0x42, 0x0006);
-		snd_ice1712_proc_init(ice);
-		synchronize_irq(pci->irq);
-	
-
-		if ((ice->res_port = request_region(ice->port, 32, "ICE1712 - Controller")) == NULL) {
-			snd_ice1712_free(ice);
-			snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->port, ice->port + 32 - 1);
-			return -EIO;
-		}
-		if ((ice->res_ddma_port = request_region(ice->ddma_port, 16, "ICE1712 - DDMA")) == NULL) {
-			snd_ice1712_free(ice);
-			snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->ddma_port, ice->ddma_port + 16 - 1);
-			return -EIO;
-		}
-		if ((ice->res_dmapath_port = request_region(ice->dmapath_port, 16, "ICE1712 - DMA path")) == NULL) {
-			snd_ice1712_free(ice);
-			snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->dmapath_port, ice->dmapath_port + 16 - 1);
-			return -EIO;
-		}
-		if ((ice->res_profi_port = request_region(ice->profi_port, 64, "ICE1712 - Professional")) == NULL) {
-			snd_ice1712_free(ice);
-			snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->profi_port, ice->profi_port + 16 - 1);
-			return -EIO;
-		}
-		if (request_irq(pci->irq, snd_ice1712_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1712", (void *) ice)) {
-			snd_ice1712_free(ice);
-			snd_printk("unable to grab IRQ %d\n", pci->irq);
-			return -EIO;
-		}
+	if ((ice->res_port = request_region(ice->port, 32, "ICE1712 - Controller")) == NULL) {
+		snd_ice1712_free(ice);
+		snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->port, ice->port + 32 - 1);
+		return -EIO;
+	}
+	if ((ice->res_ddma_port = request_region(ice->ddma_port, 16, "ICE1712 - DDMA")) == NULL) {
+		snd_ice1712_free(ice);
+		snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->ddma_port, ice->ddma_port + 16 - 1);
+		return -EIO;
+	}
+	if ((ice->res_dmapath_port = request_region(ice->dmapath_port, 16, "ICE1712 - DMA path")) == NULL) {
+		snd_ice1712_free(ice);
+		snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->dmapath_port, ice->dmapath_port + 16 - 1);
+		return -EIO;
+	}
+	if ((ice->res_profi_port = request_region(ice->profi_port, 64, "ICE1712 - Professional")) == NULL) {
+		snd_ice1712_free(ice);
+		snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->profi_port, ice->profi_port + 16 - 1);
+		return -EIO;
+	}
+	if (request_irq(pci->irq, snd_ice1712_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1712", (void *) ice)) {
+		snd_ice1712_free(ice);
+		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		return -EIO;
+	}
 	
-		ice->irq = pci->irq;
-
-		if (snd_ice1712_read_eeprom(ice) < 0) {
-			snd_ice1712_free(ice);
-			return -EIO;
-		}
-		if (snd_ice1712_chip_init(ice) < 0) {
-			snd_ice1712_free(ice);
-			return -EIO;
-		}
+	ice->irq = pci->irq;
 
-		/* unmask used interrupts */
-		outb((ice->eeprom.codec & ICE1712_CFG_2xMPU401) == 0 ? ICE1712_IRQ_MPU2 : 0 |
-			 (ice->eeprom.codec & ICE1712_CFG_NO_CON_AC97) ? ICE1712_IRQ_PBKDS | ICE1712_IRQ_CONCAP | ICE1712_IRQ_CONPBK : 0,
-			 ICEREG(ice, IRQMASK));
-		outb(0x00, ICEMT(ice, IRQ));
+	if (snd_ice1712_read_eeprom(ice) < 0) {
+		snd_ice1712_free(ice);
+		return -EIO;
 	}
+	if (snd_ice1712_chip_init(ice) < 0) {
+		snd_ice1712_free(ice);
+		return -EIO;
+	}
+
+	/* unmask used interrupts */
+	outb((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) == 0 ? ICE1712_IRQ_MPU2 : 0 |
+	     (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97) ? ICE1712_IRQ_PBKDS | ICE1712_IRQ_CONCAP | ICE1712_IRQ_CONPBK : 0,
+	     ICEREG(ice, IRQMASK));
+	outb(0x00, ICEMT(ice, IRQ));
 
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) {
 		snd_ice1712_free(ice);
@@ -2866,7 +2451,6 @@
 	snd_ice1712_hoontech_cards,
 	snd_ice1712_delta_cards,
 	snd_ice1712_ews_cards,
-	snd_vt1724_amp_cards, 
 	0,
 };
 
@@ -2878,7 +2462,6 @@
 	snd_card_t *card;
 	ice1712_t *ice;
 	int pcm_dev = 0, err;
-	int chip_type;
 	struct snd_ice1712_card_info **tbl, *c;
 
 	if (dev >= SNDRV_CARDS)
@@ -2892,16 +2475,10 @@
 	if (card == NULL)
 		return -ENOMEM;
 
-	chip_type = pci_id->driver_data;
-	if (chip_type == TYPE_ICE1712) {
-		strcpy(card->driver, "ICE1712");
-		strcpy(card->shortname, "ICEnsemble ICE1712");
-	} else {
-		strcpy(card->driver, "ICE1724");
-		strcpy(card->shortname, "ICEnsemble ICE1724");
-	}
+	strcpy(card->driver, "ICE1712");
+	strcpy(card->shortname, "ICEnsemble ICE1712");
 	
-	if ((err = snd_ice1712_create(card, pci, chip_type, omni[dev], &ice)) < 0) {
+	if ((err = snd_ice1712_create(card, pci, omni[dev], &ice)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -2928,7 +2505,7 @@
 		return err;
 	}
 	
-	if (!(ice->eeprom.codec & ICE1712_CFG_NO_CON_AC97))
+	if (ice_has_con_ac97(ice))
 		if ((err = snd_ice1712_pcm(ice, pcm_dev++, NULL)) < 0) {
 			snd_card_free(card);
 			return err;
@@ -2951,7 +2528,7 @@
 		}
 	}
 
-	if (!(ice->eeprom.codec & ICE1712_CFG_NO_CON_AC97))
+	if (ice_has_con_ac97(ice))
 		if ((err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL)) < 0) {
 			snd_card_free(card);
 			return err;
@@ -2966,7 +2543,7 @@
 			return err;
 		}
 
-		if (ice->eeprom.codec & ICE1712_CFG_2xMPU401)
+		if (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401)
 			if ((err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712,
 						       ICEREG(ice, MPU2_CTRL), 1,
 						       ice->irq, 0,
diff -Nru a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
--- a/sound/pci/ice1712/ice1712.h	Sat Feb  8 12:10:54 2003
+++ b/sound/pci/ice1712/ice1712.h	Thu Mar 20 08:41:14 2003
@@ -214,50 +214,70 @@
  */
 
 typedef struct _snd_ice1712 ice1712_t;
-typedef struct snd_ak4524 ak4524_t;
+typedef struct snd_ak4xxx akm4xxx_t;
 
 typedef struct {
 	unsigned int subvendor;	/* PCI[2c-2f] */
 	unsigned char size;	/* size of EEPROM image in bytes */
-	unsigned char version;	/* must be 1 */
-	unsigned char codec;	/* codec configuration PCI[60] */
-	unsigned char aclink;	/* ACLink configuration PCI[61] */
-	unsigned char i2sID;	/* PCI[62] */
-	unsigned char spdif;	/* S/PDIF configuration PCI[63] */
-	unsigned char gpiomask;	/* GPIO initial mask, 0 = write, 1 = don't */
-	unsigned char gpiostate; /* GPIO initial state */
-	unsigned char gpiodir;	/* GPIO direction state */
-	unsigned short ac97main;
-	unsigned short ac97pcm;
-	unsigned short ac97rec;
-	unsigned char ac97recsrc;
-	unsigned char dacID[4];	/* I2S IDs for DACs */
-	unsigned char adcID[4];	/* I2S IDs for ADCs */
-	unsigned char extra[4];
+	unsigned char version;	/* must be 1 (or 2 for vt1724) */
+	unsigned char data[32];
+	unsigned int gpiomask;
+	unsigned int gpiostate;
+	unsigned int gpiodir;
 } ice1712_eeprom_t;
 
-struct snd_ak4524 {
+enum {
+	ICE_EEP1_CODEC = 0,	/* 06 */
+	ICE_EEP1_ACLINK,	/* 07 */
+	ICE_EEP1_I2SID,		/* 08 */
+	ICE_EEP1_SPDIF,		/* 09 */
+	ICE_EEP1_GPIO_MASK,	/* 0a */
+	ICE_EEP1_GPIO_STATE,	/* 0b */
+	ICE_EEP1_GPIO_DIR,	/* 0c */
+	ICE_EEP1_AC97_MAIN_LO,	/* 0d */
+	ICE_EEP1_AC97_MAIN_HI,	/* 0e */
+	ICE_EEP1_AC97_PCM_LO,	/* 0f */
+	ICE_EEP1_AC97_PCM_HI,	/* 10 */
+	ICE_EEP1_AC97_REC_LO,	/* 11 */
+	ICE_EEP1_AC97_REC_HI,	/* 12 */
+	ICE_EEP1_AC97_RECSRC,	/* 13 */
+	ICE_EEP1_DAC_ID,	/* 14 */
+	ICE_EEP1_DAC_ID1,
+	ICE_EEP1_DAC_ID2,
+	ICE_EEP1_DAC_ID3,
+	ICE_EEP1_ADC_ID,	/* 18 */
+	ICE_EEP1_ADC_ID1,
+	ICE_EEP1_ADC_ID2,
+	ICE_EEP1_ADC_ID3
+};
+	
+#define ice_has_con_ac97(ice)	(!((ice)->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97))
+
+
+struct snd_ak4xxx {
 	unsigned int num_adcs;		/* AK4524 or AK4528 ADCs */
 	unsigned int num_dacs;		/* AK4524 or AK4528 DACs */
-	unsigned char images[4][16];
-	unsigned char ipga_gain[4][2];
-	/* */
+	unsigned char images[4][16];	/* saved register image */
+	unsigned char ipga_gain[4][2];	/* saved register image for IPGA (AK4528) */
+	ice1712_t *chip;
+	/* template should fill the following fields */
+	unsigned int idx_offset;	/* control index offset */
 	enum {
-		SND_AK4524, SND_AK4528, SND_AK4529
+		SND_AK4524, SND_AK4528, SND_AK4529, SND_AK4355, SND_AK4381
 	} type;
-	unsigned int cif: 1;
-	unsigned char data_mask;
-	unsigned char clk_mask;
+	unsigned int cif: 1;		/* CIF mode */
 	unsigned char caddr;		/* C0 and C1 bits */
-	unsigned char cs_mask;
-	unsigned char cs_addr;
-	unsigned char cs_none;
-	unsigned char add_flags;
-	unsigned char mask_flags;
-	struct snd_ak4524_ops {
-		int (*start)(ice1712_t *, unsigned char *, int);
-		void (*stop)(ice1712_t *, unsigned char *);
-		void (*set_rate_val)(ice1712_t *, unsigned int);
+	unsigned int data_mask;		/* DATA gpio bit */
+	unsigned int clk_mask;		/* CLK gpio bit */
+	unsigned int cs_mask;		/* bit mask for select/deselect address */
+	unsigned int cs_addr;		/* bits to select address */
+	unsigned int cs_none;		/* bits to deselect address */
+	unsigned int add_flags;		/* additional bits at init */
+	unsigned int mask_flags;	/* total mask bits */
+	struct snd_akm4xxx_ops {
+		int (*start)(akm4xxx_t *ak, int chip);
+		void (*stop)(akm4xxx_t *ak);
+		void (*set_rate_val)(akm4xxx_t *ak, unsigned int rate);
 	} ops;
 };
 
@@ -268,7 +288,7 @@
 
 	struct snd_ice1712_spdif_ops {
 		void (*open)(ice1712_t *, snd_pcm_substream_t *);
-		void (*setup)(ice1712_t *, snd_pcm_substream_t *);
+		void (*setup_rate)(ice1712_t *, int rate);
 		void (*close)(ice1712_t *, snd_pcm_substream_t *);
 		void (*default_get)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
 		int (*default_put)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
@@ -294,8 +314,6 @@
 	unsigned long profi_port;
 	struct resource *res_profi_port;
 
-	unsigned int config;	/* system configuration */
-
 	struct pci_dev *pci;
 	snd_card_t *card;
 	snd_pcm_t *pcm;
@@ -316,19 +334,21 @@
 	snd_rawmidi_t *rmidi[2];
 
 	spinlock_t reg_lock;
-	struct semaphore gpio_mutex;
 	snd_info_entry_t *proc_entry;
 
 	ice1712_eeprom_t eeprom;
 
 	unsigned int pro_volumes[20];
-	int omni: 1;			/* Delta Omni I/O */
+	unsigned int omni: 1;		/* Delta Omni I/O */
+	unsigned int vt1724: 1;
 	unsigned int num_total_dacs;	/* total DACs */
 	unsigned char hoontech_boxbits[4];
 	unsigned int hoontech_config;
 	unsigned short hoontech_boxconfig[4];
+	unsigned int cur_rate;		/* current rate */
 
-	struct snd_ak4524 ak4524;
+	unsigned int akm_codecs;
+	akm4xxx_t *akm;
 	struct snd_ice1712_spdif spdif;
 
 	snd_i2c_bus_t *i2c;		/* I2C bus */
@@ -336,13 +356,67 @@
 	snd_i2c_device_t *cs8427;	/* CS8427 I2C device */
 	snd_i2c_device_t *i2cdevs[2];	/* additional i2c devices */
 	
-	unsigned int gpio_direction, gpio_write_mask;
-	int vt1724;
+	struct ice1712_gpio {
+		unsigned int direction;		/* current direction bits */
+		unsigned int write_mask;	/* current mask bits */
+		unsigned int saved[2];		/* for ewx_i2c */
+		/* operators */
+		void (*set_mask)(ice1712_t *ice, unsigned int data);
+		void (*set_dir)(ice1712_t *ice, unsigned int data);
+		void (*set_data)(ice1712_t *ice, unsigned int data);
+		unsigned int (*get_data)(ice1712_t *ice);
+	} gpio;
+	struct semaphore gpio_mutex;
 };
 
 #define chip_t ice1712_t
 
 
+/*
+ * gpio access functions
+ */
+static inline void snd_ice1712_gpio_set_dir(ice1712_t *ice, unsigned int bits)
+{
+	ice->gpio.set_dir(ice, bits);
+}
+
+static inline void snd_ice1712_gpio_set_mask(ice1712_t *ice, unsigned int bits)
+{
+	ice->gpio.set_mask(ice, bits);
+}
+
+static inline void snd_ice1712_gpio_write(ice1712_t *ice, unsigned int val)
+{
+	ice->gpio.set_data(ice, val);
+}
+
+static inline unsigned int snd_ice1712_gpio_read(ice1712_t *ice)
+{
+	return ice->gpio.get_data(ice);
+}
+
+/*
+ * save and restore gpio status
+ * The access to gpio will be protected by mutex, so don't forget to
+ * restore!
+ */
+static inline void snd_ice1712_save_gpio_status(ice1712_t *ice)
+{
+	down(&ice->gpio_mutex);
+	ice->gpio.saved[0] = ice->gpio.direction;
+	ice->gpio.saved[1] = ice->gpio.write_mask;
+}
+
+static inline void snd_ice1712_restore_gpio_status(ice1712_t *ice)
+{
+	ice->gpio.set_dir(ice, ice->gpio.saved[0]);
+	ice->gpio.set_mask(ice, ice->gpio.saved[1]);
+	ice->gpio.direction = ice->gpio.saved[0];
+	ice->gpio.write_mask = ice->gpio.saved[1];
+	up(&ice->gpio_mutex);
+}
+
+/* for bit controls */
 #define ICE1712_GPIO(xiface, xname, xindex, mask, invert, xaccess) \
 { .iface = xiface, .name = xname, .access = xaccess, .info = snd_ice1712_gpio_info, \
   .get = snd_ice1712_gpio_get, .put = snd_ice1712_gpio_put, \
@@ -352,17 +426,23 @@
 int snd_ice1712_gpio_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
 int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
 
-void snd_ice1712_gpio_write_bits(ice1712_t *ice, int mask, int bits);
-void snd_ice1712_save_gpio_status(ice1712_t *ice, unsigned char *tmp);
-void snd_ice1712_restore_gpio_status(ice1712_t *ice, unsigned char *tmp);
-
+/*
+ * set gpio direction, write mask and data
+ */
+static inline void snd_ice1712_gpio_write_bits(ice1712_t *ice, unsigned int mask, unsigned int bits)
+{
+	ice->gpio.direction |= mask;
+	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
+	snd_ice1712_gpio_set_mask(ice, ~mask);
+	snd_ice1712_gpio_write(ice, mask & bits);
+}
 
 int snd_ice1712_spdif_build_controls(ice1712_t *ice);
 
-void snd_ice1712_ak4524_write(ice1712_t *ice, int chip, unsigned char addr, unsigned char data);
-void snd_ice1712_ak4524_reset(ice1712_t *ice, int state);
-void snd_ice1712_ak4524_init(ice1712_t *ice);
-int snd_ice1712_ak4524_build_controls(ice1712_t *ice);
+void snd_ice1712_akm4xxx_write(akm4xxx_t *ice, int chip, unsigned char addr, unsigned char data);
+void snd_ice1712_akm4xxx_reset(akm4xxx_t *ice, int state);
+void snd_ice1712_akm4xxx_init(akm4xxx_t *ak, const akm4xxx_t *template, ice1712_t *ice);
+int snd_ice1712_akm4xxx_build_controls(ice1712_t *ice);
 
 int snd_ice1712_init_cs8427(ice1712_t *ice, int addr);
 
diff -Nru a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/sound/pci/ice1712/ice1724.c	Thu Mar 20 08:41:20 2003
@@ -0,0 +1,1973 @@
+/*
+ *   ALSA driver for VT1724 ICEnsemble ICE1724 / VIA VT1724 (Envy24HT)
+ *
+ *	Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ *                    2002 James Stafford <jstafford@ampltd.com>
+ *                    2003 Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */      
+
+#include <sound/driver.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/mpu401.h>
+#define SNDRV_GET_ID
+#include <sound/initval.h>
+
+#include <sound/asoundef.h>
+
+#include "ice1712.h"
+#include "envy24ht.h"
+
+/* lowlevel routines */
+#include "amp.h"
+#include "revo.h"
+
+MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_DESCRIPTION("ICEnsemble ICE1724 (Envy24HT)");
+MODULE_LICENSE("GPL");
+MODULE_CLASSES("{sound}");
+MODULE_DEVICES("{"
+	       REVO_DEVICE_DESC
+	       AMP_AUDIO2000_DEVICE_DESC
+		"{VIA,VT1724},"
+		"{ICEnsemble,Generic ICE1724},"
+		"{ICEnsemble,Generic Envy24HT}}");
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;		/* Enable this card */
+
+MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(index, "Index value for ICE1724 soundcard.");
+MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
+MODULE_PARM(id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
+MODULE_PARM_DESC(id, "ID string for ICE1724 soundcard.");
+MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
+MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(enable, "Enable ICE1724 soundcard.");
+MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
+
+#ifndef PCI_VENDOR_ID_ICE
+#define PCI_VENDOR_ID_ICE		0x1412
+#endif
+#ifndef PCI_DEVICE_ID_VT1724
+#define PCI_DEVICE_ID_VT1724		0x1724
+#endif
+
+static struct pci_device_id snd_vt1724_ids[] __devinitdata = {
+	{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, snd_vt1724_ids);
+
+
+static int PRO_RATE_LOCKED = 0;
+static int PRO_RATE_RESET = 1;
+static unsigned int PRO_RATE_DEFAULT = 44100;
+
+/*
+ *  Basic I/O
+ */
+ 
+/* check whether the clock mode is spdif-in */
+static inline int is_spdif_master(ice1712_t *ice)
+{
+	return (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER) ? 1 : 0;
+}
+
+static inline int is_pro_rate_locked(ice1712_t *ice)
+{
+	return is_spdif_master(ice) || PRO_RATE_LOCKED;
+}
+
+/*
+ * ac97 section
+ */
+
+static unsigned char snd_vt1724_ac97_ready(ice1712_t *ice)
+{
+	unsigned char old_cmd;
+	int tm;
+	for (tm = 0; tm < 0x10000; tm++) {
+		old_cmd = inb(ICEMT1724(ice, AC97_CMD));
+		if (old_cmd & (VT1724_AC97_WRITE | VT1724_AC97_READ))
+			continue;
+		if (!(old_cmd & VT1724_AC97_READY))
+			continue;
+		return 0;
+	}
+	return old_cmd;
+}
+
+static int snd_vt1724_ac97_wait_bit(ice1712_t *ice, unsigned char bit)
+{
+	int tm;
+	for (tm = 0; tm < 0x10000; tm++)
+		if ((inb(ICEMT1724(ice, AC97_CMD)) & bit) == 0)
+			return 0;
+	return -EIO;
+}
+
+static void snd_vt1724_ac97_write(ac97_t *ac97,
+				  unsigned short reg,
+				  unsigned short val)
+{
+	ice1712_t *ice = (ice1712_t *)ac97->private_data;
+	unsigned char old_cmd;
+
+	old_cmd = snd_vt1724_ac97_ready(ice);
+	outb(reg, ICEMT1724(ice, AC97_INDEX));
+	outw(val, ICEMT1724(ice, AC97_DATA));
+	old_cmd &= ~(VT1724_AC97_PBK_VSR | VT1724_AC97_CAP_VSR);
+	outb(old_cmd | VT1724_AC97_WRITE, ICEMT1724(ice, AC97_CMD));
+	snd_vt1724_ac97_wait_bit(ice, VT1724_AC97_WRITE);
+}
+
+static unsigned short snd_vt1724_ac97_read(ac97_t *ac97, unsigned short reg)
+{
+	ice1712_t *ice = (ice1712_t *)ac97->private_data;
+	unsigned char old_cmd;
+
+	old_cmd = snd_vt1724_ac97_ready(ice);
+	outb(reg, ICEMT1724(ice, AC97_INDEX));
+	outb(old_cmd | VT1724_AC97_READ, ICEMT1724(ice, AC97_CMD));
+	if (snd_vt1724_ac97_wait_bit(ice, VT1724_AC97_READ) < 0)
+		return ~0;
+	return inw(ICEMT1724(ice, AC97_DATA));
+}
+
+
+/*
+ * GPIO operations
+ */
+
+/* set gpio direction 0 = read, 1 = write */
+static void snd_vt1724_set_gpio_dir(ice1712_t *ice, unsigned int data)
+{
+	outl(data, ICEREG1724(ice, GPIO_DIRECTION));
+}
+
+/* set the gpio mask (0 = writable) */
+static void snd_vt1724_set_gpio_mask(ice1712_t *ice, unsigned int data)
+{
+	outw(data, ICEREG1724(ice, GPIO_WRITE_MASK));
+	outb((data >> 16) & 0xff, ICEREG1724(ice, GPIO_WRITE_MASK_22));
+}
+
+static void snd_vt1724_set_gpio_data(ice1712_t *ice, unsigned int data)
+{
+	outw(data, ICEREG1724(ice, GPIO_DATA));
+	outb(data >> 16, ICEREG1724(ice, GPIO_DATA_22));
+}
+
+static unsigned int snd_vt1724_get_gpio_data(ice1712_t *ice)
+{
+	unsigned int data;
+	data = (unsigned int)inb(ICEREG1724(ice, GPIO_DATA_22));
+	data = (data << 16) | inw(ICEREG1724(ice, GPIO_DATA));
+	return data;
+}
+
+/*
+ *  Interrupt handler
+ */
+
+static void snd_vt1724_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	ice1712_t *ice = snd_magic_cast(ice1712_t, dev_id, return);
+	unsigned char status;
+
+	while (1) {
+		status = inb(ICEREG1724(ice, IRQSTAT));
+		if (status == 0)
+			break;
+		
+		/*  these should probably be separated at some point, 
+			but as we don't currently have MPU support on the board I will leave it */
+		if ((status & VT1724_IRQ_MPU_RX)||(status & VT1724_IRQ_MPU_TX)) {
+			if (ice->rmidi[0])
+				snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data, regs);
+			outb(VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX, ICEREG1724(ice, IRQSTAT));
+			status &= ~(VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX);
+		}
+		if (status & VT1724_IRQ_MTPCM) {
+			unsigned char mtstat = inb(ICEMT1724(ice, IRQ));
+			if (mtstat & VT1724_MULTI_PDMA0) {
+				if (ice->playback_pro_substream)
+					snd_pcm_period_elapsed(ice->playback_pro_substream);
+			}
+			if (mtstat & VT1724_MULTI_RDMA0) {
+				if (ice->capture_pro_substream)
+					snd_pcm_period_elapsed(ice->capture_pro_substream);
+			}
+			if (mtstat & VT1724_MULTI_PDMA4) {
+				if (ice->playback_con_substream)
+					snd_pcm_period_elapsed(ice->playback_con_substream);
+			}
+			if (mtstat & VT1724_MULTI_RDMA1) {
+				if (ice->capture_con_substream)
+					snd_pcm_period_elapsed(ice->capture_con_substream);
+			}
+			/* ack anyway to avoid freeze */
+			outb(mtstat, ICEMT1724(ice, IRQ));
+			/* ought to really handle this properly */
+			if (mtstat & VT1724_MULTI_FIFO_ERR) {
+				unsigned char fstat = inb(ICEMT1724(ice, DMA_FIFO_ERR));
+				outb(fstat, ICEMT1724(ice, DMA_FIFO_ERR));	
+				outb(VT1724_MULTI_FIFO_ERR | inb(ICEMT1724(ice, DMA_INT_MASK)), ICEMT1724(ice, DMA_INT_MASK));	
+				/* If I don't do this, I get machine lockup due to continual interrupts */
+			}
+
+		}
+	}
+}
+
+/*
+ *  PCM code - professional part (multitrack)
+ */
+
+static unsigned int rates[] = {
+	8000, 9600, 11025, 12000, 16000, 22050, 24000,
+	32000, 44100, 48000, 64000, 88200, 96000,
+	176400, 192000,
+};
+
+static snd_pcm_hw_constraint_list_t hw_constraints_rates_96 = {
+	.count = ARRAY_SIZE(rates) - 2, /* up to 96000 */
+	.list = rates,
+	.mask = 0,
+};
+
+static snd_pcm_hw_constraint_list_t hw_constraints_rates_192 = {
+	.count = ARRAY_SIZE(rates),
+	.list = rates,
+	.mask = 0,
+};
+
+static unsigned int hw_channels[] = {
+	2, 4, 6, 8
+};
+
+static snd_pcm_hw_constraint_list_t hw_constraints_channels = {
+	.count = ARRAY_SIZE(hw_channels),
+	.list = hw_channels,
+	.mask = 0,
+};
+
+static int snd_vt1724_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	unsigned int what;
+	unsigned int old;
+	snd_pcm_substream_t *s;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		what = 0;
+		s = substream;
+		do {
+			if (s == ice->playback_pro_substream)
+				what |= VT1724_PDMA0_PAUSE;
+			else if (s == ice->capture_pro_substream)
+				what |= VT1724_RDMA0_PAUSE;
+			else if (s == ice->playback_con_substream)
+				what |= VT1724_PDMA4_PAUSE;
+			else if (s == ice->capture_con_substream)
+				what |= VT1724_RDMA1_PAUSE;
+			s = s->link_next;
+		} while (s != substream);
+		spin_lock(&ice->reg_lock);
+		old = inl(ICEMT1724(ice, DMA_PAUSE));
+		if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
+			old |= what;
+		else
+			old &= ~what;
+		outl(old, ICEMT1724(ice, DMA_PAUSE));
+		spin_unlock(&ice->reg_lock);
+		break;
+
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_STOP:
+		what = 0;
+		s = substream;
+		do {
+			if (s == ice->playback_pro_substream) {
+				what |= VT1724_PDMA0_START;
+				snd_pcm_trigger_done(s, substream);
+			} else if (s == ice->capture_pro_substream) {
+				what |= VT1724_RDMA0_START;
+				snd_pcm_trigger_done(s, substream);
+			} else if (s == ice->playback_con_substream) {
+				what |= VT1724_PDMA4_START;
+				snd_pcm_trigger_done(s, substream);
+			} else if (s == ice->capture_con_substream) {
+				what |= VT1724_RDMA1_START;
+				snd_pcm_trigger_done(s, substream);
+			}
+			s = s->link_next;
+		} while (s != substream);
+		spin_lock(&ice->reg_lock);
+		old = inl(ICEMT1724(ice, DMA_CONTROL));
+		if (cmd == SNDRV_PCM_TRIGGER_START)
+			old |= what;
+		else
+			old &= ~what;
+		outl(old, ICEMT1724(ice, DMA_CONTROL));
+		spin_unlock(&ice->reg_lock);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/*
+ */
+
+#define DMA_STARTS	(VT1724_RDMA0_START|VT1724_PDMA0_START|VT1724_RDMA1_START|VT1724_PDMA4_START)
+#define DMA_PAUSES	(VT1724_RDMA0_PAUSE|VT1724_PDMA0_PAUSE|VT1724_RDMA1_PAUSE|VT1724_PDMA4_PAUSE)
+
+static void snd_vt1724_set_pro_rate(ice1712_t *ice, unsigned int rate, int force)
+{
+	unsigned long flags;
+	unsigned char val, old;
+	unsigned int i;
+
+	spin_lock_irqsave(&ice->reg_lock, flags);
+	if ((inb(ICEMT1724(ice, DMA_CONTROL)) & DMA_STARTS) || 
+	    (inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) {
+		/* running? we cannot change the rate now... */
+		spin_unlock_irqrestore(&ice->reg_lock, flags);
+		return;
+	}
+	if (!force && is_pro_rate_locked(ice)) {
+		spin_unlock_irqrestore(&ice->reg_lock, flags);
+		return;
+	}
+
+	if (rate == ice->cur_rate) {
+		spin_unlock_irqrestore(&ice->reg_lock, flags);
+		return;
+	}
+
+	switch (rate) {
+	case 8000: val = 6; break;
+	case 9600: val = 3; break;
+	case 11025: val = 10; break;
+	case 12000: val = 2; break;
+	case 16000: val = 5; break;
+	case 22050: val = 9; break;
+	case 24000: val = 1; break;
+	case 32000: val = 4; break;
+	case 44100: val = 8; break;
+	case 48000: val = 0; break;
+	case 64000: val = 15; break;
+	case 88200: val = 11; break;
+	case 96000: val = 7; break;
+	case 176400: val = 12; break;
+	case 192000: val = 14; break;
+	default:
+		snd_BUG();
+		val = 0;
+		break;
+	}
+	outb(val, ICEMT1724(ice, RATE));
+	ice->cur_rate = rate;
+
+	/* check MT02 */
+	if (ice->eeprom.data[ICE_EEP2_ACLINK] & 0x80) {
+		val = old = inb(ICEMT1724(ice, I2S_FORMAT));
+		if (rate > 96000)
+			val |= VT1724_MT_I2S_MCLK_128X; /* 128x MCLK */
+		else
+			val &= ~VT1724_MT_I2S_MCLK_128X; /* 256x MCLK */
+		if (val != old) {
+			outb(val, ICEMT1724(ice, I2S_FORMAT));
+			/* FIXME: is this revo only? */
+			/* assert PRST# to converters; MT05 bit 7 */
+			outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
+			spin_unlock_irqrestore(&ice->reg_lock, flags);
+			mdelay(5);
+			spin_lock_irqsave(&ice->reg_lock, flags);
+			/* deassert PRST# */
+			outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
+		}
+	}
+	spin_unlock_irqrestore(&ice->reg_lock, flags);
+
+	/* set up codecs */
+	for (i = 0; i < ice->akm_codecs; i++) {
+		if (ice->akm[i].ops.set_rate_val)
+			ice->akm[i].ops.set_rate_val(&ice->akm[i], rate);
+	}
+}
+
+static int snd_vt1724_pcm_hw_params(snd_pcm_substream_t * substream,
+				    snd_pcm_hw_params_t * hw_params)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+
+	snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0);
+	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+}
+
+static int snd_vt1724_pcm_hw_free(snd_pcm_substream_t * substream)
+{
+	return snd_pcm_lib_free_pages(substream);
+}
+
+static int snd_vt1724_playback_pro_prepare(snd_pcm_substream_t * substream)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	unsigned char val;
+	unsigned int size;
+
+	spin_lock(&ice->reg_lock);
+	val = (8 - substream->runtime->channels) >> 1;
+	outb(val, ICEMT1724(ice, BURST));
+
+	outl(substream->runtime->dma_addr, ICEMT1724(ice, PLAYBACK_ADDR));
+
+	size = (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1;
+	// outl(size, ICEMT1724(ice, PLAYBACK_SIZE));
+	outw(size, ICEMT1724(ice, PLAYBACK_SIZE));
+	outb(size >> 16, ICEMT1724(ice, PLAYBACK_SIZE) + 2);
+	size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
+	// outl(size, ICEMT1724(ice, PLAYBACK_COUNT));
+	outw(size, ICEMT1724(ice, PLAYBACK_COUNT));
+	outb(size >> 16, ICEMT1724(ice, PLAYBACK_COUNT) + 2);
+
+	spin_unlock(&ice->reg_lock);
+
+	// printk("pro prepare: ch = %d, addr = 0x%x, buffer = 0x%x, period = 0x%x\n", substream->runtime->channels, (unsigned int)substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream));
+	return 0;
+}
+
+#define CHECK_INVALID_PTR
+
+static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(snd_pcm_substream_t * substream)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	size_t ptr;
+
+	if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & VT1724_PDMA0_START))
+		return 0;
+	ptr = inl(ICEMT1724(ice, PLAYBACK_ADDR));
+#ifdef CHECK_INVALID_PTR
+	if (ptr < substream->runtime->dma_addr) {
+		snd_printd("ice1724: invalid negative ptr\n");
+		return 0;
+	}
+#endif
+	ptr -= substream->runtime->dma_addr;
+	ptr = bytes_to_frames(substream->runtime, ptr);
+#ifdef CHECK_INVALID_PTR
+	if (ptr >= substream->runtime->buffer_size) {
+		snd_printd("ice1724: invalid ptr %d (size=%d)\n", (int)ptr, (int)substream->runtime->period_size);
+		return 0;
+	}
+#endif
+	return ptr;
+}
+
+struct vt1724_pcm_reg {
+	unsigned int addr;	/* ADDR register offset */
+	unsigned int size;	/* SIZE register offset */
+	unsigned int count;	/* COUNT register offset */
+	unsigned int start;	/* start bit */
+	unsigned int pause;	/* pause bit */
+};
+
+static int snd_vt1724_pcm_prepare(snd_pcm_substream_t *substream, const struct vt1724_pcm_reg *reg)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+
+	spin_lock(&ice->reg_lock);
+	outl(substream->runtime->dma_addr, ice->profi_port + reg->addr);
+	outw((snd_pcm_lib_buffer_bytes(substream) >> 2) - 1, ice->profi_port + reg->size);
+	outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ice->profi_port + reg->count);
+	spin_unlock(&ice->reg_lock);
+	return 0;
+}
+
+static snd_pcm_uframes_t snd_vt1724_pcm_pointer(snd_pcm_substream_t *substream, const struct vt1724_pcm_reg *reg)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	size_t ptr;
+
+	if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & reg->start))
+		return 0;
+	ptr = inl(ice->profi_port + reg->addr);
+	ptr -= substream->runtime->dma_addr;
+	return bytes_to_frames(substream->runtime, ptr);
+}
+
+const static struct vt1724_pcm_reg vt1724_capture_pro_reg = {
+	.addr = VT1724_MT_CAPTURE_ADDR,
+	.size = VT1724_MT_CAPTURE_SIZE,
+	.count = VT1724_MT_CAPTURE_COUNT,
+	.start = VT1724_RDMA0_START,
+	.pause = VT1724_RDMA0_PAUSE,
+};
+
+static int snd_vt1724_capture_pro_prepare(snd_pcm_substream_t * substream)
+{
+	return snd_vt1724_pcm_prepare(substream, &vt1724_capture_pro_reg);
+}
+
+static snd_pcm_uframes_t snd_vt1724_capture_pro_pointer(snd_pcm_substream_t * substream)
+{
+	return snd_vt1724_pcm_pointer(substream, &vt1724_capture_pro_reg);
+}
+
+static snd_pcm_hardware_t snd_vt1724_playback_pro =
+{
+	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_MMAP_VALID |
+				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
+	.formats =		SNDRV_PCM_FMTBIT_S32_LE,
+	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,
+	.rate_min =		4000,
+	.rate_max =		192000,
+	.channels_min =		2,
+	.channels_max =		8,
+	.buffer_bytes_max =	(1UL << 21),	/* 18bits dword */
+	.period_bytes_min =	8 * 4 * 2,	/* FIXME: constraints needed */
+	.period_bytes_max =	(1UL << 21),
+	.periods_min =		1,
+	.periods_max =		1024,
+};
+
+static snd_pcm_hardware_t snd_vt1724_capture_pro =
+{
+	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_MMAP_VALID |
+				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
+	.formats =		SNDRV_PCM_FMTBIT_S32_LE,
+	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,
+	.rate_min =		4000,
+	.rate_max =		192000,
+	.channels_min =		2,
+	.channels_max =		2,
+	.buffer_bytes_max =	(256*1024),
+	.period_bytes_min =	2 * 4 * 2,
+	.period_bytes_max =	(256*1024),
+	.periods_min =		1,
+	.periods_max =		1024,
+};
+
+/* multi-channel playback needs alignment 8x32bit regarless of the channels
+ * actually used
+ */
+#define VT1724_BUFFER_ALIGN	0x20
+
+static int snd_vt1724_playback_pro_open(snd_pcm_substream_t * substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+
+	ice->playback_pro_substream = substream;
+	runtime->hw = snd_vt1724_playback_pro;
+	snd_pcm_set_sync(substream);
+	snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+	if ((ice->eeprom.data[ICE_EEP2_ACLINK] & 0x80) &&
+	    (ice->eeprom.data[ICE_EEP2_I2S] & 0x08))
+		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_192);
+	else
+		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_96);
+
+	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels);
+	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
+				   VT1724_BUFFER_ALIGN);
+	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+				   VT1724_BUFFER_ALIGN);
+	return 0;
+}
+
+static int snd_vt1724_capture_pro_open(snd_pcm_substream_t * substream)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+
+	ice->capture_pro_substream = substream;
+	runtime->hw = snd_vt1724_capture_pro;
+	snd_pcm_set_sync(substream);
+	snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+	if ((ice->eeprom.data[ICE_EEP2_ACLINK] & 0x80) &&
+	    (ice->eeprom.data[ICE_EEP2_I2S] & 0x08))
+		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_192);
+	else
+		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_96);
+	return 0;
+}
+
+static int snd_vt1724_playback_pro_close(snd_pcm_substream_t * substream)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+
+	if (PRO_RATE_RESET)
+		snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
+	ice->playback_pro_substream = NULL;
+
+	return 0;
+}
+
+static int snd_vt1724_capture_pro_close(snd_pcm_substream_t * substream)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+
+	if (PRO_RATE_RESET)
+		snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
+	ice->capture_pro_substream = NULL;
+	return 0;
+}
+
+static snd_pcm_ops_t snd_vt1724_playback_pro_ops = {
+	.open =		snd_vt1724_playback_pro_open,
+	.close =	snd_vt1724_playback_pro_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_vt1724_pcm_hw_params,
+	.hw_free =	snd_vt1724_pcm_hw_free,
+	.prepare =	snd_vt1724_playback_pro_prepare,
+	.trigger =	snd_vt1724_pcm_trigger,
+	.pointer =	snd_vt1724_playback_pro_pointer,
+};
+
+static snd_pcm_ops_t snd_vt1724_capture_pro_ops = {
+	.open =		snd_vt1724_capture_pro_open,
+	.close =	snd_vt1724_capture_pro_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_vt1724_pcm_hw_params,
+	.hw_free =	snd_vt1724_pcm_hw_free,
+	.prepare =	snd_vt1724_capture_pro_prepare,
+	.trigger =	snd_vt1724_pcm_trigger,
+	.pointer =	snd_vt1724_capture_pro_pointer,
+};
+
+static int __devinit snd_vt1724_pcm_profi(ice1712_t * ice, int device)
+{
+	snd_pcm_t *pcm;
+	int err;
+
+	err = snd_pcm_new(ice->card, "ICE1724", device, 1, 1, &pcm);
+	if (err < 0)
+		return err;
+
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_vt1724_playback_pro_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_vt1724_capture_pro_ops);
+
+	pcm->private_data = ice;
+	pcm->info_flags = 0;
+	strcpy(pcm->name, "ICE1724");
+
+	snd_pcm_lib_preallocate_pci_pages_for_all(ice->pci, pcm, 256*1024, 256*1024);
+
+	ice->pcm_pro = pcm;
+
+	return 0;
+}
+
+
+/*
+ * SPDIF PCM
+ */
+
+static snd_pcm_hardware_t snd_vt1724_playback_spdif =
+{
+	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_MMAP_VALID |
+				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
+	.formats =		SNDRV_PCM_FMTBIT_S32_LE,
+	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,
+	.rate_min =		4000,
+	.rate_max =		192000,
+	.channels_min =		2,
+	.channels_max =		2,
+	.buffer_bytes_max =	(256*1024),
+	.period_bytes_min =	2 * 4 * 2,
+	.period_bytes_max =	(256*1024),
+	.periods_min =		1,
+	.periods_max =		1024,
+};
+
+const static struct vt1724_pcm_reg vt1724_playback_spdif_reg = {
+	.addr = VT1724_MT_PDMA4_ADDR,
+	.size = VT1724_MT_PDMA4_SIZE,
+	.count = VT1724_MT_PDMA4_COUNT,
+	.start = VT1724_PDMA4_START,
+	.pause = VT1724_PDMA4_PAUSE,
+};
+
+const static struct vt1724_pcm_reg vt1724_capture_spdif_reg = {
+	.addr = VT1724_MT_RDMA1_ADDR,
+	.size = VT1724_MT_RDMA1_SIZE,
+	.count = VT1724_MT_RDMA1_COUNT,
+	.start = VT1724_RDMA1_START,
+	.pause = VT1724_RDMA1_PAUSE,
+};
+
+static int snd_vt1724_playback_spdif_prepare(snd_pcm_substream_t * substream)
+{
+	return snd_vt1724_pcm_prepare(substream, &vt1724_playback_spdif_reg);
+}
+
+static snd_pcm_uframes_t snd_vt1724_playback_spdif_pointer(snd_pcm_substream_t * substream)
+{
+	return snd_vt1724_pcm_pointer(substream, &vt1724_playback_spdif_reg);
+}
+
+static int snd_vt1724_capture_spdif_prepare(snd_pcm_substream_t * substream)
+{
+	return snd_vt1724_pcm_prepare(substream, &vt1724_capture_spdif_reg);
+}
+
+static snd_pcm_uframes_t snd_vt1724_capture_spdif_pointer(snd_pcm_substream_t * substream)
+{
+	return snd_vt1724_pcm_pointer(substream, &vt1724_capture_spdif_reg);
+}
+
+static int snd_vt1724_playback_spdif_open(snd_pcm_substream_t *substream)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+
+	ice->playback_con_substream = substream;
+	runtime->hw = snd_vt1724_playback_spdif;
+	snd_pcm_set_sync(substream);
+	snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+
+	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_96);
+	return 0;
+}
+
+static int snd_vt1724_playback_spdif_close(snd_pcm_substream_t * substream)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+
+	if (PRO_RATE_RESET)
+		snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
+	ice->playback_con_substream = NULL;
+
+	return 0;
+}
+
+static int snd_vt1724_capture_spdif_open(snd_pcm_substream_t *substream)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+
+	ice->capture_con_substream = substream;
+	runtime->hw = snd_vt1724_playback_spdif;
+	snd_pcm_set_sync(substream);
+	snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_96);
+	return 0;
+}
+
+static int snd_vt1724_capture_spdif_close(snd_pcm_substream_t * substream)
+{
+	ice1712_t *ice = snd_pcm_substream_chip(substream);
+
+	if (PRO_RATE_RESET)
+		snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
+	ice->capture_con_substream = NULL;
+
+	return 0;
+}
+
+static snd_pcm_ops_t snd_vt1724_playback_spdif_ops = {
+	.open =		snd_vt1724_playback_spdif_open,
+	.close =	snd_vt1724_playback_spdif_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_vt1724_pcm_hw_params,
+	.hw_free =	snd_vt1724_pcm_hw_free,
+	.prepare =	snd_vt1724_playback_spdif_prepare,
+	.trigger =	snd_vt1724_pcm_trigger,
+	.pointer =	snd_vt1724_playback_spdif_pointer,
+};
+
+static snd_pcm_ops_t snd_vt1724_capture_spdif_ops = {
+	.open =		snd_vt1724_capture_spdif_open,
+	.close =	snd_vt1724_capture_spdif_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_vt1724_pcm_hw_params,
+	.hw_free =	snd_vt1724_pcm_hw_free,
+	.prepare =	snd_vt1724_capture_spdif_prepare,
+	.trigger =	snd_vt1724_pcm_trigger,
+	.pointer =	snd_vt1724_capture_spdif_pointer,
+};
+
+
+static int __devinit snd_vt1724_pcm_spdif(ice1712_t * ice, int device)
+{
+	snd_pcm_t *pcm;
+	int play, capt;
+	int err;
+
+	if (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_OUT_INT)
+		play = 1;
+	else
+		play = 0;
+	if (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_IN)
+		capt = 1;
+	else
+		capt = 0;
+	if (! play && ! capt)
+		return 0; /* no spdif device */
+
+	err = snd_pcm_new(ice->card, "ICE1724 IEC958", device, play, capt, &pcm);
+	if (err < 0)
+		return err;
+
+	if (play)
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				&snd_vt1724_playback_spdif_ops);
+	if (capt)
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+				&snd_vt1724_capture_spdif_ops);
+
+	pcm->private_data = ice;
+	pcm->info_flags = 0;
+	strcpy(pcm->name, "ICE1724 IEC958");
+
+	snd_pcm_lib_preallocate_pci_pages_for_all(ice->pci, pcm, 64*1024, 64*1024);
+
+	ice->pcm = pcm;
+
+	return 0;
+}
+
+
+/*
+ *  Mixer section
+ */
+
+static int __devinit snd_vt1724_ac97_mixer(ice1712_t * ice)
+{
+	int err;
+
+	if (! (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S)) {
+		ac97_t ac97;
+		memset(&ac97, 0, sizeof(ac97));
+		ac97.write = snd_vt1724_ac97_write;
+		ac97.read = snd_vt1724_ac97_read;
+		ac97.private_data = ice;
+		if ((err = snd_ac97_mixer(ice->card, &ac97, &ice->ac97)) < 0)
+			printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");
+		else
+			return 0;
+	}
+	/* I2S mixer only */
+	strcat(ice->card->mixername, "ICE1724 - multitrack");
+	return 0;
+}
+
+/*
+ *
+ */
+
+static inline unsigned int eeprom_triple(ice1712_t *ice, int idx)
+{
+	return (unsigned int)ice->eeprom.data[idx] | \
+		((unsigned int)ice->eeprom.data[idx + 1] << 8) | \
+		((unsigned int)ice->eeprom.data[idx + 2] << 16);
+}
+
+static void snd_vt1724_proc_read(snd_info_entry_t *entry, 
+				 snd_info_buffer_t * buffer)
+{
+	ice1712_t *ice = snd_magic_cast(ice1712_t, entry->private_data, return);
+	unsigned int idx;
+
+	snd_iprintf(buffer, "%s\n\n", ice->card->longname);
+	snd_iprintf(buffer, "EEPROM:\n");
+
+	snd_iprintf(buffer, "  Subvendor        : 0x%x\n", ice->eeprom.subvendor);
+	snd_iprintf(buffer, "  Size             : %i bytes\n", ice->eeprom.size);
+	snd_iprintf(buffer, "  Version          : %i\n", ice->eeprom.version);
+	snd_iprintf(buffer, "  System Config    : 0x%x\n", ice->eeprom.data[ICE_EEP2_SYSCONF]);
+	snd_iprintf(buffer, "  ACLink           : 0x%x\n", ice->eeprom.data[ICE_EEP2_ACLINK]);
+	snd_iprintf(buffer, "  I2S              : 0x%x\n", ice->eeprom.data[ICE_EEP2_I2S]);
+	snd_iprintf(buffer, "  S/PDIF           : 0x%x\n", ice->eeprom.data[ICE_EEP2_SPDIF]);
+	snd_iprintf(buffer, "  GPIO direction   : 0x%x\n", ice->eeprom.gpiodir);
+	snd_iprintf(buffer, "  GPIO mask        : 0x%x\n", ice->eeprom.gpiomask);
+	snd_iprintf(buffer, "  GPIO state       : 0x%x\n", ice->eeprom.gpiostate);
+	for (idx = 0x12; idx < ice->eeprom.size; idx++)
+		snd_iprintf(buffer, "  Extra #%02i        : 0x%x\n", idx, ice->eeprom.data[idx]);
+
+	snd_iprintf(buffer, "\nRegisters:\n");
+
+	snd_iprintf(buffer, "  PSDOUT03 : 0x%08x\n", (unsigned)inl(ICEMT1724(ice, ROUTE_PLAYBACK)));
+	for (idx = 0x0; idx < 0x20 ; idx++)
+		snd_iprintf(buffer, "  CCS%02x    : 0x%02x\n", idx, inb(ice->port+idx));
+	for (idx = 0x0; idx < 0x30 ; idx++)
+		snd_iprintf(buffer, "  MT%02x     : 0x%02x\n", idx, inb(ice->profi_port+idx));
+}
+
+static void __devinit snd_vt1724_proc_init(ice1712_t * ice)
+{
+	snd_info_entry_t *entry;
+
+	if (! snd_card_proc_new(ice->card, "ice1724", &entry))
+		snd_info_set_text_ops(entry, ice, snd_vt1724_proc_read);
+}
+
+/*
+ *
+ */
+
+static int snd_vt1724_eeprom_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+	uinfo->count = sizeof(ice1712_eeprom_t);
+	return 0;
+}
+
+static int snd_vt1724_eeprom_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	
+	memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
+	return 0;
+}
+
+static snd_kcontrol_new_t snd_vt1724_eeprom __devinitdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
+	.name = "ICE1724 EEPROM",
+	.access = SNDRV_CTL_ELEM_ACCESS_READ,
+	.info = snd_vt1724_eeprom_info,
+	.get = snd_vt1724_eeprom_get
+};
+
+/*
+ */
+static int snd_vt1724_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+	uinfo->count = 1;
+	return 0;
+}
+
+static unsigned int encode_spdif_bits(snd_aes_iec958_t *diga)
+{
+	unsigned int val;
+
+	val = diga->status[0] & 0x03; /* professional, non-audio */
+	if (val & 0x01) {
+		/* professional */
+		if ((diga->status[0] & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
+			val |= 1U << 3;
+		switch (diga->status[0] & IEC958_AES0_PRO_FS) {
+		case IEC958_AES0_PRO_FS_44100:
+			break;
+		case IEC958_AES0_PRO_FS_32000:
+			val |= 3U << 12;
+			break;
+		default:
+			val |= 2U << 12;
+			break;
+		}
+	} else {
+		/* consumer */
+		val |= diga->status[0] & 0x04; /* copyright */
+		if ((diga->status[0] & IEC958_AES0_CON_EMPHASIS)== IEC958_AES0_CON_EMPHASIS_5015)
+			val |= 1U << 3;
+		val |= (unsigned int)(diga->status[1] & 0x3f) << 4; /* category */
+		val |= (unsigned int)(diga->status[3] & IEC958_AES3_CON_FS) << 12; /* fs */
+	}
+	return val;
+}
+
+static void decode_spdif_bits(snd_aes_iec958_t *diga, unsigned int val)
+{
+	memset(diga->status, 0, sizeof(diga->status));
+	diga->status[0] = val & 0x03; /* professional, non-audio */
+	if (val & 0x01) {
+		/* professional */
+		if (val & (1U << 3))
+			diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015;
+		switch ((val >> 12) & 0x7) {
+		case 0:
+			break;
+		case 2:
+			diga->status[0] |= IEC958_AES0_PRO_FS_32000;
+			break;
+		default:
+			diga->status[0] |= IEC958_AES0_PRO_FS_48000;
+			break;
+		}
+	} else {
+		/* consumer */
+		diga->status[0] |= val & (1U << 2); /* copyright */
+		if (val & (1U << 3))
+			diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015;
+		diga->status[1] |= (val >> 4) & 0x3f; /* category */
+		diga->status[3] |= (val >> 12) & 0x07; /* fs */
+	}
+}
+
+static int snd_vt1724_spdif_default_get(snd_kcontrol_t * kcontrol,
+					snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned int val;
+	val = inw(ICEMT1724(ice, SPDIF_CTRL));
+	decode_spdif_bits(&ucontrol->value.iec958, val);
+	return 0;
+}
+
+static int snd_vt1724_spdif_default_put(snd_kcontrol_t * kcontrol,
+					 snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned int val, old;
+	unsigned long flags;
+
+	val = encode_spdif_bits(&ucontrol->value.iec958);
+	spin_lock_irqsave(&ice->reg_lock, flags);
+	old = inw(ICEMT1724(ice, SPDIF_CTRL));
+	if (val != old) {
+		unsigned char cbit, disabled;
+		cbit = inb(ICEREG1724(ice, SPDIF_CFG));
+		disabled = cbit & ~VT1724_CFG_SPDIF_OUT_EN;
+		if (cbit != disabled)
+			outb(disabled, ICEREG1724(ice, SPDIF_CFG));
+		outw(val, ICEMT1724(ice, SPDIF_CTRL));
+		if (cbit != disabled)
+			outb(cbit, ICEREG1724(ice, SPDIF_CFG));
+	}
+	spin_unlock_irqrestore(&ice->reg_lock, flags);
+	return (val != old);
+}
+
+static snd_kcontrol_new_t snd_vt1724_spdif_default __devinitdata =
+{
+	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
+	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+	.info =		snd_vt1724_spdif_info,
+	.get =		snd_vt1724_spdif_default_get,
+	.put =		snd_vt1724_spdif_default_put
+};
+
+static int snd_vt1724_spdif_maskc_get(snd_kcontrol_t * kcontrol,
+				       snd_ctl_elem_value_t * ucontrol)
+{
+	ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
+						     IEC958_AES0_PROFESSIONAL |
+						     IEC958_AES0_CON_NOT_COPYRIGHT |
+						     IEC958_AES0_CON_EMPHASIS;
+	ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL |
+						     IEC958_AES1_CON_CATEGORY;
+	ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
+	return 0;
+}
+
+static int snd_vt1724_spdif_maskp_get(snd_kcontrol_t * kcontrol,
+				       snd_ctl_elem_value_t * ucontrol)
+{
+	ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
+						     IEC958_AES0_PROFESSIONAL |
+						     IEC958_AES0_PRO_FS |
+						     IEC958_AES0_PRO_EMPHASIS;
+	return 0;
+}
+
+static snd_kcontrol_new_t snd_vt1724_spdif_maskc __devinitdata =
+{
+	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
+	.info =		snd_vt1724_spdif_info,
+	.get =		snd_vt1724_spdif_maskc_get,
+};
+
+static snd_kcontrol_new_t snd_vt1724_spdif_maskp __devinitdata =
+{
+	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
+	.info =		snd_vt1724_spdif_info,
+	.get =		snd_vt1724_spdif_maskp_get,
+};
+
+static int snd_vt1724_spdif_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_vt1724_spdif_sw_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.integer.value[0] = inb(ICEREG1724(ice, SPDIF_CFG)) & VT1724_CFG_SPDIF_OUT_EN ? 1 : 0;
+	return 0;
+}
+
+static int snd_vt1724_spdif_sw_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned char old, val;
+	unsigned long flags;
+	spin_lock_irqsave(&ice->reg_lock, flags);
+	old = val = inb(ICEREG1724(ice, SPDIF_CFG));
+	val &= ~VT1724_CFG_SPDIF_OUT_EN;
+	if (ucontrol->value.integer.value[0])
+		val |= VT1724_CFG_SPDIF_OUT_EN;
+	if (old != val)
+		outb(val, ICEREG1724(ice, SPDIF_CFG));
+	spin_unlock_irqrestore(&ice->reg_lock, flags);
+	return old != val;
+}
+
+static snd_kcontrol_new_t snd_vt1724_spdif_switch __devinitdata =
+{
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	/* FIXME: the following conflict with IEC958 Playback Route */
+	// .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
+	.name =         "IEC958 Output Switch",
+	.info =		snd_vt1724_spdif_sw_info,
+	.get =		snd_vt1724_spdif_sw_get,
+	.put =		snd_vt1724_spdif_sw_put
+};
+
+
+#if 0 /* NOT USED YET */
+/*
+ * GPIO access from extern
+ */
+
+int snd_vt1724_gpio_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+int snd_vt1724_gpio_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int shift = kcontrol->private_value & 0xff;
+	int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
+	
+	snd_ice1712_save_gpio_status(ice);
+	ucontrol->value.integer.value[0] = (snd_ice1712_gpio_read(ice) & (1 << shift) ? 1 : 0) ^ invert;
+	snd_ice1712_restore_gpio_status(ice);
+	return 0;
+}
+
+int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int shift = kcontrol->private_value & 0xff;
+	int invert = (kcontrol->private_value & (1<<24)) ? mask : 0;
+	unsigned int val, nval;
+
+	if (kcontrol->private_value & (1 << 31))
+		return -EPERM;
+	nval = (ucontrol->value.integer.value[0] ? (1 << shift) : 0) ^ invert;
+	snd_ice1712_save_gpio_status(ice);
+	val = snd_ice1712_gpio_read(ice);
+	nval |= val & ~(1 << shift);
+	if (val != nval)
+		snd_ice1712_gpio_write(ice, nval);
+	snd_ice1712_restore_gpio_status(ice);
+	return val != nval;
+}
+#endif /* NOT USED YET */
+
+/*
+ *  rate
+ */
+static int snd_vt1724_pro_internal_clock_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[] = {
+		"8000",		/* 0: 6 */
+		"9600",		/* 1: 3 */
+		"11025",	/* 2: 10 */
+		"12000",	/* 3: 2 */
+		"16000",	/* 4: 5 */
+		"22050",	/* 5: 9 */
+		"24000",	/* 6: 1 */
+		"32000",	/* 7: 4 */
+		"44100",	/* 8: 8 */
+		"48000",	/* 9: 0 */
+		"64000",	/* 10: 15 */
+		"88200",	/* 11: 11 */
+		"96000",	/* 12: 7 */
+		"176400",	/* 13: 12 */
+		"192000",	/* 14: 14 */
+		"IEC958 Input",	/* 15: -- */
+	};
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 16;
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_vt1724_pro_internal_clock_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	static unsigned char xlate[16] = {
+		9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 13, 255, 14, 10
+	};
+	unsigned char val;
+	
+	spin_lock_irq(&ice->reg_lock);
+	if (is_spdif_master(ice)) {
+		ucontrol->value.enumerated.item[0] = 15;
+	} else {
+		val = xlate[inb(ICEMT1724(ice, RATE)) & 15];
+		if (val == 255) {
+			snd_BUG();
+			val = 0;
+		}
+		ucontrol->value.enumerated.item[0] = val;
+	}
+	spin_unlock_irq(&ice->reg_lock);
+	return 0;
+}
+
+static int snd_vt1724_pro_internal_clock_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned char oval;
+	int change = 0;
+
+	spin_lock_irq(&ice->reg_lock);
+	oval = inb(ICEMT1724(ice, RATE));
+	if (ucontrol->value.enumerated.item[0] == 15) {
+		outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));
+	} else {
+		PRO_RATE_DEFAULT = rates[ucontrol->value.integer.value[0] % 15];
+		spin_unlock_irq(&ice->reg_lock);
+		snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 1);
+		spin_lock_irq(&ice->reg_lock);
+	}
+	change = inb(ICEMT1724(ice, RATE)) != oval;
+	spin_unlock_irq(&ice->reg_lock);
+
+	if ((oval & VT1724_SPDIF_MASTER) != (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER)) {
+		/* notify akm chips as well */
+		if (is_spdif_master(ice)) {
+			unsigned int i;
+			for (i = 0; i < ice->akm_codecs; i++) {
+				if (ice->akm[i].ops.set_rate_val)
+					ice->akm[i].ops.set_rate_val(&ice->akm[i], 0);
+			}
+		}
+	}
+	return change;
+}
+
+static snd_kcontrol_new_t snd_vt1724_pro_internal_clock = __devinitdata {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Multi Track Internal Clock",
+	.info = snd_vt1724_pro_internal_clock_info,
+	.get = snd_vt1724_pro_internal_clock_get,
+	.put = snd_vt1724_pro_internal_clock_put
+};
+
+static int snd_vt1724_pro_rate_locking_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_vt1724_pro_rate_locking_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ucontrol->value.integer.value[0] = PRO_RATE_LOCKED;
+	return 0;
+}
+
+static int snd_vt1724_pro_rate_locking_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int change = 0, nval;
+
+	nval = ucontrol->value.integer.value[0] ? 1 : 0;
+	spin_lock_irq(&ice->reg_lock);
+	change = PRO_RATE_LOCKED != nval;
+	PRO_RATE_LOCKED = nval;
+	spin_unlock_irq(&ice->reg_lock);
+	return change;
+}
+
+static snd_kcontrol_new_t snd_vt1724_pro_rate_locking __devinitdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Multi Track Rate Locking",
+	.info = snd_vt1724_pro_rate_locking_info,
+	.get = snd_vt1724_pro_rate_locking_get,
+	.put = snd_vt1724_pro_rate_locking_put
+};
+
+static int snd_vt1724_pro_rate_reset_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_vt1724_pro_rate_reset_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ucontrol->value.integer.value[0] = PRO_RATE_RESET ? 1 : 0;
+	return 0;
+}
+
+static int snd_vt1724_pro_rate_reset_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int change = 0, nval;
+
+	nval = ucontrol->value.integer.value[0] ? 1 : 0;
+	spin_lock_irq(&ice->reg_lock);
+	change = PRO_RATE_RESET != nval;
+	PRO_RATE_RESET = nval;
+	spin_unlock_irq(&ice->reg_lock);
+	return change;
+}
+
+static snd_kcontrol_new_t snd_vt1724_pro_rate_reset __devinitdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Multi Track Rate Reset",
+	.info = snd_vt1724_pro_rate_reset_info,
+	.get = snd_vt1724_pro_rate_reset_get,
+	.put = snd_vt1724_pro_rate_reset_put
+};
+
+
+/*
+ * routing
+ */
+static int snd_vt1724_pro_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[] = {
+		"PCM Out", /* 0 */
+		"H/W In 0", "H/W In 1", /* 1-2 */
+		"IEC958 In L", "IEC958 In R", /* 3-4 */
+	};
+	
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 5;
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static inline int analog_route_shift(int idx)
+{
+	return (idx % 2) * 12 + ((idx / 2) * 3) + 8;
+}
+
+static inline int digital_route_shift(int idx)
+{
+	return idx * 3;
+}
+
+static int get_route_val(ice1712_t *ice, int shift)
+{
+	unsigned long val;
+	unsigned char eitem;
+	static unsigned char xlate[8] = {
+		0, 255, 1, 2, 255, 255, 3, 4,
+	};
+
+	val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
+	val >>= shift;
+	val &= 7;	//we now have 3 bits per output
+	eitem = xlate[val];
+	if (eitem == 255) {
+		snd_BUG();
+		return 0;
+	}
+	return eitem;
+}
+
+static int put_route_val(ice1712_t *ice, unsigned int val, int shift)
+{
+	unsigned int old_val, nval;
+	int change;
+	static unsigned char xroute[8] = {
+		0, /* PCM */
+		2, /* PSDIN0 Left */
+		3, /* PSDIN0 Right */
+		6, /* SPDIN Left */
+		7, /* SPDIN Right */
+	};
+
+	nval = xroute[val % 5];
+	val = old_val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
+	val &= ~(0x07 << shift);
+	val |= nval << shift;
+	change = val != old_val;
+	if (change)
+		outl(val, ICEMT1724(ice, ROUTE_PLAYBACK));
+	return change;
+}
+
+static int snd_vt1724_pro_route_analog_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int idx = kcontrol->id.index;
+	ucontrol->value.enumerated.item[0] = get_route_val(ice, analog_route_shift(idx));
+	return 0;
+}
+
+static int snd_vt1724_pro_route_analog_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int idx = kcontrol->id.index;
+	return put_route_val(ice, ucontrol->value.enumerated.item[0],
+			     analog_route_shift(idx));
+}
+
+static int snd_vt1724_pro_route_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int idx = kcontrol->id.index;
+	ucontrol->value.enumerated.item[0] = get_route_val(ice, digital_route_shift(idx));
+	return 0;
+}
+
+static int snd_vt1724_pro_route_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int idx = kcontrol->id.index;
+	return put_route_val(ice, ucontrol->value.enumerated.item[0],
+			     digital_route_shift(idx));
+}
+
+static snd_kcontrol_new_t snd_vt1724_mixer_pro_analog_route __devinitdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "H/W Playback Route",
+	.info = snd_vt1724_pro_route_info,
+	.get = snd_vt1724_pro_route_analog_get,
+	.put = snd_vt1724_pro_route_analog_put,
+};
+
+static snd_kcontrol_new_t snd_vt1724_mixer_pro_spdif_route __devinitdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "IEC958 Playback Route",
+	.info = snd_vt1724_pro_route_info,
+	.get = snd_vt1724_pro_route_spdif_get,
+	.put = snd_vt1724_pro_route_spdif_put,
+};
+
+
+static int snd_vt1724_pro_peak_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 22; /* FIXME: for compatibility with ice1712... */
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 255;
+	return 0;
+}
+
+static int snd_vt1724_pro_peak_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int idx;
+	
+	spin_lock_irq(&ice->reg_lock);
+	for (idx = 0; idx < 22; idx++) {
+		outb(idx, ICEMT1724(ice, MONITOR_PEAKINDEX));
+		ucontrol->value.integer.value[idx] = inb(ICEMT1724(ice, MONITOR_PEAKDATA));
+	}
+	spin_unlock_irq(&ice->reg_lock);
+	return 0;
+}
+
+static snd_kcontrol_new_t snd_vt1724_mixer_pro_peak __devinitdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Multi Track Peak",
+	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+	.info = snd_vt1724_pro_peak_info,
+	.get = snd_vt1724_pro_peak_get
+};
+
+/*
+ *
+ */
+
+static unsigned char __devinit snd_vt1724_read_i2c(ice1712_t *ice,
+						 unsigned char dev,
+						 unsigned char addr)
+{
+	long t = 0x10000;
+
+	outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));
+	outb(dev & ~VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
+	while (t-- > 0 && (inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_BUSY)) ;
+	return inb(ICEREG1724(ice, I2C_DATA));
+}
+
+static int __devinit snd_vt1724_read_eeprom(ice1712_t *ice)
+{
+	int dev = 0xa0;		/* EEPROM device address */
+	unsigned int i;
+
+	if ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_EEPROM) == 0) {
+		snd_printk("ICE1724 has not detected EEPROM\n");
+		return -EIO;
+	}
+	ice->eeprom.subvendor = (snd_vt1724_read_i2c(ice, dev, 0x00) << 0) |
+				(snd_vt1724_read_i2c(ice, dev, 0x01) << 8) | 
+				(snd_vt1724_read_i2c(ice, dev, 0x02) << 16) | 
+				(snd_vt1724_read_i2c(ice, dev, 0x03) << 24);
+	ice->eeprom.size = snd_vt1724_read_i2c(ice, dev, 0x04);
+	if (ice->eeprom.size > 32) {
+		snd_printk("invalid EEPROM (size = %i)\n", ice->eeprom.size);
+		return -EIO;
+	}
+	ice->eeprom.version = snd_vt1724_read_i2c(ice, dev, 0x05);
+	if (ice->eeprom.version != 2) {
+		snd_printk("invalid EEPROM version %i\n", ice->eeprom.version);
+		// return -EIO;
+	}
+	for (i = 0; i < ice->eeprom.size; i++)
+		ice->eeprom.data[i] = snd_vt1724_read_i2c(ice, dev, i + 6);
+
+	ice->eeprom.gpiomask = eeprom_triple(ice, ICE_EEP2_GPIO_MASK);
+	ice->eeprom.gpiostate = eeprom_triple(ice, ICE_EEP2_GPIO_STATE);
+	ice->eeprom.gpiodir = eeprom_triple(ice, ICE_EEP2_GPIO_DIR);
+
+	return 0;
+}
+
+
+
+static int __devinit snd_vt1724_chip_init(ice1712_t *ice)
+{
+	outb(VT1724_RESET , ICEREG1724(ice, CONTROL));
+	udelay(200);
+	outb(0, ICEREG1724(ice, CONTROL));
+	udelay(200);
+	outb(ice->eeprom.data[ICE_EEP2_SYSCONF], ICEREG1724(ice, SYS_CFG));
+	outb(ice->eeprom.data[ICE_EEP2_ACLINK], ICEREG1724(ice, AC97_CFG));
+	outb(ice->eeprom.data[ICE_EEP2_I2S], ICEREG1724(ice, I2S_FEATURES));
+	outb(ice->eeprom.data[ICE_EEP2_SPDIF], ICEREG1724(ice, SPDIF_CFG));
+
+	ice->gpio.write_mask = ice->eeprom.gpiomask;
+	ice->gpio.direction = ice->eeprom.gpiodir;
+	snd_vt1724_set_gpio_mask(ice, ice->eeprom.gpiomask);
+	snd_vt1724_set_gpio_dir(ice, ice->eeprom.gpiodir);
+	snd_vt1724_set_gpio_data(ice, ice->eeprom.gpiostate);
+
+	outb(0, ICEREG1724(ice, POWERDOWN));
+
+	return 0;
+}
+
+static int __devinit snd_vt1724_spdif_build_controls(ice1712_t *ice)
+{
+	int err;
+	unsigned int idx;
+	snd_kcontrol_t *kctl;
+
+	snd_assert(ice->pcm != NULL, return -EIO);
+
+	for (idx = 0; idx < 2; idx++) {
+		kctl = snd_ctl_new1(&snd_vt1724_mixer_pro_spdif_route, ice);
+		if (kctl == NULL)
+			return -ENOMEM;
+		kctl->id.index = idx;
+		err = snd_ctl_add(ice->card, kctl);
+		if (err < 0)
+			return err;
+	}
+
+	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_spdif_switch, ice));
+	if (err < 0)
+		return err;
+
+	err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_default, ice));
+	if (err < 0)
+		return err;
+	kctl->id.device = ice->pcm->device;
+	err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_maskc, ice));
+	if (err < 0)
+		return err;
+	kctl->id.device = ice->pcm->device;
+	err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_maskp, ice));
+	if (err < 0)
+		return err;
+	kctl->id.device = ice->pcm->device;
+#if 0 /* use default only */
+	err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_stream, ice));
+	if (err < 0)
+		return err;
+	kctl->id.device = ice->pcm->device;
+	ice->spdif.stream_ctl = kctl;
+#endif
+	return 0;
+}
+
+
+static int __devinit snd_vt1724_build_controls(ice1712_t *ice)
+{
+	unsigned int idx;
+	snd_kcontrol_t *kctl;
+	int err;
+
+	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_eeprom, ice));
+	if (err < 0)
+		return err;
+	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_internal_clock, ice));
+	if (err < 0)
+		return err;
+
+	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_rate_locking, ice));
+	if (err < 0)
+		return err;
+	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_rate_reset, ice));
+	if (err < 0)
+		return err;
+
+	for (idx = 0; idx < ice->num_total_dacs; idx++) {
+		kctl = snd_ctl_new1(&snd_vt1724_mixer_pro_analog_route, ice);
+		if (kctl == NULL)
+			return -ENOMEM;
+		kctl->id.index = idx;
+		err = snd_ctl_add(ice->card, kctl);
+		if (err < 0)
+			return err;
+	}
+
+	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_peak, ice));
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int snd_vt1724_free(ice1712_t *ice)
+{
+	if (ice->res_port == NULL)
+		goto __hw_end;
+	/* mask all interrupts */
+	outb(0xff, ICEMT1724(ice, DMA_INT_MASK));
+	outb(0xff, ICEREG1724(ice, IRQMASK));
+	/* --- */
+      __hw_end:
+	if (ice->irq >= 0) {
+		synchronize_irq(ice->irq);
+		free_irq(ice->irq, (void *) ice);
+	}
+	if (ice->res_port) {
+		release_resource(ice->res_port);
+		kfree_nocheck(ice->res_port);
+	}
+	if (ice->res_profi_port) {
+		release_resource(ice->res_profi_port);
+		kfree_nocheck(ice->res_profi_port);
+	}
+	if (ice->akm)
+		kfree(ice->akm);
+	snd_magic_kfree(ice);
+	return 0;
+}
+
+static int snd_vt1724_dev_free(snd_device_t *device)
+{
+	ice1712_t *ice = snd_magic_cast(ice1712_t, device->device_data, return -ENXIO);
+	return snd_vt1724_free(ice);
+}
+
+static int __devinit snd_vt1724_create(snd_card_t * card,
+				       struct pci_dev *pci,
+				       ice1712_t ** r_ice1712)
+{
+	ice1712_t *ice;
+	int err;
+	unsigned char mask;
+	static snd_device_ops_t ops = {
+		.dev_free =	snd_vt1724_dev_free,
+	};
+
+	*r_ice1712 = NULL;
+
+        /* enable PCI device */
+	if ((err = pci_enable_device(pci)) < 0)
+		return err;
+	pci_set_dma_mask(pci, 0xffffffff); 
+
+	ice = snd_magic_kcalloc(ice1712_t, 0, GFP_KERNEL);
+	if (ice == NULL)
+		return -ENOMEM;
+	ice->vt1724 = 1;
+	spin_lock_init(&ice->reg_lock);
+	init_MUTEX(&ice->gpio_mutex);
+	ice->gpio.set_mask = snd_vt1724_set_gpio_mask;
+	ice->gpio.set_dir = snd_vt1724_set_gpio_dir;
+	ice->gpio.set_data = snd_vt1724_set_gpio_data;
+	ice->gpio.get_data = snd_vt1724_get_gpio_data;
+	ice->card = card;
+	ice->pci = pci;
+	ice->irq = -1;
+	ice->port = pci_resource_start(pci, 0);
+	ice->profi_port = pci_resource_start(pci, 1);
+	pci_set_master(pci);
+	snd_vt1724_proc_init(ice);
+	synchronize_irq(pci->irq);
+
+	if ((ice->res_port = request_region(ice->port, 32, "ICE1724 - Controller")) == NULL) {
+		snd_vt1724_free(ice);
+		snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->port, ice->port + 32 - 1);
+		return -EIO;
+	}
+
+	if ((ice->res_profi_port = request_region(ice->profi_port, 128, "ICE1724 - Professional")) == NULL) {
+		snd_vt1724_free(ice);
+		snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->profi_port, ice->profi_port + 16 - 1);
+		return -EIO;
+	}
+		
+	if (request_irq(pci->irq, snd_vt1724_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1724", (void *) ice)) {
+		snd_vt1724_free(ice);
+		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		return -EIO;
+	}
+
+	ice->irq = pci->irq;
+
+	if (snd_vt1724_read_eeprom(ice) < 0) {
+		snd_vt1724_free(ice);
+		return -EIO;
+	}
+	if (snd_vt1724_chip_init(ice) < 0) {
+		snd_vt1724_free(ice);
+		return -EIO;
+	}
+
+	/* unmask used interrupts */
+	if (! (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401))
+		mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX;
+	else
+		mask = 0;
+	outb(mask, ICEREG1724(ice, IRQMASK));
+	/* don't handle FIFO overrun/underruns (just yet), since they cause machine lockups */
+	outb(VT1724_MULTI_FIFO_ERR, ICEMT1724(ice, DMA_INT_MASK));
+
+	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) {
+		snd_vt1724_free(ice);
+ 		return err;
+	}
+
+	*r_ice1712 = ice;
+	return 0;
+}
+
+
+/*
+ *
+ * Registration
+ *
+ */
+
+static struct snd_ice1712_card_info no_matched __devinitdata;
+
+static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
+	snd_vt1724_revo_cards,
+	snd_vt1724_amp_cards, 
+	0,
+};
+
+
+static int __devinit snd_vt1724_probe(struct pci_dev *pci,
+				      const struct pci_device_id *pci_id)
+{
+	static int dev;
+	snd_card_t *card;
+	ice1712_t *ice;
+	int pcm_dev = 0, err;
+	struct snd_ice1712_card_info **tbl, *c;
+
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+	if (!enable[dev]) {
+		dev++;
+		return -ENOENT;
+	}
+
+	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	if (card == NULL)
+		return -ENOMEM;
+
+	strcpy(card->driver, "ICE1724");
+	strcpy(card->shortname, "ICEnsemble ICE1724");
+	
+	if ((err = snd_vt1724_create(card, pci, &ice)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	for (tbl = card_tables; *tbl; tbl++) {
+		for (c = *tbl; c->subvendor; c++) {
+			if (c->subvendor == ice->eeprom.subvendor) {
+				strcpy(card->shortname, c->name);
+				if (c->chip_init) {
+					if ((err = c->chip_init(ice)) < 0) {
+						snd_card_free(card);
+						return err;
+					}
+				}
+				goto __found;
+			}
+		}
+	}
+	c = &no_matched;
+ __found:
+
+	if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	
+	if ((err = snd_vt1724_pcm_spdif(ice, pcm_dev++)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	
+	if ((err = snd_vt1724_ac97_mixer(ice)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	if ((err = snd_vt1724_build_controls(ice)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	if (ice->pcm) { /* has SPDIF I/O */
+		if ((err = snd_vt1724_spdif_build_controls(ice)) < 0) {
+			snd_card_free(card);
+			return err;
+		}
+	}
+
+	if (c->build_controls) {
+		if ((err = c->build_controls(ice)) < 0) {
+			snd_card_free(card);
+			return err;
+		}
+	}
+
+	if (! c->no_mpu401) {
+		if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) {
+			if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
+						       ICEREG1724(ice, MPU_CTRL), 1,
+						       ice->irq, 0,
+						       &ice->rmidi[0])) < 0) {
+				snd_card_free(card);
+				return err;
+			}
+		}
+	}
+
+	sprintf(card->longname, "%s at 0x%lx, irq %i",
+		card->shortname, ice->port, ice->irq);
+
+	if ((err = snd_card_register(card)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	pci_set_drvdata(pci, card);
+	dev++;
+	return 0;
+}
+
+static void __devexit snd_vt1724_remove(struct pci_dev *pci)
+{
+	snd_card_free(pci_get_drvdata(pci));
+	pci_set_drvdata(pci, NULL);
+}
+
+static struct pci_driver driver = {
+	.name = "ICE1724",
+	.id_table = snd_vt1724_ids,
+	.probe = snd_vt1724_probe,
+	.remove = __devexit_p(snd_vt1724_remove),
+};
+
+static int __init alsa_card_ice1724_init(void)
+{
+	int err;
+
+	if ((err = pci_module_init(&driver)) < 0) {
+#ifdef MODULE
+		printk(KERN_ERR "ICE1724 soundcard not found or device busy\n");
+#endif
+		return err;
+	}
+	return 0;
+}
+
+static void __exit alsa_card_ice1724_exit(void)
+{
+	pci_unregister_driver(&driver);
+}
+
+module_init(alsa_card_ice1724_init)
+module_exit(alsa_card_ice1724_exit)
+
+#ifndef MODULE
+
+/* format is: snd-ice1724=enable,index,id */
+
+static int __init alsa_card_ice1724_setup(char *str)
+{
+	static unsigned __initdata nr_dev = 0;
+
+	if (nr_dev >= SNDRV_CARDS)
+		return 0;
+	(void)(get_option(&str,&enable[nr_dev]) == 2 &&
+	       get_option(&str,&index[nr_dev]) == 2 &&
+	       get_id(&str,&id[nr_dev]) == 2);
+	nr_dev++;
+	return 1;
+}
+
+__setup("snd-ice1724=", alsa_card_ice1724_setup);
+
+#endif /* ifndef MODULE */
diff -Nru a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/sound/pci/ice1712/revo.c	Thu Mar 20 08:41:20 2003
@@ -0,0 +1,169 @@
+/*
+ *   ALSA driver for ICEnsemble ICE1712 (Envy24)
+ *
+ *   Lowlevel functions for M-Audio Revolution 7.1
+ *
+ *	Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */      
+
+#include <sound/driver.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+
+#include "ice1712.h"
+#include "envy24ht.h"
+#include "revo.h"
+
+/*
+ * change the rate of envy24HT, AK4355 and AK4381
+ */
+static void revo_set_rate_val(akm4xxx_t *ak, unsigned int rate)
+{
+	unsigned char old, tmp, dfs;
+	int reg, shift;
+
+	if (rate == 0)	/* no hint - S/PDIF input is master, simply return */
+		return;
+
+	/* adjust DFS on codecs */
+	if (rate > 96000)
+		dfs = 2;
+	else if (rate > 48000)
+		dfs = 1;
+	else
+		dfs = 0;
+
+	if (ak->type == SND_AK4355) {
+		reg = 2;
+		shift = 4;
+	} else {
+		reg = 1;
+		shift = 3;
+	}
+	tmp = ak->images[0][reg];
+	old = (tmp >> shift) & 0x03;
+	if (old == dfs)
+		return;
+
+	/* reset DFS */
+	snd_ice1712_akm4xxx_reset(ak, 1);
+	tmp = ak->images[0][reg];
+	tmp &= ~(0x03 << shift);
+	tmp |= dfs << shift;
+	snd_ice1712_akm4xxx_write(ak, 0, reg, tmp);
+	snd_ice1712_akm4xxx_reset(ak, 0);
+}
+
+/*
+ * initialize the chips on M-Audio Revolution cards
+ */
+
+static akm4xxx_t akm_revo_front __devinitdata = {
+	.type = SND_AK4381,
+	.num_dacs = 2,
+	.caddr = 1,
+	.cif = 0,
+	.data_mask = VT1724_REVO_CDOUT,
+	.clk_mask = VT1724_REVO_CCLK,
+	.cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
+	.cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2,
+	.cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
+	.add_flags = VT1724_REVO_CCLK, /* high at init */
+	.mask_flags = 0,
+	.ops = {
+		.set_rate_val = revo_set_rate_val
+	}
+};
+
+static akm4xxx_t akm_revo_surround __devinitdata = {
+	.type = SND_AK4355,
+	.idx_offset = 1,
+	.num_dacs = 6,
+	.caddr = 3,
+	.cif = 0,
+	.data_mask = VT1724_REVO_CDOUT,
+	.clk_mask = VT1724_REVO_CCLK,
+	.cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
+	.cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS1,
+	.cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
+	.add_flags = VT1724_REVO_CCLK, /* high at init */
+	.mask_flags = 0,
+	.ops = {
+		.set_rate_val = revo_set_rate_val
+	}
+};
+
+static int __devinit revo_init(ice1712_t *ice)
+{
+	akm4xxx_t *ak;
+
+	/* determine I2C, DACs and ADCs */
+	switch (ice->eeprom.subvendor) {
+	case VT1724_SUBDEVICE_REVOLUTION71:
+		ice->num_total_dacs = 8;
+		break;
+	default:
+		snd_BUG();
+		return -EINVAL;
+	}
+
+	/* second stage of initialization, analog parts and others */
+	ak = ice->akm = kmalloc(sizeof(akm4xxx_t) * 2, GFP_KERNEL);
+	if (! ak)
+		return -ENOMEM;
+	ice->akm_codecs = 2;
+	switch (ice->eeprom.subvendor) {
+	case VT1724_SUBDEVICE_REVOLUTION71:
+		snd_ice1712_akm4xxx_init(ak, &akm_revo_front, ice);
+		snd_ice1712_akm4xxx_init(ak + 1, &akm_revo_surround, ice);
+		/* unmute all codecs */
+		snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE);
+		break;
+	}
+
+	return 0;
+}
+
+
+static int __devinit revo_add_controls(ice1712_t *ice)
+{
+	int err;
+
+	switch (ice->eeprom.subvendor) {
+	case VT1724_SUBDEVICE_REVOLUTION71:
+		err = snd_ice1712_akm4xxx_build_controls(ice);
+		if (err < 0)
+			return err;
+	}
+	return 0;
+}
+
+/* entry point */
+struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = {
+	{
+		VT1724_SUBDEVICE_REVOLUTION71,
+		"M Audio Revolution-7.1",
+		revo_init,
+		revo_add_controls,
+	},
+	{ } /* terminator */
+};
diff -Nru a/sound/pci/ice1712/revo.h b/sound/pci/ice1712/revo.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/sound/pci/ice1712/revo.h	Thu Mar 20 08:41:21 2003
@@ -0,0 +1,48 @@
+#ifndef __SOUND_REVO_H
+#define __SOUND_REVO_H
+
+/*
+ *   ALSA driver for ICEnsemble ICE1712 (Envy24)
+ *
+ *   Lowlevel functions for M-Audio Revolution 7.1
+ *
+ *	Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
+ *
+ *   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
+ *
+ */      
+
+#define REVO_DEVICE_DESC \
+		"{MidiMan M Audio,Revolution 7.1},"
+
+#define VT1724_SUBDEVICE_REVOLUTION71	0x12143036
+
+/* entry point */
+extern struct snd_ice1712_card_info snd_vt1724_revo_cards[];
+
+
+/*
+ *  MidiMan M-Audio Revolution GPIO definitions
+ */
+
+#define VT1724_REVO_CCLK	0x02
+#define VT1724_REVO_CDIN	0x04	/* not used */
+#define VT1724_REVO_CDOUT	0x08
+#define VT1724_REVO_CS0		0x10	/* not used */
+#define VT1724_REVO_CS1		0x20	/* front AKM4381 chipselect */
+#define VT1724_REVO_CS2		0x40	/* surround AKM4355 chipselect */
+#define VT1724_REVO_MUTE	(1<<22)	/* 0 = all mute, 1 = normal operation */
+
+#endif /* __SOUND_REVO_H */
diff -Nru a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
--- a/sound/pci/intel8x0.c	Wed Mar  5 21:39:37 2003
+++ b/sound/pci/intel8x0.c	Fri Mar 21 10:24:37 2003
@@ -50,6 +50,7 @@
 		"{Intel,82801BA-ICH2},"
 		"{Intel,82801CA-ICH3},"
 		"{Intel,82801DB-ICH4},"
+		"{Intel,ICH5},"
 		"{Intel,MX440},"
 		"{SiS,SI7012},"
 		"{NVidia,NForce Audio},"
@@ -122,6 +123,9 @@
 #ifndef PCI_DEVICE_ID_INTEL_ICH4
 #define PCI_DEVICE_ID_INTEL_ICH4	0x24c5
 #endif
+#ifndef PCI_DEVICE_ID_INTEL_ICH5
+#define PCI_DEVICE_ID_INTEL_ICH5	0x24d5
+#endif
 #ifndef PCI_DEVICE_ID_SI_7012
 #define PCI_DEVICE_ID_SI_7012		0x7012
 #endif
@@ -191,6 +195,10 @@
 #define   ICH_PCM_6		0x00200000	/* 6 channels (not all chips) */
 #define   ICH_PCM_4		0x00100000	/* 4 channels (not all chips) */
 #define   ICH_PCM_2		0x00000000	/* 2 channels (stereo) */
+#define   ICH_SIS_PCM_246_MASK	0x000000c0	/* 6 channels (SIS7012) */
+#define   ICH_SIS_PCM_6		0x00000080	/* 6 channels (SIS7012) */
+#define   ICH_SIS_PCM_4		0x00000040	/* 4 channels (SIS7012) */
+#define   ICH_SIS_PCM_2		0x00000000	/* 2 channels (SIS7012) */
 #define   ICH_SRIE		0x00000020	/* secondary resume interrupt enable */
 #define   ICH_PRIE		0x00000010	/* primary resume interrupt enable */
 #define   ICH_ACLINK		0x00000008	/* AClink shut off */
@@ -385,6 +393,7 @@
 	{ 0x8086, 0x2445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL },	/* 82801BA */
 	{ 0x8086, 0x2485, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL },	/* ICH3 */
 	{ 0x8086, 0x24c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH4 */
+	{ 0x8086, 0x24d5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH5 */
 	{ 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL },	/* 440MX */
 	{ 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS },	/* SI7012 */
 	{ 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL },	/* NFORCE */
@@ -818,11 +827,20 @@
 
 static void snd_intel8x0_setup_multi_channels(intel8x0_t *chip, int channels)
 {
-	unsigned int cnt = igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_246_MASK;
-	if (chip->multi4 && channels == 4)
-		cnt |= ICH_PCM_4;
-	else if (chip->multi6 && channels == 6)
-		cnt |= ICH_PCM_6;
+	unsigned int cnt = igetdword(chip, ICHREG(GLOB_CNT));
+	if (chip->device_type == DEVICE_SIS) {
+		cnt &= ~ICH_SIS_PCM_246_MASK;
+		if (chip->multi4 && channels == 4)
+			cnt |= ICH_SIS_PCM_4;
+		else if (chip->multi6 && channels == 6)
+			cnt |= ICH_SIS_PCM_6;
+	} else {
+		cnt &= ~ICH_PCM_246_MASK;
+		if (chip->multi4 && channels == 4)
+			cnt |= ICH_PCM_4;
+		else if (chip->multi6 && channels == 6)
+			cnt |= ICH_PCM_6;
+	}
 	iputdword(chip, ICHREG(GLOB_CNT), cnt);
 }
 
@@ -1508,12 +1526,17 @@
 	{ ALID_SPDIFIN, { 0, 0, 0 }, -1 },
 };
 
+static struct ac97_quirk ac97_quirks[] = {
+	{ 0x1028, 0x0126, "Dell Optiplex GX260", AC97_TUNE_HP_ONLY },
+	{ 0x1734, 0x0088, "Fujisu-Siemens D1522", AC97_TUNE_HP_ONLY },
+	{ } /* terminator */
+};
 
 static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock)
 {
 	ac97_t ac97, *x97;
 	ichdev_t *ichdev;
-	int err, i, channels = 2, codecs;
+	int err, i, num, channels = 2, codecs, _codecs;
 	unsigned int glob_sta = 0;
 
 	for (i = 0; i <= ICHD_LAST; i++) {
@@ -1589,6 +1612,7 @@
 	if ((err = snd_ac97_mixer(chip->card, &ac97, &x97)) < 0)
 		return err;
 	chip->ac97[0] = x97;
+	snd_ac97_tune_hardware(chip->ac97[0], chip->pci, ac97_quirks);
 	chip->ichd[ICHD_PCMOUT].ac97 = x97;
 	chip->ichd[ICHD_PCMIN].ac97 = x97;
 	if (x97->ext_id & AC97_EI_VRM)
@@ -1604,20 +1628,20 @@
 		snd_ac97_update_bits(x97, AC97_EXTENDED_ID, AC97_EI_DACS_SLOT_MASK, 0);
 	/* AnalogDevices CNR boards uses special codec chaining */
 	/* skip standard test method for secondary codecs in this case */
-	if (x97->flags & AC97_AD_MULTI) {
+	if (x97->flags & AC97_AD_MULTI)
 		codecs = 1;
-		goto __skip_secondary;
-	}
 	if (codecs < 2)
 		goto __skip_secondary;
-	for (i = 1; i < codecs; i++) {
-		ac97.num = i;
+	for (i = 1, num = 1, _codecs = codecs; num < _codecs; num++) {
+		ac97.num = num;
 		if ((err = snd_ac97_mixer(chip->card, &ac97, &x97)) < 0) {
 			snd_printk("Unable to initialize codec #%i [device = %i, GLOB_STA = 0x%x]\n", i, chip->device_type, glob_sta);
-			codecs = i;
-			break;
+			codecs--;
+			continue;
 		}
-		chip->ac97[i] = x97;
+		chip->ac97[i++] = x97;
+		if (!ac97_is_audio(x97))
+			continue;
 		switch (chip->device_type) {
 		case DEVICE_INTEL_ICH4:
 			if (chip->ichd[ICHD_PCM2IN].ac97 == NULL)
@@ -1656,14 +1680,16 @@
 		}
 		iputbyte(chip, ICHREG(SDM), tmp);
 	}
-      	for (i = 0; i < 3; i++) {
-		if ((x97 = chip->ac97[i]) == NULL)
+      	for (i = 0; i < codecs; i++) {
+		x97 = chip->ac97[i];
+		if (!ac97_is_audio(x97))
 			continue;
 		if (x97->scaps & AC97_SCAP_SURROUND_DAC)
 			chip->multi4 = 1;
 	}
-      	for (i = 0; i < 3 && chip->multi4; i++) {
-		if ((x97 = chip->ac97[i]) == NULL)
+      	for (i = 0; i < codecs && chip->multi4; i++) {
+		x97 = chip->ac97[i];
+		if (!ac97_is_audio(x97))
 			continue;
 		if (x97->scaps & AC97_SCAP_CENTER_LFE_DAC)
 			chip->multi6 = 1;
@@ -1674,7 +1700,10 @@
 		if (chip->multi4)
 			goto __6ch;
 		for ( ; i < codecs; i++) {
-			if (ac97_is_rev22(x97 = chip->ac97[i])) {
+			x97 = chip->ac97[i];
+			if (!ac97_is_audio(x97))
+				continue;
+			if (ac97_is_rev22(x97)) {
 				snd_ac97_update_bits(x97, AC97_EXTENDED_ID, AC97_EI_DACS_SLOT_MASK, 1);
 				chip->multi4 = 1;
 				break;
@@ -1682,7 +1711,10 @@
 		}
 	      __6ch:
 		for ( ; i < codecs && chip->multi4; i++) {
-			if (ac97_is_rev22(x97 = chip->ac97[i])) {
+			x97 = chip->ac97[i];
+			if (!ac97_is_audio(x97))
+				continue;
+			if (ac97_is_rev22(x97)) {
 				snd_ac97_update_bits(x97, AC97_EXTENDED_ID, AC97_EI_DACS_SLOT_MASK, 2);
 				chip->multi6 = 1;
 				break;
@@ -1691,7 +1723,10 @@
 		/* ok, some older codecs might support only AMAP */
 		if (!chip->multi4) {
 			for (i = 1; i < codecs; i++) {
-				if (ac97_can_amap(x97 = chip->ac97[i])) {
+				x97 = chip->ac97[i];
+				if (!ac97_is_audio(x97))
+					continue;
+				if (ac97_can_amap(x97)) {
 					if (x97->addr == 1) {
 						chip->multi4 = 1;
 						break;
@@ -1699,7 +1734,9 @@
 				}
 			}
 			for ( ; i < codecs && chip->multi4; i++) {
-				if (ac97_can_amap(x97 = chip->ac97[i])) {
+				if (!ac97_is_audio(x97))
+					continue;
+				if (ac97_can_amap(x97)) {
 					if (x97->addr == 2) {
 						chip->multi6 = 1;
 						break;
@@ -2302,6 +2339,7 @@
 	{ PCI_DEVICE_ID_INTEL_440MX, "Intel 440MX" },
 	{ PCI_DEVICE_ID_INTEL_ICH3, "Intel 82801CA-ICH3" },
 	{ PCI_DEVICE_ID_INTEL_ICH4, "Intel 82801DB-ICH4" },
+	{ PCI_DEVICE_ID_INTEL_ICH5, "Intel ICH5" },
 	{ PCI_DEVICE_ID_SI_7012, "SiS SI7012" },
 	{ PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia NForce" },
 	{ PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia NForce2" },
@@ -2433,12 +2471,12 @@
 
 static struct pci_driver driver = {
 	.name = "Intel ICH",
-	id_table: snd_intel8x0_ids,
-	probe: snd_intel8x0_probe,
-	remove: __devexit_p(snd_intel8x0_remove),
+	.id_table = snd_intel8x0_ids,
+	.probe = snd_intel8x0_probe,
+	.remove = __devexit_p(snd_intel8x0_remove),
 #ifdef CONFIG_PM
-	suspend: snd_intel8x0_suspend,
-	resume: snd_intel8x0_resume,
+	.suspend = snd_intel8x0_suspend,
+	.resume = snd_intel8x0_resume,
 #endif
 };
 
diff -Nru a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
--- a/sound/pci/korg1212/korg1212.c	Tue Feb 11 05:51:13 2003
+++ b/sound/pci/korg1212/korg1212.c	Tue Feb 25 05:46:07 2003
@@ -42,6 +42,7 @@
 // ----------------------------------------------------------------------------
 #define K1212_DEBUG_LEVEL		0
 #define K1212_DEBUG_PRINTK		printk
+//#define K1212_DEBUG_PRINTK(x...)	printk("<0>" x)
 
 // ----------------------------------------------------------------------------
 // Record/Play Buffer Allocation Method. If K1212_LARGEALLOC is defined all 
@@ -178,13 +179,21 @@
 #define kAudioChannels		(k16BitChannels + k32BitChannels)
 #define kPlayBufferFrames	1024
 
-#define K1212_CHANNELS     	16
+#define K1212_ANALOG_CHANNELS	2
+#define K1212_SPDIF_CHANNELS	2
+#define K1212_ADAT_CHANNELS	8
+#define K1212_CHANNELS		(K1212_ADAT_CHANNELS + K1212_ANALOG_CHANNELS)
+#define K1212_MIN_CHANNELS	1
+#define K1212_MAX_CHANNELS	K1212_CHANNELS
 #define K1212_FRAME_SIZE        (sizeof(KorgAudioFrame))
 #define K1212_MAX_SAMPLES	(kPlayBufferFrames*kNumBuffers)
-#define K1212_PERIODS		(K1212_BUF_SIZE/K1212_BLOCK_SIZE)
-#define K1212_PERIOD_BYTES	(K1212_BLOCK_SIZE)
-#define K1212_BLOCK_SIZE        (K1212_FRAME_SIZE*kPlayBufferFrames)
-#define K1212_BUF_SIZE          (K1212_BLOCK_SIZE*kNumBuffers)
+#define K1212_PERIODS		(kNumBuffers)
+#define K1212_PERIOD_BYTES	(K1212_FRAME_SIZE*kPlayBufferFrames)
+#define K1212_BUF_SIZE          (K1212_PERIOD_BYTES*kNumBuffers)
+#define K1212_ANALOG_BUF_SIZE	(K1212_ANALOG_CHANNELS * 2 * kPlayBufferFrames * kNumBuffers)
+#define K1212_SPDIF_BUF_SIZE	(K1212_SPDIF_CHANNELS * 3 * kPlayBufferFrames * kNumBuffers)
+#define K1212_ADAT_BUF_SIZE	(K1212_ADAT_CHANNELS * 2 * kPlayBufferFrames * kNumBuffers)
+#define K1212_MAX_BUF_SIZE	(K1212_ANALOG_BUF_SIZE + K1212_ADAT_BUF_SIZE)
 
 #define k1212MinADCSens     0x7f
 #define k1212MaxADCSens     0x00
@@ -314,9 +323,9 @@
 } SensBits;
 
 struct _snd_korg1212 {
-        struct pci_dev *pci;
         snd_card_t *card;
-        snd_pcm_t *pcm16;
+        struct pci_dev *pci;
+        snd_pcm_t *pcm;
         int irq;
 
         spinlock_t    lock;
@@ -362,9 +371,9 @@
         u16 * sensRegPtr;	     // address of the sensitivity setting register
         u32 * idRegPtr;		     // address of the device and vendor ID registers
 
-
         size_t periodsize;
-        size_t currentBuffer;
+	int channels;
+        int currentBuffer;
 
         snd_pcm_substream_t *playback_substream;
         snd_pcm_substream_t *capture_substream;
@@ -383,6 +392,11 @@
 
         u16 leftADCInSens;           // ADC left channel input sensitivity
         u16 rightADCInSens;          // ADC right channel input sensitivity
+
+	int opencnt;			// Open/Close count
+	int setcnt;			// SetupForPlay count
+	int playcnt;			// TriggerPlay count
+
 };
 
 MODULE_DESCRIPTION("korg1212");
@@ -465,7 +479,6 @@
 
 static snd_korg1212rc rc;
 
-
 MODULE_DEVICE_TABLE(pci, snd_korg1212_ids);
 
 typedef union swap_u32 { unsigned char c[4]; u32 i; } swap_u32;
@@ -521,11 +534,6 @@
 
 #endif /* not used */
 
-void TickDelay(int time)
-{
-        udelay(time);
-}
-
 #define SetBitInWord(theWord,bitPosition)       (*theWord) |= (0x0001 << bitPosition)
 #define SetBitInDWord(theWord,bitPosition)      (*theWord) |= (0x00000001 << bitPosition)
 #define ClearBitInWord(theWord,bitPosition)     (*theWord) &= ~(0x0001 << bitPosition)
@@ -536,76 +544,95 @@
 {
         u32 retryCount;
         u16 mailBox3Lo;
+	snd_korg1212rc rc = K1212_CMDRET_Success;
 
-        if (korg1212->outDoorbellPtr) {
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- 0x%08x 0x%08x [%s]\n", doorbellVal, mailBox0Val, stateName[korg1212->cardState]);
+        if (!korg1212->outDoorbellPtr) {
+#if K1212_DEBUG_LEVEL > 1
+		K1212_DEBUG_PRINTK("K1212_DEBUG: CardUninitialized\n");
 #endif
-                for (retryCount = 0; retryCount < MAX_COMMAND_RETRIES; retryCount++) {
+                return K1212_CMDRET_CardUninitialized;
+	}
 
-                        writel(mailBox3Val, korg1212->mailbox3Ptr);
-                        writel(mailBox2Val, korg1212->mailbox2Ptr);
-                        writel(mailBox1Val, korg1212->mailbox1Ptr);
-                        writel(mailBox0Val, korg1212->mailbox0Ptr);
-                        writel(doorbellVal, korg1212->outDoorbellPtr);  // interrupt the card
-
-                        // --------------------------------------------------------------
-                        // the reboot command will not give an acknowledgement.
-                        // --------------------------------------------------------------
-                        switch (doorbellVal) {
-                                case K1212_DB_RebootCard:
-                                case K1212_DB_BootFromDSPPage4:
-                                case K1212_DB_StartDSPDownload:
-                                        return K1212_CMDRET_Success;
-                                default:
-                                        break;
-                        }
+#if K1212_DEBUG_LEVEL > 0
+	K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- 0x%08x 0x%08x [%s]\n", doorbellVal, mailBox0Val, stateName[korg1212->cardState]);
+#endif
+        for (retryCount = 0; retryCount < MAX_COMMAND_RETRIES; retryCount++) {
+		writel(mailBox3Val, korg1212->mailbox3Ptr);
+                writel(mailBox2Val, korg1212->mailbox2Ptr);
+                writel(mailBox1Val, korg1212->mailbox1Ptr);
+                writel(mailBox0Val, korg1212->mailbox0Ptr);
+                writel(doorbellVal, korg1212->outDoorbellPtr);  // interrupt the card
+
+                // --------------------------------------------------------------
+                // the reboot command will not give an acknowledgement.
+                // --------------------------------------------------------------
+                if ( doorbellVal == K1212_DB_RebootCard ||
+                	doorbellVal == K1212_DB_BootFromDSPPage4 ||
+                        doorbellVal == K1212_DB_StartDSPDownload ) {
+                        rc = K1212_CMDRET_Success;
+                        break;
+                }
 
-                        // --------------------------------------------------------------
-                        // See if the card acknowledged the command.  Wait a bit, then
-                        // read in the low word of mailbox3.  If the MSB is set and the
-                        // low byte is equal to the doorbell value, then it ack'd.
-                        // --------------------------------------------------------------
-                        TickDelay(COMMAND_ACK_DELAY);
-                        mailBox3Lo = readl(korg1212->mailbox3Ptr);
-                        if (mailBox3Lo & COMMAND_ACK_MASK) {
-                                if ((mailBox3Lo & DOORBELL_VAL_MASK) == (doorbellVal & DOORBELL_VAL_MASK)) {
-                                        korg1212->cmdRetryCount += retryCount;
-                                        return K1212_CMDRET_Success;
-                                }
+                // --------------------------------------------------------------
+                // See if the card acknowledged the command.  Wait a bit, then
+                // read in the low word of mailbox3.  If the MSB is set and the
+                // low byte is equal to the doorbell value, then it ack'd.
+                // --------------------------------------------------------------
+                udelay(COMMAND_ACK_DELAY);
+                mailBox3Lo = readl(korg1212->mailbox3Ptr);
+                if (mailBox3Lo & COMMAND_ACK_MASK) {
+                	if ((mailBox3Lo & DOORBELL_VAL_MASK) == (doorbellVal & DOORBELL_VAL_MASK)) {
+#if K1212_DEBUG_LEVEL > 1
+				K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- Success\n");
+#endif
+                                rc = K1212_CMDRET_Success;
+				break;
                         }
                 }
-                korg1212->cmdRetryCount += retryCount;
-                return K1212_CMDRET_NoAckFromCard;
-        } else {
-                return K1212_CMDRET_CardUninitialized;
-        }
+	}
+        korg1212->cmdRetryCount += retryCount;
+
+	if (retryCount >= MAX_COMMAND_RETRIES) {
+#if K1212_DEBUG_LEVEL > 1
+		K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- NoAckFromCard\n");
+#endif
+        	rc = K1212_CMDRET_NoAckFromCard;
+	}
+
+	return rc;
 }
 
 static void snd_korg1212_WaitForCardStopAck(korg1212_t *korg1212)
 {
-        unsigned long endtime = jiffies + 20 * HZ;
+        u32 endtime = jiffies + 2 * HZ;
 
 #if K1212_DEBUG_LEVEL > 0
-        K1212_DEBUG_PRINTK("K1212_DEBUG: WaitForCardStopAck [%s]\n", stateName[korg1212->cardState]);
+        K1212_DEBUG_PRINTK("K1212_DEBUG: WaitForCardStopAck.in [%s] %lu %lu\n", stateName[korg1212->cardState], jiffies, korg1212->inIRQ);
 #endif
 
         if (korg1212->inIRQ)
                 return;
 
         do {
-                if (readl(&korg1212->sharedBufferPtr->cardCommand) == 0)
+                if (readl(&korg1212->sharedBufferPtr->cardCommand) == 0) {
+#if K1212_DEBUG_LEVEL > 0
+        		K1212_DEBUG_PRINTK("K1212_DEBUG: WaitForCardStopAck.out [%s] %lu %lu\n", stateName[korg1212->cardState], jiffies, korg1212->inIRQ);
+#endif
                         return;
+		}
                 if (!korg1212->inIRQ)
                         schedule();
         } while (time_before(jiffies, endtime));
 
+#if K1212_DEBUG_LEVEL > 0
+        K1212_DEBUG_PRINTK("K1212_DEBUG: WaitForCardStopAck.out TO [%s] %lu %lu\n", stateName[korg1212->cardState], jiffies, korg1212->inIRQ);
+#endif
         writel(0, &korg1212->sharedBufferPtr->cardCommand);
 }
 
 static void snd_korg1212_TurnOnIdleMonitor(korg1212_t *korg1212)
 {
-        TickDelay(INTERCOMMAND_DELAY);
+        udelay(INTERCOMMAND_DELAY);
         korg1212->idleMonitorOn = 1;
         rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
                         K1212_MODE_MonitorOn, 0, 0, 0);
@@ -641,18 +668,22 @@
 static int snd_korg1212_OpenCard(korg1212_t * korg1212)
 {
 #if K1212_DEBUG_LEVEL > 0
-	K1212_DEBUG_PRINTK("K1212_DEBUG: OpenCard [%s]\n", stateName[korg1212->cardState]);
+	K1212_DEBUG_PRINTK("K1212_DEBUG: OpenCard [%s] %d\n", stateName[korg1212->cardState], korg1212->opencnt);
 #endif
-        snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
+        if (korg1212->opencnt++ == 0)
+		snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
         return 1;
 }
 
 static int snd_korg1212_CloseCard(korg1212_t * korg1212)
 {
 #if K1212_DEBUG_LEVEL > 0
-	K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard [%s]\n", stateName[korg1212->cardState]);
+	K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard [%s] %d\n", stateName[korg1212->cardState], korg1212->opencnt);
 #endif
 
+	if (--(korg1212->opencnt))
+		return 0;
+
         if (korg1212->cardState == K1212_STATE_SETUP) {
                 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
                                 K1212_MODE_StopPlay, 0, 0, 0);
@@ -676,9 +707,12 @@
 static int snd_korg1212_SetupForPlay(korg1212_t * korg1212)
 {
 #if K1212_DEBUG_LEVEL > 0
-	K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay [%s]\n", stateName[korg1212->cardState]);
+	K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay [%s] %d\n", stateName[korg1212->cardState], korg1212->setcnt);
 #endif
 
+        if (korg1212->setcnt++)
+		return 0;
+
         snd_korg1212_setCardState(korg1212, K1212_STATE_SETUP);
         rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
                                         K1212_MODE_SetupPlay, 0, 0, 0);
@@ -687,17 +721,20 @@
 	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
 #endif
         if (rc != K1212_CMDRET_Success) {
-                return 0;
+                return 1;
         }
-        return 1;
+        return 0;
 }
 
 static int snd_korg1212_TriggerPlay(korg1212_t * korg1212)
 {
 #if K1212_DEBUG_LEVEL > 0
-	K1212_DEBUG_PRINTK("K1212_DEBUG: TriggerPlay [%s]\n", stateName[korg1212->cardState]);
+	K1212_DEBUG_PRINTK("K1212_DEBUG: TriggerPlay [%s] %d\n", stateName[korg1212->cardState], korg1212->playcnt);
 #endif
 
+        if (korg1212->playcnt++)
+		return 0;
+
         snd_korg1212_setCardState(korg1212, K1212_STATE_PLAYING);
         rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_TriggerPlay, 0, 0, 0, 0);
 
@@ -706,23 +743,28 @@
 #endif
 
         if (rc != K1212_CMDRET_Success) {
-                return 0;
+                return 1;
         }
-        return 1;
+        return 0;
 }
 
 static int snd_korg1212_StopPlay(korg1212_t * korg1212)
 {
 #if K1212_DEBUG_LEVEL > 0
-	K1212_DEBUG_PRINTK("K1212_DEBUG: StopPlay [%s]\n", stateName[korg1212->cardState]);
+	K1212_DEBUG_PRINTK("K1212_DEBUG: StopPlay [%s] %d\n", stateName[korg1212->cardState], korg1212->playcnt);
 #endif
 
+        if (--(korg1212->playcnt)) 
+		return 0;
+
+	korg1212->setcnt = 0;
+
         if (korg1212->cardState != K1212_STATE_ERRORSTOP) {
                 writel(0xffffffff, &korg1212->sharedBufferPtr->cardCommand);
                 snd_korg1212_WaitForCardStopAck(korg1212);
         }
         snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
-        return 1;
+        return 0;
 }
 
 static void snd_korg1212_EnableCardInterrupts(korg1212_t * korg1212)
@@ -802,7 +844,7 @@
         korg1212->clkSrcRate = parm;
         korg1212->clkRate = rate;
 
-	TickDelay(INTERCOMMAND_DELAY);
+	udelay(INTERCOMMAND_DELAY);
 	rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SetClockSourceRate,
 					  ClockSourceSelector[korg1212->clkSrcRate],
 					  0, 0, 0);
@@ -869,7 +911,7 @@
         // flag.  Also, clear out mailbox 3, so we don't lockup.
         // ----------------------------------------------------------------------------
         writel(0, korg1212->mailbox3Ptr);
-        TickDelay(LOADSHIFT_DELAY);
+        udelay(LOADSHIFT_DELAY);
 
         // ----------------------------------------------------------------------------
         // determine whether we are running a 48K or 44.1K clock.  This info is used
@@ -910,7 +952,7 @@
                 ClearBitInWord(&controlValue, SET_SENS_LOADSHIFT_BITPOS);
                 ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS);
                 writew(controlValue, korg1212->sensRegPtr);                          // load/shift goes low
-                TickDelay(LOADSHIFT_DELAY);
+                udelay(LOADSHIFT_DELAY);
 
                 for (bitPosition = 15; bitPosition >= 0; bitPosition--) {       // for all the bits
                         if (channel == 0) {
@@ -929,10 +971,10 @@
 
                         ClearBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
                         writew(controlValue, korg1212->sensRegPtr);                       // clock goes low
-                        TickDelay(SENSCLKPULSE_WIDTH);
+                        udelay(SENSCLKPULSE_WIDTH);
                         SetBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
                         writew(controlValue, korg1212->sensRegPtr);                       // clock goes high
-                        TickDelay(SENSCLKPULSE_WIDTH);
+                        udelay(SENSCLKPULSE_WIDTH);
                 }
 
                 // ----------------------------------------------------------------------------
@@ -943,19 +985,19 @@
                 ClearBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
                 SetBitInWord(&controlValue, SET_SENS_LOADSHIFT_BITPOS);
                 writew(controlValue, korg1212->sensRegPtr);                   // load shift goes high - clk low
-                TickDelay(SENSCLKPULSE_WIDTH);
+                udelay(SENSCLKPULSE_WIDTH);
 
                 if (clkIs48K)
                         SetBitInWord(&controlValue, SET_SENS_DATA_BITPOS);
 
                 writew(controlValue, korg1212->sensRegPtr);                   // set/clear data bit
-                TickDelay(ONE_RTC_TICK);
+                udelay(ONE_RTC_TICK);
                 SetBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
                 writew(controlValue, korg1212->sensRegPtr);                   // clock goes high
-                TickDelay(SENSCLKPULSE_WIDTH);
+                udelay(SENSCLKPULSE_WIDTH);
                 ClearBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
                 writew(controlValue, korg1212->sensRegPtr);                   // clock goes low
-                TickDelay(SENSCLKPULSE_WIDTH);
+                udelay(SENSCLKPULSE_WIDTH);
         }
 
         // ----------------------------------------------------------------------------
@@ -963,7 +1005,7 @@
         // Also, if the card was in monitor mode, restore it.
         // ----------------------------------------------------------------------------
         for (count = 0; count < 10; count++)
-                TickDelay(SENSCLKPULSE_WIDTH);
+                udelay(SENSCLKPULSE_WIDTH);
 
         if (monModeSet) {
                 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
@@ -1011,7 +1053,7 @@
 	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Configure Buffer Memory - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
 #endif
 
-        TickDelay(INTERCOMMAND_DELAY);
+        udelay(INTERCOMMAND_DELAY);
 
         rc = snd_korg1212_Send1212Command(korg1212,
                         K1212_DB_ConfigureMiscMemory,
@@ -1029,7 +1071,7 @@
         // --------------------------------------------------------------------------------
         // Initialize the routing and volume tables, then update the card's state.
         // --------------------------------------------------------------------------------
-        TickDelay(INTERCOMMAND_DELAY);
+        udelay(INTERCOMMAND_DELAY);
 
         for (channel = 0; channel < kAudioChannels; channel++) {
                 korg1212->sharedBufferPtr->volumeData[channel] = k1212MaxVolume;
@@ -1039,7 +1081,7 @@
 
         snd_korg1212_WriteADCSensitivity(korg1212);
 
-	TickDelay(INTERCOMMAND_DELAY);
+	udelay(INTERCOMMAND_DELAY);
 	rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SetClockSourceRate,
 					  ClockSourceSelector[korg1212->clkSrcRate],
 					  0, 0, 0);
@@ -1056,7 +1098,6 @@
         wake_up_interruptible(&korg1212->wait);
 }
 
-
 static void snd_korg1212_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
         u32 doorbellValue;
@@ -1092,10 +1133,11 @@
                 // an error occurred - stop the card
                 // ------------------------------------------------------------------------
                 case K1212_ISRCODE_DMAERROR:
-#if K1212_DEBUG_LEVEL > 0
+#if K1212_DEBUG_LEVEL > 1
                         K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DMAE count - %ld, %x, [%s].\n", korg1212->irqcount, doorbellValue, stateName[korg1212->cardState]);
 #endif
                         writel(0, &korg1212->sharedBufferPtr->cardCommand);
+			snd_korg1212_setCardState(korg1212, K1212_STATE_ERRORSTOP);
                         break;
 
                 // ------------------------------------------------------------------------
@@ -1103,14 +1145,14 @@
                 // the semaphore in case someone is waiting for this.
                 // ------------------------------------------------------------------------
                 case K1212_ISRCODE_CARDSTOPPED:
-#if K1212_DEBUG_LEVEL > 0
+#if K1212_DEBUG_LEVEL > 1
                         K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ CSTP count - %ld, %x, [%s].\n", korg1212->irqcount, doorbellValue, stateName[korg1212->cardState]);
 #endif
                         writel(0, &korg1212->sharedBufferPtr->cardCommand);
                         break;
 
                 default:
-#if K1212_DEBUG_LEVEL > 1
+#if K1212_DEBUG_LEVEL > 3
                         K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DFLT count - %ld, %x, cpos=%d [%s].\n", korg1212->irqcount, doorbellValue, 
 				korg1212->currentBuffer, stateName[korg1212->cardState]);
 #endif
@@ -1170,7 +1212,7 @@
 
 static snd_pcm_hardware_t snd_korg1212_playback_info =
 {
-	.info =               (SNDRV_PCM_INFO_MMAP |
+	.info =              (SNDRV_PCM_INFO_MMAP |
                               SNDRV_PCM_INFO_MMAP_VALID |
                               SNDRV_PCM_INFO_INTERLEAVED),
 	.formats =	      SNDRV_PCM_FMTBIT_S16_LE,
@@ -1178,11 +1220,11 @@
                               SNDRV_PCM_RATE_48000),
         .rate_min =           44100,
         .rate_max =           48000,
-        .channels_min =       K1212_CHANNELS,
-        .channels_max =       K1212_CHANNELS,
-        .buffer_bytes_max =   K1212_BUF_SIZE,
-        .period_bytes_min =   K1212_PERIOD_BYTES,
-        .period_bytes_max =   K1212_PERIOD_BYTES,
+        .channels_min =       K1212_MIN_CHANNELS,
+        .channels_max =       K1212_MAX_CHANNELS,
+        .buffer_bytes_max =   K1212_MAX_BUF_SIZE,
+        .period_bytes_min =   K1212_MIN_CHANNELS * 2 * kPlayBufferFrames,
+        .period_bytes_max =   K1212_MAX_CHANNELS * 2 * kPlayBufferFrames,
         .periods_min =        K1212_PERIODS,
         .periods_max =        K1212_PERIODS,
         .fifo_size =          0,
@@ -1190,7 +1232,7 @@
 
 static snd_pcm_hardware_t snd_korg1212_capture_info =
 {
-        .info =               (SNDRV_PCM_INFO_MMAP |
+        .info =              (SNDRV_PCM_INFO_MMAP |
                               SNDRV_PCM_INFO_MMAP_VALID |
                               SNDRV_PCM_INFO_INTERLEAVED),
         .formats =	      SNDRV_PCM_FMTBIT_S16_LE,
@@ -1198,36 +1240,116 @@
                               SNDRV_PCM_RATE_48000),
         .rate_min =           44100,
         .rate_max =           48000,
-        .channels_min =       K1212_CHANNELS,
-        .channels_max =       K1212_CHANNELS,
-        .buffer_bytes_max =   K1212_BUF_SIZE,
-        .period_bytes_min =   K1212_PERIOD_BYTES,
-        .period_bytes_max =   K1212_PERIOD_BYTES,
+        .channels_min =       K1212_MIN_CHANNELS,
+        .channels_max =       K1212_MAX_CHANNELS,
+        .buffer_bytes_max =   K1212_MAX_BUF_SIZE,
+        .period_bytes_min =   K1212_MIN_CHANNELS * 2 * kPlayBufferFrames,
+        .period_bytes_max =   K1212_MAX_CHANNELS * 2 * kPlayBufferFrames,
         .periods_min =        K1212_PERIODS,
         .periods_max =        K1212_PERIODS,
         .fifo_size =          0,
 };
 
-static void snd_korg1212_free_pcm(snd_pcm_t *pcm)
+static int snd_korg1212_silence(korg1212_t *korg1212, int pos, int count, int offset, int size)
 {
-        korg1212_t *korg1212 = (korg1212_t *) pcm->private_data;
+	KorgAudioFrame * dst =  korg1212->playDataBufsPtr[0].bufferData + pos;
+	int i;
+
+#if K1212_DEBUG_LEVEL > 2
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_silence pos=%d offset=%d size=%d count=%d\n", pos, offset, size, count);
+#endif
+	snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
 
+	for (i=0; i < count; i++) {
 #if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_free_pcm [%s]\n", stateName[korg1212->cardState]);
+		if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||
+		     (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {
+			K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_silence KERNEL EFAULT dst=%p iter=%d\n", dst, i);
+			return -EFAULT;
+		}
+#endif
+		memset((void*) dst + offset, 0, size);
+		dst++;
+	}
+
+	return 0;
+}
+
+static int snd_korg1212_copy_to(korg1212_t *korg1212, void *dst, int pos, int count, int offset, int size)
+{
+	KorgAudioFrame * src =  korg1212->recordDataBufsPtr[0].bufferData + pos;
+	int i, rc;
+
+#if K1212_DEBUG_LEVEL > 2
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to pos=%d offset=%d size=%d\n", pos, offset, size);
 #endif
+	snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
 
-        korg1212->pcm16 = NULL;
+	for (i=0; i < count; i++) {
+#if K1212_DEBUG_LEVEL > 0
+		if ( (void *) src < (void *) korg1212->recordDataBufsPtr ||
+		     (void *) src > (void *) korg1212->recordDataBufsPtr[8].bufferData ) {
+			K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);
+			return -EFAULT;
+		}
+#endif
+		rc = copy_to_user((void*) dst + offset, src, size);
+		if (rc) {
+#if K1212_DEBUG_LEVEL > 0
+			K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i);
+#endif
+			return -EFAULT;
+		}
+		src++;
+		dst += size;
+	}
+
+	return 0;
 }
 
-static unsigned int period_bytes[] = { K1212_PERIOD_BYTES };
+static int snd_korg1212_copy_from(korg1212_t *korg1212, void *src, int pos, int count, int offset, int size)
+{
+	KorgAudioFrame * dst =  korg1212->playDataBufsPtr[0].bufferData + pos;
+	int i, rc;
 
-#define PERIOD_BYTES sizeof(period_bytes) / sizeof(period_bytes[0])
+#if K1212_DEBUG_LEVEL > 2
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_from pos=%d offset=%d size=%d count=%d\n", pos, offset, size, count);
+#endif
 
-static snd_pcm_hw_constraint_list_t hw_constraints_period_bytes = {
-        .count = PERIOD_BYTES,
-        .list = period_bytes,
-        .mask = 0
-};
+	snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
+
+	for (i=0; i < count; i++) {
+#if K1212_DEBUG_LEVEL > 0
+		if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||
+		     (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {
+			K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_from KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);
+			return -EFAULT;
+		}
+#endif
+		rc = copy_from_user((void*) dst + offset, src, size);
+		if (rc) {
+#if K1212_DEBUG_LEVEL > 0
+			K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_from USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i);
+#endif
+			return -EFAULT;
+		}
+		dst++;
+		src += size;
+	}
+
+	return 0;
+}
+
+static void snd_korg1212_free_pcm(snd_pcm_t *pcm)
+{
+        korg1212_t *korg1212 = (korg1212_t *) pcm->private_data;
+
+#if K1212_DEBUG_LEVEL > 0
+		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_free_pcm [%s]\n", stateName[korg1212->cardState]);
+#endif
+
+        korg1212->pcm = NULL;
+}
 
 static int snd_korg1212_playback_open(snd_pcm_substream_t *substream)
 {
@@ -1239,11 +1361,11 @@
 		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_open [%s]\n", stateName[korg1212->cardState]);
 #endif
 
-        spin_lock_irqsave(&korg1212->lock, flags);
+        snd_pcm_set_sync(substream);    // ???
 
-        snd_korg1212_OpenCard(korg1212);
+        spin_lock_irqsave(&korg1212->lock, flags);
 
-        snd_pcm_set_sync(substream);    // ???
+	snd_korg1212_OpenCard(korg1212);
 
         runtime->hw = snd_korg1212_playback_info;
 	runtime->dma_area = (char *) korg1212->playDataBufsPtr;
@@ -1251,14 +1373,15 @@
 
         korg1212->playback_substream = substream;
         korg1212->periodsize = K1212_PERIODS;
+	korg1212->channels = K1212_CHANNELS;
 
         spin_unlock_irqrestore(&korg1212->lock, flags);
 
-        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, K1212_BUF_SIZE, K1212_BUF_SIZE);
-        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
+        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, kPlayBufferFrames, kPlayBufferFrames);
         return 0;
 }
 
+
 static int snd_korg1212_capture_open(snd_pcm_substream_t *substream)
 {
         unsigned long flags;
@@ -1269,11 +1392,11 @@
 		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_open [%s]\n", stateName[korg1212->cardState]);
 #endif
 
-        spin_lock_irqsave(&korg1212->lock, flags);
+        snd_pcm_set_sync(substream);    // ???
 
-        snd_korg1212_OpenCard(korg1212);
+        spin_lock_irqsave(&korg1212->lock, flags);
 
-        snd_pcm_set_sync(substream);    // ???
+	snd_korg1212_OpenCard(korg1212);
 
         runtime->hw = snd_korg1212_capture_info;
 	runtime->dma_area = (char *) korg1212->recordDataBufsPtr;
@@ -1281,11 +1404,11 @@
 
         korg1212->capture_substream = substream;
         korg1212->periodsize = K1212_PERIODS;
+	korg1212->channels = K1212_CHANNELS;
 
         spin_unlock_irqrestore(&korg1212->lock, flags);
 
-        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, K1212_BUF_SIZE, K1212_BUF_SIZE);
-        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes);
+        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, kPlayBufferFrames, kPlayBufferFrames);
         return 0;
 }
 
@@ -1298,12 +1421,14 @@
 		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_close [%s]\n", stateName[korg1212->cardState]);
 #endif
 
+	snd_korg1212_silence(korg1212, 0, K1212_MAX_SAMPLES, 0, korg1212->channels * 2);
+
         spin_lock_irqsave(&korg1212->lock, flags);
 
         korg1212->playback_substream = NULL;
         korg1212->periodsize = 0;
 
-        snd_korg1212_CloseCard(korg1212);
+	snd_korg1212_CloseCard(korg1212);
 
         spin_unlock_irqrestore(&korg1212->lock, flags);
         return 0;
@@ -1323,43 +1448,28 @@
         korg1212->capture_substream = NULL;
         korg1212->periodsize = 0;
 
-        snd_korg1212_CloseCard(korg1212);
+	snd_korg1212_CloseCard(korg1212);
 
         spin_unlock_irqrestore(&korg1212->lock, flags);
         return 0;
 }
 
-static int snd_korg1212_channel_info(snd_pcm_substream_t *substream,
-				    snd_pcm_channel_info_t *info)
-{
-	int chn = info->channel;
-
-	// snd_assert(info->channel < kAudioChannels + 1, return -EINVAL);
-
-        info->offset = 0;
-        // if (chn < k16BitChannels) {
-                info->first = chn * 16;
-        // } else {
-        //         info->first = k16BitChannels * 16 + (chn - k16BitChannels - 1) * 32;
-        // }
-        info->step = sizeof(KorgAudioFrame) * 8;
-
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_channel_info %d:, offset=%ld, first=%d, step=%d\n", chn, info->offset, info->first, info->step);
-#endif
-
-	return 0;
-}
-
 static int snd_korg1212_ioctl(snd_pcm_substream_t *substream,
 			     unsigned int cmd, void *arg)
 {
 #if K1212_DEBUG_LEVEL > 0
 		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_ioctl: cmd=%d\n", cmd);
 #endif
+
 	if (cmd == SNDRV_PCM_IOCTL1_CHANNEL_INFO ) {
 		snd_pcm_channel_info_t *info = arg;
-		return snd_korg1212_channel_info(substream, info);
+        	info->offset = 0;
+        	info->first = info->channel * 16;
+        	info->step = 256;
+#if K1212_DEBUG_LEVEL > 0
+		K1212_DEBUG_PRINTK("K1212_DEBUG: channel_info %d:, offset=%ld, first=%d, step=%d\n", info->channel, info->offset, info->first, info->step);
+#endif
+		return 0;
 	}
 
         return snd_pcm_lib_ioctl(substream, cmd, arg);
@@ -1381,13 +1491,14 @@
                 spin_unlock_irqrestore(&korg1212->lock, flags);
                 return err;
         }
-
+/*
         if (params_format(params) != SNDRV_PCM_FORMAT_S16_LE) {
                 spin_unlock_irqrestore(&korg1212->lock, flags);
                 return -EINVAL;
         }
-
-        korg1212->periodsize = K1212_BLOCK_SIZE;
+*/
+	korg1212->channels = params_channels(params);
+        korg1212->periodsize = K1212_PERIOD_BYTES;
 
         spin_unlock_irqrestore(&korg1212->lock, flags);
 
@@ -1398,6 +1509,7 @@
 {
         korg1212_t *korg1212 = _snd_pcm_substream_chip(substream);
         unsigned long flags;
+	int rc;
 
 #if K1212_DEBUG_LEVEL > 0
 		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_prepare [%s]\n", stateName[korg1212->cardState]);
@@ -1405,18 +1517,19 @@
 
         spin_lock_irqsave(&korg1212->lock, flags);
 
-        snd_korg1212_SetupForPlay(korg1212);
-
-        korg1212->currentBuffer = -1;
+        rc = snd_korg1212_SetupForPlay(korg1212);
+        korg1212->currentBuffer = 0;
 
         spin_unlock_irqrestore(&korg1212->lock, flags);
-        return 0;
+
+	return rc ? -EINVAL : 0;
 }
 
 static int snd_korg1212_trigger(snd_pcm_substream_t *substream,
                            int cmd)
 {
         korg1212_t *korg1212 = _snd_pcm_substream_chip(substream);
+	int rc;
 
 #if K1212_DEBUG_LEVEL > 0
 		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_trigger [%s] cmd=%d\n", stateName[korg1212->cardState], cmd);
@@ -1424,72 +1537,82 @@
 
         switch (cmd) {
                 case SNDRV_PCM_TRIGGER_START:
-                        korg1212->running = 1;
-                        snd_korg1212_TriggerPlay(korg1212);
+/*
+			if (korg1212->running) {
+#if K1212_DEBUG_LEVEL > 1
+				K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_trigger: Already running?\n");
+#endif
+				break;
+			}
+*/
+                        korg1212->running++;
+                        rc = snd_korg1212_TriggerPlay(korg1212);
                         break;
 
                 case SNDRV_PCM_TRIGGER_STOP:
-                        korg1212->running = 0;
-                        snd_korg1212_StopPlay(korg1212);
+/*
+			if (!korg1212->running) {
+#if K1212_DEBUG_LEVEL > 1
+				K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_trigger: Already stopped?\n");
+#endif
+				break;
+			}
+*/
+                        korg1212->running--;
+                        rc = snd_korg1212_StopPlay(korg1212);
                         break;
 
                 default:
-                        return -EINVAL;
+			rc = 1;
+			break;
         }
-        return 0;
+        return rc ? -EINVAL : 0;
 }
 
-static snd_pcm_uframes_t snd_korg1212_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_korg1212_playback_pointer(snd_pcm_substream_t *substream)
 {
         korg1212_t *korg1212 = _snd_pcm_substream_chip(substream);
         snd_pcm_uframes_t pos;
 
-	if (korg1212->currentBuffer < 0)
-		return 0;
-
 	pos = korg1212->currentBuffer * kPlayBufferFrames;
 
-#if K1212_DEBUG_LEVEL > 1
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_pointer [%s] %ld\n", stateName[korg1212->cardState], pos);
+#if K1212_DEBUG_LEVEL > 2
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_pointer [%s] %ld\n", 
+			stateName[korg1212->cardState], pos);
 #endif
 
         return pos;
 }
 
-static int snd_korg1212_playback_copy(snd_pcm_substream_t *substream,
-                        int channel, /* not used (interleaved data) */
-                        snd_pcm_uframes_t pos,
-                        void *src,
-                        snd_pcm_uframes_t count)
+static snd_pcm_uframes_t snd_korg1212_capture_pointer(snd_pcm_substream_t *substream)
 {
         korg1212_t *korg1212 = _snd_pcm_substream_chip(substream);
-	KorgAudioFrame * dst = korg1212->playDataBufsPtr[0].bufferData + pos;
+        snd_pcm_uframes_t pos;
 
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_copy [%s] %ld %ld\n", stateName[korg1212->cardState], pos, count);
+	pos = korg1212->currentBuffer * kPlayBufferFrames;
+
+#if K1212_DEBUG_LEVEL > 2
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_pointer [%s] %ld\n",
+			stateName[korg1212->cardState], pos);
 #endif
- 
-	snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
 
-        return copy_from_user(dst, src, count * K1212_FRAME_SIZE) ? -EFAULT : 0;
+        return pos;
 }
 
-static int snd_korg1212_capture_copy(snd_pcm_substream_t *substream,
+static int snd_korg1212_playback_copy(snd_pcm_substream_t *substream,
                         int channel, /* not used (interleaved data) */
                         snd_pcm_uframes_t pos,
-                        void *dst,
+                        void *src,
                         snd_pcm_uframes_t count)
 {
         korg1212_t *korg1212 = _snd_pcm_substream_chip(substream);
-	KorgAudioFrame * src = korg1212->recordDataBufsPtr[0].bufferData + pos;
 
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_copy [%s] %ld %ld\n", stateName[korg1212->cardState], pos, count);
+#if K1212_DEBUG_LEVEL > 2
+		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_copy [%s] %ld %ld\n", stateName[korg1212->cardState], pos, count);
 #endif
+ 
+	return snd_korg1212_copy_from(korg1212, src, pos, count, 0, korg1212->channels * 2);
 
-	snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
-
-        return copy_to_user(dst, src, count * K1212_FRAME_SIZE) ? -EFAULT : 0;
 }
 
 static int snd_korg1212_playback_silence(snd_pcm_substream_t *substream,
@@ -1498,17 +1621,27 @@
                            snd_pcm_uframes_t count)
 {
         korg1212_t *korg1212 = _snd_pcm_substream_chip(substream);
-	KorgAudioFrame * dst = korg1212->playDataBufsPtr[0].bufferData + pos;
 
 #if K1212_DEBUG_LEVEL > 0
 		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_silence [%s]\n", stateName[korg1212->cardState]);
 #endif
 
-	snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
+	return snd_korg1212_silence(korg1212, pos, count, 0, korg1212->channels * 2);
+}
 
-        memset(dst, 0, count * K1212_FRAME_SIZE);
+static int snd_korg1212_capture_copy(snd_pcm_substream_t *substream,
+                        int channel, /* not used (interleaved data) */
+                        snd_pcm_uframes_t pos,
+                        void *dst,
+                        snd_pcm_uframes_t count)
+{
+        korg1212_t *korg1212 = _snd_pcm_substream_chip(substream);
 
-        return 0;
+#if K1212_DEBUG_LEVEL > 2
+		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_copy [%s] %ld %ld\n", stateName[korg1212->cardState], pos, count);
+#endif
+
+	return snd_korg1212_copy_to(korg1212, dst, pos, count, 0, korg1212->channels * 2);
 }
 
 static snd_pcm_ops_t snd_korg1212_playback_ops = {
@@ -1518,7 +1651,7 @@
         .hw_params =	snd_korg1212_hw_params,
         .prepare =	snd_korg1212_prepare,
         .trigger =	snd_korg1212_trigger,
-        .pointer =	snd_korg1212_pointer,
+        .pointer =	snd_korg1212_playback_pointer,
         .copy =		snd_korg1212_playback_copy,
         .silence =	snd_korg1212_playback_silence,
 };
@@ -1530,7 +1663,7 @@
 	.hw_params =	snd_korg1212_hw_params,
 	.prepare =	snd_korg1212_prepare,
 	.trigger =	snd_korg1212_trigger,
-	.pointer =	snd_korg1212_pointer,
+	.pointer =	snd_korg1212_capture_pointer,
 	.copy =		snd_korg1212_capture_copy,
 };
 
@@ -1555,7 +1688,7 @@
 
         u->value.integer.value[0] = korg1212->volumePhase[i];
 
-	if (i >= 8) 
+	if (i >= 8)
         	u->value.integer.value[1] = korg1212->volumePhase[i+1];
 
         spin_unlock_irqrestore(&korg1212->lock, flags);
@@ -1703,13 +1836,13 @@
 
 	i = kcontrol->private_value;
 
-	if (u->value.enumerated.item[0] != (unsigned int)korg1212->sharedBufferPtr->volumeData[i]) {
+	if (u->value.enumerated.item[0] != (unsigned) korg1212->sharedBufferPtr->volumeData[i]) {
 		korg1212->sharedBufferPtr->routeData[i] = u->value.enumerated.item[0];
 		change = 1;
 	}
 
 	if (i >= 8) {
-		if (u->value.enumerated.item[1] != (unsigned int)korg1212->sharedBufferPtr->volumeData[i+1]) {
+		if (u->value.enumerated.item[1] != (unsigned) korg1212->sharedBufferPtr->volumeData[i+1]) {
 			korg1212->sharedBufferPtr->routeData[i+1] = u->value.enumerated.item[1];
 			change = 1;
 		}
@@ -1720,7 +1853,7 @@
         return change;
 }
 
-static int snd_korg1212_control_analog_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_korg1212_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
         uinfo->count = 2;
@@ -1729,7 +1862,7 @@
         return 0;
 }
 
-static int snd_korg1212_control_analog_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
+static int snd_korg1212_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
 {
 	korg1212_t *korg1212 = _snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
@@ -1744,7 +1877,7 @@
         return 0;
 }
 
-static int snd_korg1212_control_analog_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
+static int snd_korg1212_control_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
 {
 	korg1212_t *korg1212 = _snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
@@ -1855,9 +1988,9 @@
                 .access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE,
                 .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
                 .name =		"ADC Attenuation",
-                .info =		snd_korg1212_control_analog_info,
-                .get =		snd_korg1212_control_analog_get,
-                .put =		snd_korg1212_control_analog_put,
+                .info =		snd_korg1212_control_info,
+                .get =		snd_korg1212_control_get,
+                .put =		snd_korg1212_control_put,
         }
 };
 
@@ -1875,7 +2008,7 @@
 	snd_iprintf(buffer, korg1212->card->longname);
 	snd_iprintf(buffer, " (index #%d)\n", korg1212->card->number + 1);
 	snd_iprintf(buffer, "\nGeneral settings\n");
-	snd_iprintf(buffer, "    period size: %d bytes\n", K1212_BLOCK_SIZE);
+	snd_iprintf(buffer, "    period size: %d bytes\n", K1212_PERIOD_BYTES);
 	snd_iprintf(buffer, "     clock mode: %s\n", clockSourceName[korg1212->clkSrcRate] );
 	snd_iprintf(buffer, "  left ADC Sens: %d\n", korg1212->leftADCInSens );
 	snd_iprintf(buffer, " right ADC Sens: %d\n", korg1212->rightADCInSens );
@@ -1901,19 +2034,132 @@
 		snd_info_set_text_ops(entry, korg1212, snd_korg1212_proc_read);
 }
 
-static int __devinit snd_korg1212_create(korg1212_t *korg1212)
+static int
+snd_korg1212_free(korg1212_t *korg1212)
+{
+        snd_korg1212_TurnOffIdleMonitor(korg1212);
+
+        if (korg1212->irq >= 0) {
+                synchronize_irq(korg1212->irq);                
+                snd_korg1212_DisableCardInterrupts(korg1212);
+                free_irq(korg1212->irq, (void *)korg1212);
+                korg1212->irq = -1;
+        }
+        
+        if (korg1212->iobase != 0) {
+                iounmap((void *)korg1212->iobase);
+                korg1212->iobase = 0;
+        }
+        
+        if (korg1212->res_iomem != NULL) {
+                release_resource(korg1212->res_iomem);
+                kfree_nocheck(korg1212->res_iomem);
+                korg1212->res_iomem = NULL;
+        }
+        
+        if (korg1212->res_ioport != NULL) {
+                release_resource(korg1212->res_ioport);
+                kfree_nocheck(korg1212->res_ioport);
+                korg1212->res_ioport = NULL;
+        }
+        
+        if (korg1212->res_iomem2 != NULL) {
+                release_resource(korg1212->res_iomem2);
+                kfree_nocheck(korg1212->res_iomem2);
+                korg1212->res_iomem2 = NULL;
+        }
+
+        // ----------------------------------------------------
+        // free up memory resources used for the DSP download.
+        // ----------------------------------------------------
+        if (korg1212->dspMemPtr) {
+                snd_free_pci_pages(korg1212->pci, korg1212->dspCodeSize,
+                                   korg1212->dspMemPtr, (dma_addr_t)korg1212->dspMemPhy);
+                korg1212->dspMemPhy = 0;
+                korg1212->dspMemPtr = 0;
+                korg1212->dspCodeSize = 0;
+        }
+
+#ifndef K1212_LARGEALLOC
+
+        // ------------------------------------------------------
+        // free up memory resources used for the Play/Rec Buffers
+        // ------------------------------------------------------
+	if (korg1212->playDataBufsPtr) {
+                snd_free_pci_pages(korg1212->pci, korg1212->DataBufsSize,
+                                   korg1212->playDataBufsPtr, (dma_addr_t)korg1212->PlayDataPhy);
+		korg1212->PlayDataPhy = 0;
+		korg1212->playDataBufsPtr = NULL;
+        }
+
+	if (korg1212->recordDataBufsPtr) {
+                snd_free_pci_pages(korg1212->pci, korg1212->DataBufsSize,
+                                   korg1212->recordDataBufsPtr, (dma_addr_t)korg1212->RecDataPhy);
+		korg1212->RecDataPhy = 0;
+		korg1212->recordDataBufsPtr = NULL;
+        }
+
+#endif
+
+        // ----------------------------------------------------
+        // free up memory resources used for the Shared Buffers
+        // ----------------------------------------------------
+	if (korg1212->sharedBufferPtr) {
+                snd_free_pci_pages(korg1212->pci, (u32) sizeof(KorgSharedBuffer),
+                                   korg1212->sharedBufferPtr, (dma_addr_t)korg1212->sharedBufferPhy);
+		korg1212->sharedBufferPhy = 0;
+		korg1212->sharedBufferPtr = NULL;
+        }
+        
+        snd_magic_kfree(korg1212);
+        return 0;
+}
+
+static int snd_korg1212_dev_free(snd_device_t *device)
+{
+        korg1212_t *korg1212 = snd_magic_cast(korg1212_t, device->device_data, return -ENXIO);
+#if K1212_DEBUG_LEVEL > 0
+        K1212_DEBUG_PRINTK("K1212_DEBUG: Freeing device\n");
+#endif
+	return snd_korg1212_free(korg1212);
+}
+
+static int __devinit snd_korg1212_create(snd_card_t * card, struct pci_dev *pci,
+                                         korg1212_t ** rchip)
+
 {
-        struct pci_dev *pci = korg1212->pci;
         int err;
         unsigned int i;
 	unsigned ioport_size, iomem_size, iomem2_size;
 	dma_addr_t phys_addr;
+        korg1212_t * korg1212;
+
+        static snd_device_ops_t ops = {
+                .dev_free = snd_korg1212_dev_free,
+        };
+
+        * rchip = NULL;
+        if ((err = pci_enable_device(pci)) < 0)
+                return err;
+
+        korg1212 = snd_magic_kcalloc(korg1212_t, 0, GFP_KERNEL);
+        if (korg1212 == NULL)
+                return -ENOMEM;
+
+	korg1212->card = card;
+	korg1212->pci = pci;
+
+        init_waitqueue_head(&korg1212->wait);
+        spin_lock_init(&korg1212->lock);
 
         korg1212->irq = -1;
         korg1212->clkSource = K1212_CLKIDX_Local;
         korg1212->clkRate = 44100;
         korg1212->inIRQ = 0;
         korg1212->running = 0;
+	korg1212->opencnt = 0;
+	korg1212->playcnt = 0;
+	korg1212->setcnt = 0;
         snd_korg1212_setCardState(korg1212, K1212_STATE_UNINITIALIZED);
         korg1212->idleMonitorOn = 0;
         korg1212->clkSrcRate = K1212_CLKIDX_LocalAt44_1K;
@@ -1923,9 +2169,6 @@
         for (i=0; i<kAudioChannels; i++)
                 korg1212->volumePhase[i] = 0;
 
-        if ((err = pci_enable_device(pci)) < 0)
-                return err;
-
         korg1212->iomem = pci_resource_start(korg1212->pci, 0);
         korg1212->ioport = pci_resource_start(korg1212->pci, 1);
         korg1212->iomem2 = pci_resource_start(korg1212->pci, 2);
@@ -1948,27 +2191,27 @@
 
         korg1212->res_iomem = request_mem_region(korg1212->iomem, iomem_size, "korg1212");
         if (korg1212->res_iomem == NULL) {
-		snd_printk("unable to grab region 0x%lx-0x%lx\n",
+		snd_printk(KERN_ERR "unable to grab region 0x%lx-0x%lx\n",
                            korg1212->iomem, korg1212->iomem + iomem_size - 1);
                 return -EBUSY;
         }
 
         korg1212->res_ioport = request_region(korg1212->ioport, ioport_size, "korg1212");
         if (korg1212->res_ioport == NULL) {
-		snd_printk("unable to grab region 0x%lx-0x%lx\n",
+		snd_printk(KERN_ERR "unable to grab region 0x%lx-0x%lx\n",
                            korg1212->ioport, korg1212->ioport + ioport_size - 1);
                 return -EBUSY;
         }
 
         korg1212->res_iomem2 = request_mem_region(korg1212->iomem2, iomem2_size, "korg1212");
         if (korg1212->res_iomem2 == NULL) {
-		snd_printk("unable to grab region 0x%lx-0x%lx\n",
+		snd_printk(KERN_ERR "unable to grab region 0x%lx-0x%lx\n",
                            korg1212->iomem2, korg1212->iomem2 + iomem2_size - 1);
                 return -EBUSY;
         }
 
         if ((korg1212->iobase = (unsigned long) ioremap(korg1212->iomem, iomem_size)) == 0) {
-		snd_printk("unable to remap memory region 0x%lx-0x%lx\n", korg1212->iobase,
+		snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", korg1212->iobase,
                            korg1212->iobase + iomem_size - 1);
                 return -EBUSY;
         }
@@ -1978,14 +2221,12 @@
                           "korg1212", (void *) korg1212);
 
         if (err) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
                 return -EBUSY;
         }
 
         korg1212->irq = pci->irq;
 
-        init_waitqueue_head(&korg1212->wait);
-        spin_lock_init(&korg1212->lock);
 	pci_set_master(korg1212->pci);
 
         korg1212->statusRegPtr = (u32 *) (korg1212->iobase + STATUS_REG_OFFSET);
@@ -2029,7 +2270,7 @@
 	korg1212->sharedBufferPhy = (unsigned long)phys_addr;
 
         if (korg1212->sharedBufferPtr == NULL) {
-		snd_printk("can not allocate shared buffer memory (%d bytes)\n", sizeof(KorgSharedBuffer));
+		snd_printk(KERN_ERR "can not allocate shared buffer memory (%d bytes)\n", sizeof(KorgSharedBuffer));
                 return -ENOMEM;
         }
 
@@ -2045,7 +2286,7 @@
 	korg1212->PlayDataPhy = (u32)phys_addr;
 
         if (korg1212->playDataBufsPtr == NULL) {
-		snd_printk("can not allocate play data buffer memory (%d bytes)\n", korg1212->DataBufsSize);
+		snd_printk(KERN_ERR "can not allocate play data buffer memory (%d bytes)\n", korg1212->DataBufsSize);
                 return -ENOMEM;
         }
 
@@ -2058,7 +2299,7 @@
 	korg1212->RecDataPhy = (u32)phys_addr;
 
         if (korg1212->recordDataBufsPtr == NULL) {
-		snd_printk("can not allocate record data buffer memory (%d bytes)\n", korg1212->DataBufsSize);
+		snd_printk(KERN_ERR "can not allocate record data buffer memory (%d bytes)\n", korg1212->DataBufsSize);
                 return -ENOMEM;
         }
 
@@ -2086,7 +2327,7 @@
 	korg1212->dspMemPhy = (u32)phys_addr;
 
         if (korg1212->dspMemPtr == NULL) {
-		snd_printk("can not allocate dsp code memory (%d bytes)\n", korg1212->dspCodeSize);
+		snd_printk(KERN_ERR "can not allocate dsp code memory (%d bytes)\n", korg1212->dspCodeSize);
                 return -ENOMEM;
         }
 
@@ -2106,7 +2347,7 @@
 
 	mdelay(CARD_BOOT_DELAY_IN_MS);
 
-        if (snd_korg1212_downloadDSPCode(korg1212))
+        if (snd_korg1212_downloadDSPCode(korg1212)) 
         	return -EBUSY;
 
 	printk(KERN_INFO "dspMemPhy       = %08x U[%08x]\n"
@@ -2122,17 +2363,21 @@
                korg1212->RoutingTablePhy, LowerWordSwap(korg1212->RoutingTablePhy),
                korg1212->AdatTimeCodePhy, LowerWordSwap(korg1212->AdatTimeCodePhy));
 
-        if ((err = snd_pcm_new(korg1212->card, "korg1212", 0, 1, 1, &korg1212->pcm16)) < 0)
+        if ((err = snd_pcm_new(korg1212->card, "korg1212", 0, 1, 1, &korg1212->pcm)) < 0)
                 return err;
 
-        korg1212->pcm16->private_data = korg1212;
-        korg1212->pcm16->private_free = snd_korg1212_free_pcm;
-        strcpy(korg1212->pcm16->name, "korg1212");
+	korg1212->pcm->private_data = korg1212;
+        korg1212->pcm->private_free = snd_korg1212_free_pcm;
+        strcpy(korg1212->pcm->name, "korg1212");
+
+        snd_pcm_set_ops(korg1212->pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_korg1212_playback_ops);
+        
+	snd_pcm_set_ops(korg1212->pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_korg1212_capture_ops);
 
-        snd_pcm_set_ops(korg1212->pcm16, SNDRV_PCM_STREAM_PLAYBACK, &snd_korg1212_playback_ops);
-        snd_pcm_set_ops(korg1212->pcm16, SNDRV_PCM_STREAM_CAPTURE, &snd_korg1212_capture_ops);
+	korg1212->pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
 
-	korg1212->pcm16->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
+	//snd_pcm_lib_preallocate_pages_for_all(korg1212->pcm,
+	//			K1212_MAX_BUF_SIZE, K1212_MAX_BUF_SIZE, GFP_KERNEL);
 
         for (i = 0; i < K1212_CONTROL_ELEMENTS; i++) {
                 err = snd_ctl_add(korg1212->card, snd_ctl_new1(&snd_korg1212_controls[i], korg1212));
@@ -2141,103 +2386,21 @@
         }
 
         snd_korg1212_proc_init(korg1212);
-
-	return 0;
-
-}
-
-static void
-snd_korg1212_free(void *private_data)
-{
-        korg1212_t *korg1212 = (korg1212_t *)private_data;
-
-        if (korg1212 == NULL) {
-                return;
-        }
-
-        snd_korg1212_TurnOffIdleMonitor(korg1212);
-
-        snd_korg1212_DisableCardInterrupts(korg1212);
-
-        if (korg1212->irq >= 0) {
-                free_irq(korg1212->irq, (void *)korg1212);
-                korg1212->irq = -1;
-        }
-        if (korg1212->iobase != 0) {
-                iounmap((void *)korg1212->iobase);
-                korg1212->iobase = 0;
-        }
-        if (korg1212->res_iomem != NULL) {
-                release_resource(korg1212->res_iomem);
-                kfree_nocheck(korg1212->res_iomem);
-                korg1212->res_iomem = NULL;
-        }
-        if (korg1212->res_ioport != NULL) {
-                release_resource(korg1212->res_ioport);
-                kfree_nocheck(korg1212->res_ioport);
-                korg1212->res_ioport = NULL;
-        }
-        if (korg1212->res_iomem2 != NULL) {
-                release_resource(korg1212->res_iomem2);
-                kfree_nocheck(korg1212->res_iomem2);
-                korg1212->res_iomem2 = NULL;
-        }
-
-        // ----------------------------------------------------
-        // free up memory resources used for the DSP download.
-        // ----------------------------------------------------
-        if (korg1212->dspMemPtr) {
-                snd_free_pci_pages(korg1212->pci, korg1212->dspCodeSize,
-                                   korg1212->dspMemPtr, (dma_addr_t)korg1212->dspMemPhy);
-                korg1212->dspMemPhy = 0;
-                korg1212->dspMemPtr = 0;
-                korg1212->dspCodeSize = 0;
-        }
-
-#ifndef K1212_LARGEALLOC
-
-        // ------------------------------------------------------
-        // free up memory resources used for the Play/Rec Buffers
-        // ------------------------------------------------------
-	if (korg1212->playDataBufsPtr) {
-                snd_free_pci_pages(korg1212->pci, korg1212->DataBufsSize,
-                                   korg1212->playDataBufsPtr, (dma_addr_t)korg1212->PlayDataPhy);
-		korg1212->PlayDataPhy = 0;
-		korg1212->playDataBufsPtr = NULL;
-        }
-
-	if (korg1212->recordDataBufsPtr) {
-                snd_free_pci_pages(korg1212->pci, korg1212->DataBufsSize,
-                                   korg1212->recordDataBufsPtr, (dma_addr_t)korg1212->RecDataPhy);
-		korg1212->RecDataPhy = 0;
-		korg1212->recordDataBufsPtr = NULL;
+        
+        if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, korg1212, &ops)) < 0) {
+                snd_korg1212_free(korg1212);
+                return err;
         }
+        
+        * rchip = korg1212;
+	return 0;
 
-#endif
-
-        // ----------------------------------------------------
-        // free up memory resources used for the Shared Buffers
-        // ----------------------------------------------------
-	if (korg1212->sharedBufferPtr) {
-                snd_free_pci_pages(korg1212->pci, (u32) sizeof(KorgSharedBuffer),
-                                   korg1212->sharedBufferPtr, (dma_addr_t)korg1212->sharedBufferPhy);
-		korg1212->sharedBufferPhy = 0;
-		korg1212->sharedBufferPtr = NULL;
-        }
 }
 
 /*
  * Card initialisation
  */
 
-static void snd_korg1212_card_free(snd_card_t *card)
-{
-#if K1212_DEBUG_LEVEL > 0
-        K1212_DEBUG_PRINTK("K1212_DEBUG: Freeing card\n");
-#endif
-	snd_korg1212_free(card->private_data);
-}
-
 static int __devinit
 snd_korg1212_probe(struct pci_dev *pci,
 		const struct pci_device_id *pci_id)
@@ -2254,16 +2417,11 @@
 		dev++;
 		return -ENOENT;
 	}
-	if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
-				 sizeof(korg1212_t))) == NULL)
+	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+        if (card == NULL)
 		return -ENOMEM;
 
-	card->private_free = snd_korg1212_card_free;
-	korg1212 = (korg1212_t *)card->private_data;
-	korg1212->card = card;
-	korg1212->pci = pci;
-
-	if ((err = snd_korg1212_create(korg1212)) < 0) {
+        if ((err = snd_korg1212_create(card, pci, &korg1212)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -2281,22 +2439,23 @@
 		snd_card_free(card);
 		return err;
 	}
-	pci_set_drvdata(pci, card);
+	pci_set_drvdata(pci, korg1212);
 	dev++;
 	return 0;
 }
 
 static void __devexit snd_korg1212_remove(struct pci_dev *pci)
 {
-	snd_card_free(pci_get_drvdata(pci));
+	korg1212_t *korg1212 = pci_get_drvdata(pci);
+	snd_card_free(korg1212->card);
 	pci_set_drvdata(pci, NULL);
 }
 
 static struct pci_driver driver = {
-	.name	  = "korg1212",
+	.name = "korg1212",
 	.id_table = snd_korg1212_ids,
-	.probe	  = snd_korg1212_probe,
-	.remove	  = __devexit_p(snd_korg1212_remove),
+	.probe = snd_korg1212_probe,
+	.remove = __devexit_p(snd_korg1212_remove),
 };
 
 static int __init alsa_card_korg1212_init(void)
diff -Nru a/sound/pci/maestro3.c b/sound/pci/maestro3.c
--- a/sound/pci/maestro3.c	Sun Feb 16 05:47:43 2003
+++ b/sound/pci/maestro3.c	Thu Mar 20 08:41:15 2003
@@ -941,13 +941,14 @@
 	},
 	/* Dell Inspiron 8000 */
 	{
-		.name = "Dell Insprion 8000",
+		.name = "Dell Inspiron 8000",
 		.vendor = 0x1028,
 		.device = 0x00a4,
 		.amp_gpio = -1,
 		.irda_workaround = 1,
 	},
-	/* FIXME: Inspiron 8100 and 8200 ids should be here, too */
+	/* FIXME: Inspiron 8100 id should probably be here, too
+	 * (8200 irrelevant: has intel8x0 with CS4205) */
 	/* END */
 	{ 0 }
 };
diff -Nru a/sound/pci/rme9652/hammerfall_mem.c b/sound/pci/rme9652/hammerfall_mem.c
--- a/sound/pci/rme9652/hammerfall_mem.c	Fri Feb 21 11:45:47 2003
+++ b/sound/pci/rme9652/hammerfall_mem.c	Thu Mar 20 08:41:15 2003
@@ -25,7 +25,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
-    $Id: hammerfall_mem.c,v 1.7 2003/01/06 14:21:28 perex Exp $
+    $Id: hammerfall_mem.c,v 1.8 2003/02/25 13:35:44 perex Exp $
 
 
     Tue Oct 17 2000  Jaroslav Kysela <perex@suse.cz>
diff -Nru a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
--- a/sound/pci/rme9652/hdsp.c	Sun Feb 16 05:47:44 2003
+++ b/sound/pci/rme9652/hdsp.c	Thu Mar 20 08:41:15 2003
@@ -72,7 +72,7 @@
 MODULE_DESCRIPTION("RME Hammerfall DSP");
 MODULE_LICENSE("GPL");
 MODULE_CLASSES("{sound}");
-MODULE_DEVICES("{{RME,Hammerfall-DSP},");
+MODULE_DEVICES("{{RME,Hammerfall-DSP}}");
 
 typedef enum {
 	Digiface,
@@ -2310,7 +2310,8 @@
 
 	channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
 	snd_assert(channel_buf != NULL, return -EIO);
-	copy_from_user(channel_buf + pos * 4, src, count * 4);
+	if (copy_from_user(channel_buf + pos * 4, src, count * 4))
+		return -EFAULT;
 	return count;
 }
 
@@ -2324,7 +2325,8 @@
 
 	channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
 	snd_assert(channel_buf != NULL, return -EIO);
-	copy_to_user(dst, channel_buf + pos * 4, count * 4);
+	if (copy_to_user(dst, channel_buf + pos * 4, count * 4))
+		return -EFAULT;
 	return count;
 }
 
@@ -2634,16 +2636,16 @@
 	snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	if (r->min > 48000) {
 		snd_interval_t t = {
-			min: hdsp->ds_channels,
-			max: hdsp->ds_channels,
-			integer: 1,
+			.min = hdsp->ds_channels,
+			.max = hdsp->ds_channels,
+			.integer = 1,
 		};
 		return snd_interval_refine(c, &t);
 	} else if (r->max < 64000) {
 		snd_interval_t t = {
-			min: hdsp->ss_channels,
-			max: hdsp->ss_channels,
-			integer: 1,
+			.min = hdsp->ss_channels,
+			.max = hdsp->ss_channels,
+			.integer = 1,
 		};
 		return snd_interval_refine(c, &t);
 	}
@@ -2658,16 +2660,16 @@
 	snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	if (c->min >= hdsp->ss_channels) {
 		snd_interval_t t = {
-			min: 32000,
-			max: 48000,
-			integer: 1,
+			.min = 32000,
+			.max = 48000,
+			.integer = 1,
 		};
 		return snd_interval_refine(r, &t);
 	} else if (c->max <= hdsp->ds_channels) {
 		snd_interval_t t = {
-			min: 64000,
-			max: 96000,
-			integer: 1,
+			.min = 64000,
+			.max = 96000,
+			.integer = 1,
 		};
 		return snd_interval_refine(r, &t);
 	}
diff -Nru a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
--- a/sound/pci/rme9652/rme9652.c	Sat Feb  8 12:10:55 2003
+++ b/sound/pci/rme9652/rme9652.c	Thu Mar 20 08:41:15 2003
@@ -2326,16 +2326,16 @@
 	snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	if (r->min > 48000) {
 		snd_interval_t t = {
-			min: rme9652->ds_channels,
-			max: rme9652->ds_channels,
-			integer: 1,
+			.min = rme9652->ds_channels,
+			.max = rme9652->ds_channels,
+			.integer = 1,
 		};
 		return snd_interval_refine(c, &t);
 	} else if (r->max < 88200) {
 		snd_interval_t t = {
-			min: rme9652->ss_channels,
-			max: rme9652->ss_channels,
-			integer: 1,
+			.min = rme9652->ss_channels,
+			.max = rme9652->ss_channels,
+			.integer = 1,
 		};
 		return snd_interval_refine(c, &t);
 	}
@@ -2350,16 +2350,16 @@
 	snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	if (c->min >= rme9652->ss_channels) {
 		snd_interval_t t = {
-			min: 44100,
-			max: 48000,
-			integer: 1,
+			.min = 44100,
+			.max = 48000,
+			.integer = 1,
 		};
 		return snd_interval_refine(r, &t);
 	} else if (c->max <= rme9652->ds_channels) {
 		snd_interval_t t = {
-			min: 88200,
-			max: 96000,
-			integer: 1,
+			.min = 88200,
+			.max = 96000,
+			.integer = 1,
 		};
 		return snd_interval_refine(r, &t);
 	}
diff -Nru a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
--- a/sound/pci/sonicvibes.c	Sat Feb  8 12:10:55 2003
+++ b/sound/pci/sonicvibes.c	Thu Mar 20 08:41:15 2003
@@ -267,14 +267,14 @@
 MODULE_DEVICE_TABLE(pci, snd_sonic_ids);
 
 static ratden_t sonicvibes_adc_clock = {
-	num_min: 4000 * 65536,
-	num_max: 48000UL * 65536,
-	num_step: 1,
-	den: 65536,
+	.num_min = 4000 * 65536,
+	.num_max = 48000UL * 65536,
+	.num_step = 1,
+	.den = 65536,
 };
 static snd_pcm_hw_constraint_ratdens_t snd_sonicvibes_hw_constraints_adc_clock = {
-	nrats: 1,
-	rats: &sonicvibes_adc_clock,
+	.nrats = 1,
+	.rats = &sonicvibes_adc_clock,
 };
 
 /*
diff -Nru a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
--- a/sound/pci/trident/trident.c	Sat Nov 23 03:15:32 2002
+++ b/sound/pci/trident/trident.c	Thu Mar 20 08:41:15 2003
@@ -100,7 +100,7 @@
 
 	if ((err = snd_trident_create(card, pci,
 				      pcm_channels[dev],
-				      2,
+				      ((pci->vendor << 16) | pci->device) == TRIDENT_DEVICE_ID_SI7018 ? 1 : 2,
 				      wavetable_size[dev],
 				      &trident)) < 0) {
 		snd_card_free(card);
diff -Nru a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
--- a/sound/pci/trident/trident_main.c	Sun Feb 16 05:47:44 2003
+++ b/sound/pci/trident/trident_main.c	Thu Mar 20 08:41:15 2003
@@ -41,7 +41,6 @@
 #include <sound/control.h>
 #include <sound/trident.h>
 #include <sound/asoundef.h>
-#include <sound/pcm_sgbuf.h>
 
 #include <asm/io.h>
 
@@ -514,6 +513,29 @@
 }
 
 /*---------------------------------------------------------------------------
+   snd_trident_write_eso_reg
+  
+   Description: This routine will write the new ESO offset
+                register to hardware.
+  
+   Paramters:   trident - pointer to target device class for 4DWave.
+                voice - synthesizer voice structure
+                ESO - new ESO value
+  
+  ---------------------------------------------------------------------------*/
+
+static void snd_trident_write_eso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int ESO)
+{
+	voice->ESO = ESO;
+	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
+	if (trident->device != TRIDENT_DEVICE_ID_NX) {
+		outw(voice->ESO, TRID_REG(trident, CH_DX_ESO_DELTA) + 2);
+	} else {
+		outl(((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_ESO));
+	}
+}
+
+/*---------------------------------------------------------------------------
    snd_trident_write_vol_reg
   
    Description: This routine will write the new voice volume
@@ -924,7 +946,7 @@
 		evoice->spurious_threshold = voice->spurious_threshold;
 		evoice->LBA = voice->LBA;
 		evoice->CSO = 0;
-		evoice->ESO = (runtime->period_size * 2) - 1; /* in samples */
+		evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
 		evoice->CTRL = voice->CTRL;
 		evoice->FMC = 3;
 		evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
@@ -941,6 +963,9 @@
 		evoice->Attribute = 0;
 #endif
 		snd_trident_write_voice_regs(trident, evoice);
+		evoice->isync2 = 1;
+		evoice->isync_mark = runtime->period_size;
+		evoice->ESO = (runtime->period_size * 2) - 1;
 	}
 
 	spin_unlock(&trident->reg_lock);
@@ -984,6 +1009,8 @@
 	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
 	unsigned int val, ESO_bytes;
 
+	snd_assert(substream->dma_device.type == SNDRV_DMA_TYPE_PCI, return -EIO);
+
 	spin_lock(&trident->reg_lock);
 
 	// Initilize the channel and set channel Mode
@@ -992,13 +1019,11 @@
 	// Set DMA channel operation mode register
 	outb(0x54, TRID_REG(trident, LEGACY_DMAR11));
 
-	// Set channel buffer Address
-	/* FIXME: LEGACY_DMAR0 correctly set? */
+	// Set channel buffer Address, DMAR0 expects contiguous PCI memory area	
+	voice->LBA = runtime->dma_addr;
+	outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0));
 	if (voice->memblk)
 		voice->LBA = voice->memblk->offset;
-	else
-		voice->LBA = runtime->dma_addr;
-	outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0));
 
 	// set ESO
 	ESO_bytes = snd_pcm_lib_buffer_bytes(substream) - 1;
@@ -1007,7 +1032,7 @@
 	ESO_bytes++;
 
 	// Set channel sample rate, 4.12 format
-	val = ((unsigned int) 48000L << 12) / runtime->rate;
+	val = (((unsigned int) 48000L << 12) + (runtime->rate/2)) / runtime->rate;
 	outw(val, TRID_REG(trident, T4D_SBDELTA_DELTA_R));
 
 	// Set channel interrupt blk length
@@ -1034,15 +1059,13 @@
 
 	voice->Delta = snd_trident_convert_rate(runtime->rate);
 	voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
+	voice->isync = 1;
+	voice->isync_mark = runtime->period_size;
+	voice->isync_max = runtime->buffer_size;
 
 	// Set voice parameters
 	voice->CSO = 0;
-	/* the +2 is a correction for a h/w problem. if not
-	   used, the ESO interrupt is received before the capture pointer
-	   has actually reached the ESO point. this causes errors in
-	   the mid-level code.
-	*/
-	voice->ESO = (runtime->period_size * 2) + 2 - 1;
+	voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1;
 	voice->CTRL = snd_trident_control_mode(substream);
 	voice->FMC = 3;
 	voice->RVol = 0x7f;
@@ -1160,7 +1183,7 @@
 		evoice->spurious_threshold = voice->spurious_threshold;
 		evoice->LBA = voice->LBA;
 		evoice->CSO = 0;
-		evoice->ESO = (runtime->period_size * 2) + 8 - 1; /* in samples, 8 means correction */
+		evoice->ESO = (runtime->period_size * 2) + 20 - 1; /* in samples, 20 means correction */
 		evoice->CTRL = voice->CTRL;
 		evoice->FMC = 3;
 		evoice->GVSel = 0;
@@ -1172,6 +1195,9 @@
 		evoice->Pan = 0x7f;			/* mute */
 		evoice->Attribute = 0;
 		snd_trident_write_voice_regs(trident, evoice);
+		evoice->isync2 = 1;
+		evoice->isync_mark = runtime->period_size;
+		evoice->ESO = (runtime->period_size * 2) - 1;
 	}
 	
 	spin_unlock(&trident->reg_lock);
@@ -1234,7 +1260,7 @@
 		evoice->spurious_threshold = voice->spurious_threshold;
 		evoice->LBA = voice->LBA;
 		evoice->CSO = 0;
-		evoice->ESO = (runtime->period_size * 2) - 1; /* in samples */
+		evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
 		evoice->CTRL = voice->CTRL;
 		evoice->FMC = 3;
 		evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
@@ -1246,6 +1272,9 @@
 		evoice->Pan = 0x7f;			/* mute */
 		evoice->Attribute = 0;
 		snd_trident_write_voice_regs(trident, evoice);
+		evoice->isync2 = 1;
+		evoice->isync_mark = runtime->period_size;
+		evoice->ESO = (runtime->period_size * 2) - 1;
 	}
 
 	spin_unlock(&trident->reg_lock);
@@ -1348,16 +1377,20 @@
 		voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);
 
 		/* set Loop Back Address */
-		/* FIXME: LBAO?? */
 		LBAO = runtime->dma_addr;
 		if (voice->memblk)
 			voice->LBA = voice->memblk->offset;
 		else
 			voice->LBA = LBAO;
 
+		voice->isync = 1;
+		voice->isync3 = 1;
+		voice->isync_mark = runtime->period_size;
+		voice->isync_max = runtime->buffer_size;
+
 		/* set target ESO for channel */
 		RESO = runtime->buffer_size - 1;
-		voice->ESO = (runtime->period_size * 2) - 1;
+		voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1;
 
 		/* set ctrl mode */
 		voice->CTRL = snd_trident_control_mode(substream);
@@ -1421,7 +1454,7 @@
 			evoice->spurious_threshold = voice->spurious_threshold;
 			evoice->LBA = voice->LBA;
 			evoice->CSO = 0;
-			evoice->ESO = (runtime->period_size * 2) - 1; /* in samples */
+			evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */
 			evoice->CTRL = voice->CTRL;
 			evoice->FMC = 3;
 			evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;
@@ -1433,6 +1466,9 @@
 			evoice->Pan = 0x7f;			/* mute */
 			evoice->Attribute = 0;
 			snd_trident_write_voice_regs(trident, evoice);
+			evoice->isync2 = 1;
+			evoice->isync_mark = runtime->period_size;
+			evoice->ESO = (runtime->period_size * 2) - 1;
 		}
 
 		outl(trident->spdif_pcm_bits, TRID_REG(trident, SI_SPDIF_CS));
@@ -1499,6 +1535,8 @@
 			} else {
 				what |= 1 << (evoice->number & 0x1f);
 				whati |= 1 << (evoice->number & 0x1f);
+				if (go)
+					evoice->stimer = val;
 			}
 			if (go) {
 				voice->running = 1;
@@ -1579,7 +1617,7 @@
 
 	spin_unlock(&trident->reg_lock);
 
-	if (++cso >= runtime->buffer_size)
+	if (cso >= runtime->buffer_size)
 		cso = 0;
 
 	return cso;
@@ -1612,8 +1650,6 @@
 	if (result > 0)
 		result = runtime->buffer_size - result;
 
-	// printk("capture result = 0x%x, cso = 0x%x\n", result, cso);
-
 	return result;
 }
 
@@ -1833,6 +1869,7 @@
 		return -EAGAIN;
 	voice->spdif = 1;
 	voice->substream = substream;
+	spin_lock_irq(&trident->reg_lock);
 	trident->spdif_pcm_bits = trident->spdif_bits;
 	spin_unlock_irq(&trident->reg_lock);
 
@@ -2023,18 +2060,6 @@
 	.pointer =	snd_trident_capture_pointer,
 };
 
-static snd_pcm_ops_t snd_trident_nx_capture_ops = {
-	.open =		snd_trident_capture_open,
-	.close =	snd_trident_capture_close,
-	.ioctl =	snd_trident_ioctl,
-	.hw_params =	snd_trident_capture_hw_params,
-	.hw_free =	snd_trident_hw_free,
-	.prepare =	snd_trident_capture_prepare,
-	.trigger =	snd_trident_trigger,
-	.pointer =	snd_trident_capture_pointer,
-	.page =		snd_pcm_sgbuf_ops_page,
-};
-
 static snd_pcm_ops_t snd_trident_si7018_capture_ops = {
 	.open =		snd_trident_capture_open,
 	.close =	snd_trident_capture_close,
@@ -2080,18 +2105,6 @@
 	.pointer =	snd_trident_spdif_pointer,
 };
 
-static snd_pcm_ops_t snd_trident_nx_spdif_ops = {
-	.open =		snd_trident_spdif_open,
-	.close =	snd_trident_spdif_close,
-	.ioctl =	snd_trident_ioctl,
-	.hw_params =	snd_trident_spdif_hw_params,
-	.hw_free =	snd_trident_hw_free,
-	.prepare =	snd_trident_spdif_prepare,
-	.trigger =	snd_trident_trigger,
-	.pointer =	snd_trident_spdif_pointer,
-	.page =		snd_pcm_sgbuf_ops_page,
-};
-
 static snd_pcm_ops_t snd_trident_spdif_7018_ops = {
 	.open =		snd_trident_spdif_open,
 	.close =	snd_trident_spdif_close,
@@ -2160,24 +2173,27 @@
 
 	if (trident->tlb.entries) {
 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_playback_ops);
-		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_capture_ops);
 	} else {
 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_playback_ops);
-		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
-				trident->device != TRIDENT_DEVICE_ID_SI7018 ?
-				&snd_trident_capture_ops :
-				&snd_trident_si7018_capture_ops);
 	}
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+			trident->device != TRIDENT_DEVICE_ID_SI7018 ?
+			&snd_trident_capture_ops :
+			&snd_trident_si7018_capture_ops);
 
 	pcm->info_flags = 0;
 	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
 	strcpy(pcm->name, "Trident 4DWave");
 	trident->pcm = pcm;
 
-	if (trident->tlb.entries)
-		snd_pcm_lib_preallocate_sg_pages_for_all(trident->pci, pcm, 64*1024, 128*1024);
-	else
+	if (trident->tlb.entries) {
+		snd_pcm_substream_t *substream;
+		for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
+			snd_pcm_lib_preallocate_sg_pages(trident->pci, substream, 64*1024, 128*1024);
+		snd_pcm_lib_preallocate_pci_pages(trident->pci, pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream, 64*1024, 128*1024);
+	} else {
 		snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, pcm, 64*1024, 128*1024);
+	}
 
 	if (rpcm)
 		*rpcm = pcm;
@@ -2262,9 +2278,7 @@
 
 	spdif->private_data = trident;
 	spdif->private_free = snd_trident_spdif_pcm_free;
-	if (trident->tlb.entries) {
-		snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_spdif_ops);
-	} else if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
+	if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
 		snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_ops);
 	} else {
 		snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_7018_ops);
@@ -2273,10 +2287,7 @@
 	strcpy(spdif->name, "Trident 4DWave IEC958");
 	trident->spdif = spdif;
 
-	if (trident->tlb.entries)
-		snd_pcm_lib_preallocate_sg_pages_for_all(trident->pci, spdif, 64*1024, 128*1024);
-	else
-		snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, spdif, 64*1024, 128*1024);
+	snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, spdif, 64*1024, 128*1024);
 
 	if (rpcm)
 		*rpcm = spdif;
@@ -2947,6 +2958,7 @@
 	_ac97.read = snd_trident_codec_read;
 	_ac97.private_data = trident;
 	trident->ac97_detect = 1;
+
       __again:
 	if ((err = snd_ac97_mixer(trident->card, &_ac97, &trident->ac97)) < 0) {
 		if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
@@ -2958,6 +2970,24 @@
 		}
 		return err;
 	}
+	
+	/* secondary codec? */
+	if (trident->device == TRIDENT_DEVICE_ID_SI7018 &&
+	    (inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0) {
+		_ac97.num = 1;
+		err = snd_ac97_mixer(trident->card, &_ac97, &trident->ac97_sec);
+		if (err < 0)
+			snd_printk("SI7018: the secondary codec - invalid access\n");
+#if 0	// only for my testing purpose --jk
+		{
+			ac97_t *mc97;
+			err = snd_ac97_modem(trident->card, &_ac97, &mc97);
+			if (err < 0)
+				snd_printk("snd_ac97_modem returned error %i\n", err);
+		}
+#endif
+	}
+	
 	trident->ac97_detect = 0;
 
 	if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
@@ -3012,17 +3042,29 @@
 		kctl->put(kctl, &uctl);
 	}
 	if (trident->device == TRIDENT_DEVICE_ID_NX || trident->device == TRIDENT_DEVICE_ID_SI7018) {
+
 		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_spdif_control, trident))) < 0)
 			return err;
+		if (trident->ac97->ext_id & AC97_EI_SPDIF)
+			kctl->id.index++;
+		if (trident->ac97_sec && (trident->ac97_sec->ext_id & AC97_EI_SPDIF))
+			kctl->id.index++;
+		idx = kctl->id.index;
 		kctl->put(kctl, &uctl);
+
 		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_spdif_default, trident))) < 0)
 			return err;
+		kctl->id.index = idx;
 		kctl->id.device = pcm_spdif_device;
+
 		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_spdif_mask, trident))) < 0)
 			return err;
+		kctl->id.index = idx;
 		kctl->id.device = pcm_spdif_device;
+
 		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_trident_spdif_stream, trident))) < 0)
 			return err;
+		kctl->id.index = idx;
 		kctl->id.device = pcm_spdif_device;
 		trident->spdif_pcm_ctl = kctl;
 	}
@@ -3181,6 +3223,12 @@
 		goto __si7018_retry;
 	}
       __si7018_ok:
+	/* wait for the second codec */
+	do {
+		if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_SECONDARY_READY) != 0)
+			break;
+		do_delay(trident);
+	} while (time_after_eq(end_time, jiffies));
 	/* enable 64 channel mode */
 	outl(BANK_B_EN, TRID_REG(trident, T4D_LFO_GC_CIR));
 	return 0;
@@ -3640,7 +3688,7 @@
 static void snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	trident_t *trident = snd_magic_cast(trident_t, dev_id, return);
-	unsigned int audio_int, chn_int, stimer, channel, mask;
+	unsigned int audio_int, chn_int, stimer, channel, mask, tmp;
 	int delta;
 	snd_trident_voice_t *voice;
 
@@ -3679,16 +3727,42 @@
 				continue;
 			}
 			voice->stimer = stimer;
+			if (voice->isync) {
+				if (!voice->isync3) {
+					tmp = inw(TRID_REG(trident, T4D_SBBL_SBCL));
+					if (trident->bDMAStart & 0x40)
+						tmp >>= 1;
+					if (tmp > 0)
+						tmp = voice->isync_max - tmp;
+				} else {
+					tmp = inl(TRID_REG(trident, NX_SPCTRL_SPCSO)) & 0x00ffffff;
+				}
+				if (tmp < voice->isync_mark) {
+					if (tmp > 0x10)
+						tmp = voice->isync_ESO - 7;
+					else
+						tmp = voice->isync_ESO + 2;
+					/* update ESO for IRQ voice to preserve sync */
+					snd_trident_stop_voice(trident, voice->number);
+					snd_trident_write_eso_reg(trident, voice, tmp);
+					snd_trident_start_voice(trident, voice->number);
+				}
+			} else if (voice->isync2) {
+				voice->isync2 = 0;
+				/* write original ESO and update CSO for IRQ voice to preserve sync */
+				snd_trident_stop_voice(trident, voice->number);
+				snd_trident_write_cso_reg(trident, voice, voice->isync_mark);
+				snd_trident_write_eso_reg(trident, voice, voice->ESO);
+				snd_trident_start_voice(trident, voice->number);
+			}
+#if 0
 			if (voice->extra) {
 				/* update CSO for extra voice to preserve sync */
 				snd_trident_stop_voice(trident, voice->extra->number);
 				snd_trident_write_cso_reg(trident, voice->extra, 0);
 				snd_trident_start_voice(trident, voice->extra->number);
-			} else if (voice->spdif) {
-				snd_trident_stop_voice(trident, voice->number);
-				snd_trident_write_cso_reg(trident, voice, 0);
-				snd_trident_start_voice(trident, voice->number);
 			}
+#endif
 			spin_unlock(&trident->reg_lock);
 			snd_pcm_period_elapsed(voice->substream);
 			spin_lock(&trident->reg_lock);
diff -Nru a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
--- a/sound/pci/trident/trident_memory.c	Mon Jan 27 09:30:54 2003
+++ b/sound/pci/trident/trident_memory.c	Thu Mar 20 08:41:15 2003
@@ -28,7 +28,6 @@
 #include <linux/time.h>
 #include <sound/core.h>
 #include <sound/trident.h>
-#include <sound/pcm_sgbuf.h>
 
 /* page arguments of these two macros are Trident page (4096 bytes), not like
  * aligned pages in others
@@ -181,23 +180,26 @@
 }
 
 /*
- * page allocation for DMA
+ * page allocation for DMA (Scatter-Gather version)
  */
-snd_util_memblk_t *
-snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream)
+static snd_util_memblk_t *
+snd_trident_alloc_sg_pages(trident_t *trident, snd_pcm_substream_t *substream)
 {
 	snd_util_memhdr_t *hdr;
 	snd_util_memblk_t *blk;
+	snd_pcm_runtime_t *runtime = substream->runtime;
 	int idx, page;
-	struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, _snd_pcm_substream_sgbuf(substream), return NULL);
+	struct snd_sg_buf *sgbuf = runtime->dma_private;
 
-	snd_assert(trident != NULL, return NULL);
-	snd_assert(sgbuf->size > 0 && sgbuf->size < SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
+	snd_assert(substream->dma_device.type == SNDRV_DMA_TYPE_PCI_SG, return NULL);
+	snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
 	hdr = trident->tlb.memhdr;
 	snd_assert(hdr != NULL, return NULL);
 
+	
+
 	down(&hdr->block_mutex);
-	blk = search_empty(hdr, sgbuf->size);
+	blk = search_empty(hdr, runtime->dma_bytes);
 	if (blk == NULL) {
 		up(&hdr->block_mutex);
 		return NULL;
@@ -223,6 +225,61 @@
 	}
 	up(&hdr->block_mutex);
 	return blk;
+}
+
+/*
+ * page allocation for DMA (contiguous version)
+ */
+static snd_util_memblk_t *
+snd_trident_alloc_cont_pages(trident_t *trident, snd_pcm_substream_t *substream)
+{
+	snd_util_memhdr_t *hdr;
+	snd_util_memblk_t *blk;
+	int page;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	dma_addr_t addr;
+	unsigned long ptr;
+
+	snd_assert(substream->dma_device.type == SNDRV_DMA_TYPE_PCI, return NULL);
+	snd_assert(runtime->dma_bytes> 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
+	hdr = trident->tlb.memhdr;
+	snd_assert(hdr != NULL, return NULL);
+
+	down(&hdr->block_mutex);
+	blk = search_empty(hdr, runtime->dma_bytes);
+	if (blk == NULL) {
+		up(&hdr->block_mutex);
+		return NULL;
+	}
+			   
+	/* set TLB entries */
+	addr = runtime->dma_addr;
+	ptr = (unsigned long)runtime->dma_area;
+	for (page = firstpg(blk); page <= lastpg(blk); page++,
+	     ptr += SNDRV_TRIDENT_PAGE_SIZE, addr += SNDRV_TRIDENT_PAGE_SIZE) {
+		if (! is_valid_page(addr)) {
+			__snd_util_mem_free(hdr, blk);
+			up(&hdr->block_mutex);
+			return NULL;
+		}
+		set_tlb_bus(trident, page, ptr, addr);
+	}
+	up(&hdr->block_mutex);
+	return blk;
+}
+
+/*
+ * page allocation for DMA
+ */
+snd_util_memblk_t *
+snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream)
+{
+	snd_assert(trident != NULL, return NULL);
+	snd_assert(substream != NULL, return NULL);
+	if (substream->dma_device.type == SNDRV_DMA_TYPE_PCI_SG)
+		return snd_trident_alloc_sg_pages(trident, substream);
+	else
+		return snd_trident_alloc_cont_pages(trident, substream);
 }
 
 
diff -Nru a/sound/pci/trident/trident_synth.c b/sound/pci/trident/trident_synth.c
--- a/sound/pci/trident/trident_synth.c	Sat Feb  8 12:10:56 2003
+++ b/sound/pci/trident/trident_synth.c	Thu Mar 20 08:41:15 2003
@@ -600,7 +600,7 @@
 		size <<= 1;
 
 	trident->synth.current_size -= size;
-	if (trident->synth.current_size < 0)	/* shouldnt need this check... */
+	if (trident->synth.current_size < 0)	/* shouldn't need this check... */
 		trident->synth.current_size = 0;
 
 	return 0;
@@ -909,7 +909,7 @@
 						   SNDRV_SEQ_PORT_TYPE_MIDI_GS |
 						   SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE |
 						   SNDRV_SEQ_PORT_TYPE_SYNTH,
-						   16,
+						   16, 0,
 						   name);
 	if (p->chset->port < 0) {
 		result = p->chset->port;
diff -Nru a/sound/pci/via82xx.c b/sound/pci/via82xx.c
--- a/sound/pci/via82xx.c	Tue Feb 18 10:38:27 2003
+++ b/sound/pci/via82xx.c	Thu Mar 20 08:41:15 2003
@@ -52,7 +52,6 @@
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
-#include <sound/pcm_sgbuf.h>
 #include <sound/pcm_params.h>
 #include <sound/info.h>
 #include <sound/ac97_codec.h>
@@ -599,12 +598,12 @@
 		status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG);
 		if (! status)
 			continue;
-		outb(status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
 		if (viadev->substream && viadev->running) {
 			spin_unlock(&chip->reg_lock);
 			snd_pcm_period_elapsed(viadev->substream);
 			spin_lock(&chip->reg_lock);
 		}
+		outb(status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
 	}
 	spin_unlock(&chip->reg_lock);
 }
@@ -820,6 +819,7 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
 	snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
+	snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate);
 	via686_setup_format(chip, viadev, runtime);
 	return 0;
 }
@@ -912,15 +912,15 @@
 	fmt = (runtime->format == SNDRV_PCM_FORMAT_S16_LE) ? VIA_REG_MULTPLAY_FMT_16BIT : VIA_REG_MULTPLAY_FMT_8BIT;
 	fmt |= runtime->channels << 4;
 	outb(fmt, VIADEV_REG(viadev, OFS_MULTPLAY_FORMAT));
-	/* set sample number to slot 3, 4, 7, 8, 6, 9 */
+	/* set sample number to slot 3, 4, 7, 8, 6, 9 (for VIA8233/C,8235) */
 	/* corresponding to FL, FR, RL, RR, C, LFE ?? */
 	switch (runtime->channels) {
 	case 1: slots = (1<<0) | (1<<4); break;
 	case 2: slots = (1<<0) | (2<<4); break;
 	case 3: slots = (1<<0) | (2<<4) | (5<<8); break;
 	case 4: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12); break;
-	case 5: slots = (1<<0) | (2<<4) | (5<<8) | (3<<12) | (4<<16); break;
-	case 6: slots = (1<<0) | (2<<4) | (5<<8) | (6<<12) | (3<<16) | (4<<20); break;
+	case 5: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12) | (5<<16); break;
+	case 6: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12) | (5<<16) | (6<<20); break;
 	default: slots = 0; break;
 	}
 	/* STOP index is never reached */
@@ -1438,7 +1438,7 @@
 }
 
 static struct ac97_quirk ac97_quirks[] = {
-	{ 0x1106, 0x4161, AC97_TUNE_HP_ONLY }, /* ASRock K7VT2 */
+	{ 0x1106, 0x4161, "ASRock K7VT2", AC97_TUNE_HP_ONLY },
 	{ } /* terminator */
 };
 
@@ -1457,7 +1457,7 @@
 	if ((err = snd_ac97_mixer(chip->card, &ac97, &chip->ac97)) < 0)
 		return err;
 
-	snd_ac97_tune_hardware(&chip->ac97, chip->pci, ac97_quirks);
+	snd_ac97_tune_hardware(chip->ac97, chip->pci, ac97_quirks);
 
 	if (chip->chip_type != TYPE_VIA686) {
 		/* use slot 10/11 */
diff -Nru a/sound/sound_core.c b/sound/sound_core.c
--- a/sound/sound_core.c	Tue Feb 25 02:52:02 2003
+++ b/sound/sound_core.c	Sat Mar 22 07:38:05 2003
@@ -567,7 +567,7 @@
 		printk(KERN_ERR "soundcore: sound device already in use.\n");
 		return -EBUSY;
 	}
-	devfs_mk_dir (NULL, "sound", NULL);
+	devfs_mk_dir ("sound");
 
 	return 0;
 }
diff -Nru a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c
--- a/sound/synth/emux/emux_seq.c	Sat Feb  8 12:10:56 2003
+++ b/sound/synth/emux/emux_seq.c	Thu Mar 20 08:41:15 2003
@@ -176,7 +176,8 @@
 	}
 
 	p->chset.port = snd_seq_event_port_attach(emu->client, callback,
-						  cap, type, max_channels, name);
+						  cap, type, max_channels,
+						  emu->max_voices, name);
 
 	return p;
 }
diff -Nru a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
--- a/sound/usb/usbaudio.c	Mon Feb 24 09:56:55 2003
+++ b/sound/usb/usbaudio.c	Thu Mar 20 08:41:15 2003
@@ -584,14 +584,14 @@
  * unlink active urbs.
  * return the number of active urbs.
  */
-static int deactivate_urbs(snd_usb_substream_t *subs)
+static int deactivate_urbs(snd_usb_substream_t *subs, int force)
 {
 	unsigned int i;
 	int alive;
 
 	subs->running = 0;
 
-	if (subs->stream->chip->shutdown) /* to be sure... */
+	if (!force && subs->stream->chip->shutdown) /* to be sure... */
 		return 0;
 
 #ifndef SND_USB_ASYNC_UNLINK
@@ -669,7 +669,7 @@
 
  __error:
 	// snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
-	deactivate_urbs(subs);
+	deactivate_urbs(subs, 0);
 	return -EPIPE;
 }
 
@@ -730,7 +730,7 @@
 		err = start_urbs(subs, substream->runtime);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
-		err = deactivate_urbs(subs);
+		err = deactivate_urbs(subs, 0);
 		break;
 	default:
 		err = -EINVAL;
@@ -758,12 +758,12 @@
 /*
  * release a substream
  */
-static void release_substream_urbs(snd_usb_substream_t *subs)
+static void release_substream_urbs(snd_usb_substream_t *subs, int force)
 {
 	int i;
 
 	/* stop urbs (to be sure) */
-	if (deactivate_urbs(subs) > 0)
+	if (deactivate_urbs(subs, force) > 0)
 		wait_clear_urbs(subs);
 
 	for (i = 0; i < MAX_URBS; i++)
@@ -869,13 +869,13 @@
 			/* allocate a capture buffer per urb */
 			u->buf = kmalloc(maxsize * u->packets, GFP_KERNEL);
 			if (! u->buf) {
-				release_substream_urbs(subs);
+				release_substream_urbs(subs, 0);
 				return -ENOMEM;
 			}
 		}
 		u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
 		if (! u->urb) {
-			release_substream_urbs(subs);
+			release_substream_urbs(subs, 0);
 			return -ENOMEM;
 		}
 		u->urb->dev = subs->dev;
@@ -895,7 +895,7 @@
 			u->packets = NRPACKS;
 			u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
 			if (! u->urb) {
-				release_substream_urbs(subs);
+				release_substream_urbs(subs, 0);
 				return -ENOMEM;
 			}
 			u->urb->transfer_buffer = subs->syncbuf + i * NRPACKS * 3;
@@ -1051,7 +1051,7 @@
 	}
 
 	/* create a data pipe */
-	ep = get_endpoint(alts, 0)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+	ep = fmt->endpoint & USB_ENDPOINT_NUMBER_MASK;
 	if (is_playback)
 		subs->datapipe = usb_sndisocpipe(dev, ep);
 	else
@@ -1062,9 +1062,16 @@
 	subs->fill_max = 0;
 
 	/* we need a sync pipe in async OUT or adaptive IN mode */
-	attr = get_endpoint(alts, 0)->bmAttributes & EP_ATTR_MASK;
+	attr = fmt->ep_attr & EP_ATTR_MASK;
 	if ((is_playback && attr == EP_ATTR_ASYNC) ||
 	    (! is_playback && attr == EP_ATTR_ADAPTIVE)) {
+		/*
+		 * QUIRK: plantronics headset has adaptive-in
+		 * although it's really not...
+		 */
+		if (dev->descriptor.idVendor == 0x047f &&
+		    dev->descriptor.idProduct == 0x0ca1)
+			goto _ok;
 		/* check endpoint */
 		if (altsd->bNumEndpoints < 2 ||
 		    get_endpoint(alts, 1)->bmAttributes != 0x01 ||
@@ -1088,6 +1095,7 @@
 		subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
 	}
 
+ _ok:
 	if ((err = init_usb_pitch(dev, subs->interface, alts, fmt)) < 0 ||
 	    (err = init_usb_sample_rate(dev, subs->interface, alts, fmt,
 					runtime->rate)) < 0)
@@ -1140,7 +1148,7 @@
 	snd_usb_substream_t *subs = (snd_usb_substream_t *)runtime->private_data;
 	int err;
 
-	release_substream_urbs(subs);
+	release_substream_urbs(subs, 0);
 	if ((err = set_format(subs, runtime)) < 0)
 		return err;
 
@@ -1189,7 +1197,7 @@
 
 	/* check the format */
 	if (! snd_mask_test(fmts, fp->format)) {
-		printk(KERN_DEBUG "   > check: no supported format %d\n", fp->format);
+		hwc_debug("   > check: no supported format %d\n", fp->format);
 		return 0;
 	}
 	/* check the channels */
@@ -1477,7 +1485,7 @@
 	snd_usb_stream_t *as = snd_pcm_substream_chip(substream);
 	snd_usb_substream_t *subs = &as->substream[direction];
 
-	release_substream_urbs(subs);
+	release_substream_urbs(subs, 0);
 	if (subs->interface >= 0)
 		usb_set_interface(subs->dev, subs->interface, 0);
 	subs->pcm_substream = NULL;
@@ -1548,15 +1556,11 @@
 
 /*
  * parse descriptor buffer and return the pointer starting the given
- * descriptor type and interface.
- * if altsetting is not -1, seek the buffer until the matching alternate
- * setting is found.
+ * descriptor type.
  */
-void *snd_usb_find_desc(void *descstart, int desclen, void *after, 
-			u8 dtype, int iface, int altsetting)
+void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype)
 {
 	u8 *p, *end, *next;
-	int ifc = -1, as = -1;
 
 	p = descstart;
 	end = p + desclen;
@@ -1566,15 +1570,7 @@
 		next = p + p[0];
 		if (next > end)
 			return NULL;
-		if (p[1] == USB_DT_INTERFACE) {
-			/* minimum length of interface descriptor */
-			if (p[0] < 9)
-				return NULL;
-			ifc = p[2];
-			as = p[3];
-		}
-		if (p[1] == dtype && (!after || (void *)p > after) &&
-		    (iface == -1 || iface == ifc) && (altsetting == -1 || altsetting == as)) {
+		if (p[1] == dtype && (!after || (void *)p > after)) {
 			return p;
 		}
 		p = next;
@@ -1585,12 +1581,12 @@
 /*
  * find a class-specified interface descriptor with the given subtype.
  */
-void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype, int iface, int altsetting)
+void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype)
 {
 	unsigned char *p = after;
 
 	while ((p = snd_usb_find_desc(buffer, buflen, p,
-				      USB_DT_CS_INTERFACE, iface, altsetting)) != NULL) {
+				      USB_DT_CS_INTERFACE)) != NULL) {
 		if (p[0] >= 3 && p[2] == dsubtype)
 			return p;
 	}
@@ -1651,7 +1647,7 @@
 			    fp->endpoint & USB_DIR_IN ? "IN" : "OUT",
 			    sync_types[(fp->ep_attr & EP_ATTR_MASK) >> 2]);
 		if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
-			snd_iprintf(buffer, "    Rates: %d - %d (continous)\n",
+			snd_iprintf(buffer, "    Rates: %d - %d (continuous)\n",
 				    fp->rate_min, fp->rate_max);
 		} else {
 			unsigned int i;
@@ -1942,7 +1938,7 @@
 }
 
 
-static int parse_audio_endpoints(snd_usb_audio_t *chip, unsigned char *buffer, int buflen, int iface_no)
+static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no)
 {
 	struct usb_device *dev;
 	struct usb_host_config *config;
@@ -1963,7 +1959,8 @@
 		alts = &iface->altsetting[i];
 		altsd = get_iface_desc(alts);
 		/* skip invalid one */
-		if (altsd->bInterfaceClass != USB_CLASS_AUDIO ||
+		if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
+		     altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
 		    altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING ||
 		    altsd->bNumEndpoints < 1)
 			continue;
@@ -1977,7 +1974,7 @@
 		altno = altsd->bAlternateSetting;
 
 		/* get audio formats */
-		fmt = snd_usb_find_csint_desc(buffer, buflen, NULL, AS_GENERAL, iface_no, altno);
+		fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL);
 		if (!fmt) {
 			snd_printk(KERN_ERR "%d:%u:%d : AS_GENERAL descriptor not found\n",
 				   dev->devnum, iface_no, altno);
@@ -1993,7 +1990,7 @@
 		format = (fmt[6] << 8) | fmt[5]; /* remember the format value */
 			
 		/* get format type */
-		fmt = snd_usb_find_csint_desc(buffer, buflen, NULL, FORMAT_TYPE, iface_no, altno);
+		fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, FORMAT_TYPE);
 		if (!fmt) {
 			snd_printk(KERN_ERR "%d:%u:%d : no FORMAT_TYPE desc\n", 
 				   dev->devnum, iface_no, altno);
@@ -2023,7 +2020,7 @@
 			continue;
 		}
 
-		csep = snd_usb_find_desc(buffer, buflen, NULL, USB_DT_CS_ENDPOINT, iface_no, altno);
+		csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
 		if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) {
 			snd_printk(KERN_ERR "%d:%u:%d : no or invalid class specific endpoint descriptor\n", 
 				   dev->devnum, iface_no, altno);
@@ -2111,17 +2108,19 @@
 /*
  * parse audio control descriptor and create pcm/midi streams
  */
-static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif,
-				  unsigned char *buffer, int buflen)
+static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif)
 {
 	struct usb_device *dev = chip->dev;
 	struct usb_host_config *config;
+	struct usb_host_interface *host_iface;
 	struct usb_interface *iface;
 	unsigned char *p1;
 	int i, j;
 
 	/* find audiocontrol interface */
-	if (!(p1 = snd_usb_find_csint_desc(buffer, buflen, NULL, HEADER, ctrlif, -1))) {
+	config = dev->actconfig;
+	host_iface = &config->interface[ctrlif].altsetting[0];
+	if (!(p1 = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen, NULL, HEADER))) {
 		snd_printk(KERN_ERR "cannot find HEADER\n");
 		return -EINVAL;
 	}
@@ -2133,7 +2132,6 @@
 	/*
 	 * parse all USB audio streaming interfaces
 	 */
-	config = dev->actconfig;
 	for (i = 0; i < p1[7]; i++) {
 		struct usb_host_interface *alts;
 		struct usb_interface_descriptor *altsd;
@@ -2150,7 +2148,8 @@
 		}
 		alts = &iface->altsetting[0];
 		altsd = get_iface_desc(alts);
-		if (altsd->bInterfaceClass == USB_CLASS_AUDIO &&
+		if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
+		     altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
 		    altsd->bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) {
 			if (snd_usb_create_midi_interface(chip, iface, NULL) < 0) {
 				snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", dev->devnum, ctrlif, j);
@@ -2159,13 +2158,14 @@
 			usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
 			continue;
 		}
-		if (altsd->bInterfaceClass != USB_CLASS_AUDIO ||
+		if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
+		     altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
 		    altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) {
 			snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", dev->devnum, ctrlif, j, altsd->bInterfaceClass);
 			/* skip non-supported classes */
 			continue;
 		}
-		if (! parse_audio_endpoints(chip, buffer, buflen, j)) {
+		if (! parse_audio_endpoints(chip, j)) {
 			usb_set_interface(dev, j, 0); /* reset the current interface */
 			usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
 		}
@@ -2205,6 +2205,40 @@
 	return 0;
 }
 
+/*
+ * create a stream for an interface with proper descriptors
+ */
+static int create_standard_interface_quirk(snd_usb_audio_t *chip,
+					   struct usb_interface *iface)
+{
+	struct usb_host_interface *alts;
+	struct usb_interface_descriptor *altsd;
+	int err;
+
+	alts = &iface->altsetting[0];
+	altsd = get_iface_desc(alts);
+	switch (altsd->bInterfaceSubClass) {
+	case USB_SUBCLASS_AUDIO_STREAMING:
+		err = parse_audio_endpoints(chip, altsd->bInterfaceNumber);
+		if (!err)
+			usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0); /* reset the current interface */
+		break;
+	case USB_SUBCLASS_MIDI_STREAMING:
+		err = snd_usb_create_midi_interface(chip, iface, NULL);
+		break;
+	default:
+		snd_printk(KERN_ERR "if %d: non-supported subclass %d\n",
+			   altsd->bInterfaceNumber, altsd->bInterfaceSubClass);
+		return -ENODEV;
+	}
+	if (err < 0) {
+		snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
+			   altsd->bInterfaceNumber, err);
+		return err;
+	}
+	return 0;
+}
+
 static int snd_usb_create_quirk(snd_usb_audio_t *chip,
 				struct usb_interface *iface,
 				const snd_usb_audio_quirk_t *quirk);
@@ -2288,6 +2322,8 @@
 		return create_composite_quirk(chip, iface, quirk);
 	case QUIRK_AUDIO_FIXED_ENDPOINT:
 		return create_fixed_stream_quirk(chip, iface, quirk);
+	case QUIRK_STANDARD_INTERFACE:
+		return create_standard_interface_quirk(chip, iface);
 	default:
 		snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
 		return -ENXIO;
@@ -2405,42 +2441,6 @@
 
 
 /*
- * allocate and get description buffer
- * must be freed later.
- */
-static int alloc_desc_buffer(struct usb_device *dev, int index, unsigned char **bufptr)
-{
-	int err, buflen;
-	unsigned char buf[8];
-	unsigned char *buffer;
-
-	*bufptr = 0;
-	err = usb_get_descriptor(dev, USB_DT_CONFIG, index, buf, 8);
-	if (err < 0) {
-		snd_printk(KERN_ERR "%d:%d: cannot get first 8 bytes\n", index, dev->devnum);
-		return err;
-	}
-	if (buf[1] != USB_DT_CONFIG || buf[0] < 9) {
-		snd_printk(KERN_ERR "%d:%d: invalid config desc\n", index, dev->devnum);
-		return -EINVAL;
-	}
-	buflen = combine_word(&buf[2]);
-	if (!(buffer = kmalloc(buflen, GFP_KERNEL))) {
-		snd_printk(KERN_ERR "cannot malloc descriptor (size = %d)\n", buflen);
-		return -ENOMEM;
-	}
-	err = usb_get_descriptor(dev, USB_DT_CONFIG, index, buffer, buflen);
-	if (err < 0) {
-		snd_printk(KERN_ERR "%d:%d: cannot get DT_CONFIG: error %d\n", index, dev->devnum, err);
-		kfree(buffer);
-		return err;
-	}
-	*bufptr = buffer;
-	return buflen;
-}
-
-
-/*
  * probe the active usb device
  *
  * note that this can be called multiple times per a device, when it
@@ -2532,20 +2532,10 @@
 
 	if (err > 0) {
 		/* create normal USB audio interfaces */
-		unsigned char *buffer;
-		unsigned int index;
-		int buflen;
-
-		index = dev->actconfig - config;
-		buflen = alloc_desc_buffer(dev, index, &buffer);
-		if (buflen <= 0)
-			goto __error;
-		if (snd_usb_create_streams(chip, ifnum, buffer, buflen) < 0 ||
-		    snd_usb_create_mixer(chip, ifnum, buffer, buflen) < 0) {
-			kfree(buffer);
+		if (snd_usb_create_streams(chip, ifnum) < 0 ||
+		    snd_usb_create_mixer(chip, ifnum) < 0) {
 			goto __error;
 		}
-		kfree(buffer);
 	}
 
 	/* we are allowed to call snd_card_register() many times */
@@ -2595,7 +2585,8 @@
 				subs = &as->substream[idx];
 				if (!subs->num_formats)
 					continue;
-				release_substream_urbs(subs);
+				release_substream_urbs(subs, 1);
+				subs->interface = -1;
 			}
 		}
 		/* release the midi resources */
diff -Nru a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
--- a/sound/usb/usbaudio.h	Sun Feb 16 05:47:44 2003
+++ b/sound/usb/usbaudio.h	Thu Mar 20 08:41:15 2003
@@ -146,6 +146,7 @@
 /*
  * Information about devices with broken descriptors
  */
+
 #define QUIRK_ANY_INTERFACE -1
 
 #define QUIRK_MIDI_FIXED_ENDPOINT	0
@@ -153,6 +154,7 @@
 #define QUIRK_MIDI_MIDIMAN		2
 #define QUIRK_COMPOSITE			3
 #define QUIRK_AUDIO_FIXED_ENDPOINT	4
+#define QUIRK_STANDARD_INTERFACE	5
 
 #define QUIRK_BOOT_MASK			0x80
 #define QUIRK_BOOT_EXTIGY		(QUIRK_BOOT_MASK | 0)
@@ -185,6 +187,8 @@
 
 /* for QUIRK_AUDIO_FIXED_ENDPOINT, data points to an audioformat structure */
 
+/* for QUIRK_STANDARD_INTERFACE, data is NULL */
+
 /*
  */
 
@@ -194,10 +198,10 @@
 
 unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size);
 
-void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype, int iface, int altsetting);
-void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsubtype, int iface, int altsetting);
+void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype);
+void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsubtype);
 
-int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif, unsigned char *buffer, int buflen);
+int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif);
 
 int snd_usb_create_midi_interface(snd_usb_audio_t *chip, struct usb_interface *iface, const snd_usb_audio_quirk_t *quirk);
 void snd_usbmidi_disconnect(struct list_head *p);
diff -Nru a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
--- a/sound/usb/usbmidi.c	Sat Feb  8 12:10:57 2003
+++ b/sound/usb/usbmidi.c	Thu Mar 20 08:41:15 2003
@@ -131,7 +131,7 @@
 {
 	int err = usb_submit_urb(urb, flags);
 	if (err < 0 && err != -ENODEV)
-		printk(KERN_ERR "snd-usb-midi: usb_submit_urb: %d\n", err);
+		snd_printk(KERN_ERR "usb_submit_urb: %d\n", err);
 	return err;
 }
 
@@ -146,7 +146,7 @@
 	    status == -EILSEQ ||
 	    status == -ETIMEDOUT)
 		return -ENODEV; /* device removed */
-	printk(KERN_ERR "snd-usb-midi: urb status %d\n", status);
+	snd_printk(KERN_ERR "urb status %d\n", status);
 	return 0; /* continue */
 }
 
@@ -435,8 +435,10 @@
 					port = &umidi->endpoints[i].out->ports[j];
 					break;
 				}
-	if (!port)
+	if (!port) {
+		snd_BUG();
 		return -ENXIO;
+	}
 	substream->runtime->private_data = port;
 	port->state = STATE_UNKNOWN;
 	return 0;
@@ -526,6 +528,8 @@
 	    (get_endpoint(hostif, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
 		return NULL;
 
+	snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n",
+		    intfd->bAlternateSetting);
 	usb_set_interface(umidi->chip->dev, intfd->bInterfaceNumber,
 			  intfd->bAlternateSetting);
 	return get_endpoint(hostif, 1);
@@ -774,8 +778,8 @@
 			}
 		}
 	}
-	printk(KERN_INFO "snd-usb-midi: created %d output and %d input ports\n",
-	       out_ports, in_ports);
+	snd_printdd(KERN_INFO "created %d output and %d input ports\n",
+		    out_ports, in_ports);
 	return 0;
 }
 
@@ -804,10 +808,10 @@
 	    ms_header->bLength >= 7 &&
 	    ms_header->bDescriptorType == USB_DT_CS_INTERFACE &&
 	    ms_header->bDescriptorSubtype == HEADER)
-		printk(KERN_INFO "snd-usb-midi: MIDIStreaming version %02x.%02x\n",
-		       ms_header->bcdMSC[1], ms_header->bcdMSC[0]);
+		snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n",
+			    ms_header->bcdMSC[1], ms_header->bcdMSC[0]);
 	else
-		printk(KERN_WARNING "snd-usb-midi: MIDIStreaming interface descriptor not found\n");
+		snd_printk(KERN_WARNING "MIDIStreaming interface descriptor not found\n");
 
 	epidx = 0;
 	for (i = 0; i < intfd->bNumEndpoints; ++i) {
@@ -824,25 +828,25 @@
 		if ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
 			if (endpoints[epidx].out_ep) {
 				if (++epidx >= MIDI_MAX_ENDPOINTS) {
-					printk(KERN_WARNING "snd-usb-midi: too many endpoints\n");
+					snd_printk(KERN_WARNING "too many endpoints\n");
 					break;
 				}
 			}
 			endpoints[epidx].out_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 			endpoints[epidx].out_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
-			printk(KERN_INFO "snd-usb-midi: EP %02X: %d jack(s)\n",
-			       ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
+			snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n",
+				    ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
 		} else {
 			if (endpoints[epidx].in_ep) {
 				if (++epidx >= MIDI_MAX_ENDPOINTS) {
-					printk(KERN_WARNING "snd-usb-midi: too many endpoints\n");
+					snd_printk(KERN_WARNING "too many endpoints\n");
 					break;
 				}
 			}
 			endpoints[epidx].in_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 			endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
-			printk(KERN_INFO "snd-usb-midi: EP %02X: %d jack(s)\n",
-			       ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
+			snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n",
+				    ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
 		}
 	}
 	return 0;
diff -Nru a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
--- a/sound/usb/usbmixer.c	Sat Feb  8 12:10:57 2003
+++ b/sound/usb/usbmixer.c	Thu Mar 20 08:41:15 2003
@@ -182,7 +182,7 @@
 
 	p = NULL;
 	while ((p = snd_usb_find_desc(state->buffer, state->buflen, p,
-				      USB_DT_CS_INTERFACE, state->ctrlif, -1)) != NULL) {
+				      USB_DT_CS_INTERFACE)) != NULL) {
 		if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT && p[3] == unit)
 			return p;
 	}
@@ -1462,20 +1462,21 @@
  *
  * walk through all OUTPUT_TERMINAL descriptors to search for mixers
  */
-int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif, unsigned char *buffer, int buflen)
+int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif)
 {
 	unsigned char *desc;
 	mixer_build_t state;
 	int err;
 	const struct usbmix_ctl_map *map;
 	struct usb_device_descriptor *dev = &chip->dev->descriptor;
+	struct usb_host_interface *hostif = &chip->dev->actconfig->interface[ctrlif].altsetting[0];
 
 	strcpy(chip->card->mixername, "USB Mixer");
 
 	memset(&state, 0, sizeof(state));
 	state.chip = chip;
-	state.buffer = buffer;
-	state.buflen = buflen;
+	state.buffer = hostif->extra;
+	state.buflen = hostif->extralen;
 	state.ctrlif = ctrlif;
 	state.vendor = dev->idVendor;
 	state.product = dev->idProduct;
@@ -1489,7 +1490,7 @@
 	}
 
 	desc = NULL;
-	while ((desc = snd_usb_find_csint_desc(buffer, buflen, desc, OUTPUT_TERMINAL, ctrlif, -1)) != NULL) {
+	while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, OUTPUT_TERMINAL)) != NULL) {
 		if (desc[0] < 9)
 			continue; /* invalid descriptor? */
 		set_bit(desc[3], state.unitbitmap);  /* mark terminal ID as visited */
diff -Nru a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
--- a/sound/usb/usbquirks.h	Sun Feb 16 05:47:44 2003
+++ b/sound/usb/usbquirks.h	Thu Mar 20 08:41:15 2003
@@ -26,6 +26,11 @@
  * In a perfect world, this file would be empty.
  */
 
+/*
+ * Use this for devices where other interfaces are standard compliant,
+ * to prevent the quirk being applied to those interfaces. (To work with
+ * hotplugging, bDeviceClass must be set to USB_CLASS_PER_INTERFACE.)
+ */
 #define USB_DEVICE_VENDOR_SPEC(vend, prod) \
 	.match_flags = USB_DEVICE_ID_MATCH_VENDOR | \
 		       USB_DEVICE_ID_MATCH_PRODUCT | \
@@ -226,16 +231,10 @@
 },
 
 /*
- * Once upon a time people thought, "Wouldn't it be nice if there was a
- * standard for USB MIDI devices, so that device drivers would not be forced
- * to know about the quirks of specific devices?"  So Roland went ahead and
- * wrote the USB Device Class Definition for MIDI Devices, and the USB-IF
- * endorsed it, and now everybody designing USB MIDI devices does so in
- * agreement with this standard (or at least tries to).
+ * Roland/RolandED/Edirol devices
  *
- * And if you prefer a happy end, you can imagine that Roland devices set a
- * good example. Instead of being completely fucked up due to the lack of
- * class-specific descriptors.
+ * The USB MIDI Specification has been written by Roland,
+ * but a 100% conforming Roland device has yet to be found.
  */
 {
 	USB_DEVICE(0x0582, 0x0000),
@@ -507,15 +506,33 @@
 	}
 },
 {
-	USB_DEVICE_VENDOR_SPEC(0x0582, 0x0025),
+	/*
+	 * This quirk is for the "Advanced Driver" mode. If off, the UA-20
+	 * has ID 0x0026 and is standard compliant, but has only 16-bit PCM
+	 * and no MIDI.
+	 */
+	USB_DEVICE(0x0582, 0x0025),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
 		.product_name = "UA-20",
-		.ifnum = 3,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.out_cables = 0x0001,
-			.in_cables  = 0x0001
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = & (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 1,
+				.type = QUIRK_STANDARD_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_STANDARD_INTERFACE
+			},
+			{
+				.ifnum = 3,
+				.type = QUIRK_STANDARD_INTERFACE
+			},
+			{
+				.ifnum = -1
+			}
 		}
 	}
 },
@@ -639,6 +656,24 @@
 	}
 },
 {
+	/*
+	 * For hardware revision 1.05; in the later revisions (1.10 and
+	 * 1.21), 0x1031 is the ID for the device without firmware.
+	 * Thanks to Olaf Giesbrecht <Olaf_Giesbrecht@yahoo.de>
+	 */
+	USB_DEVICE_VER(0x0763, 0x1031, 0x0100, 0x0109),
+	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+		.vendor_name = "M-Audio",
+		.product_name = "MidiSport 8x8",
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_MIDI_MIDIMAN,
+		.data = & (const snd_usb_midi_endpoint_info_t) {
+			.out_cables = 0x01ff,
+			.in_cables  = 0x01ff
+		}
+	}
+},
+{
 	USB_DEVICE_VENDOR_SPEC(0x0763, 0x1033),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "M-Audio",
@@ -687,6 +722,22 @@
 		.data = & (const snd_usb_midi_endpoint_info_t) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
+		}
+	}
+},
+
+/* Mark of the Unicorn devices */
+{
+	/* thanks to Woodley Packard <sweaglesw@thibs.menloschool.org> */
+	USB_DEVICE(0x07fd, 0x0001),
+	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+		.vendor_name = "MOTU",
+		.product_name = "Fastlane",
+		.ifnum = 1,
+		.type = QUIRK_MIDI_FIXED_ENDPOINT,
+		.data = & (const snd_usb_midi_endpoint_info_t) {
+			.out_cables = 0x0003,
+			.in_cables  = 0x0003
 		}
 	}
 },
